Hello community, here is the log from the commit of package rubygem-mysql2 for openSUSE:Factory checked in at 2015-02-10 20:22:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-mysql2 (Old) and /work/SRC/openSUSE:Factory/.rubygem-mysql2.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-mysql2" Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-mysql2/rubygem-mysql2.changes 2014-10-23 14:20:28.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.rubygem-mysql2.new/rubygem-mysql2.changes 2015-02-10 20:22:22.000000000 +0100 @@ -1,0 +2,5 @@ +Mon Feb 9 06:46:39 UTC 2015 - [email protected] + +- updated to version 0.3.17, no changelog + +------------------------------------------------------------------- Old: ---- mysql2-0.3.16.gem New: ---- mysql2-0.3.17.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-mysql2.spec ++++++ --- /var/tmp/diff_new_pack.thHPEf/_old 2015-02-10 20:22:23.000000000 +0100 +++ /var/tmp/diff_new_pack.thHPEf/_new 2015-02-10 20:22:23.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package rubygem-mysql2 # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,8 +16,15 @@ # +# +# This file was generated with a gem2rpm.yml and not just plain gem2rpm. +# All sections marked as MANUAL, license headers, summaries and descriptions +# can be maintained in that file. Please consult this file before editing any +# of those fields +# + Name: rubygem-mysql2 -Version: 0.3.16 +Version: 0.3.17 Release: 0 %define mod_name mysql2 %define mod_full_name %{mod_name}-%{version} ++++++ mysql2-0.3.16.gem -> mysql2-0.3.17.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/README.md new/README.md --- old/README.md 1970-01-01 01:00:00.000000000 +0100 +++ new/README.md 1970-01-01 01:00:00.000000000 +0100 @@ -1,16 +1,16 @@ -# Mysql2 - A modern, simple and very fast Mysql library for Ruby - binding to libmysql +# Mysql2 - A modern, simple and very fast MySQL library for Ruby - binding to libmysql [](https://travis-ci.org/brianmario/mysql2) The Mysql2 gem is meant to serve the extremely common use-case of connecting, querying and iterating on results. -Some database libraries out there serve as direct 1:1 mappings of the already complex C API's available. +Some database libraries out there serve as direct 1:1 mappings of the already complex C APIs available. This one is not. It also forces the use of UTF-8 [or binary] for the connection [and all strings in 1.9, unless Encoding.default_internal is set then it'll convert from UTF-8 to that encoding] and uses encoding-aware MySQL API calls where it can. The API consists of two classes: -`Mysql2::Client` - your connection to the database +`Mysql2::Client` - your connection to the database. `Mysql2::Result` - returned from issuing a #query on the connection. It includes Enumerable. @@ -26,7 +26,7 @@ * Option `--with-mysql-dir`, if provided (see below). * Option `--with-mysql-config`, if provided (see below). -* Several typical paths for `msyql_config` (default for the majority of users). +* Several typical paths for `mysql_config` (default for the majority of users). * The directory `/usr/local`. ### Configuration options @@ -104,7 +104,10 @@ # conveniently, row is a hash # the keys are the fields, as you'd expect # the values are pre-built ruby primitives mapped from their corresponding field types in MySQL - # Here's an otter: http://farm1.static.flickr.com/130/398077070_b8795d0ef3_b.jpg + puts row["id"] # row["id"].class == Fixnum + if row["dne"] # non-existant hash entry is nil + puts row["dne"] + end end ``` @@ -335,7 +338,7 @@ ### Skipping casting -Mysql2 casting is fast, but not as fast as not casting data. In rare cases where typecasting is not needed, it will be faster to disable it by providing :cast => false. +Mysql2 casting is fast, but not as fast as not casting data. In rare cases where typecasting is not needed, it will be faster to disable it by providing :cast => false. (Note that :cast => false overrides :cast_booleans => true.) ``` ruby client = Mysql2::Client.new Files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ext/mysql2/client.c new/ext/mysql2/client.c --- old/ext/mysql2/client.c 1970-01-01 01:00:00.000000000 +0100 +++ new/ext/mysql2/client.c 1970-01-01 01:00:00.000000000 +0100 @@ -6,7 +6,9 @@ #include <sys/types.h> #include <sys/socket.h> #endif +#ifndef _MSC_VER #include <unistd.h> +#endif #include <fcntl.h> #include "wait_for_single_fd.h" @@ -167,26 +169,30 @@ #ifndef _WIN32 /* - * Redirect clientfd to a dummy socket for mysql_close to - * write, shutdown, and close on as a no-op. - * We do this hack because we want to call mysql_close to release - * memory, but do not want mysql_close to drop connections in the - * parent if the socket got shared in fork. + * Redirect clientfd to /dev/null for mysql_close and SSL_close to write, + * shutdown, and close. The hack is needed to prevent shutdown() from breaking + * a socket that may be in use by the parent or other processes after fork. + * + * /dev/null is used to absorb writes; previously a dummy socket was used, but + * it could not abosrb writes and caused openssl to go into an infinite loop. + * * Returns Qtrue or Qfalse (success or failure) + * + * Note: if this function is needed on Windows, use "nul" instead of "/dev/null" */ static VALUE invalidate_fd(int clientfd) { #ifdef SOCK_CLOEXEC /* Atomically set CLOEXEC on the new FD in case another thread forks */ - int sockfd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + int sockfd = open("/dev/null", O_RDWR | O_CLOEXEC); if (sockfd < 0) { /* Maybe SOCK_CLOEXEC is defined but not available on this kernel */ - int sockfd = socket(AF_UNIX, SOCK_STREAM, 0); + int sockfd = open("/dev/null", O_RDWR); fcntl(sockfd, F_SETFD, FD_CLOEXEC); } #else /* Well we don't have SOCK_CLOEXEC, so just set FD_CLOEXEC quickly */ - int sockfd = socket(AF_UNIX, SOCK_STREAM, 0); + int sockfd = open("/dev/null", O_RDWR); fcntl(sockfd, F_SETFD, FD_CLOEXEC); #endif @@ -326,10 +332,10 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE port, VALUE database, VALUE socket, VALUE flags) { struct nogvl_connect_args args; - VALUE rv; - GET_CLIENT(self); time_t start_time, end_time; unsigned int elapsed_time, connect_timeout; + VALUE rv; + GET_CLIENT(self); args.host = NIL_P(host) ? NULL : StringValuePtr(host); args.unix_socket = NIL_P(socket) ? NULL : StringValuePtr(socket); @@ -349,11 +355,11 @@ time(&end_time); /* avoid long connect timeout from system time changes */ if (end_time < start_time) - start_time = end_time; + start_time = end_time; elapsed_time = end_time - start_time; /* avoid an early timeout due to time truncating milliseconds off the start time */ if (elapsed_time > 0) - elapsed_time--; + elapsed_time--; if (elapsed_time >= wrapper->connect_timeout) break; connect_timeout = wrapper->connect_timeout - elapsed_time; @@ -764,17 +770,17 @@ switch(opt) { case MYSQL_OPT_CONNECT_TIMEOUT: - intval = NUM2INT(value); + intval = NUM2UINT(value); retval = &intval; break; case MYSQL_OPT_READ_TIMEOUT: - intval = NUM2INT(value); + intval = NUM2UINT(value); retval = &intval; break; case MYSQL_OPT_WRITE_TIMEOUT: - intval = NUM2INT(value); + intval = NUM2UINT(value); retval = &intval; break; @@ -1233,6 +1239,13 @@ } } + /* Initializing mysql library, so different threads could call Client.new */ + /* without race condition in the library */ + if (mysql_library_init(0, NULL, NULL) != 0) { + rb_raise(rb_eRuntimeError, "Could not initialize MySQL client library"); + return; + } + #if 0 mMysql2 = rb_define_module("Mysql2"); Teach RDoc about Mysql2 constant. #endif @@ -1365,6 +1378,10 @@ #ifdef CLIENT_SECURE_CONNECTION rb_const_set(cMysql2Client, rb_intern("SECURE_CONNECTION"), LONG2NUM(CLIENT_SECURE_CONNECTION)); +#else + /* HACK because MySQL5.7 no longer defines this constant, + * but we're using it in our default connection flags. */ + rb_const_set(cMysql2Client, rb_intern("SECURE_CONNECTION"), LONG2NUM(0)); #endif #ifdef CLIENT_MULTI_STATEMENTS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ext/mysql2/client.h new/ext/mysql2/client.h --- old/ext/mysql2/client.h 1970-01-01 01:00:00.000000000 +0100 +++ new/ext/mysql2/client.h 1970-01-01 01:00:00.000000000 +0100 @@ -41,7 +41,7 @@ VALUE active_thread; /* rb_thread_current() or Qnil */ long server_version; int reconnect_enabled; - int connect_timeout; + unsigned int connect_timeout; int active; int connected; int initialized; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ext/mysql2/infile.c new/ext/mysql2/infile.c --- old/ext/mysql2/infile.c 1970-01-01 01:00:00.000000000 +0100 +++ new/ext/mysql2/infile.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,7 +1,9 @@ #include <mysql2_ext.h> #include <errno.h> +#ifndef _MSC_VER #include <unistd.h> +#endif #include <fcntl.h> #define ERROR_LEN 1024 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ext/mysql2/result.c new/ext/mysql2/result.c --- old/ext/mysql2/result.c 1970-01-01 01:00:00.000000000 +0100 +++ new/ext/mysql2/result.c 1970-01-01 01:00:00.000000000 +0100 @@ -176,6 +176,20 @@ } #endif +/* Interpret microseconds digits left-aligned in fixed-width field. + * e.g. 10.123 seconds means 10 seconds and 123000 microseconds, + * because the microseconds are to the right of the decimal point. + */ +static unsigned int msec_char_to_uint(char *msec_char, size_t len) +{ + int i; + for (i = 0; i < (len - 1); i++) { + if (msec_char[i] == '\0') { + msec_char[i] = '0'; + } + } + return (unsigned int)strtoul(msec_char, NULL, 10); +} 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; @@ -274,13 +288,16 @@ } case MYSQL_TYPE_TIME: { /* TIME field */ int tokens; - unsigned int hour=0, min=0, sec=0; - tokens = sscanf(row[i], "%2u:%2u:%2u", &hour, &min, &sec); + unsigned int hour=0, min=0, sec=0, msec=0; + char msec_char[7] = {'0','0','0','0','0','0','\0'}; + + tokens = sscanf(row[i], "%2u:%2u:%2u.%6s", &hour, &min, &sec, msec_char); if (tokens < 3) { val = Qnil; break; } - val = rb_funcall(rb_cTime, db_timezone, 6, opt_time_year, opt_time_month, opt_time_month, UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec)); + msec = msec_char_to_uint(msec_char, sizeof(msec_char)); + val = rb_funcall(rb_cTime, db_timezone, 6, opt_time_year, opt_time_month, opt_time_month, UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec), UINT2NUM(msec)); if (!NIL_P(app_timezone)) { if (app_timezone == intern_local) { val = rb_funcall(val, intern_localtime, 0); @@ -294,9 +311,10 @@ case MYSQL_TYPE_DATETIME: { /* DATETIME field */ int tokens; unsigned int year=0, month=0, day=0, hour=0, min=0, sec=0, msec=0; + char msec_char[7] = {'0','0','0','0','0','0','\0'}; uint64_t seconds; - tokens = sscanf(row[i], "%4u-%2u-%2u %2u:%2u:%2u.%6u", &year, &month, &day, &hour, &min, &sec, &msec); + tokens = sscanf(row[i], "%4u-%2u-%2u %2u:%2u:%2u.%6s", &year, &month, &day, &hour, &min, &sec, msec_char); if (tokens < 6) { /* msec might be empty */ val = Qnil; break; @@ -307,7 +325,7 @@ val = Qnil; } else { if (month < 1 || day < 1) { - rb_raise(cMysql2Error, "Invalid date: %s", row[i]); + rb_raise(cMysql2Error, "Invalid date in field '%.*s': %s", fields[i].name_length, fields[i].name, row[i]); val = Qnil; } else { if (seconds < MYSQL2_MIN_TIME || seconds > MYSQL2_MAX_TIME) { /* use DateTime for larger date range, does not support microseconds */ @@ -324,7 +342,8 @@ val = rb_funcall(val, intern_new_offset, 1, opt_utc_offset); } } - } else { /* use Time, supports microseconds */ + } else { + msec = msec_char_to_uint(msec_char, sizeof(msec_char)); val = rb_funcall(rb_cTime, db_timezone, 7, UINT2NUM(year), UINT2NUM(month), UINT2NUM(day), UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec), UINT2NUM(msec)); if (!NIL_P(app_timezone)) { if (app_timezone == intern_local) { @@ -351,7 +370,7 @@ val = Qnil; } else { if (month < 1 || day < 1) { - rb_raise(cMysql2Error, "Invalid date: %s", row[i]); + rb_raise(cMysql2Error, "Invalid date in field '%.*s': %s", fields[i].name_length, fields[i].name, row[i]); val = Qnil; } else { val = rb_funcall(cDate, intern_new, 3, UINT2NUM(year), UINT2NUM(month), UINT2NUM(day)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/mysql2/error.rb new/lib/mysql2/error.rb --- old/lib/mysql2/error.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/mysql2/error.rb 1970-01-01 01:00:00.000000000 +0100 @@ -5,7 +5,8 @@ REPLACEMENT_CHAR = '?' ENCODE_OPTS = {:undef => :replace, :invalid => :replace, :replace => REPLACEMENT_CHAR} - attr_accessor :error_number, :sql_state + attr_accessor :error_number + attr_reader :sql_state attr_writer :server_version # Mysql gem compatibility @@ -18,10 +19,8 @@ super(clean_message(msg)) end - if "".respond_to? :encode - def sql_state=(state) - @sql_state = state.encode(ENCODE_OPTS) - end + def sql_state=(state) + @sql_state = ''.respond_to?(:encode) ? state.encode(ENCODE_OPTS) : state end private diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/mysql2/version.rb new/lib/mysql2/version.rb --- old/lib/mysql2/version.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/mysql2/version.rb 1970-01-01 01:00:00.000000000 +0100 @@ -1,3 +1,3 @@ module Mysql2 - VERSION = "0.3.16" + VERSION = "0.3.17" end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 1970-01-01 01:00:00.000000000 +0100 +++ new/metadata 1970-01-01 01:00:00.000000000 +0100 @@ -1,14 +1,14 @@ --- !ruby/object:Gem::Specification name: mysql2 version: !ruby/object:Gem::Version - version: 0.3.16 + version: 0.3.17 platform: ruby authors: - Brian Lopez autorequire: bindir: bin cert_chain: [] -date: 2014-05-15 00:00:00.000000000 Z +date: 2014-11-11 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: eventmachine diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spec/mysql2/client_spec.rb new/spec/mysql2/client_spec.rb --- old/spec/mysql2/client_spec.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/spec/mysql2/client_spec.rb 1970-01-01 01:00:00.000000000 +0100 @@ -91,15 +91,26 @@ result = client.query("SELECT @something;") result.first['@something'].should eq('setting_value') - # simulate a broken connection + # get the current connection id + result = client.query("SELECT CONNECTION_ID()") + first_conn_id = result.first['CONNECTION_ID()'] + + # break the current connection begin - Timeout.timeout(1, Timeout::Error) do - client.query("SELECT sleep(2)") - end - rescue Timeout::Error + client.query("KILL #{first_conn_id}") + rescue Mysql2::Error end - client.ping.should be_false + client.ping # reconnect now + + # get the new connection id + result = client.query("SELECT CONNECTION_ID()") + second_conn_id = result.first['CONNECTION_ID()'] + + # confirm reconnect by checking the new connection id + first_conn_id.should_not == second_conn_id + + # At last, check that the init command executed result = client.query("SELECT @something;") result.first['@something'].should eq('setting_value') end @@ -109,17 +120,20 @@ end it "should be able to connect via SSL options" do - ssl = @client.query "SHOW VARIABLES LIKE 'have_%ssl'" - ssl_enabled = ssl.any? {|x| x['Value'] == 'ENABLED'} - pending("DON'T WORRY, THIS TEST PASSES - but SSL is not enabled in your MySQL daemon.") unless ssl_enabled - pending("DON'T WORRY, THIS TEST PASSES - but you must update the SSL cert paths in this test and remove this pending state.") + ssl = @client.query "SHOW VARIABLES LIKE 'have_ssl'" + ssl_uncompiled = ssl.any? {|x| x['Value'] == 'OFF'} + pending("DON'T WORRY, THIS TEST PASSES - but SSL is not compiled into your MySQL daemon.") if ssl_uncompiled + ssl_disabled = ssl.any? {|x| x['Value'] == 'DISABLED'} + pending("DON'T WORRY, THIS TEST PASSES - but SSL is not enabled in your MySQL daemon.") if ssl_disabled + + # You may need to adjust the lines below to match your SSL certificate paths ssl_client = nil lambda { ssl_client = Mysql2::Client.new( - :sslkey => '/path/to/client-key.pem', - :sslcert => '/path/to/client-cert.pem', - :sslca => '/path/to/ca-cert.pem', - :sslcapath => '/path/to/newcerts/', + :sslkey => '/etc/mysql/client-key.pem', + :sslcert => '/etc/mysql/client-cert.pem', + :sslca => '/etc/mysql/ca-cert.pem', + :sslcapath => '/etc/mysql/', :sslcipher => 'DHE-RSA-AES256-SHA' ) }.should_not raise_error(Mysql2::Error) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spec/mysql2/result_spec.rb new/spec/mysql2/result_spec.rb --- old/spec/mysql2/result_spec.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/spec/mysql2/result_spec.rb 1970-01-01 01:00:00.000000000 +0100 @@ -335,6 +335,16 @@ @test_result['enum_test'].should eql('val1') end + it "should raise an error given an invalid DATETIME" do + begin + @client.query("SELECT CAST('1972-00-27 00:00:00' AS DATETIME) as bad_datetime").each + rescue Mysql2::Error => e + error = e + end + + error.message.should eql("Invalid date in field 'bad_datetime': 1972-00-27 00:00:00") + end + if defined? Encoding context "string encoding for ENUM values" do it "should default to the connection's encoding if Encoding.default_internal is nil" do -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
