do_mysql 0.9.12-x86-mingw32 → 0.10.0-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HISTORY.markdown +17 -0
 - data/Manifest.txt +2 -2
 - data/{README.txt → README.markdown} +2 -1
 - data/Rakefile +3 -3
 - data/ext/do_mysql_ext/do_mysql_ext.c +255 -106
 - data/ext/do_mysql_ext/error.h +527 -0
 - data/ext/do_mysql_ext/extconf.rb +1 -6
 - data/lib/do_mysql.rb +20 -17
 - data/lib/do_mysql/encoding.rb +38 -0
 - data/lib/do_mysql/transaction.rb +9 -13
 - data/lib/do_mysql/version.rb +1 -1
 - data/lib/do_mysql_ext.so +0 -0
 - data/spec/connection_spec.rb +43 -1
 - data/spec/result_spec.rb +7 -0
 - data/spec/spec_helper.rb +107 -11
 - data/tasks/gem.rake +1 -53
 - data/tasks/release.rake +7 -7
 - data/tasks/retrieve.rake +1 -1
 - data/tasks/spec.rake +1 -0
 - data/tasks/ssl.rake +29 -0
 - metadata +13 -10
 - data/History.txt +0 -9
 
    
        data/HISTORY.markdown
    ADDED
    
    | 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ## 0.10.0 2009-10-15
         
     | 
| 
      
 2 
     | 
    
         
            +
            * Improvements
         
     | 
| 
      
 3 
     | 
    
         
            +
              * JRuby Support (using *do_jdbc*)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ## 0.9.12 2009-05-17
         
     | 
| 
      
 6 
     | 
    
         
            +
            * Improvements
         
     | 
| 
      
 7 
     | 
    
         
            +
              * Windows support
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            ## 0.9.11 2009-01-19
         
     | 
| 
      
 10 
     | 
    
         
            +
            * Improvements
         
     | 
| 
      
 11 
     | 
    
         
            +
              * Ruby 1.9 support
         
     | 
| 
      
 12 
     | 
    
         
            +
            * Fixes
         
     | 
| 
      
 13 
     | 
    
         
            +
              * Reconnecting now works properly
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            ## 0.9.9 2008-11-27
         
     | 
| 
      
 16 
     | 
    
         
            +
            * Improvements
         
     | 
| 
      
 17 
     | 
    
         
            +
              * Added initial support for Ruby 1.9 [John Harrison]
         
     | 
    
        data/Manifest.txt
    CHANGED
    
    
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -8,9 +8,9 @@ require 'lib/do_mysql/version' 
     | 
|
| 
       8 
8 
     | 
    
         
             
            ROOT    = Pathname(__FILE__).dirname.expand_path
         
     | 
| 
       9 
9 
     | 
    
         
             
            JRUBY   = RUBY_PLATFORM =~ /java/
         
     | 
| 
       10 
10 
     | 
    
         
             
            WINDOWS = Gem.win_platform?
         
     | 
| 
       11 
     | 
    
         
            -
            SUDO    =  
     | 
| 
       12 
     | 
    
         
            -
            BINARY_VERSION = '5.0. 
     | 
| 
      
 11 
     | 
    
         
            +
            SUDO    = WINDOWS ? '' : ('sudo' unless ENV['SUDOLESS'])
         
     | 
| 
      
 12 
     | 
    
         
            +
            BINARY_VERSION = '5.0.85'
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
            Dir['tasks/*.rake'].each { |f| import f }
         
     | 
| 
      
 14 
     | 
    
         
            +
            Dir['tasks/*.rake'].sort.each { |f| import f }
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
            CLEAN.include(%w[ {tmp,pkg}/ **/*.{o,so,bundle,jar,log,a,gem,dSYM,obj,pdb,exp,DS_Store,rbc,db} ext/do_mysql_ext/Makefile ext-java/target ])
         
     | 
| 
         @@ -6,14 +6,12 @@ 
     | 
|
| 
       6 
6 
     | 
    
         
             
            #include <mysql.h>
         
     | 
| 
       7 
7 
     | 
    
         
             
            #include <errmsg.h>
         
     | 
| 
       8 
8 
     | 
    
         
             
            #include <mysqld_error.h>
         
     | 
| 
      
 9 
     | 
    
         
            +
            #include "error.h"
         
     | 
| 
       9 
10 
     | 
    
         | 
| 
       10 
11 
     | 
    
         
             
            #define RUBY_CLASS(name) rb_const_get(rb_cObject, rb_intern(name))
         
     | 
| 
       11 
     | 
    
         
            -
            #define RUBY_STRING(char_ptr) rb_str_new2(char_ptr)
         
     | 
| 
       12 
     | 
    
         
            -
            #define TAINTED_STRING(name, length) rb_tainted_str_new(name, length)
         
     | 
| 
       13 
12 
     | 
    
         
             
            #define DRIVER_CLASS(klass, parent) (rb_define_class_under(mDOMysql, klass, parent))
         
     | 
| 
       14 
13 
     | 
    
         
             
            #define CONST_GET(scope, constant) (rb_funcall(scope, ID_CONST_GET, 1, rb_str_new2(constant)))
         
     | 
| 
       15 
     | 
    
         
            -
            #define CHECK_AND_RAISE(mysql_result_value,  
     | 
| 
       16 
     | 
    
         
            -
            #define PUTS(string) rb_funcall(rb_mKernel, rb_intern("puts"), 1, RUBY_STRING(string))
         
     | 
| 
      
 14 
     | 
    
         
            +
            #define CHECK_AND_RAISE(mysql_result_value, query) if (0 != mysql_result_value) { raise_error(self, db, query); }
         
     | 
| 
       17 
15 
     | 
    
         | 
| 
       18 
16 
     | 
    
         
             
            #ifndef RSTRING_PTR
         
     | 
| 
       19 
17 
     | 
    
         
             
            #define RSTRING_PTR(s) (RSTRING(s)->ptr)
         
     | 
| 
         @@ -35,6 +33,37 @@ 
     | 
|
| 
       35 
33 
     | 
    
         
             
            #define do_int64 signed long long int
         
     | 
| 
       36 
34 
     | 
    
         
             
            #endif
         
     | 
| 
       37 
35 
     | 
    
         | 
| 
      
 36 
     | 
    
         
            +
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
      
 37 
     | 
    
         
            +
            #include <ruby/encoding.h>
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            #define DO_STR_NEW2(str, encoding) \
         
     | 
| 
      
 40 
     | 
    
         
            +
              ({ \
         
     | 
| 
      
 41 
     | 
    
         
            +
                VALUE _string = rb_str_new2((const char *)str); \
         
     | 
| 
      
 42 
     | 
    
         
            +
                if(encoding != -1) { \
         
     | 
| 
      
 43 
     | 
    
         
            +
                  rb_enc_associate_index(_string, encoding); \
         
     | 
| 
      
 44 
     | 
    
         
            +
                } \
         
     | 
| 
      
 45 
     | 
    
         
            +
                _string; \
         
     | 
| 
      
 46 
     | 
    
         
            +
              })
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            #define DO_STR_NEW(str, len, encoding) \
         
     | 
| 
      
 49 
     | 
    
         
            +
              ({ \
         
     | 
| 
      
 50 
     | 
    
         
            +
                VALUE _string = rb_str_new((const char *)str, (long)len); \
         
     | 
| 
      
 51 
     | 
    
         
            +
                if(encoding != -1) { \
         
     | 
| 
      
 52 
     | 
    
         
            +
                  rb_enc_associate_index(_string, encoding); \
         
     | 
| 
      
 53 
     | 
    
         
            +
                } \
         
     | 
| 
      
 54 
     | 
    
         
            +
                _string; \
         
     | 
| 
      
 55 
     | 
    
         
            +
              })
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            #else
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            #define DO_STR_NEW2(str, encoding) \
         
     | 
| 
      
 60 
     | 
    
         
            +
              rb_str_new2((const char *)str)
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            #define DO_STR_NEW(str, len, encoding) \
         
     | 
| 
      
 63 
     | 
    
         
            +
              rb_str_new((const char *)str, (long)len)
         
     | 
| 
      
 64 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
       38 
67 
     | 
    
         
             
            // To store rb_intern values
         
     | 
| 
       39 
68 
     | 
    
         
             
            static ID ID_TO_I;
         
     | 
| 
       40 
69 
     | 
    
         
             
            static ID ID_TO_F;
         
     | 
| 
         @@ -56,6 +85,7 @@ static VALUE mExtlib; 
     | 
|
| 
       56 
85 
     | 
    
         | 
| 
       57 
86 
     | 
    
         
             
            // References to DataObjects base classes
         
     | 
| 
       58 
87 
     | 
    
         
             
            static VALUE mDO;
         
     | 
| 
      
 88 
     | 
    
         
            +
            static VALUE mEncoding;
         
     | 
| 
       59 
89 
     | 
    
         
             
            static VALUE cDO_Quoting;
         
     | 
| 
       60 
90 
     | 
    
         
             
            static VALUE cDO_Connection;
         
     | 
| 
       61 
91 
     | 
    
         
             
            static VALUE cDO_Command;
         
     | 
| 
         @@ -74,8 +104,9 @@ static VALUE cConnection; 
     | 
|
| 
       74 
104 
     | 
    
         
             
            static VALUE cCommand;
         
     | 
| 
       75 
105 
     | 
    
         
             
            static VALUE cResult;
         
     | 
| 
       76 
106 
     | 
    
         
             
            static VALUE cReader;
         
     | 
| 
       77 
     | 
    
         
            -
            static VALUE eMysqlError;
         
     | 
| 
       78 
107 
     | 
    
         
             
            static VALUE eArgumentError;
         
     | 
| 
      
 108 
     | 
    
         
            +
            static VALUE eConnectionError;
         
     | 
| 
      
 109 
     | 
    
         
            +
            static VALUE eDataError;
         
     | 
| 
       79 
110 
     | 
    
         | 
| 
       80 
111 
     | 
    
         
             
            // Figures out what we should cast a given mysql field type to
         
     | 
| 
       81 
112 
     | 
    
         
             
            static VALUE infer_ruby_type(MYSQL_FIELD *field) {
         
     | 
| 
         @@ -100,8 +131,6 @@ static VALUE infer_ruby_type(MYSQL_FIELD *field) { 
     | 
|
| 
       100 
131 
     | 
    
         
             
                case MYSQL_TYPE_TIMESTAMP:
         
     | 
| 
       101 
132 
     | 
    
         
             
                case MYSQL_TYPE_DATETIME:
         
     | 
| 
       102 
133 
     | 
    
         
             
                  return rb_cDateTime;
         
     | 
| 
       103 
     | 
    
         
            -
                case MYSQL_TYPE_TIME:
         
     | 
| 
       104 
     | 
    
         
            -
                  return rb_cDateTime;
         
     | 
| 
       105 
134 
     | 
    
         
             
                case MYSQL_TYPE_DATE:
         
     | 
| 
       106 
135 
     | 
    
         
             
                case MYSQL_TYPE_NEWDATE:
         
     | 
| 
       107 
136 
     | 
    
         
             
                  return rb_cDate;
         
     | 
| 
         @@ -239,7 +268,7 @@ static VALUE parse_date_time(const char *date) { 
     | 
|
| 
       239 
268 
     | 
    
         
             
                  hour_offset = 0;
         
     | 
| 
       240 
269 
     | 
    
         
             
                  minute_offset = 0;
         
     | 
| 
       241 
270 
     | 
    
         
             
                  sec = 0;
         
     | 
| 
       242 
     | 
    
         
            -
                } 
     | 
| 
      
 271 
     | 
    
         
            +
                }
         
     | 
| 
       243 
272 
     | 
    
         
             
                // We read the Date and Time, default to the current locale's offset
         
     | 
| 
       244 
273 
     | 
    
         | 
| 
       245 
274 
     | 
    
         
             
                // Get localtime
         
     | 
| 
         @@ -261,7 +290,7 @@ static VALUE parse_date_time(const char *date) { 
     | 
|
| 
       261 
290 
     | 
    
         | 
| 
       262 
291 
     | 
    
         
             
              } else {
         
     | 
| 
       263 
292 
     | 
    
         
             
                // Something went terribly wrong
         
     | 
| 
       264 
     | 
    
         
            -
                rb_raise( 
     | 
| 
      
 293 
     | 
    
         
            +
                rb_raise(eDataError, "Couldn't parse date: %s", date);
         
     | 
| 
       265 
294 
     | 
    
         
             
              }
         
     | 
| 
       266 
295 
     | 
    
         | 
| 
       267 
296 
     | 
    
         
             
              jd = jd_from_date(year, month, day);
         
     | 
| 
         @@ -295,7 +324,7 @@ static VALUE parse_date_time(const char *date) { 
     | 
|
| 
       295 
324 
     | 
    
         
             
            }
         
     | 
| 
       296 
325 
     | 
    
         | 
| 
       297 
326 
     | 
    
         
             
            // Convert C-string to a Ruby instance of Ruby type "type"
         
     | 
| 
       298 
     | 
    
         
            -
            static VALUE typecast(const char *value, long length, const VALUE type) {
         
     | 
| 
      
 327 
     | 
    
         
            +
            static VALUE typecast(const char *value, long length, const VALUE type, int encoding) {
         
     | 
| 
       299 
328 
     | 
    
         | 
| 
       300 
329 
     | 
    
         
             
              if(NULL == value) {
         
     | 
| 
       301 
330 
     | 
    
         
             
                return Qnil;
         
     | 
| 
         @@ -304,11 +333,11 @@ static VALUE typecast(const char *value, long length, const VALUE type) { 
     | 
|
| 
       304 
333 
     | 
    
         
             
              if (type == rb_cInteger) {
         
     | 
| 
       305 
334 
     | 
    
         
             
                return rb_cstr2inum(value, 10);
         
     | 
| 
       306 
335 
     | 
    
         
             
              } else if (type == rb_cString) {
         
     | 
| 
       307 
     | 
    
         
            -
                return  
     | 
| 
      
 336 
     | 
    
         
            +
                return DO_STR_NEW(value, length, encoding);
         
     | 
| 
       308 
337 
     | 
    
         
             
              } else if (type == rb_cFloat) {
         
     | 
| 
       309 
338 
     | 
    
         
             
                return rb_float_new(rb_cstr_to_dbl(value, Qfalse));
         
     | 
| 
       310 
339 
     | 
    
         
             
              } else if (type == rb_cBigDecimal) {
         
     | 
| 
       311 
     | 
    
         
            -
                return rb_funcall(rb_cBigDecimal, ID_NEW, 1,  
     | 
| 
      
 340 
     | 
    
         
            +
                return rb_funcall(rb_cBigDecimal, ID_NEW, 1, rb_str_new(value, length));
         
     | 
| 
       312 
341 
     | 
    
         
             
              } else if (type == rb_cDate) {
         
     | 
| 
       313 
342 
     | 
    
         
             
                return parse_date(value);
         
     | 
| 
       314 
343 
     | 
    
         
             
              } else if (type == rb_cDateTime) {
         
     | 
| 
         @@ -318,15 +347,15 @@ static VALUE typecast(const char *value, long length, const VALUE type) { 
     | 
|
| 
       318 
347 
     | 
    
         
             
              } else if (type == rb_cTrueClass) {
         
     | 
| 
       319 
348 
     | 
    
         
             
                return (0 == value || 0 == strcmp("0", value)) ? Qfalse : Qtrue;
         
     | 
| 
       320 
349 
     | 
    
         
             
              } else if (type == rb_cByteArray) {
         
     | 
| 
       321 
     | 
    
         
            -
                return rb_funcall(rb_cByteArray, ID_NEW, 1,  
     | 
| 
      
 350 
     | 
    
         
            +
                return rb_funcall(rb_cByteArray, ID_NEW, 1, rb_str_new(value, length));
         
     | 
| 
       322 
351 
     | 
    
         
             
              } else if (type == rb_cClass) {
         
     | 
| 
       323 
     | 
    
         
            -
                return rb_funcall(rb_cObject, rb_intern("full_const_get"), 1,  
     | 
| 
      
 352 
     | 
    
         
            +
                return rb_funcall(rb_cObject, rb_intern("full_const_get"), 1, rb_str_new(value, length));
         
     | 
| 
       324 
353 
     | 
    
         
             
              } else if (type == rb_cObject) {
         
     | 
| 
       325 
354 
     | 
    
         
             
                return rb_marshal_load(rb_str_new(value, length));
         
     | 
| 
       326 
355 
     | 
    
         
             
              } else if (type == rb_cNilClass) {
         
     | 
| 
       327 
356 
     | 
    
         
             
                return Qnil;
         
     | 
| 
       328 
357 
     | 
    
         
             
              } else {
         
     | 
| 
       329 
     | 
    
         
            -
                return  
     | 
| 
      
 358 
     | 
    
         
            +
                return DO_STR_NEW(value, length, encoding);
         
     | 
| 
       330 
359 
     | 
    
         
             
              }
         
     | 
| 
       331 
360 
     | 
    
         | 
| 
       332 
361 
     | 
    
         
             
            }
         
     | 
| 
         @@ -354,17 +383,31 @@ static void data_objects_debug(VALUE string, struct timeval* start) { 
     | 
|
| 
       354 
383 
     | 
    
         
             
                rb_funcall(logger, ID_DEBUG, 1, rb_str_new(message, length + strlen(total_time) + 3));
         
     | 
| 
       355 
384 
     | 
    
         
             
              }
         
     | 
| 
       356 
385 
     | 
    
         
             
            }
         
     | 
| 
       357 
     | 
    
         
            -
             
     | 
| 
      
 386 
     | 
    
         
            +
             
     | 
| 
      
 387 
     | 
    
         
            +
            static void raise_error(VALUE self, MYSQL *db, VALUE query) {
         
     | 
| 
      
 388 
     | 
    
         
            +
              VALUE exception;
         
     | 
| 
      
 389 
     | 
    
         
            +
              const char *exception_type = "SQLError";
         
     | 
| 
       358 
390 
     | 
    
         
             
              char *mysql_error_message = (char *)mysql_error(db);
         
     | 
| 
      
 391 
     | 
    
         
            +
              int mysql_error_code = mysql_errno(db);
         
     | 
| 
       359 
392 
     | 
    
         | 
| 
       360 
     | 
    
         
            -
               
     | 
| 
       361 
     | 
    
         
            -
             
     | 
| 
       362 
     | 
    
         
            -
               
     | 
| 
       363 
     | 
    
         
            -
             
     | 
| 
       364 
     | 
    
         
            -
             
     | 
| 
       365 
     | 
    
         
            -
             
     | 
| 
       366 
     | 
    
         
            -
                 
     | 
| 
      
 393 
     | 
    
         
            +
              struct errcodes *errs;
         
     | 
| 
      
 394 
     | 
    
         
            +
             
     | 
| 
      
 395 
     | 
    
         
            +
              for (errs = errors; errs->error_name; errs++) {
         
     | 
| 
      
 396 
     | 
    
         
            +
                if(errs->error_no == mysql_error_code) {
         
     | 
| 
      
 397 
     | 
    
         
            +
                  exception_type = errs->exception;
         
     | 
| 
      
 398 
     | 
    
         
            +
                  break;
         
     | 
| 
      
 399 
     | 
    
         
            +
                }
         
     | 
| 
       367 
400 
     | 
    
         
             
              }
         
     | 
| 
      
 401 
     | 
    
         
            +
             
     | 
| 
      
 402 
     | 
    
         
            +
              VALUE uri = rb_funcall(rb_iv_get(self, "@connection"), rb_intern("to_s"), 0);
         
     | 
| 
      
 403 
     | 
    
         
            +
             
     | 
| 
      
 404 
     | 
    
         
            +
              exception = rb_funcall(CONST_GET(mDO, exception_type), ID_NEW, 5,
         
     | 
| 
      
 405 
     | 
    
         
            +
                                     rb_str_new2(mysql_error_message),
         
     | 
| 
      
 406 
     | 
    
         
            +
                                     INT2NUM(mysql_error_code),
         
     | 
| 
      
 407 
     | 
    
         
            +
                                     rb_str_new2(mysql_sqlstate(db)),
         
     | 
| 
      
 408 
     | 
    
         
            +
                                     query,
         
     | 
| 
      
 409 
     | 
    
         
            +
                                     uri);
         
     | 
| 
      
 410 
     | 
    
         
            +
              rb_exc_raise(exception);
         
     | 
| 
       368 
411 
     | 
    
         
             
            }
         
     | 
| 
       369 
412 
     | 
    
         | 
| 
       370 
413 
     | 
    
         
             
            static char * get_uri_option(VALUE query_hash, char * key) {
         
     | 
| 
         @@ -373,7 +416,7 @@ static char * get_uri_option(VALUE query_hash, char * key) { 
     | 
|
| 
       373 
416 
     | 
    
         | 
| 
       374 
417 
     | 
    
         
             
              if(!rb_obj_is_kind_of(query_hash, rb_cHash)) { return NULL; }
         
     | 
| 
       375 
418 
     | 
    
         | 
| 
       376 
     | 
    
         
            -
              query_value = rb_hash_aref(query_hash,  
     | 
| 
      
 419 
     | 
    
         
            +
              query_value = rb_hash_aref(query_hash, rb_str_new2(key));
         
     | 
| 
       377 
420 
     | 
    
         | 
| 
       378 
421 
     | 
    
         
             
              if (Qnil != query_value) {
         
     | 
| 
       379 
422 
     | 
    
         
             
                value = StringValuePtr(query_value);
         
     | 
| 
         @@ -382,6 +425,15 @@ static char * get_uri_option(VALUE query_hash, char * key) { 
     | 
|
| 
       382 
425 
     | 
    
         
             
              return value;
         
     | 
| 
       383 
426 
     | 
    
         
             
            }
         
     | 
| 
       384 
427 
     | 
    
         | 
| 
      
 428 
     | 
    
         
            +
            static void assert_file_exists(char * file, char * message) {
         
     | 
| 
      
 429 
     | 
    
         
            +
              if (file == NULL) { return; }
         
     | 
| 
      
 430 
     | 
    
         
            +
              if (rb_funcall(rb_cFile, rb_intern("exist?"), 1, rb_str_new2(file)) == Qfalse) {
         
     | 
| 
      
 431 
     | 
    
         
            +
                rb_raise(eArgumentError, message);
         
     | 
| 
      
 432 
     | 
    
         
            +
              }
         
     | 
| 
      
 433 
     | 
    
         
            +
            }
         
     | 
| 
      
 434 
     | 
    
         
            +
             
     | 
| 
      
 435 
     | 
    
         
            +
            static void full_connect(VALUE self, MYSQL *db);
         
     | 
| 
      
 436 
     | 
    
         
            +
             
     | 
| 
       385 
437 
     | 
    
         
             
            #ifdef _WIN32
         
     | 
| 
       386 
438 
     | 
    
         
             
            static MYSQL_RES* cCommand_execute_sync(VALUE self, MYSQL* db, VALUE query) {
         
     | 
| 
       387 
439 
     | 
    
         
             
              int retval;
         
     | 
| 
         @@ -389,16 +441,14 @@ static MYSQL_RES* cCommand_execute_sync(VALUE self, MYSQL* db, VALUE query) { 
     | 
|
| 
       389 
441 
     | 
    
         
             
              char* str = RSTRING_PTR(query);
         
     | 
| 
       390 
442 
     | 
    
         
             
              int len   = RSTRING_LEN(query);
         
     | 
| 
       391 
443 
     | 
    
         | 
| 
       392 
     | 
    
         
            -
              VALUE connection = rb_iv_get(self, "@connection");
         
     | 
| 
       393 
     | 
    
         
            -
             
     | 
| 
       394 
444 
     | 
    
         
             
              if(mysql_ping(db) && mysql_errno(db) == CR_SERVER_GONE_ERROR) {
         
     | 
| 
       395 
     | 
    
         
            -
                 
     | 
| 
       396 
     | 
    
         
            -
             
     | 
| 
       397 
     | 
    
         
            -
             
     | 
| 
      
 445 
     | 
    
         
            +
                // Ok, we do one more try here by doing a full connect
         
     | 
| 
      
 446 
     | 
    
         
            +
                VALUE connection = rb_iv_get(self, "@connection");
         
     | 
| 
      
 447 
     | 
    
         
            +
                full_connect(connection, db);
         
     | 
| 
       398 
448 
     | 
    
         
             
              }
         
     | 
| 
       399 
449 
     | 
    
         
             
              gettimeofday(&start, NULL);
         
     | 
| 
       400 
450 
     | 
    
         
             
              retval = mysql_real_query(db, str, len);
         
     | 
| 
       401 
     | 
    
         
            -
              CHECK_AND_RAISE(retval,  
     | 
| 
      
 451 
     | 
    
         
            +
              CHECK_AND_RAISE(retval, query);
         
     | 
| 
       402 
452 
     | 
    
         | 
| 
       403 
453 
     | 
    
         
             
              data_objects_debug(query, &start);
         
     | 
| 
       404 
454 
     | 
    
         | 
| 
         @@ -413,16 +463,13 @@ static MYSQL_RES* cCommand_execute_async(VALUE self, MYSQL* db, VALUE query) { 
     | 
|
| 
       413 
463 
     | 
    
         
             
              char* str = RSTRING_PTR(query);
         
     | 
| 
       414 
464 
     | 
    
         
             
              int len   = RSTRING_LEN(query);
         
     | 
| 
       415 
465 
     | 
    
         | 
| 
       416 
     | 
    
         
            -
               
     | 
| 
       417 
     | 
    
         
            -
             
     | 
| 
       418 
     | 
    
         
            -
             
     | 
| 
       419 
     | 
    
         
            -
                CHECK_AND_RAISE(mysql_errno(db), "Mysql server has gone away. \
         
     | 
| 
       420 
     | 
    
         
            -
                                         Please report this issue to the Datamapper project. \
         
     | 
| 
       421 
     | 
    
         
            -
                                         Specify your at least your MySQL version when filing a ticket");
         
     | 
| 
      
 466 
     | 
    
         
            +
              if((retval = mysql_ping(db)) && mysql_errno(db) == CR_SERVER_GONE_ERROR) {
         
     | 
| 
      
 467 
     | 
    
         
            +
                VALUE connection = rb_iv_get(self, "@connection");
         
     | 
| 
      
 468 
     | 
    
         
            +
                full_connect(connection, db);
         
     | 
| 
       422 
469 
     | 
    
         
             
              }
         
     | 
| 
       423 
470 
     | 
    
         
             
              retval = mysql_send_query(db, str, len);
         
     | 
| 
       424 
471 
     | 
    
         | 
| 
       425 
     | 
    
         
            -
              CHECK_AND_RAISE(retval,  
     | 
| 
      
 472 
     | 
    
         
            +
              CHECK_AND_RAISE(retval, query);
         
     | 
| 
       426 
473 
     | 
    
         
             
              gettimeofday(&start, NULL);
         
     | 
| 
       427 
474 
     | 
    
         | 
| 
       428 
475 
     | 
    
         
             
              socket_fd = db->net.fd;
         
     | 
| 
         @@ -447,7 +494,7 @@ static MYSQL_RES* cCommand_execute_async(VALUE self, MYSQL* db, VALUE query) { 
     | 
|
| 
       447 
494 
     | 
    
         
             
              }
         
     | 
| 
       448 
495 
     | 
    
         | 
| 
       449 
496 
     | 
    
         
             
              retval = mysql_read_query_result(db);
         
     | 
| 
       450 
     | 
    
         
            -
              CHECK_AND_RAISE(retval,  
     | 
| 
      
 497 
     | 
    
         
            +
              CHECK_AND_RAISE(retval, query);
         
     | 
| 
       451 
498 
     | 
    
         | 
| 
       452 
499 
     | 
    
         
             
              data_objects_debug(query, &start);
         
     | 
| 
       453 
500 
     | 
    
         | 
| 
         @@ -455,51 +502,48 @@ static MYSQL_RES* cCommand_execute_async(VALUE self, MYSQL* db, VALUE query) { 
     | 
|
| 
       455 
502 
     | 
    
         
             
            }
         
     | 
| 
       456 
503 
     | 
    
         
             
            #endif
         
     | 
| 
       457 
504 
     | 
    
         | 
| 
       458 
     | 
    
         
            -
             
     | 
| 
      
 505 
     | 
    
         
            +
             
     | 
| 
      
 506 
     | 
    
         
            +
            static void full_connect(VALUE self, MYSQL* db) {
         
     | 
| 
      
 507 
     | 
    
         
            +
              // Check to see if we're on the db machine.  If so, try to use the socket
         
     | 
| 
       459 
508 
     | 
    
         
             
              VALUE r_host, r_user, r_password, r_path, r_query, r_port;
         
     | 
| 
       460 
509 
     | 
    
         | 
| 
       461 
510 
     | 
    
         
             
              char *host = "localhost", *user = "root", *password = NULL, *path;
         
     | 
| 
       462 
511 
     | 
    
         
             
              char *database = "", *socket = NULL;
         
     | 
| 
       463 
     | 
    
         
            -
               
     | 
| 
      
 512 
     | 
    
         
            +
              VALUE encoding = Qnil;
         
     | 
| 
      
 513 
     | 
    
         
            +
             
     | 
| 
      
 514 
     | 
    
         
            +
              MYSQL *result;
         
     | 
| 
       464 
515 
     | 
    
         | 
| 
       465 
516 
     | 
    
         
             
              int port = 3306;
         
     | 
| 
       466 
517 
     | 
    
         
             
              unsigned long client_flags = 0;
         
     | 
| 
       467 
518 
     | 
    
         
             
              int encoding_error;
         
     | 
| 
       468 
519 
     | 
    
         | 
| 
       469 
     | 
    
         
            -
               
     | 
| 
       470 
     | 
    
         
            -
             
     | 
| 
       471 
     | 
    
         
            -
             
     | 
| 
       472 
     | 
    
         
            -
              rb_iv_set(self, "@using_socket", Qfalse);
         
     | 
| 
       473 
     | 
    
         
            -
             
     | 
| 
       474 
     | 
    
         
            -
              r_host = rb_funcall(uri, rb_intern("host"), 0);
         
     | 
| 
       475 
     | 
    
         
            -
              if (Qnil != r_host) {
         
     | 
| 
       476 
     | 
    
         
            -
                host = StringValuePtr(r_host);
         
     | 
| 
      
 520 
     | 
    
         
            +
              if((r_host = rb_iv_get(self, "@host")) != Qnil) {
         
     | 
| 
      
 521 
     | 
    
         
            +
                host     = StringValuePtr(r_host);
         
     | 
| 
       477 
522 
     | 
    
         
             
              }
         
     | 
| 
       478 
523 
     | 
    
         | 
| 
       479 
     | 
    
         
            -
              r_user =  
     | 
| 
       480 
     | 
    
         
            -
             
     | 
| 
       481 
     | 
    
         
            -
                user = StringValuePtr(r_user);
         
     | 
| 
      
 524 
     | 
    
         
            +
              if((r_user = rb_iv_get(self, "@user")) != Qnil) {
         
     | 
| 
      
 525 
     | 
    
         
            +
                user     = StringValuePtr(r_user);
         
     | 
| 
       482 
526 
     | 
    
         
             
              }
         
     | 
| 
       483 
527 
     | 
    
         | 
| 
       484 
     | 
    
         
            -
              r_password =  
     | 
| 
       485 
     | 
    
         
            -
              if (Qnil != r_password) {
         
     | 
| 
      
 528 
     | 
    
         
            +
              if((r_password = rb_iv_get(self, "@password")) != Qnil) {
         
     | 
| 
       486 
529 
     | 
    
         
             
                password = StringValuePtr(r_password);
         
     | 
| 
       487 
530 
     | 
    
         
             
              }
         
     | 
| 
       488 
531 
     | 
    
         | 
| 
       489 
     | 
    
         
            -
               
     | 
| 
       490 
     | 
    
         
            -
             
     | 
| 
       491 
     | 
    
         
            -
               
     | 
| 
      
 532 
     | 
    
         
            +
              if((r_port = rb_iv_get(self, "@port")) != Qnil) {
         
     | 
| 
      
 533 
     | 
    
         
            +
                port = NUM2INT(r_port);
         
     | 
| 
      
 534 
     | 
    
         
            +
              }
         
     | 
| 
      
 535 
     | 
    
         
            +
             
     | 
| 
      
 536 
     | 
    
         
            +
              if((r_path = rb_iv_get(self, "@path")) != Qnil) {
         
     | 
| 
      
 537 
     | 
    
         
            +
                path = StringValuePtr(r_path);
         
     | 
| 
       492 
538 
     | 
    
         
             
                database = strtok(path, "/");
         
     | 
| 
       493 
539 
     | 
    
         
             
              }
         
     | 
| 
       494 
540 
     | 
    
         | 
| 
       495 
541 
     | 
    
         
             
              if (NULL == database || 0 == strlen(database)) {
         
     | 
| 
       496 
     | 
    
         
            -
                rb_raise( 
     | 
| 
      
 542 
     | 
    
         
            +
                rb_raise(eConnectionError, "Database must be specified");
         
     | 
| 
       497 
543 
     | 
    
         
             
              }
         
     | 
| 
       498 
544 
     | 
    
         | 
| 
       499 
     | 
    
         
            -
               
     | 
| 
       500 
     | 
    
         
            -
              r_query = rb_funcall(uri, rb_intern("query"), 0);
         
     | 
| 
      
 545 
     | 
    
         
            +
              r_query        = rb_iv_get(self, "@query");
         
     | 
| 
       501 
546 
     | 
    
         | 
| 
       502 
     | 
    
         
            -
              // Check to see if we're on the db machine.  If so, try to use the socket
         
     | 
| 
       503 
547 
     | 
    
         
             
              if (0 == strcasecmp(host, "localhost")) {
         
     | 
| 
       504 
548 
     | 
    
         
             
                socket = get_uri_option(r_query, "socket");
         
     | 
| 
       505 
549 
     | 
    
         
             
                if (NULL != socket) {
         
     | 
| 
         @@ -507,18 +551,30 @@ static VALUE cConnection_initialize(VALUE self, VALUE uri) { 
     | 
|
| 
       507 
551 
     | 
    
         
             
                }
         
     | 
| 
       508 
552 
     | 
    
         
             
              }
         
     | 
| 
       509 
553 
     | 
    
         | 
| 
       510 
     | 
    
         
            -
             
     | 
| 
       511 
     | 
    
         
            -
               
     | 
| 
       512 
     | 
    
         
            -
             
     | 
| 
       513 
     | 
    
         
            -
              }
         
     | 
| 
      
 554 
     | 
    
         
            +
            #ifdef HAVE_MYSQL_SSL_SET
         
     | 
| 
      
 555 
     | 
    
         
            +
              char *ssl_client_key, *ssl_client_cert, *ssl_ca_cert, *ssl_ca_path, *ssl_cipher;
         
     | 
| 
      
 556 
     | 
    
         
            +
              VALUE r_ssl;
         
     | 
| 
       514 
557 
     | 
    
         | 
| 
       515 
     | 
    
         
            -
               
     | 
| 
       516 
     | 
    
         
            -
             
     | 
| 
       517 
     | 
    
         
            -
              if (!encoding) { encoding = "utf8"; }
         
     | 
| 
      
 558 
     | 
    
         
            +
              if(rb_obj_is_kind_of(r_query, rb_cHash)) {
         
     | 
| 
      
 559 
     | 
    
         
            +
                r_ssl = rb_hash_aref(r_query, rb_str_new2("ssl"));
         
     | 
| 
       518 
560 
     | 
    
         | 
| 
       519 
     | 
    
         
            -
             
     | 
| 
       520 
     | 
    
         
            -
               
     | 
| 
       521 
     | 
    
         
            -
             
     | 
| 
      
 561 
     | 
    
         
            +
                if(rb_obj_is_kind_of(r_ssl, rb_cHash)) {
         
     | 
| 
      
 562 
     | 
    
         
            +
                  ssl_client_key  = get_uri_option(r_ssl, "client_key");
         
     | 
| 
      
 563 
     | 
    
         
            +
                  ssl_client_cert = get_uri_option(r_ssl, "client_cert");
         
     | 
| 
      
 564 
     | 
    
         
            +
                  ssl_ca_cert     = get_uri_option(r_ssl, "ca_cert");
         
     | 
| 
      
 565 
     | 
    
         
            +
                  ssl_ca_path     = get_uri_option(r_ssl, "ca_path");
         
     | 
| 
      
 566 
     | 
    
         
            +
                  ssl_cipher      = get_uri_option(r_ssl, "cipher");
         
     | 
| 
      
 567 
     | 
    
         
            +
             
     | 
| 
      
 568 
     | 
    
         
            +
                  assert_file_exists(ssl_client_key,  "client_key doesn't exist");
         
     | 
| 
      
 569 
     | 
    
         
            +
                  assert_file_exists(ssl_client_cert, "client_cert doesn't exist");
         
     | 
| 
      
 570 
     | 
    
         
            +
                  assert_file_exists(ssl_ca_cert,     "ca_cert doesn't exist");
         
     | 
| 
      
 571 
     | 
    
         
            +
             
     | 
| 
      
 572 
     | 
    
         
            +
                  mysql_ssl_set(db, ssl_client_key, ssl_client_cert, ssl_ca_cert, ssl_ca_path, ssl_cipher);
         
     | 
| 
      
 573 
     | 
    
         
            +
                } else if(r_ssl != Qnil) {
         
     | 
| 
      
 574 
     | 
    
         
            +
                  rb_raise(eArgumentError, "ssl must be passed a hash");
         
     | 
| 
      
 575 
     | 
    
         
            +
                }
         
     | 
| 
      
 576 
     | 
    
         
            +
              }
         
     | 
| 
      
 577 
     | 
    
         
            +
            #endif
         
     | 
| 
       522 
578 
     | 
    
         | 
| 
       523 
579 
     | 
    
         
             
              result = (MYSQL *)mysql_real_connect(
         
     | 
| 
       524 
580 
     | 
    
         
             
                db,
         
     | 
| 
         @@ -532,8 +588,16 @@ static VALUE cConnection_initialize(VALUE self, VALUE uri) { 
     | 
|
| 
       532 
588 
     | 
    
         
             
              );
         
     | 
| 
       533 
589 
     | 
    
         | 
| 
       534 
590 
     | 
    
         
             
              if (NULL == result) {
         
     | 
| 
       535 
     | 
    
         
            -
                 
     | 
| 
      
 591 
     | 
    
         
            +
                raise_error(self, db, Qnil);
         
     | 
| 
      
 592 
     | 
    
         
            +
              }
         
     | 
| 
      
 593 
     | 
    
         
            +
             
     | 
| 
      
 594 
     | 
    
         
            +
            #ifdef HAVE_MYSQL_SSL_SET
         
     | 
| 
      
 595 
     | 
    
         
            +
              const char *ssl_cipher_used = mysql_get_ssl_cipher(db);
         
     | 
| 
      
 596 
     | 
    
         
            +
             
     | 
| 
      
 597 
     | 
    
         
            +
              if (NULL != ssl_cipher_used) {
         
     | 
| 
      
 598 
     | 
    
         
            +
                rb_iv_set(self, "@ssl_cipher", rb_str_new2(ssl_cipher_used));
         
     | 
| 
       536 
599 
     | 
    
         
             
              }
         
     | 
| 
      
 600 
     | 
    
         
            +
            #endif
         
     | 
| 
       537 
601 
     | 
    
         | 
| 
       538 
602 
     | 
    
         
             
            #ifdef MYSQL_OPT_RECONNECT
         
     | 
| 
       539 
603 
     | 
    
         
             
              my_bool reconnect = 1;
         
     | 
| 
         @@ -541,41 +605,110 @@ static VALUE cConnection_initialize(VALUE self, VALUE uri) { 
     | 
|
| 
       541 
605 
     | 
    
         
             
            #endif
         
     | 
| 
       542 
606 
     | 
    
         | 
| 
       543 
607 
     | 
    
         
             
              // Set the connections character set
         
     | 
| 
       544 
     | 
    
         
            -
               
     | 
| 
       545 
     | 
    
         
            -
             
     | 
| 
       546 
     | 
    
         
            -
             
     | 
| 
      
 608 
     | 
    
         
            +
              encoding = rb_iv_get(self, "@encoding");
         
     | 
| 
      
 609 
     | 
    
         
            +
             
     | 
| 
      
 610 
     | 
    
         
            +
              VALUE my_encoding = rb_hash_aref(CONST_GET(mEncoding, "MAP"), encoding);
         
     | 
| 
      
 611 
     | 
    
         
            +
              if(my_encoding != Qnil) {
         
     | 
| 
      
 612 
     | 
    
         
            +
                encoding_error = mysql_set_character_set(db, RSTRING_PTR(my_encoding));
         
     | 
| 
      
 613 
     | 
    
         
            +
                if (0 != encoding_error) {
         
     | 
| 
      
 614 
     | 
    
         
            +
                  raise_error(self, db, Qnil);
         
     | 
| 
      
 615 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 616 
     | 
    
         
            +
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
      
 617 
     | 
    
         
            +
                  rb_iv_set(self, "@encoding_id", INT2FIX(rb_enc_find_index(RSTRING_PTR(encoding))));
         
     | 
| 
      
 618 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 619 
     | 
    
         
            +
                  rb_iv_set(self, "@my_encoding", my_encoding);
         
     | 
| 
      
 620 
     | 
    
         
            +
                }
         
     | 
| 
      
 621 
     | 
    
         
            +
              } else {
         
     | 
| 
      
 622 
     | 
    
         
            +
                rb_warn("Encoding %s is not a known Ruby encoding for MySQL\n", RSTRING_PTR(encoding));
         
     | 
| 
      
 623 
     | 
    
         
            +
                rb_iv_set(self, "@encoding", rb_str_new2("UTF-8"));
         
     | 
| 
      
 624 
     | 
    
         
            +
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
      
 625 
     | 
    
         
            +
                rb_iv_set(self, "@encoding_id", INT2FIX(rb_enc_find_index("UTF-8")));
         
     | 
| 
      
 626 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 627 
     | 
    
         
            +
                rb_iv_set(self, "@my_encoding", rb_str_new2("utf8"));
         
     | 
| 
       547 
628 
     | 
    
         
             
              }
         
     | 
| 
       548 
629 
     | 
    
         | 
| 
       549 
630 
     | 
    
         
             
              // Disable sql_auto_is_null
         
     | 
| 
       550 
631 
     | 
    
         
             
              cCommand_execute(self, db, rb_str_new2("SET sql_auto_is_null = 0"));
         
     | 
| 
       551 
     | 
    
         
            -
               
     | 
| 
      
 632 
     | 
    
         
            +
              // removed NO_AUTO_VALUE_ON_ZERO because of MySQL bug http://bugs.mysql.com/bug.php?id=42270
         
     | 
| 
      
 633 
     | 
    
         
            +
              // added NO_BACKSLASH_ESCAPES so that backslashes should not be escaped as in other databases
         
     | 
| 
      
 634 
     | 
    
         
            +
              cCommand_execute(self, db, rb_str_new2("SET SESSION sql_mode = 'ANSI,NO_BACKSLASH_ESCAPES,NO_DIR_IN_CREATE,NO_ENGINE_SUBSTITUTION,NO_UNSIGNED_SUBTRACTION,TRADITIONAL'"));
         
     | 
| 
       552 
635 
     | 
    
         | 
| 
       553 
     | 
    
         
            -
              rb_iv_set(self, "@uri", uri);
         
     | 
| 
       554 
636 
     | 
    
         
             
              rb_iv_set(self, "@connection", Data_Wrap_Struct(rb_cObject, 0, 0, db));
         
     | 
| 
       555 
     | 
    
         
            -
             
     | 
| 
       556 
     | 
    
         
            -
              return Qtrue;
         
     | 
| 
       557 
637 
     | 
    
         
             
            }
         
     | 
| 
       558 
638 
     | 
    
         | 
| 
       559 
     | 
    
         
            -
            static VALUE  
     | 
| 
       560 
     | 
    
         
            -
              VALUE  
     | 
| 
       561 
     | 
    
         
            -
              MYSQL *db;
         
     | 
| 
      
 639 
     | 
    
         
            +
            static VALUE cConnection_initialize(VALUE self, VALUE uri) {
         
     | 
| 
      
 640 
     | 
    
         
            +
              VALUE r_host, r_user, r_password, r_path, r_query, r_port;
         
     | 
| 
       562 
641 
     | 
    
         | 
| 
       563 
     | 
    
         
            -
               
     | 
| 
      
 642 
     | 
    
         
            +
              MYSQL *db = 0;
         
     | 
| 
      
 643 
     | 
    
         
            +
              db = (MYSQL *)mysql_init(NULL);
         
     | 
| 
       564 
644 
     | 
    
         | 
| 
       565 
     | 
    
         
            -
               
     | 
| 
       566 
     | 
    
         
            -
             
     | 
| 
      
 645 
     | 
    
         
            +
              rb_iv_set(self, "@using_socket", Qfalse);
         
     | 
| 
      
 646 
     | 
    
         
            +
              rb_iv_set(self, "@ssl_cipher", Qnil);
         
     | 
| 
       567 
647 
     | 
    
         | 
| 
       568 
     | 
    
         
            -
               
     | 
| 
      
 648 
     | 
    
         
            +
              r_host = rb_funcall(uri, rb_intern("host"), 0);
         
     | 
| 
      
 649 
     | 
    
         
            +
              if (Qnil != r_host) {
         
     | 
| 
      
 650 
     | 
    
         
            +
                rb_iv_set(self, "@host", r_host);
         
     | 
| 
      
 651 
     | 
    
         
            +
              }
         
     | 
| 
      
 652 
     | 
    
         
            +
             
     | 
| 
      
 653 
     | 
    
         
            +
              r_user = rb_funcall(uri, rb_intern("user"), 0);
         
     | 
| 
      
 654 
     | 
    
         
            +
              if (Qnil != r_user) {
         
     | 
| 
      
 655 
     | 
    
         
            +
                rb_iv_set(self, "@user", r_user);
         
     | 
| 
      
 656 
     | 
    
         
            +
              }
         
     | 
| 
      
 657 
     | 
    
         
            +
             
     | 
| 
      
 658 
     | 
    
         
            +
              r_password = rb_funcall(uri, rb_intern("password"), 0);
         
     | 
| 
      
 659 
     | 
    
         
            +
              if (Qnil != r_password) {
         
     | 
| 
      
 660 
     | 
    
         
            +
                rb_iv_set(self, "@password", r_password);
         
     | 
| 
      
 661 
     | 
    
         
            +
              }
         
     | 
| 
      
 662 
     | 
    
         
            +
             
     | 
| 
      
 663 
     | 
    
         
            +
              r_path = rb_funcall(uri, rb_intern("path"), 0);
         
     | 
| 
      
 664 
     | 
    
         
            +
              if (Qnil != r_path) {
         
     | 
| 
      
 665 
     | 
    
         
            +
                rb_iv_set(self, "@path", r_path);
         
     | 
| 
      
 666 
     | 
    
         
            +
              }
         
     | 
| 
      
 667 
     | 
    
         
            +
             
     | 
| 
      
 668 
     | 
    
         
            +
              r_port = rb_funcall(uri, rb_intern("port"), 0);
         
     | 
| 
      
 669 
     | 
    
         
            +
              if (Qnil != r_port) {
         
     | 
| 
      
 670 
     | 
    
         
            +
                rb_iv_set(self, "@port", r_port);
         
     | 
| 
      
 671 
     | 
    
         
            +
              }
         
     | 
| 
      
 672 
     | 
    
         
            +
             
     | 
| 
      
 673 
     | 
    
         
            +
              // Pull the querystring off the URI
         
     | 
| 
      
 674 
     | 
    
         
            +
              r_query = rb_funcall(uri, rb_intern("query"), 0);
         
     | 
| 
      
 675 
     | 
    
         
            +
              rb_iv_set(self, "@query", r_query);
         
     | 
| 
      
 676 
     | 
    
         
            +
             
     | 
| 
      
 677 
     | 
    
         
            +
              const char* encoding = get_uri_option(r_query, "encoding");
         
     | 
| 
      
 678 
     | 
    
         
            +
              if (!encoding) { encoding = get_uri_option(r_query, "charset"); }
         
     | 
| 
      
 679 
     | 
    
         
            +
              if (!encoding) { encoding = "UTF-8"; }
         
     | 
| 
       569 
680 
     | 
    
         | 
| 
       570 
     | 
    
         
            -
              encoding  
     | 
| 
      
 681 
     | 
    
         
            +
              rb_iv_set(self, "@encoding", rb_str_new2(encoding));
         
     | 
| 
       571 
682 
     | 
    
         | 
| 
       572 
     | 
    
         
            -
               
     | 
| 
      
 683 
     | 
    
         
            +
              full_connect(self, db);
         
     | 
| 
      
 684 
     | 
    
         
            +
             
     | 
| 
      
 685 
     | 
    
         
            +
              rb_iv_set(self, "@uri", uri);
         
     | 
| 
      
 686 
     | 
    
         
            +
             
     | 
| 
      
 687 
     | 
    
         
            +
              return Qtrue;
         
     | 
| 
      
 688 
     | 
    
         
            +
            }
         
     | 
| 
      
 689 
     | 
    
         
            +
             
     | 
| 
      
 690 
     | 
    
         
            +
            static VALUE cConnection_character_set(VALUE self) {
         
     | 
| 
      
 691 
     | 
    
         
            +
              return rb_iv_get(self, "@encoding");
         
     | 
| 
       573 
692 
     | 
    
         
             
            }
         
     | 
| 
       574 
693 
     | 
    
         | 
| 
       575 
694 
     | 
    
         
             
            static VALUE cConnection_is_using_socket(VALUE self) {
         
     | 
| 
       576 
695 
     | 
    
         
             
              return rb_iv_get(self, "@using_socket");
         
     | 
| 
       577 
696 
     | 
    
         
             
            }
         
     | 
| 
       578 
697 
     | 
    
         | 
| 
      
 698 
     | 
    
         
            +
            static VALUE cConnection_ssl_cipher(VALUE self) {
         
     | 
| 
      
 699 
     | 
    
         
            +
              return rb_iv_get(self, "@ssl_cipher");
         
     | 
| 
      
 700 
     | 
    
         
            +
            }
         
     | 
| 
      
 701 
     | 
    
         
            +
             
     | 
| 
      
 702 
     | 
    
         
            +
            static VALUE cConnection_secure(VALUE self) {
         
     | 
| 
      
 703 
     | 
    
         
            +
              VALUE blank_cipher = rb_funcall(rb_iv_get(self, "@ssl_cipher"), rb_intern("blank?"), 0);
         
     | 
| 
      
 704 
     | 
    
         
            +
             
     | 
| 
      
 705 
     | 
    
         
            +
              if (blank_cipher == Qtrue) {
         
     | 
| 
      
 706 
     | 
    
         
            +
                return Qfalse;
         
     | 
| 
      
 707 
     | 
    
         
            +
              } else {
         
     | 
| 
      
 708 
     | 
    
         
            +
                return Qtrue;
         
     | 
| 
      
 709 
     | 
    
         
            +
              }
         
     | 
| 
      
 710 
     | 
    
         
            +
            }
         
     | 
| 
      
 711 
     | 
    
         
            +
             
     | 
| 
       579 
712 
     | 
    
         
             
            static VALUE cConnection_dispose(VALUE self) {
         
     | 
| 
       580 
713 
     | 
    
         
             
              VALUE connection_container = rb_iv_get(self, "@connection");
         
     | 
| 
       581 
714 
     | 
    
         | 
| 
         @@ -633,18 +766,18 @@ static VALUE cCommand_set_types(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       633 
766 
     | 
    
         
             
            }
         
     | 
| 
       634 
767 
     | 
    
         | 
| 
       635 
768 
     | 
    
         
             
            VALUE cConnection_quote_time(VALUE self, VALUE value) {
         
     | 
| 
       636 
     | 
    
         
            -
              return rb_funcall(value, ID_STRFTIME, 1,  
     | 
| 
      
 769 
     | 
    
         
            +
              return rb_funcall(value, ID_STRFTIME, 1, rb_str_new2("'%Y-%m-%d %H:%M:%S'"));
         
     | 
| 
       637 
770 
     | 
    
         
             
            }
         
     | 
| 
       638 
771 
     | 
    
         | 
| 
       639 
772 
     | 
    
         | 
| 
       640 
773 
     | 
    
         
             
            VALUE cConnection_quote_date_time(VALUE self, VALUE value) {
         
     | 
| 
       641 
774 
     | 
    
         
             
              // TODO: Support non-local dates. we need to call #new_offset on the date to be
         
     | 
| 
       642 
775 
     | 
    
         
             
              // quoted and pass in the current locale's date offset (self.new_offset((hours * 3600).to_r / 86400)
         
     | 
| 
       643 
     | 
    
         
            -
              return rb_funcall(value, ID_STRFTIME, 1,  
     | 
| 
      
 776 
     | 
    
         
            +
              return rb_funcall(value, ID_STRFTIME, 1, rb_str_new2("'%Y-%m-%d %H:%M:%S'"));
         
     | 
| 
       644 
777 
     | 
    
         
             
            }
         
     | 
| 
       645 
778 
     | 
    
         | 
| 
       646 
779 
     | 
    
         
             
            VALUE cConnection_quote_date(VALUE self, VALUE value) {
         
     | 
| 
       647 
     | 
    
         
            -
              return rb_funcall(value, ID_STRFTIME, 1,  
     | 
| 
      
 780 
     | 
    
         
            +
              return rb_funcall(value, ID_STRFTIME, 1, rb_str_new2("'%Y-%m-%d'"));
         
     | 
| 
       648 
781 
     | 
    
         
             
            }
         
     | 
| 
       649 
782 
     | 
    
         | 
| 
       650 
783 
     | 
    
         
             
            static VALUE cConnection_quote_string(VALUE self, VALUE string) {
         
     | 
| 
         @@ -666,7 +799,8 @@ static VALUE cConnection_quote_string(VALUE self, VALUE string) { 
     | 
|
| 
       666 
799 
     | 
    
         | 
| 
       667 
800 
     | 
    
         
             
              // Wrap the escaped string in single-quotes, this is DO's convention
         
     | 
| 
       668 
801 
     | 
    
         
             
              escaped[0] = escaped[quoted_length + 1] = '\'';
         
     | 
| 
       669 
     | 
    
         
            -
              result =  
     | 
| 
      
 802 
     | 
    
         
            +
              result = DO_STR_NEW(escaped, quoted_length + 2, FIX2INT(rb_iv_get(self, "@encoding_id")));
         
     | 
| 
      
 803 
     | 
    
         
            +
             
     | 
| 
       670 
804 
     | 
    
         
             
              free(escaped);
         
     | 
| 
       671 
805 
     | 
    
         
             
              return result;
         
     | 
| 
       672 
806 
     | 
    
         
             
            }
         
     | 
| 
         @@ -693,7 +827,7 @@ static VALUE cCommand_execute_non_query(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       693 
827 
     | 
    
         
             
              VALUE connection = rb_iv_get(self, "@connection");
         
     | 
| 
       694 
828 
     | 
    
         
             
              VALUE mysql_connection = rb_iv_get(connection, "@connection");
         
     | 
| 
       695 
829 
     | 
    
         
             
              if (Qnil == mysql_connection) {
         
     | 
| 
       696 
     | 
    
         
            -
                rb_raise( 
     | 
| 
      
 830 
     | 
    
         
            +
                rb_raise(eConnectionError, "This connection has already been closed.");
         
     | 
| 
       697 
831 
     | 
    
         
             
              }
         
     | 
| 
       698 
832 
     | 
    
         | 
| 
       699 
833 
     | 
    
         
             
              MYSQL *db = DATA_PTR(mysql_connection);
         
     | 
| 
         @@ -721,7 +855,7 @@ static VALUE cCommand_execute_reader(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       721 
855 
     | 
    
         
             
              VALUE connection = rb_iv_get(self, "@connection");
         
     | 
| 
       722 
856 
     | 
    
         
             
              VALUE mysql_connection = rb_iv_get(connection, "@connection");
         
     | 
| 
       723 
857 
     | 
    
         
             
              if (Qnil == mysql_connection) {
         
     | 
| 
       724 
     | 
    
         
            -
                rb_raise( 
     | 
| 
      
 858 
     | 
    
         
            +
                rb_raise(eConnectionError, "This connection has already been closed.");
         
     | 
| 
       725 
859 
     | 
    
         
             
              }
         
     | 
| 
       726 
860 
     | 
    
         | 
| 
       727 
861 
     | 
    
         
             
              MYSQL *db = DATA_PTR(mysql_connection);
         
     | 
| 
         @@ -740,8 +874,9 @@ static VALUE cCommand_execute_reader(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       740 
874 
     | 
    
         
             
              field_count = mysql_field_count(db);
         
     | 
| 
       741 
875 
     | 
    
         | 
| 
       742 
876 
     | 
    
         
             
              reader = rb_funcall(cReader, ID_NEW, 0);
         
     | 
| 
      
 877 
     | 
    
         
            +
              rb_iv_set(reader, "@connection", connection);
         
     | 
| 
       743 
878 
     | 
    
         
             
              rb_iv_set(reader, "@reader", Data_Wrap_Struct(rb_cObject, 0, 0, response));
         
     | 
| 
       744 
     | 
    
         
            -
              rb_iv_set(reader, "@opened",  
     | 
| 
      
 879 
     | 
    
         
            +
              rb_iv_set(reader, "@opened", Qfalse);
         
     | 
| 
       745 
880 
     | 
    
         
             
              rb_iv_set(reader, "@field_count", INT2NUM(field_count));
         
     | 
| 
       746 
881 
     | 
    
         | 
| 
       747 
882 
     | 
    
         
             
              field_names = rb_ary_new();
         
     | 
| 
         @@ -759,7 +894,7 @@ static VALUE cCommand_execute_reader(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       759 
894 
     | 
    
         | 
| 
       760 
895 
     | 
    
         
             
              for(i = 0; i < field_count; i++) {
         
     | 
| 
       761 
896 
     | 
    
         
             
                field = mysql_fetch_field_direct(response, i);
         
     | 
| 
       762 
     | 
    
         
            -
                rb_ary_push(field_names,  
     | 
| 
      
 897 
     | 
    
         
            +
                rb_ary_push(field_names, rb_str_new2(field->name));
         
     | 
| 
       763 
898 
     | 
    
         | 
| 
       764 
899 
     | 
    
         
             
                if (1 == guess_default_field_types) {
         
     | 
| 
       765 
900 
     | 
    
         
             
                  rb_ary_push(field_types, infer_ruby_type(field));
         
     | 
| 
         @@ -795,6 +930,7 @@ static VALUE cReader_close(VALUE self) { 
     | 
|
| 
       795 
930 
     | 
    
         | 
| 
       796 
931 
     | 
    
         
             
              mysql_free_result(reader);
         
     | 
| 
       797 
932 
     | 
    
         
             
              rb_iv_set(self, "@reader", Qnil);
         
     | 
| 
      
 933 
     | 
    
         
            +
              rb_iv_set(self, "@opened", Qfalse);
         
     | 
| 
       798 
934 
     | 
    
         | 
| 
       799 
935 
     | 
    
         
             
              return Qtrue;
         
     | 
| 
       800 
936 
     | 
    
         
             
            }
         
     | 
| 
         @@ -823,16 +959,24 @@ static VALUE cReader_next(VALUE self) { 
     | 
|
| 
       823 
959 
     | 
    
         
             
              result = mysql_fetch_row(reader);
         
     | 
| 
       824 
960 
     | 
    
         
             
              lengths = mysql_fetch_lengths(reader);
         
     | 
| 
       825 
961 
     | 
    
         | 
| 
       826 
     | 
    
         
            -
              rb_iv_set(self, "@ 
     | 
| 
      
 962 
     | 
    
         
            +
              rb_iv_set(self, "@opened", result ? Qtrue : Qfalse);
         
     | 
| 
       827 
963 
     | 
    
         | 
| 
       828 
964 
     | 
    
         
             
              if (!result) {
         
     | 
| 
       829 
965 
     | 
    
         
             
                return Qfalse;
         
     | 
| 
       830 
966 
     | 
    
         
             
              }
         
     | 
| 
       831 
967 
     | 
    
         | 
| 
      
 968 
     | 
    
         
            +
              int enc = -1;
         
     | 
| 
      
 969 
     | 
    
         
            +
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
      
 970 
     | 
    
         
            +
              VALUE encoding_id = rb_iv_get(rb_iv_get(self, "@connection"), "@encoding_id");
         
     | 
| 
      
 971 
     | 
    
         
            +
              if (encoding_id != Qnil) {
         
     | 
| 
      
 972 
     | 
    
         
            +
                enc = FIX2INT(encoding_id);
         
     | 
| 
      
 973 
     | 
    
         
            +
              }
         
     | 
| 
      
 974 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 975 
     | 
    
         
            +
             
     | 
| 
       832 
976 
     | 
    
         
             
              for (i = 0; i < reader->field_count; i++) {
         
     | 
| 
       833 
977 
     | 
    
         
             
                // The field_type data could be cached in a c-array
         
     | 
| 
       834 
978 
     | 
    
         
             
                field_type = rb_ary_entry(field_types, i);
         
     | 
| 
       835 
     | 
    
         
            -
                rb_ary_push(row, typecast(result[i], lengths[i], field_type));
         
     | 
| 
      
 979 
     | 
    
         
            +
                rb_ary_push(row, typecast(result[i], lengths[i], field_type, enc));
         
     | 
| 
       836 
980 
     | 
    
         
             
              }
         
     | 
| 
       837 
981 
     | 
    
         | 
| 
       838 
982 
     | 
    
         
             
              rb_iv_set(self, "@values", row);
         
     | 
| 
         @@ -841,9 +985,9 @@ static VALUE cReader_next(VALUE self) { 
     | 
|
| 
       841 
985 
     | 
    
         
             
            }
         
     | 
| 
       842 
986 
     | 
    
         | 
| 
       843 
987 
     | 
    
         
             
            static VALUE cReader_values(VALUE self) {
         
     | 
| 
       844 
     | 
    
         
            -
              VALUE state = rb_iv_get(self, "@ 
     | 
| 
      
 988 
     | 
    
         
            +
              VALUE state = rb_iv_get(self, "@opened");
         
     | 
| 
       845 
989 
     | 
    
         
             
              if ( state == Qnil || state == Qfalse ) {
         
     | 
| 
       846 
     | 
    
         
            -
                rb_raise( 
     | 
| 
      
 990 
     | 
    
         
            +
                rb_raise(eDataError, "Reader is not initialized");
         
     | 
| 
       847 
991 
     | 
    
         
             
              }
         
     | 
| 
       848 
992 
     | 
    
         
             
              else {
         
     | 
| 
       849 
993 
     | 
    
         
             
                return rb_iv_get(self, "@values");
         
     | 
| 
         @@ -858,15 +1002,11 @@ static VALUE cReader_field_count(VALUE self) { 
     | 
|
| 
       858 
1002 
     | 
    
         
             
              return rb_iv_get(self, "@field_count");
         
     | 
| 
       859 
1003 
     | 
    
         
             
            }
         
     | 
| 
       860 
1004 
     | 
    
         | 
| 
       861 
     | 
    
         
            -
            static VALUE cReader_row_count(VALUE self) {
         
     | 
| 
       862 
     | 
    
         
            -
              return rb_iv_get(self, "@row_count");
         
     | 
| 
       863 
     | 
    
         
            -
            }
         
     | 
| 
       864 
     | 
    
         
            -
             
     | 
| 
       865 
1005 
     | 
    
         
             
            void Init_do_mysql_ext() {
         
     | 
| 
       866 
1006 
     | 
    
         
             
              rb_require("bigdecimal");
         
     | 
| 
       867 
1007 
     | 
    
         
             
              rb_require("date");
         
     | 
| 
       868 
1008 
     | 
    
         | 
| 
       869 
     | 
    
         
            -
              rb_funcall(rb_mKernel, rb_intern("require"), 1,  
     | 
| 
      
 1009 
     | 
    
         
            +
              rb_funcall(rb_mKernel, rb_intern("require"), 1, rb_str_new2("data_objects"));
         
     | 
| 
       870 
1010 
     | 
    
         | 
| 
       871 
1011 
     | 
    
         
             
              ID_TO_I = rb_intern("to_i");
         
     | 
| 
       872 
1012 
     | 
    
         
             
              ID_TO_F = rb_intern("to_f");
         
     | 
| 
         @@ -908,11 +1048,15 @@ void Init_do_mysql_ext() { 
     | 
|
| 
       908 
1048 
     | 
    
         
             
              mDOMysql = rb_define_module_under(mDO, "Mysql");
         
     | 
| 
       909 
1049 
     | 
    
         | 
| 
       910 
1050 
     | 
    
         
             
              eArgumentError = CONST_GET(rb_mKernel, "ArgumentError");
         
     | 
| 
       911 
     | 
    
         
            -
               
     | 
| 
      
 1051 
     | 
    
         
            +
              eConnectionError = CONST_GET(mDO, "ConnectionError");
         
     | 
| 
      
 1052 
     | 
    
         
            +
              eDataError = CONST_GET(mDO, "DataError");
         
     | 
| 
      
 1053 
     | 
    
         
            +
              mEncoding = rb_define_module_under(mDOMysql, "Encoding");
         
     | 
| 
       912 
1054 
     | 
    
         | 
| 
       913 
1055 
     | 
    
         
             
              cConnection = DRIVER_CLASS("Connection", cDO_Connection);
         
     | 
| 
       914 
1056 
     | 
    
         
             
              rb_define_method(cConnection, "initialize", cConnection_initialize, 1);
         
     | 
| 
       915 
1057 
     | 
    
         
             
              rb_define_method(cConnection, "using_socket?", cConnection_is_using_socket, 0);
         
     | 
| 
      
 1058 
     | 
    
         
            +
              rb_define_method(cConnection, "ssl_cipher", cConnection_ssl_cipher, 0);
         
     | 
| 
      
 1059 
     | 
    
         
            +
              rb_define_method(cConnection, "secure?", cConnection_secure, 0);
         
     | 
| 
       916 
1060 
     | 
    
         
             
              rb_define_method(cConnection, "character_set", cConnection_character_set , 0);
         
     | 
| 
       917 
1061 
     | 
    
         
             
              rb_define_method(cConnection, "dispose", cConnection_dispose, 0);
         
     | 
| 
       918 
1062 
     | 
    
         
             
              rb_define_method(cConnection, "quote_string", cConnection_quote_string, 1);
         
     | 
| 
         @@ -935,5 +1079,10 @@ void Init_do_mysql_ext() { 
     | 
|
| 
       935 
1079 
     | 
    
         
             
              rb_define_method(cReader, "values", cReader_values, 0);
         
     | 
| 
       936 
1080 
     | 
    
         
             
              rb_define_method(cReader, "fields", cReader_fields, 0);
         
     | 
| 
       937 
1081 
     | 
    
         
             
              rb_define_method(cReader, "field_count", cReader_field_count, 0);
         
     | 
| 
       938 
     | 
    
         
            -
             
     | 
| 
      
 1082 
     | 
    
         
            +
             
     | 
| 
      
 1083 
     | 
    
         
            +
              struct errcodes *errs;
         
     | 
| 
      
 1084 
     | 
    
         
            +
             
     | 
| 
      
 1085 
     | 
    
         
            +
              for (errs = errors; errs->error_name; errs++) {
         
     | 
| 
      
 1086 
     | 
    
         
            +
                rb_const_set(mDOMysql, rb_intern(errs->error_name), INT2NUM(errs->error_no));
         
     | 
| 
      
 1087 
     | 
    
         
            +
              }
         
     | 
| 
       939 
1088 
     | 
    
         
             
            }
         
     |