Skip to content

Move error_number and sql_state into Mysql2::Error initializer #545

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 10, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions ext/mysql2/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
VALUE cMysql2Client;
extern VALUE mMysql2, cMysql2Error;
static VALUE sym_id, sym_version, sym_header_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream;
static ID intern_merge, intern_merge_bang, intern_error_number_eql, intern_sql_state_eql;
static ID intern_brackets, intern_new;
static ID intern_brackets, intern_new, intern_merge, intern_merge_bang, intern_new_with_args;

#ifndef HAVE_RB_HASH_DUP
VALUE rb_hash_dup(VALUE other) {
Expand Down Expand Up @@ -124,9 +123,11 @@ static VALUE rb_raise_mysql2_error(mysql_client_wrapper *wrapper) {
rb_enc_associate(rb_sql_state, rb_usascii_encoding());
#endif

e = rb_funcall(cMysql2Error, intern_new, 2, rb_error_msg, LONG2FIX(wrapper->server_version));
rb_funcall(e, intern_error_number_eql, 1, UINT2NUM(mysql_errno(wrapper->client)));
rb_funcall(e, intern_sql_state_eql, 1, rb_sql_state);
e = rb_funcall(cMysql2Error, intern_new_with_args, 4,
rb_error_msg,
LONG2FIX(wrapper->server_version),
UINT2NUM(mysql_errno(wrapper->client)),
rb_sql_state);
rb_exc_raise(e);
return Qnil;
}
Expand Down Expand Up @@ -1301,8 +1302,7 @@ void init_mysql2_client() {
intern_new = rb_intern("new");
intern_merge = rb_intern("merge");
intern_merge_bang = rb_intern("merge!");
intern_error_number_eql = rb_intern("error_number=");
intern_sql_state_eql = rb_intern("sql_state=");
intern_new_with_args = rb_intern("new_with_args");

#ifdef CLIENT_LONG_PASSWORD
rb_const_set(cMysql2Client, rb_intern("LONG_PASSWORD"),
Expand Down
12 changes: 2 additions & 10 deletions ext/mysql2/result.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,11 +357,7 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co
}

if (mysql_stmt_bind_result(wrapper->stmt_wrapper->stmt, wrapper->result_buffers)) {
rb_raise_mysql2_stmt_error2(wrapper->stmt_wrapper->stmt
#ifdef HAVE_RUBY_ENCODING_H
, conn_enc
#endif
);
rb_raise_mysql2_stmt_error(wrapper->stmt_wrapper);
}

{
Expand All @@ -372,11 +368,7 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co

case 1:
/* error */
rb_raise_mysql2_stmt_error2(wrapper->stmt_wrapper->stmt
#ifdef HAVE_RUBY_ENCODING_H
, conn_enc
#endif
);
rb_raise_mysql2_stmt_error(wrapper->stmt_wrapper);

case MYSQL_NO_DATA:
/* no more row */
Expand Down
62 changes: 23 additions & 39 deletions ext/mysql2/statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

VALUE cMysql2Statement;
extern VALUE mMysql2, cMysql2Error, cBigDecimal, cDateTime, cDate;
static VALUE sym_stream, intern_error_number_eql, intern_sql_state_eql, intern_each;
static VALUE sym_stream, intern_new_with_args, intern_each;
static VALUE intern_usec, intern_sec, intern_min, intern_hour, intern_day, intern_month, intern_year;

#define GET_STATEMENT(self) \
Expand Down Expand Up @@ -31,15 +31,17 @@ void decr_mysql2_stmt(mysql_stmt_wrapper *stmt_wrapper) {
}
}

VALUE rb_raise_mysql2_stmt_error2(MYSQL_STMT *stmt
#ifdef HAVE_RUBY_ENCODING_H
, rb_encoding *conn_enc
#endif
) {
VALUE rb_error_msg = rb_str_new2(mysql_stmt_error(stmt));
VALUE rb_sql_state = rb_tainted_str_new2(mysql_stmt_sqlstate(stmt));
VALUE e = rb_exc_new3(cMysql2Error, rb_error_msg);

void rb_raise_mysql2_stmt_error(mysql_stmt_wrapper *stmt_wrapper) {
VALUE e;
GET_CLIENT(stmt_wrapper->client);
VALUE rb_error_msg = rb_str_new2(mysql_stmt_error(stmt_wrapper->stmt));
VALUE rb_sql_state = rb_tainted_str_new2(mysql_stmt_sqlstate(stmt_wrapper->stmt));

#ifdef HAVE_RUBY_ENCODING_H
rb_encoding *conn_enc;
conn_enc = rb_to_encoding(wrapper->encoding);

rb_encoding *default_internal_enc = rb_default_internal_encoding();

rb_enc_associate(rb_error_msg, conn_enc);
Expand All @@ -49,30 +51,13 @@ VALUE rb_raise_mysql2_stmt_error2(MYSQL_STMT *stmt
rb_sql_state = rb_str_export_to_enc(rb_sql_state, default_internal_enc);
}
#endif
rb_funcall(e, intern_error_number_eql, 1, UINT2NUM(mysql_stmt_errno(stmt)));
rb_funcall(e, intern_sql_state_eql, 1, rb_sql_state);
rb_exc_raise(e);
return Qnil;
}

static void rb_raise_mysql2_stmt_error(VALUE self) {
#ifdef HAVE_RUBY_ENCODING_H
rb_encoding *conn_enc;
#endif
GET_STATEMENT(self);

#ifdef HAVE_RUBY_ENCODING_H
{
GET_CLIENT(stmt_wrapper->client);
conn_enc = rb_to_encoding(wrapper->encoding);
}
#endif

rb_raise_mysql2_stmt_error2(stmt_wrapper->stmt
#ifdef HAVE_RUBY_ENCODING_H
, conn_enc
#endif
);
e = rb_funcall(cMysql2Error, intern_new_with_args, 4,
rb_error_msg,
LONG2FIX(wrapper->server_version),
UINT2NUM(mysql_stmt_errno(stmt_wrapper->stmt)),
rb_sql_state);
rb_exc_raise(e);
}


Expand Down Expand Up @@ -146,7 +131,7 @@ VALUE rb_mysql_stmt_new(VALUE rb_client, VALUE sql) {
args.sql_len = RSTRING_LEN(sql);

if ((VALUE)rb_thread_call_without_gvl(nogvl_prepare_statement, &args, RUBY_UBF_IO, 0) == Qfalse) {
rb_raise_mysql2_stmt_error(rb_stmt);
rb_raise_mysql2_stmt_error(stmt_wrapper);
}
}

Expand Down Expand Up @@ -335,13 +320,13 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) {
// copies bind_buffers into internal storage
if (mysql_stmt_bind_param(stmt, bind_buffers)) {
FREE_BINDS;
rb_raise_mysql2_stmt_error(self);
rb_raise_mysql2_stmt_error(stmt_wrapper);
}
}

if ((VALUE)rb_thread_call_without_gvl(nogvl_execute, stmt, RUBY_UBF_IO, 0) == Qfalse) {
FREE_BINDS;
rb_raise_mysql2_stmt_error(self);
rb_raise_mysql2_stmt_error(stmt_wrapper);
}

FREE_BINDS;
Expand All @@ -352,7 +337,7 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) {
// either CR_OUT_OF_MEMORY or CR_UNKNOWN_ERROR. both fatal.

MARK_CONN_INACTIVE(stmt_wrapper->client);
rb_raise_mysql2_stmt_error(self);
rb_raise_mysql2_stmt_error(stmt_wrapper);
}
// no data and no error, so query was not a SELECT
return Qnil;
Expand All @@ -367,7 +352,7 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) {
// recieve the whole result set from the server
if (rb_thread_call_without_gvl(nogvl_stmt_store_result, stmt, RUBY_UBF_IO, 0) == Qfalse) {
mysql_free_result(metadata);
rb_raise_mysql2_stmt_error(self);
rb_raise_mysql2_stmt_error(stmt_wrapper);
}
MARK_CONN_INACTIVE(stmt_wrapper->client);
}
Expand Down Expand Up @@ -440,8 +425,7 @@ void init_mysql2_statement() {

sym_stream = ID2SYM(rb_intern("stream"));

intern_error_number_eql = rb_intern("error_number=");
intern_sql_state_eql = rb_intern("sql_state=");
intern_new_with_args = rb_intern("new_with_args");
intern_each = rb_intern("each");

intern_usec = rb_intern("usec");
Expand Down
6 changes: 1 addition & 5 deletions ext/mysql2/statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ void init_mysql2_statement();
void decr_mysql2_stmt(mysql_stmt_wrapper *stmt_wrapper);

VALUE rb_mysql_stmt_new(VALUE rb_client, VALUE sql);
VALUE rb_raise_mysql2_stmt_error2(MYSQL_STMT *stmt
#ifdef HAVE_RUBY_ENCODING_H
, rb_encoding* conn_enc
#endif
);
void rb_raise_mysql2_stmt_error(mysql_stmt_wrapper *stmt_wrapper);

#endif
17 changes: 10 additions & 7 deletions lib/mysql2/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,25 @@ class Error < StandardError
:replace => '?'.freeze,
}.freeze

attr_accessor :error_number
attr_reader :sql_state
attr_writer :server_version
attr_reader :error_number, :sql_state

# Mysql gem compatibility
alias_method :errno, :error_number
alias_method :error, :message

def initialize(msg, server_version = nil)
self.server_version = server_version
def initialize(msg)
@server_version ||= nil

super(clean_message(msg))
end

def sql_state=(state)
@sql_state = state.respond_to?(:encode) ? state.encode(ENCODE_OPTS) : state
def self.new_with_args(msg, server_version, error_number, sql_state)
err = allocate
err.instance_variable_set('@server_version', server_version)
err.instance_variable_set('@error_number', error_number)
err.instance_variable_set('@sql_state', sql_state.respond_to?(:encode) ? sql_state.encode(ENCODE_OPTS) : sql_state)
err.send(:initialize, msg)
err
end

private
Expand Down