Skip to content
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

Backports from master for 0.3.19 #645

Merged
merged 11 commits into from Jul 30, 2015
1 change: 1 addition & 0 deletions Gemfile
Expand Up @@ -14,6 +14,7 @@ end
group :development do
gem 'pry'
gem 'eventmachine' unless RUBY_PLATFORM =~ /mswin|mingw/
gem 'rake-compiler-dock', '~> 0.4.2'
end

platforms :rbx do
Expand Down
2 changes: 2 additions & 0 deletions appveyor.yml
Expand Up @@ -29,6 +29,8 @@ environment:
- ruby_version: "200-x64"
- ruby_version: "21"
- ruby_version: "21-x64"
- ruby_version: "22"
- ruby_version: "22-x64"
cache:
- vendor
services:
Expand Down
91 changes: 43 additions & 48 deletions ext/mysql2/client.c
Expand Up @@ -16,7 +16,7 @@

VALUE cMysql2Client;
extern VALUE mMysql2, cMysql2Error;
static VALUE sym_id, sym_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream;
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;

#ifndef HAVE_RB_HASH_DUP
Expand Down Expand Up @@ -287,7 +287,7 @@ static VALUE rb_mysql_client_escape(RB_MYSQL_UNUSED VALUE klass, VALUE str) {
oldLen = RSTRING_LEN(str);
newStr = xmalloc(oldLen*2+1);

newLen = mysql_escape_string((char *)newStr, StringValuePtr(str), oldLen);
newLen = mysql_escape_string((char *)newStr, RSTRING_PTR(str), oldLen);
if (newLen == oldLen) {
/* no need to return a new ruby string if nothing changed */
xfree(newStr);
Expand Down Expand Up @@ -337,13 +337,13 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE po
VALUE rv;
GET_CLIENT(self);

args.host = NIL_P(host) ? NULL : StringValuePtr(host);
args.unix_socket = NIL_P(socket) ? NULL : StringValuePtr(socket);
args.port = NIL_P(port) ? 0 : NUM2INT(port);
args.user = NIL_P(user) ? NULL : StringValuePtr(user);
args.passwd = NIL_P(pass) ? NULL : StringValuePtr(pass);
args.db = NIL_P(database) ? NULL : StringValuePtr(database);
args.mysql = wrapper->client;
args.host = NIL_P(host) ? NULL : StringValueCStr(host);
args.unix_socket = NIL_P(socket) ? NULL : StringValueCStr(socket);
args.port = NIL_P(port) ? 0 : NUM2INT(port);
args.user = NIL_P(user) ? NULL : StringValueCStr(user);
args.passwd = NIL_P(pass) ? NULL : StringValueCStr(pass);
args.db = NIL_P(database) ? NULL : StringValueCStr(database);
args.mysql = wrapper->client;
args.client_flag = NUM2ULONG(flags);

if (wrapper->connect_timeout)
Expand Down Expand Up @@ -669,7 +669,7 @@ static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
/* ensure the string is in the encoding the connection is expecting */
args.sql = rb_str_export_to_enc(args.sql, conn_enc);
#endif
args.sql_ptr = StringValuePtr(args.sql);
args.sql_ptr = RSTRING_PTR(args.sql);
args.sql_len = RSTRING_LEN(args.sql);

/* see if this connection is still waiting on a result from a previous query */
Expand Down Expand Up @@ -736,9 +736,14 @@ static VALUE rb_mysql_client_real_escape(VALUE self, VALUE str) {
oldLen = RSTRING_LEN(str);
newStr = xmalloc(oldLen*2+1);

newLen = mysql_real_escape_string(wrapper->client, (char *)newStr, StringValuePtr(str), oldLen);
newLen = mysql_real_escape_string(wrapper->client, (char *)newStr, RSTRING_PTR(str), oldLen);
if (newLen == oldLen) {
/* no need to return a new ruby string if nothing changed */
#ifdef HAVE_RUBY_ENCODING_H
if (default_internal_enc) {
str = rb_str_export_to_enc(str, default_internal_enc);
}
#endif
xfree(newStr);
return str;
} else {
Expand Down Expand Up @@ -800,17 +805,17 @@ static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) {
break;

case MYSQL_READ_DEFAULT_FILE:
charval = (const char *)StringValuePtr(value);
charval = (const char *)StringValueCStr(value);
retval = charval;
break;

case MYSQL_READ_DEFAULT_GROUP:
charval = (const char *)StringValuePtr(value);
charval = (const char *)StringValueCStr(value);
retval = charval;
break;

case MYSQL_INIT_COMMAND:
charval = (const char *)StringValuePtr(value);
charval = (const char *)StringValueCStr(value);
retval = charval;
break;

Expand Down Expand Up @@ -843,30 +848,23 @@ static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) {
*
* Returns a string that represents the client library version.
*/
static VALUE rb_mysql_client_info(VALUE self) {
VALUE version, client_info;
#ifdef HAVE_RUBY_ENCODING_H
rb_encoding *default_internal_enc;
rb_encoding *conn_enc;
GET_CLIENT(self);
#endif
version = rb_hash_new();
static VALUE rb_mysql_client_info(RB_MYSQL_UNUSED VALUE klass) {
VALUE version_info, version, header_version;
version_info = rb_hash_new();

#ifdef HAVE_RUBY_ENCODING_H
default_internal_enc = rb_default_internal_encoding();
conn_enc = rb_to_encoding(wrapper->encoding);
#endif
version = rb_str_new2(mysql_get_client_info());
header_version = rb_str_new2(MYSQL_LINK_VERSION);

rb_hash_aset(version, sym_id, LONG2NUM(mysql_get_client_version()));
client_info = rb_str_new2(mysql_get_client_info());
#ifdef HAVE_RUBY_ENCODING_H
rb_enc_associate(client_info, conn_enc);
if (default_internal_enc) {
client_info = rb_str_export_to_enc(client_info, default_internal_enc);
}
rb_enc_associate(version, rb_usascii_encoding());
rb_enc_associate(header_version, rb_usascii_encoding());
#endif
rb_hash_aset(version, sym_version, client_info);
return version;

rb_hash_aset(version_info, sym_id, LONG2NUM(mysql_get_client_version()));
rb_hash_aset(version_info, sym_version, version);
rb_hash_aset(version_info, sym_header_version, header_version);

return version_info;
}

/* call-seq:
Expand Down Expand Up @@ -907,14 +905,10 @@ static VALUE rb_mysql_client_server_info(VALUE self) {
* Return the file descriptor number for this client.
*/
static VALUE rb_mysql_client_socket(VALUE self) {
GET_CLIENT(self);
#ifndef _WIN32
{
int fd_set_fd;
REQUIRE_CONNECTED(wrapper);
fd_set_fd = wrapper->client->net.fd;
return INT2NUM(fd_set_fd);
}
GET_CLIENT(self);
REQUIRE_CONNECTED(wrapper);
return INT2NUM(wrapper->client->net.fd);
#else
rb_raise(cMysql2Error, "Raw access to the mysql file descriptor isn't supported on Windows");
#endif
Expand Down Expand Up @@ -987,7 +981,7 @@ static VALUE rb_mysql_client_select_db(VALUE self, VALUE db)
REQUIRE_CONNECTED(wrapper);

args.mysql = wrapper->client;
args.db = StringValuePtr(db);
args.db = StringValueCStr(db);

if (rb_thread_call_without_gvl(nogvl_select_db, &args, RUBY_UBF_IO, 0) == Qfalse)
rb_raise_mysql2_error(wrapper);
Expand Down Expand Up @@ -1183,11 +1177,11 @@ static VALUE set_ssl_options(VALUE self, VALUE key, VALUE cert, VALUE ca, VALUE
GET_CLIENT(self);

mysql_ssl_set(wrapper->client,
NIL_P(key) ? NULL : StringValuePtr(key),
NIL_P(cert) ? NULL : StringValuePtr(cert),
NIL_P(ca) ? NULL : StringValuePtr(ca),
NIL_P(capath) ? NULL : StringValuePtr(capath),
NIL_P(cipher) ? NULL : StringValuePtr(cipher));
NIL_P(key) ? NULL : StringValueCStr(key),
NIL_P(cert) ? NULL : StringValueCStr(cert),
NIL_P(ca) ? NULL : StringValueCStr(ca),
NIL_P(capath) ? NULL : StringValueCStr(capath),
NIL_P(cipher) ? NULL : StringValueCStr(cipher));

return self;
}
Expand Down Expand Up @@ -1254,12 +1248,12 @@ void init_mysql2_client() {
rb_define_alloc_func(cMysql2Client, allocate);

rb_define_singleton_method(cMysql2Client, "escape", rb_mysql_client_escape, 1);
rb_define_singleton_method(cMysql2Client, "info", rb_mysql_client_info, 0);

rb_define_method(cMysql2Client, "close", rb_mysql_client_close, 0);
rb_define_method(cMysql2Client, "query", rb_mysql_client_query, -1);
rb_define_method(cMysql2Client, "abandon_results!", rb_mysql_client_abandon_results, 0);
rb_define_method(cMysql2Client, "escape", rb_mysql_client_real_escape, 1);
rb_define_method(cMysql2Client, "info", rb_mysql_client_info, 0);
rb_define_method(cMysql2Client, "server_info", rb_mysql_client_server_info, 0);
rb_define_method(cMysql2Client, "socket", rb_mysql_client_socket, 0);
rb_define_method(cMysql2Client, "async_result", rb_mysql_client_async_result, 0);
Expand Down Expand Up @@ -1293,6 +1287,7 @@ void init_mysql2_client() {

sym_id = ID2SYM(rb_intern("id"));
sym_version = ID2SYM(rb_intern("version"));
sym_header_version = ID2SYM(rb_intern("header_version"));
sym_async = ID2SYM(rb_intern("async"));
sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
sym_as = ID2SYM(rb_intern("as"));
Expand Down
2 changes: 1 addition & 1 deletion ext/mysql2/extconf.rb
Expand Up @@ -36,7 +36,7 @@ def asplode lib
/usr/local/lib/mysql5*
].map{|dir| "#{dir}/bin" }

GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5}"
GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5,mariadb_config}"

# If the user has provided a --with-mysql-dir argument, we must respect it or fail.
inc, lib = dir_config('mysql')
Expand Down
22 changes: 11 additions & 11 deletions ext/mysql2/result.c
Expand Up @@ -50,6 +50,10 @@ static rb_encoding *binaryEncoding;
#define MYSQL2_MIN_TIME 62171150401ULL
#endif

#define GET_RESULT(obj) \
mysql2_result_wrapper *wrapper; \
Data_Get_Struct(self, mysql2_result_wrapper, wrapper);

static VALUE cMysql2Result;
static VALUE cBigDecimal, cDate, cDateTime;
static VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month, opt_utc_offset;
Expand Down Expand Up @@ -103,9 +107,8 @@ static void *nogvl_fetch_row(void *ptr) {
}

static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, short int symbolize_keys) {
mysql2_result_wrapper * wrapper;
VALUE rb_field;
GetMysql2Result(self, wrapper);
GET_RESULT(self);

if (wrapper->fields == Qnil) {
wrapper->numberOfFields = mysql_num_fields(wrapper->result);
Expand Down Expand Up @@ -193,7 +196,6 @@ static unsigned int msec_char_to_uint(char *msec_char, size_t len)

static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezone, int symbolizeKeys, int asArray, int castBool, int cast, MYSQL_FIELD * fields) {
VALUE rowVal;
mysql2_result_wrapper * wrapper;
MYSQL_ROW row;
unsigned int i = 0;
unsigned long * fieldLengths;
Expand All @@ -202,7 +204,7 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
rb_encoding *default_internal_enc;
rb_encoding *conn_enc;
#endif
GetMysql2Result(self, wrapper);
GET_RESULT(self);

#ifdef HAVE_RUBY_ENCODING_H
default_internal_enc = rb_default_internal_encoding();
Expand Down Expand Up @@ -413,12 +415,11 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
}

static VALUE rb_mysql_result_fetch_fields(VALUE self) {
mysql2_result_wrapper * wrapper;
unsigned int i = 0;
short int symbolizeKeys = 0;
VALUE defaults;

GetMysql2Result(self, wrapper);
GET_RESULT(self);

defaults = rb_iv_get(self, "@query_options");
Check_Type(defaults, T_HASH);
Expand All @@ -443,13 +444,12 @@ static VALUE rb_mysql_result_fetch_fields(VALUE self) {
static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
VALUE defaults, opts, block;
ID db_timezone, app_timezone, dbTz, appTz;
mysql2_result_wrapper * wrapper;
unsigned long i;
const char * errstr;
int symbolizeKeys, asArray, castBool, cacheRows, cast;
MYSQL_FIELD * fields = NULL;

GetMysql2Result(self, wrapper);
GET_RESULT(self);

defaults = rb_iv_get(self, "@query_options");
Check_Type(defaults, T_HASH);
Expand All @@ -466,7 +466,7 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
cast = RTEST(rb_hash_aref(opts, sym_cast));

if (wrapper->is_streaming && cacheRows) {
rb_warn("cacheRows is ignored if streaming is true");
rb_warn(":cache_rows is ignored if :stream is true");
}

dbTz = rb_hash_aref(opts, sym_database_timezone);
Expand Down Expand Up @@ -577,9 +577,8 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
}

static VALUE rb_mysql_result_count(VALUE self) {
mysql2_result_wrapper *wrapper;
GET_RESULT(self);

GetMysql2Result(self, wrapper);
if (wrapper->is_streaming) {
/* This is an unsigned long per result.h */
return ULONG2NUM(wrapper->numberOfRows);
Expand All @@ -598,6 +597,7 @@ static VALUE rb_mysql_result_count(VALUE self) {
VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_RES *r) {
VALUE obj;
mysql2_result_wrapper * wrapper;

obj = Data_Make_Struct(cMysql2Result, mysql2_result_wrapper, rb_mysql_result_mark, rb_mysql_result_free, wrapper);
wrapper->numberOfFields = 0;
wrapper->numberOfRows = 0;
Expand Down
2 changes: 0 additions & 2 deletions ext/mysql2/result.h
Expand Up @@ -19,6 +19,4 @@ typedef struct {
mysql_client_wrapper *client_wrapper;
} mysql2_result_wrapper;

#define GetMysql2Result(obj, sval) (sval = (mysql2_result_wrapper*)DATA_PTR(obj));

#endif
4 changes: 4 additions & 0 deletions lib/mysql2/client.rb
Expand Up @@ -82,6 +82,10 @@ def query_info
info_hash
end

def info
self.class.info
end

private
def self.local_offset
::Time.local(2010).utc_offset.to_r / 86400
Expand Down