mysql2 0.4.10 → 0.5.3
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.
- checksums.yaml +5 -5
 - data/README.md +66 -32
 - data/ext/mysql2/client.c +125 -59
 - data/ext/mysql2/client.h +1 -39
 - data/ext/mysql2/extconf.rb +24 -21
 - data/ext/mysql2/mysql2_ext.c +2 -1
 - data/ext/mysql2/mysql2_ext.h +8 -4
 - data/ext/mysql2/mysql_enc_name_to_ruby.h +60 -56
 - data/ext/mysql2/mysql_enc_to_ruby.h +64 -3
 - data/ext/mysql2/result.c +32 -85
 - data/ext/mysql2/result.h +2 -3
 - data/ext/mysql2/statement.c +81 -72
 - data/ext/mysql2/statement.h +0 -2
 - data/ext/mysql2/wait_for_single_fd.h +2 -1
 - data/lib/mysql2.rb +17 -15
 - data/lib/mysql2/client.rb +33 -27
 - data/lib/mysql2/em.rb +2 -4
 - data/lib/mysql2/error.rb +51 -22
 - data/lib/mysql2/result.rb +2 -0
 - data/lib/mysql2/statement.rb +3 -9
 - data/lib/mysql2/version.rb +1 -1
 - data/support/5072E1F5.asc +5 -5
 - data/support/mysql_enc_to_ruby.rb +8 -3
 - data/support/ruby_enc_to_mysql.rb +7 -5
 - metadata +8 -58
 - data/examples/eventmachine.rb +0 -21
 - data/examples/threaded.rb +0 -18
 - data/spec/configuration.yml.example +0 -11
 - data/spec/em/em_spec.rb +0 -136
 - data/spec/my.cnf.example +0 -9
 - data/spec/mysql2/client_spec.rb +0 -1039
 - data/spec/mysql2/error_spec.rb +0 -82
 - data/spec/mysql2/result_spec.rb +0 -545
 - data/spec/mysql2/statement_spec.rb +0 -776
 - data/spec/rcov.opts +0 -3
 - data/spec/spec_helper.rb +0 -108
 - data/spec/ssl/ca-cert.pem +0 -17
 - data/spec/ssl/ca-key.pem +0 -27
 - data/spec/ssl/ca.cnf +0 -22
 - data/spec/ssl/cert.cnf +0 -22
 - data/spec/ssl/client-cert.pem +0 -17
 - data/spec/ssl/client-key.pem +0 -27
 - data/spec/ssl/client-req.pem +0 -15
 - data/spec/ssl/gen_certs.sh +0 -48
 - data/spec/ssl/pkcs8-client-key.pem +0 -28
 - data/spec/ssl/pkcs8-server-key.pem +0 -28
 - data/spec/ssl/server-cert.pem +0 -17
 - data/spec/ssl/server-key.pem +0 -27
 - data/spec/ssl/server-req.pem +0 -15
 - data/spec/test_data +0 -1
 
    
        data/ext/mysql2/result.c
    CHANGED
    
    | 
         @@ -1,52 +1,21 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #include <mysql2_ext.h>
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            #include "mysql_enc_to_ruby.h"
         
     | 
| 
      
 4 
     | 
    
         
            +
            #define MYSQL2_CHARSETNR_SIZE (sizeof(mysql2_mysql_enc_to_rb)/sizeof(mysql2_mysql_enc_to_rb[0]))
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       6 
6 
     | 
    
         
             
            static rb_encoding *binaryEncoding;
         
     | 
| 
       7 
     | 
    
         
            -
            #endif
         
     | 
| 
       8 
7 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
            #if (SIZEOF_INT < SIZEOF_LONG) || defined(HAVE_RUBY_ENCODING_H)
         
     | 
| 
       10 
8 
     | 
    
         
             
            /* on 64bit platforms we can handle dates way outside 2038-01-19T03:14:07
         
     | 
| 
       11 
9 
     | 
    
         
             
             *
         
     | 
| 
       12 
10 
     | 
    
         
             
             * (9999*31557600) + (12*2592000) + (31*86400) + (11*3600) + (59*60) + 59
         
     | 
| 
       13 
11 
     | 
    
         
             
             */
         
     | 
| 
       14 
12 
     | 
    
         
             
            #define MYSQL2_MAX_TIME 315578267999ULL
         
     | 
| 
       15 
     | 
    
         
            -
            #else
         
     | 
| 
       16 
     | 
    
         
            -
            /**
         
     | 
| 
       17 
     | 
    
         
            -
             * On 32bit platforms the maximum date the Time class can handle is 2038-01-19T03:14:07
         
     | 
| 
       18 
     | 
    
         
            -
             * 2038 years + 1 month + 19 days + 3 hours + 14 minutes + 7 seconds = 64318634047 seconds
         
     | 
| 
       19 
     | 
    
         
            -
             *
         
     | 
| 
       20 
     | 
    
         
            -
             * (2038*31557600) + (1*2592000) + (19*86400) + (3*3600) + (14*60) + 7
         
     | 
| 
       21 
     | 
    
         
            -
             */
         
     | 
| 
       22 
     | 
    
         
            -
            #define MYSQL2_MAX_TIME 64318634047ULL
         
     | 
| 
       23 
     | 
    
         
            -
            #endif
         
     | 
| 
       24 
13 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
            #if defined(HAVE_RUBY_ENCODING_H)
         
     | 
| 
       26 
14 
     | 
    
         
             
            /* 0000-1-1 00:00:00 UTC
         
     | 
| 
       27 
15 
     | 
    
         
             
             *
         
     | 
| 
       28 
16 
     | 
    
         
             
             * (0*31557600) + (1*2592000) + (1*86400) + (0*3600) + (0*60) + 0
         
     | 
| 
       29 
17 
     | 
    
         
             
             */
         
     | 
| 
       30 
18 
     | 
    
         
             
            #define MYSQL2_MIN_TIME 2678400ULL
         
     | 
| 
       31 
     | 
    
         
            -
            #elif SIZEOF_INT < SIZEOF_LONG /* 64bit Ruby 1.8 */
         
     | 
| 
       32 
     | 
    
         
            -
            /* 0139-1-1 00:00:00 UTC
         
     | 
| 
       33 
     | 
    
         
            -
             *
         
     | 
| 
       34 
     | 
    
         
            -
             * (139*31557600) + (1*2592000) + (1*86400) + (0*3600) + (0*60) + 0
         
     | 
| 
       35 
     | 
    
         
            -
             */
         
     | 
| 
       36 
     | 
    
         
            -
            #define MYSQL2_MIN_TIME 4389184800ULL
         
     | 
| 
       37 
     | 
    
         
            -
            #elif defined(NEGATIVE_TIME_T)
         
     | 
| 
       38 
     | 
    
         
            -
            /* 1901-12-13 20:45:52 UTC : The oldest time in 32-bit signed time_t.
         
     | 
| 
       39 
     | 
    
         
            -
             *
         
     | 
| 
       40 
     | 
    
         
            -
             * (1901*31557600) + (12*2592000) + (13*86400) + (20*3600) + (45*60) + 52
         
     | 
| 
       41 
     | 
    
         
            -
             */
         
     | 
| 
       42 
     | 
    
         
            -
            #define MYSQL2_MIN_TIME 60023299552ULL
         
     | 
| 
       43 
     | 
    
         
            -
            #else
         
     | 
| 
       44 
     | 
    
         
            -
            /* 1970-01-01 00:00:01 UTC : The Unix epoch - the oldest time in portable time_t.
         
     | 
| 
       45 
     | 
    
         
            -
             *
         
     | 
| 
       46 
     | 
    
         
            -
             * (1970*31557600) + (1*2592000) + (1*86400) + (0*3600) + (0*60) + 1
         
     | 
| 
       47 
     | 
    
         
            -
             */
         
     | 
| 
       48 
     | 
    
         
            -
            #define MYSQL2_MIN_TIME 62171150401ULL
         
     | 
| 
       49 
     | 
    
         
            -
            #endif
         
     | 
| 
       50 
19 
     | 
    
         | 
| 
       51 
20 
     | 
    
         
             
            #define GET_RESULT(self) \
         
     | 
| 
       52 
21 
     | 
    
         
             
              mysql2_result_wrapper *wrapper; \
         
     | 
| 
         @@ -61,17 +30,18 @@ typedef struct { 
     | 
|
| 
       61 
30 
     | 
    
         
             
              int streaming;
         
     | 
| 
       62 
31 
     | 
    
         
             
              ID db_timezone;
         
     | 
| 
       63 
32 
     | 
    
         
             
              ID app_timezone;
         
     | 
| 
       64 
     | 
    
         
            -
               
     | 
| 
      
 33 
     | 
    
         
            +
              int block_given; /* boolean */
         
     | 
| 
       65 
34 
     | 
    
         
             
            } result_each_args;
         
     | 
| 
       66 
35 
     | 
    
         | 
| 
       67 
     | 
    
         
            -
            VALUE cBigDecimal, cDateTime, cDate;
         
     | 
| 
       68 
     | 
    
         
            -
            static VALUE cMysql2Result;
         
     | 
| 
       69 
     | 
    
         
            -
            static VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month, opt_utc_offset;
         
     | 
| 
       70 
36 
     | 
    
         
             
            extern VALUE mMysql2, cMysql2Client, cMysql2Error;
         
     | 
| 
       71 
     | 
    
         
            -
            static  
     | 
| 
       72 
     | 
    
         
            -
            static VALUE  
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
      
 37 
     | 
    
         
            +
            static VALUE cMysql2Result, cDateTime, cDate;
         
     | 
| 
      
 38 
     | 
    
         
            +
            static VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month, opt_utc_offset;
         
     | 
| 
      
 39 
     | 
    
         
            +
            static ID intern_new, intern_utc, intern_local, intern_localtime, intern_local_offset,
         
     | 
| 
      
 40 
     | 
    
         
            +
              intern_civil, intern_new_offset, intern_merge, intern_BigDecimal,
         
     | 
| 
      
 41 
     | 
    
         
            +
              intern_query_options;
         
     | 
| 
      
 42 
     | 
    
         
            +
            static VALUE sym_symbolize_keys, sym_as, sym_array, sym_database_timezone,
         
     | 
| 
      
 43 
     | 
    
         
            +
              sym_application_timezone, sym_local, sym_utc, sym_cast_booleans,
         
     | 
| 
      
 44 
     | 
    
         
            +
              sym_cache_rows, sym_cast, sym_stream, sym_name;
         
     | 
| 
       75 
45 
     | 
    
         | 
| 
       76 
46 
     | 
    
         
             
            /* Mark any VALUEs that are only referenced in C, so the GC won't get them. */
         
     | 
| 
       77 
47 
     | 
    
         
             
            static void rb_mysql_result_mark(void * wrapper) {
         
     | 
| 
         @@ -179,29 +149,19 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, int symbo 
     | 
|
| 
       179 
149 
     | 
    
         
             
              rb_field = rb_ary_entry(wrapper->fields, idx);
         
     | 
| 
       180 
150 
     | 
    
         
             
              if (rb_field == Qnil) {
         
     | 
| 
       181 
151 
     | 
    
         
             
                MYSQL_FIELD *field = NULL;
         
     | 
| 
       182 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       183 
152 
     | 
    
         
             
                rb_encoding *default_internal_enc = rb_default_internal_encoding();
         
     | 
| 
       184 
153 
     | 
    
         
             
                rb_encoding *conn_enc = rb_to_encoding(wrapper->encoding);
         
     | 
| 
       185 
     | 
    
         
            -
            #endif
         
     | 
| 
       186 
154 
     | 
    
         | 
| 
       187 
155 
     | 
    
         
             
                field = mysql_fetch_field_direct(wrapper->result, idx);
         
     | 
| 
       188 
156 
     | 
    
         
             
                if (symbolize_keys) {
         
     | 
| 
       189 
     | 
    
         
            -
            #ifdef HAVE_RB_INTERN3
         
     | 
| 
       190 
157 
     | 
    
         
             
                  rb_field = rb_intern3(field->name, field->name_length, rb_utf8_encoding());
         
     | 
| 
       191 
158 
     | 
    
         
             
                  rb_field = ID2SYM(rb_field);
         
     | 
| 
       192 
     | 
    
         
            -
            #else
         
     | 
| 
       193 
     | 
    
         
            -
                  VALUE colStr;
         
     | 
| 
       194 
     | 
    
         
            -
                  colStr = rb_str_new(field->name, field->name_length);
         
     | 
| 
       195 
     | 
    
         
            -
                  rb_field = ID2SYM(rb_to_id(colStr));
         
     | 
| 
       196 
     | 
    
         
            -
            #endif
         
     | 
| 
       197 
159 
     | 
    
         
             
                } else {
         
     | 
| 
       198 
160 
     | 
    
         
             
                  rb_field = rb_str_new(field->name, field->name_length);
         
     | 
| 
       199 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       200 
161 
     | 
    
         
             
                  rb_enc_associate(rb_field, conn_enc);
         
     | 
| 
       201 
162 
     | 
    
         
             
                  if (default_internal_enc) {
         
     | 
| 
       202 
163 
     | 
    
         
             
                    rb_field = rb_str_export_to_enc(rb_field, default_internal_enc);
         
     | 
| 
       203 
164 
     | 
    
         
             
                  }
         
     | 
| 
       204 
     | 
    
         
            -
            #endif
         
     | 
| 
       205 
165 
     | 
    
         
             
                }
         
     | 
| 
       206 
166 
     | 
    
         
             
                rb_ary_store(wrapper->fields, idx, rb_field);
         
     | 
| 
       207 
167 
     | 
    
         
             
              }
         
     | 
| 
         @@ -209,7 +169,6 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, int symbo 
     | 
|
| 
       209 
169 
     | 
    
         
             
              return rb_field;
         
     | 
| 
       210 
170 
     | 
    
         
             
            }
         
     | 
| 
       211 
171 
     | 
    
         | 
| 
       212 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       213 
172 
     | 
    
         
             
            static VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_encoding *default_internal_enc, rb_encoding *conn_enc) {
         
     | 
| 
       214 
173 
     | 
    
         
             
              /* if binary flag is set, respect its wishes */
         
     | 
| 
       215 
174 
     | 
    
         
             
              if (field.flags & BINARY_FLAG && field.charsetnr == 63) {
         
     | 
| 
         @@ -222,7 +181,8 @@ static VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_e 
     | 
|
| 
       222 
181 
     | 
    
         
             
                const char *enc_name;
         
     | 
| 
       223 
182 
     | 
    
         
             
                int enc_index;
         
     | 
| 
       224 
183 
     | 
    
         | 
| 
       225 
     | 
    
         
            -
                enc_name = mysql2_mysql_enc_to_rb[field.charsetnr-1];
         
     | 
| 
      
 184 
     | 
    
         
            +
                enc_name = (field.charsetnr-1 < MYSQL2_CHARSETNR_SIZE) ? mysql2_mysql_enc_to_rb[field.charsetnr-1] : NULL;
         
     | 
| 
      
 185 
     | 
    
         
            +
                
         
     | 
| 
       226 
186 
     | 
    
         
             
                if (enc_name != NULL) {
         
     | 
| 
       227 
187 
     | 
    
         
             
                  /* use the field encoding we were able to match */
         
     | 
| 
       228 
188 
     | 
    
         
             
                  enc_index = rb_enc_find_index(enc_name);
         
     | 
| 
         @@ -238,7 +198,6 @@ static VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_e 
     | 
|
| 
       238 
198 
     | 
    
         
             
              }
         
     | 
| 
       239 
199 
     | 
    
         
             
              return val;
         
     | 
| 
       240 
200 
     | 
    
         
             
            }
         
     | 
| 
       241 
     | 
    
         
            -
            #endif
         
     | 
| 
       242 
201 
     | 
    
         | 
| 
       243 
202 
     | 
    
         
             
            /* Interpret microseconds digits left-aligned in fixed-width field.
         
     | 
| 
       244 
203 
     | 
    
         
             
             * e.g. 10.123 seconds means 10 seconds and 123000 microseconds,
         
     | 
| 
         @@ -262,8 +221,8 @@ static void rb_mysql_result_alloc_result_buffers(VALUE self, MYSQL_FIELD *fields 
     | 
|
| 
       262 
221 
     | 
    
         
             
              if (wrapper->result_buffers != NULL) return;
         
     | 
| 
       263 
222 
     | 
    
         | 
| 
       264 
223 
     | 
    
         
             
              wrapper->result_buffers = xcalloc(wrapper->numberOfFields, sizeof(MYSQL_BIND));
         
     | 
| 
       265 
     | 
    
         
            -
              wrapper->is_null = xcalloc(wrapper->numberOfFields, sizeof( 
     | 
| 
       266 
     | 
    
         
            -
              wrapper->error = xcalloc(wrapper->numberOfFields, sizeof( 
     | 
| 
      
 224 
     | 
    
         
            +
              wrapper->is_null = xcalloc(wrapper->numberOfFields, sizeof(my_bool));
         
     | 
| 
      
 225 
     | 
    
         
            +
              wrapper->error = xcalloc(wrapper->numberOfFields, sizeof(my_bool));
         
     | 
| 
       267 
226 
     | 
    
         
             
              wrapper->length = xcalloc(wrapper->numberOfFields, sizeof(unsigned long));
         
     | 
| 
       268 
227 
     | 
    
         | 
| 
       269 
228 
     | 
    
         
             
              for (i = 0; i < wrapper->numberOfFields; i++) {
         
     | 
| 
         @@ -278,12 +237,12 @@ static void rb_mysql_result_alloc_result_buffers(VALUE self, MYSQL_FIELD *fields 
     | 
|
| 
       278 
237 
     | 
    
         
             
                    wrapper->result_buffers[i].buffer_length = sizeof(signed char);
         
     | 
| 
       279 
238 
     | 
    
         
             
                    break;
         
     | 
| 
       280 
239 
     | 
    
         
             
                  case MYSQL_TYPE_SHORT:        // short int
         
     | 
| 
      
 240 
     | 
    
         
            +
                  case MYSQL_TYPE_YEAR:         // short int
         
     | 
| 
       281 
241 
     | 
    
         
             
                    wrapper->result_buffers[i].buffer = xcalloc(1, sizeof(short int));
         
     | 
| 
       282 
242 
     | 
    
         
             
                    wrapper->result_buffers[i].buffer_length = sizeof(short int);
         
     | 
| 
       283 
243 
     | 
    
         
             
                    break;
         
     | 
| 
       284 
244 
     | 
    
         
             
                  case MYSQL_TYPE_INT24:        // int
         
     | 
| 
       285 
245 
     | 
    
         
             
                  case MYSQL_TYPE_LONG:         // int
         
     | 
| 
       286 
     | 
    
         
            -
                  case MYSQL_TYPE_YEAR:         // int
         
     | 
| 
       287 
246 
     | 
    
         
             
                    wrapper->result_buffers[i].buffer = xcalloc(1, sizeof(int));
         
     | 
| 
       288 
247 
     | 
    
         
             
                    wrapper->result_buffers[i].buffer_length = sizeof(int);
         
     | 
| 
       289 
248 
     | 
    
         
             
                    break;
         
     | 
| 
         @@ -335,16 +294,12 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co 
     | 
|
| 
       335 
294 
     | 
    
         
             
              VALUE rowVal;
         
     | 
| 
       336 
295 
     | 
    
         
             
              unsigned int i = 0;
         
     | 
| 
       337 
296 
     | 
    
         | 
| 
       338 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       339 
297 
     | 
    
         
             
              rb_encoding *default_internal_enc;
         
     | 
| 
       340 
298 
     | 
    
         
             
              rb_encoding *conn_enc;
         
     | 
| 
       341 
     | 
    
         
            -
            #endif
         
     | 
| 
       342 
299 
     | 
    
         
             
              GET_RESULT(self);
         
     | 
| 
       343 
300 
     | 
    
         | 
| 
       344 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       345 
301 
     | 
    
         
             
              default_internal_enc = rb_default_internal_encoding();
         
     | 
| 
       346 
302 
     | 
    
         
             
              conn_enc = rb_to_encoding(wrapper->encoding);
         
     | 
| 
       347 
     | 
    
         
            -
            #endif
         
     | 
| 
       348 
303 
     | 
    
         | 
| 
       349 
304 
     | 
    
         
             
              if (wrapper->fields == Qnil) {
         
     | 
| 
       350 
305 
     | 
    
         
             
                wrapper->numberOfFields = mysql_num_fields(wrapper->result);
         
     | 
| 
         @@ -413,6 +368,7 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co 
     | 
|
| 
       413 
368 
     | 
    
         
             
                      }
         
     | 
| 
       414 
369 
     | 
    
         
             
                      break;
         
     | 
| 
       415 
370 
     | 
    
         
             
                    case MYSQL_TYPE_SHORT:        // short int
         
     | 
| 
      
 371 
     | 
    
         
            +
                    case MYSQL_TYPE_YEAR:         // short int
         
     | 
| 
       416 
372 
     | 
    
         
             
                      if (result_buffer->is_unsigned) {
         
     | 
| 
       417 
373 
     | 
    
         
             
                        val = UINT2NUM(*((unsigned short int*)result_buffer->buffer));
         
     | 
| 
       418 
374 
     | 
    
         
             
                      } else  {
         
     | 
| 
         @@ -421,7 +377,6 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co 
     | 
|
| 
       421 
377 
     | 
    
         
             
                      break;
         
     | 
| 
       422 
378 
     | 
    
         
             
                    case MYSQL_TYPE_INT24:        // int
         
     | 
| 
       423 
379 
     | 
    
         
             
                    case MYSQL_TYPE_LONG:         // int
         
     | 
| 
       424 
     | 
    
         
            -
                    case MYSQL_TYPE_YEAR:         // int
         
     | 
| 
       425 
380 
     | 
    
         
             
                      if (result_buffer->is_unsigned) {
         
     | 
| 
       426 
381 
     | 
    
         
             
                        val = UINT2NUM(*((unsigned int*)result_buffer->buffer));
         
     | 
| 
       427 
382 
     | 
    
         
             
                      } else {
         
     | 
| 
         @@ -492,7 +447,7 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co 
     | 
|
| 
       492 
447 
     | 
    
         
             
                    }
         
     | 
| 
       493 
448 
     | 
    
         
             
                    case MYSQL_TYPE_DECIMAL:      // char[]
         
     | 
| 
       494 
449 
     | 
    
         
             
                    case MYSQL_TYPE_NEWDECIMAL:   // char[]
         
     | 
| 
       495 
     | 
    
         
            -
                      val = rb_funcall( 
     | 
| 
      
 450 
     | 
    
         
            +
                      val = rb_funcall(rb_mKernel, intern_BigDecimal, 1, rb_str_new(result_buffer->buffer, *(result_buffer->length)));
         
     | 
| 
       496 
451 
     | 
    
         
             
                      break;
         
     | 
| 
       497 
452 
     | 
    
         
             
                    case MYSQL_TYPE_STRING:       // char[]
         
     | 
| 
       498 
453 
     | 
    
         
             
                    case MYSQL_TYPE_VAR_STRING:   // char[]
         
     | 
| 
         @@ -506,9 +461,7 @@ static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, co 
     | 
|
| 
       506 
461 
     | 
    
         
             
                    case MYSQL_TYPE_GEOMETRY:     // char[]
         
     | 
| 
       507 
462 
     | 
    
         
             
                    default:
         
     | 
| 
       508 
463 
     | 
    
         
             
                      val = rb_str_new(result_buffer->buffer, *(result_buffer->length));
         
     | 
| 
       509 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       510 
464 
     | 
    
         
             
                      val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc);
         
     | 
| 
       511 
     | 
    
         
            -
            #endif
         
     | 
| 
       512 
465 
     | 
    
         
             
                      break;
         
     | 
| 
       513 
466 
     | 
    
         
             
                  }
         
     | 
| 
       514 
467 
     | 
    
         
             
                }
         
     | 
| 
         @@ -530,16 +483,12 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, MYSQL_FIELD * fields, const r 
     | 
|
| 
       530 
483 
     | 
    
         
             
              unsigned int i = 0;
         
     | 
| 
       531 
484 
     | 
    
         
             
              unsigned long * fieldLengths;
         
     | 
| 
       532 
485 
     | 
    
         
             
              void * ptr;
         
     | 
| 
       533 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       534 
486 
     | 
    
         
             
              rb_encoding *default_internal_enc;
         
     | 
| 
       535 
487 
     | 
    
         
             
              rb_encoding *conn_enc;
         
     | 
| 
       536 
     | 
    
         
            -
            #endif
         
     | 
| 
       537 
488 
     | 
    
         
             
              GET_RESULT(self);
         
     | 
| 
       538 
489 
     | 
    
         | 
| 
       539 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       540 
490 
     | 
    
         
             
              default_internal_enc = rb_default_internal_encoding();
         
     | 
| 
       541 
491 
     | 
    
         
             
              conn_enc = rb_to_encoding(wrapper->encoding);
         
     | 
| 
       542 
     | 
    
         
            -
            #endif
         
     | 
| 
       543 
492 
     | 
    
         | 
| 
       544 
493 
     | 
    
         
             
              ptr = wrapper->result;
         
     | 
| 
       545 
494 
     | 
    
         
             
              row = (MYSQL_ROW)rb_thread_call_without_gvl(nogvl_fetch_row, ptr, RUBY_UBF_IO, 0);
         
     | 
| 
         @@ -569,9 +518,7 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, MYSQL_FIELD * fields, const r 
     | 
|
| 
       569 
518 
     | 
    
         
             
                      val = Qnil;
         
     | 
| 
       570 
519 
     | 
    
         
             
                    } else {
         
     | 
| 
       571 
520 
     | 
    
         
             
                      val = rb_str_new(row[i], fieldLengths[i]);
         
     | 
| 
       572 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       573 
521 
     | 
    
         
             
                      val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc);
         
     | 
| 
       574 
     | 
    
         
            -
            #endif
         
     | 
| 
       575 
522 
     | 
    
         
             
                    }
         
     | 
| 
       576 
523 
     | 
    
         
             
                  } else {
         
     | 
| 
       577 
524 
     | 
    
         
             
                    switch(type) {
         
     | 
| 
         @@ -602,9 +549,9 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, MYSQL_FIELD * fields, const r 
     | 
|
| 
       602 
549 
     | 
    
         
             
                      if (fields[i].decimals == 0) {
         
     | 
| 
       603 
550 
     | 
    
         
             
                        val = rb_cstr2inum(row[i], 10);
         
     | 
| 
       604 
551 
     | 
    
         
             
                      } else if (strtod(row[i], NULL) == 0.000000){
         
     | 
| 
       605 
     | 
    
         
            -
                        val = rb_funcall( 
     | 
| 
      
 552 
     | 
    
         
            +
                        val = rb_funcall(rb_mKernel, intern_BigDecimal, 1, opt_decimal_zero);
         
     | 
| 
       606 
553 
     | 
    
         
             
                      }else{
         
     | 
| 
       607 
     | 
    
         
            -
                        val = rb_funcall( 
     | 
| 
      
 554 
     | 
    
         
            +
                        val = rb_funcall(rb_mKernel, intern_BigDecimal, 1, rb_str_new(row[i], fieldLengths[i]));
         
     | 
| 
       608 
555 
     | 
    
         
             
                      }
         
     | 
| 
       609 
556 
     | 
    
         
             
                      break;
         
     | 
| 
       610 
557 
     | 
    
         
             
                    case MYSQL_TYPE_FLOAT:      /* FLOAT field */
         
     | 
| 
         @@ -722,9 +669,7 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, MYSQL_FIELD * fields, const r 
     | 
|
| 
       722 
669 
     | 
    
         
             
                    case MYSQL_TYPE_GEOMETRY:   /* Spatial fielda */
         
     | 
| 
       723 
670 
     | 
    
         
             
                    default:
         
     | 
| 
       724 
671 
     | 
    
         
             
                      val = rb_str_new(row[i], fieldLengths[i]);
         
     | 
| 
       725 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       726 
672 
     | 
    
         
             
                      val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc);
         
     | 
| 
       727 
     | 
    
         
            -
            #endif
         
     | 
| 
       728 
673 
     | 
    
         
             
                      break;
         
     | 
| 
       729 
674 
     | 
    
         
             
                    }
         
     | 
| 
       730 
675 
     | 
    
         
             
                  }
         
     | 
| 
         @@ -751,7 +696,7 @@ static VALUE rb_mysql_result_fetch_fields(VALUE self) { 
     | 
|
| 
       751 
696 
     | 
    
         | 
| 
       752 
697 
     | 
    
         
             
              GET_RESULT(self);
         
     | 
| 
       753 
698 
     | 
    
         | 
| 
       754 
     | 
    
         
            -
              defaults =  
     | 
| 
      
 699 
     | 
    
         
            +
              defaults = rb_ivar_get(self, intern_query_options);
         
     | 
| 
       755 
700 
     | 
    
         
             
              Check_Type(defaults, T_HASH);
         
     | 
| 
       756 
701 
     | 
    
         
             
              if (rb_hash_aref(defaults, sym_symbolize_keys) == Qtrue) {
         
     | 
| 
       757 
702 
     | 
    
         
             
                symbolizeKeys = 1;
         
     | 
| 
         @@ -796,7 +741,7 @@ static VALUE rb_mysql_result_each_(VALUE self, 
     | 
|
| 
       796 
741 
     | 
    
         
             
                    row = fetch_row_func(self, fields, args);
         
     | 
| 
       797 
742 
     | 
    
         
             
                    if (row != Qnil) {
         
     | 
| 
       798 
743 
     | 
    
         
             
                      wrapper->numberOfRows++;
         
     | 
| 
       799 
     | 
    
         
            -
                      if (args->block_given 
     | 
| 
      
 744 
     | 
    
         
            +
                      if (args->block_given) {
         
     | 
| 
       800 
745 
     | 
    
         
             
                        rb_yield(row);
         
     | 
| 
       801 
746 
     | 
    
         
             
                      }
         
     | 
| 
       802 
747 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -846,7 +791,7 @@ static VALUE rb_mysql_result_each_(VALUE self, 
     | 
|
| 
       846 
791 
     | 
    
         
             
                      return Qnil;
         
     | 
| 
       847 
792 
     | 
    
         
             
                    }
         
     | 
| 
       848 
793 
     | 
    
         | 
| 
       849 
     | 
    
         
            -
                    if (args->block_given 
     | 
| 
      
 794 
     | 
    
         
            +
                    if (args->block_given) {
         
     | 
| 
       850 
795 
     | 
    
         
             
                      rb_yield(row);
         
     | 
| 
       851 
796 
     | 
    
         
             
                    }
         
     | 
| 
       852 
797 
     | 
    
         
             
                  }
         
     | 
| 
         @@ -864,7 +809,7 @@ static VALUE rb_mysql_result_each_(VALUE self, 
     | 
|
| 
       864 
809 
     | 
    
         | 
| 
       865 
810 
     | 
    
         
             
            static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
         
     | 
| 
       866 
811 
     | 
    
         
             
              result_each_args args;
         
     | 
| 
       867 
     | 
    
         
            -
              VALUE defaults, opts,  
     | 
| 
      
 812 
     | 
    
         
            +
              VALUE defaults, opts, (*fetch_row_func)(VALUE, MYSQL_FIELD *fields, const result_each_args *args);
         
     | 
| 
       868 
813 
     | 
    
         
             
              ID db_timezone, app_timezone, dbTz, appTz;
         
     | 
| 
       869 
814 
     | 
    
         
             
              int symbolizeKeys, asArray, castBool, cacheRows, cast;
         
     | 
| 
       870 
815 
     | 
    
         | 
| 
         @@ -874,9 +819,12 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) { 
     | 
|
| 
       874 
819 
     | 
    
         
             
                rb_raise(cMysql2Error, "Statement handle already closed");
         
     | 
| 
       875 
820 
     | 
    
         
             
              }
         
     | 
| 
       876 
821 
     | 
    
         | 
| 
       877 
     | 
    
         
            -
              defaults =  
     | 
| 
      
 822 
     | 
    
         
            +
              defaults = rb_ivar_get(self, intern_query_options);
         
     | 
| 
       878 
823 
     | 
    
         
             
              Check_Type(defaults, T_HASH);
         
     | 
| 
       879 
     | 
    
         
            -
             
     | 
| 
      
 824 
     | 
    
         
            +
             
     | 
| 
      
 825 
     | 
    
         
            +
              // A block can be passed to this method, but since we don't call the block directly from C,
         
     | 
| 
      
 826 
     | 
    
         
            +
              // we don't need to capture it into a variable here with the "&" scan arg.
         
     | 
| 
      
 827 
     | 
    
         
            +
              if (rb_scan_args(argc, argv, "01", &opts) == 1) {
         
     | 
| 
       880 
828 
     | 
    
         
             
                opts = rb_funcall(defaults, intern_merge, 1, opts);
         
     | 
| 
       881 
829 
     | 
    
         
             
              } else {
         
     | 
| 
       882 
830 
     | 
    
         
             
                opts = defaults;
         
     | 
| 
         @@ -942,7 +890,7 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) { 
     | 
|
| 
       942 
890 
     | 
    
         
             
              args.cast = cast;
         
     | 
| 
       943 
891 
     | 
    
         
             
              args.db_timezone = db_timezone;
         
     | 
| 
       944 
892 
     | 
    
         
             
              args.app_timezone = app_timezone;
         
     | 
| 
       945 
     | 
    
         
            -
              args.block_given =  
     | 
| 
      
 893 
     | 
    
         
            +
              args.block_given = rb_block_given_p();
         
     | 
| 
       946 
894 
     | 
    
         | 
| 
       947 
895 
     | 
    
         
             
              if (wrapper->stmt_wrapper) {
         
     | 
| 
       948 
896 
     | 
    
         
             
                fetch_row_func = rb_mysql_result_fetch_row_stmt;
         
     | 
| 
         @@ -1007,7 +955,7 @@ VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_ 
     | 
|
| 
       1007 
955 
     | 
    
         
             
              }
         
     | 
| 
       1008 
956 
     | 
    
         | 
| 
       1009 
957 
     | 
    
         
             
              rb_obj_call_init(obj, 0, NULL);
         
     | 
| 
       1010 
     | 
    
         
            -
               
     | 
| 
      
 958 
     | 
    
         
            +
              rb_ivar_set(obj, intern_query_options, options);
         
     | 
| 
       1011 
959 
     | 
    
         | 
| 
       1012 
960 
     | 
    
         
             
              /* Options that cannot be changed in results.each(...) { |row| }
         
     | 
| 
       1013 
961 
     | 
    
         
             
               * should be processed here. */
         
     | 
| 
         @@ -1017,7 +965,6 @@ VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_ 
     | 
|
| 
       1017 
965 
     | 
    
         
             
            }
         
     | 
| 
       1018 
966 
     | 
    
         | 
| 
       1019 
967 
     | 
    
         
             
            void init_mysql2_result() {
         
     | 
| 
       1020 
     | 
    
         
            -
              cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
         
     | 
| 
       1021 
968 
     | 
    
         
             
              cDate = rb_const_get(rb_cObject, rb_intern("Date"));
         
     | 
| 
       1022 
969 
     | 
    
         
             
              cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
         
     | 
| 
       1023 
970 
     | 
    
         | 
| 
         @@ -1036,6 +983,8 @@ void init_mysql2_result() { 
     | 
|
| 
       1036 
983 
     | 
    
         
             
              intern_local_offset = rb_intern("local_offset");
         
     | 
| 
       1037 
984 
     | 
    
         
             
              intern_civil        = rb_intern("civil");
         
     | 
| 
       1038 
985 
     | 
    
         
             
              intern_new_offset   = rb_intern("new_offset");
         
     | 
| 
      
 986 
     | 
    
         
            +
              intern_BigDecimal   = rb_intern("BigDecimal");
         
     | 
| 
      
 987 
     | 
    
         
            +
              intern_query_options = rb_intern("@query_options");
         
     | 
| 
       1039 
988 
     | 
    
         | 
| 
       1040 
989 
     | 
    
         
             
              sym_symbolize_keys  = ID2SYM(rb_intern("symbolize_keys"));
         
     | 
| 
       1041 
990 
     | 
    
         
             
              sym_as              = ID2SYM(rb_intern("as"));
         
     | 
| 
         @@ -1058,7 +1007,5 @@ void init_mysql2_result() { 
     | 
|
| 
       1058 
1007 
     | 
    
         
             
              opt_time_month = INT2NUM(1);
         
     | 
| 
       1059 
1008 
     | 
    
         
             
              opt_utc_offset = INT2NUM(0);
         
     | 
| 
       1060 
1009 
     | 
    
         | 
| 
       1061 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       1062 
1010 
     | 
    
         
             
              binaryEncoding = rb_enc_find("binary");
         
     | 
| 
       1063 
     | 
    
         
            -
            #endif
         
     | 
| 
       1064 
1011 
     | 
    
         
             
            }
         
     | 
    
        data/ext/mysql2/result.h
    CHANGED
    
    | 
         @@ -1,6 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #ifndef MYSQL2_RESULT_H
         
     | 
| 
       2 
2 
     | 
    
         
             
            #define MYSQL2_RESULT_H
         
     | 
| 
       3 
     | 
    
         
            -
            #include <stdbool.h>
         
     | 
| 
       4 
3 
     | 
    
         | 
| 
       5 
4 
     | 
    
         
             
            void init_mysql2_result(void);
         
     | 
| 
       6 
5 
     | 
    
         
             
            VALUE rb_mysql_result_to_obj(VALUE client, VALUE encoding, VALUE options, MYSQL_RES *r, VALUE statement);
         
     | 
| 
         @@ -22,8 +21,8 @@ typedef struct { 
     | 
|
| 
       22 
21 
     | 
    
         
             
              mysql_client_wrapper *client_wrapper;
         
     | 
| 
       23 
22 
     | 
    
         
             
              /* statement result bind buffers */
         
     | 
| 
       24 
23 
     | 
    
         
             
              MYSQL_BIND *result_buffers;
         
     | 
| 
       25 
     | 
    
         
            -
               
     | 
| 
       26 
     | 
    
         
            -
               
     | 
| 
      
 24 
     | 
    
         
            +
              my_bool *is_null;
         
     | 
| 
      
 25 
     | 
    
         
            +
              my_bool *error;
         
     | 
| 
       27 
26 
     | 
    
         
             
              unsigned long *length;
         
     | 
| 
       28 
27 
     | 
    
         
             
            } mysql2_result_wrapper;
         
     | 
| 
       29 
28 
     | 
    
         | 
    
        data/ext/mysql2/statement.c
    CHANGED
    
    | 
         @@ -1,12 +1,10 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #include <mysql2_ext.h>
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            VALUE  
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            static VALUE sym_stream, intern_new_with_args, intern_each, intern_to_s;
         
     | 
| 
       6 
     | 
    
         
            -
            static VALUE intern_sec_fraction, intern_usec, intern_sec, intern_min, intern_hour, intern_day, intern_month, intern_year 
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            static ID id_cmp;
         
     | 
| 
       9 
     | 
    
         
            -
            #endif
         
     | 
| 
      
 3 
     | 
    
         
            +
            extern VALUE mMysql2, cMysql2Error;
         
     | 
| 
      
 4 
     | 
    
         
            +
            static VALUE cMysql2Statement, cBigDecimal, cDateTime, cDate;
         
     | 
| 
      
 5 
     | 
    
         
            +
            static VALUE sym_stream, intern_new_with_args, intern_each, intern_to_s, intern_merge_bang;
         
     | 
| 
      
 6 
     | 
    
         
            +
            static VALUE intern_sec_fraction, intern_usec, intern_sec, intern_min, intern_hour, intern_day, intern_month, intern_year,
         
     | 
| 
      
 7 
     | 
    
         
            +
              intern_query_options;
         
     | 
| 
       10 
8 
     | 
    
         | 
| 
       11 
9 
     | 
    
         
             
            #define GET_STATEMENT(self) \
         
     | 
| 
       12 
10 
     | 
    
         
             
              mysql_stmt_wrapper *stmt_wrapper; \
         
     | 
| 
         @@ -21,7 +19,7 @@ static void rb_mysql_stmt_mark(void * ptr) { 
     | 
|
| 
       21 
19 
     | 
    
         
             
              rb_gc_mark(stmt_wrapper->client);
         
     | 
| 
       22 
20 
     | 
    
         
             
            }
         
     | 
| 
       23 
21 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
            static void *nogvl_stmt_close(void * 
     | 
| 
      
 22 
     | 
    
         
            +
            static void *nogvl_stmt_close(void *ptr) {
         
     | 
| 
       25 
23 
     | 
    
         
             
              mysql_stmt_wrapper *stmt_wrapper = ptr;
         
     | 
| 
       26 
24 
     | 
    
         
             
              if (stmt_wrapper->stmt) {
         
     | 
| 
       27 
25 
     | 
    
         
             
                mysql_stmt_close(stmt_wrapper->stmt);
         
     | 
| 
         @@ -30,7 +28,7 @@ static void *nogvl_stmt_close(void * ptr) { 
     | 
|
| 
       30 
28 
     | 
    
         
             
              return NULL;
         
     | 
| 
       31 
29 
     | 
    
         
             
            }
         
     | 
| 
       32 
30 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
            static void rb_mysql_stmt_free(void * 
     | 
| 
      
 31 
     | 
    
         
            +
            static void rb_mysql_stmt_free(void *ptr) {
         
     | 
| 
       34 
32 
     | 
    
         
             
              mysql_stmt_wrapper *stmt_wrapper = ptr;
         
     | 
| 
       35 
33 
     | 
    
         
             
              decr_mysql2_stmt(stmt_wrapper);
         
     | 
| 
       36 
34 
     | 
    
         
             
            }
         
     | 
| 
         @@ -50,7 +48,6 @@ void rb_raise_mysql2_stmt_error(mysql_stmt_wrapper *stmt_wrapper) { 
     | 
|
| 
       50 
48 
     | 
    
         
             
              VALUE rb_error_msg = rb_str_new2(mysql_stmt_error(stmt_wrapper->stmt));
         
     | 
| 
       51 
49 
     | 
    
         
             
              VALUE rb_sql_state = rb_tainted_str_new2(mysql_stmt_sqlstate(stmt_wrapper->stmt));
         
     | 
| 
       52 
50 
     | 
    
         | 
| 
       53 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       54 
51 
     | 
    
         
             
              rb_encoding *conn_enc;
         
     | 
| 
       55 
52 
     | 
    
         
             
              conn_enc = rb_to_encoding(wrapper->encoding);
         
     | 
| 
       56 
53 
     | 
    
         | 
| 
         @@ -62,7 +59,6 @@ void rb_raise_mysql2_stmt_error(mysql_stmt_wrapper *stmt_wrapper) { 
     | 
|
| 
       62 
59 
     | 
    
         
             
                rb_error_msg = rb_str_export_to_enc(rb_error_msg, default_internal_enc);
         
     | 
| 
       63 
60 
     | 
    
         
             
                rb_sql_state = rb_str_export_to_enc(rb_sql_state, default_internal_enc);
         
     | 
| 
       64 
61 
     | 
    
         
             
              }
         
     | 
| 
       65 
     | 
    
         
            -
            #endif
         
     | 
| 
       66 
62 
     | 
    
         | 
| 
       67 
63 
     | 
    
         
             
              e = rb_funcall(cMysql2Error, intern_new_with_args, 4,
         
     | 
| 
       68 
64 
     | 
    
         
             
                             rb_error_msg,
         
     | 
| 
         @@ -96,9 +92,7 @@ static void *nogvl_prepare_statement(void *ptr) { 
     | 
|
| 
       96 
92 
     | 
    
         
             
            VALUE rb_mysql_stmt_new(VALUE rb_client, VALUE sql) {
         
     | 
| 
       97 
93 
     | 
    
         
             
              mysql_stmt_wrapper *stmt_wrapper;
         
     | 
| 
       98 
94 
     | 
    
         
             
              VALUE rb_stmt;
         
     | 
| 
       99 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       100 
95 
     | 
    
         
             
              rb_encoding *conn_enc;
         
     | 
| 
       101 
     | 
    
         
            -
            #endif
         
     | 
| 
       102 
96 
     | 
    
         | 
| 
       103 
97 
     | 
    
         
             
              Check_Type(sql, T_STRING);
         
     | 
| 
       104 
98 
     | 
    
         | 
| 
         @@ -114,9 +108,7 @@ VALUE rb_mysql_stmt_new(VALUE rb_client, VALUE sql) { 
     | 
|
| 
       114 
108 
     | 
    
         
             
              {
         
     | 
| 
       115 
109 
     | 
    
         
             
                GET_CLIENT(rb_client);
         
     | 
| 
       116 
110 
     | 
    
         
             
                stmt_wrapper->stmt = mysql_stmt_init(wrapper->client);
         
     | 
| 
       117 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       118 
111 
     | 
    
         
             
                conn_enc = rb_to_encoding(wrapper->encoding);
         
     | 
| 
       119 
     | 
    
         
            -
            #endif
         
     | 
| 
       120 
112 
     | 
    
         
             
              }
         
     | 
| 
       121 
113 
     | 
    
         
             
              if (stmt_wrapper->stmt == NULL) {
         
     | 
| 
       122 
114 
     | 
    
         
             
                rb_raise(cMysql2Error, "Unable to initialize prepared statement: out of memory");
         
     | 
| 
         @@ -124,7 +116,7 @@ VALUE rb_mysql_stmt_new(VALUE rb_client, VALUE sql) { 
     | 
|
| 
       124 
116 
     | 
    
         | 
| 
       125 
117 
     | 
    
         
             
              // set STMT_ATTR_UPDATE_MAX_LENGTH attr
         
     | 
| 
       126 
118 
     | 
    
         
             
              {
         
     | 
| 
       127 
     | 
    
         
            -
                 
     | 
| 
      
 119 
     | 
    
         
            +
                my_bool truth = 1;
         
     | 
| 
       128 
120 
     | 
    
         
             
                if (mysql_stmt_attr_set(stmt_wrapper->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &truth)) {
         
     | 
| 
       129 
121 
     | 
    
         
             
                  rb_raise(cMysql2Error, "Unable to initialize prepared statement: set STMT_ATTR_UPDATE_MAX_LENGTH");
         
     | 
| 
       130 
122 
     | 
    
         
             
                }
         
     | 
| 
         @@ -134,11 +126,8 @@ VALUE rb_mysql_stmt_new(VALUE rb_client, VALUE sql) { 
     | 
|
| 
       134 
126 
     | 
    
         
             
              {
         
     | 
| 
       135 
127 
     | 
    
         
             
                struct nogvl_prepare_statement_args args;
         
     | 
| 
       136 
128 
     | 
    
         
             
                args.stmt = stmt_wrapper->stmt;
         
     | 
| 
       137 
     | 
    
         
            -
                args.sql = sql;
         
     | 
| 
       138 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       139 
129 
     | 
    
         
             
                // ensure the string is in the encoding the connection is expecting
         
     | 
| 
       140 
     | 
    
         
            -
                args.sql = rb_str_export_to_enc( 
     | 
| 
       141 
     | 
    
         
            -
            #endif
         
     | 
| 
      
 130 
     | 
    
         
            +
                args.sql = rb_str_export_to_enc(sql, conn_enc);
         
     | 
| 
       142 
131 
     | 
    
         
             
                args.sql_ptr = RSTRING_PTR(sql);
         
     | 
| 
       143 
132 
     | 
    
         
             
                args.sql_len = RSTRING_LEN(sql);
         
     | 
| 
       144 
133 
     | 
    
         | 
| 
         @@ -154,7 +143,7 @@ VALUE rb_mysql_stmt_new(VALUE rb_client, VALUE sql) { 
     | 
|
| 
       154 
143 
     | 
    
         
             
             *
         
     | 
| 
       155 
144 
     | 
    
         
             
             * Returns the number of parameters the prepared statement expects.
         
     | 
| 
       156 
145 
     | 
    
         
             
             */
         
     | 
| 
       157 
     | 
    
         
            -
            static VALUE  
     | 
| 
      
 146 
     | 
    
         
            +
            static VALUE rb_mysql_stmt_param_count(VALUE self) {
         
     | 
| 
       158 
147 
     | 
    
         
             
              GET_STATEMENT(self);
         
     | 
| 
       159 
148 
     | 
    
         | 
| 
       160 
149 
     | 
    
         
             
              return ULL2NUM(mysql_stmt_param_count(stmt_wrapper->stmt));
         
     | 
| 
         @@ -164,13 +153,13 @@ static VALUE param_count(VALUE self) { 
     | 
|
| 
       164 
153 
     | 
    
         
             
             *
         
     | 
| 
       165 
154 
     | 
    
         
             
             * Returns the number of fields the prepared statement returns.
         
     | 
| 
       166 
155 
     | 
    
         
             
             */
         
     | 
| 
       167 
     | 
    
         
            -
            static VALUE  
     | 
| 
      
 156 
     | 
    
         
            +
            static VALUE rb_mysql_stmt_field_count(VALUE self) {
         
     | 
| 
       168 
157 
     | 
    
         
             
              GET_STATEMENT(self);
         
     | 
| 
       169 
158 
     | 
    
         | 
| 
       170 
159 
     | 
    
         
             
              return UINT2NUM(mysql_stmt_field_count(stmt_wrapper->stmt));
         
     | 
| 
       171 
160 
     | 
    
         
             
            }
         
     | 
| 
       172 
161 
     | 
    
         | 
| 
       173 
     | 
    
         
            -
            static void * 
     | 
| 
      
 162 
     | 
    
         
            +
            static void *nogvl_stmt_execute(void *ptr) {
         
     | 
| 
       174 
163 
     | 
    
         
             
              MYSQL_STMT *stmt = ptr;
         
     | 
| 
       175 
164 
     | 
    
         | 
| 
       176 
165 
     | 
    
         
             
              if (mysql_stmt_execute(stmt)) {
         
     | 
| 
         @@ -196,7 +185,7 @@ static void set_buffer_for_string(MYSQL_BIND* bind_buffer, unsigned long *length 
     | 
|
| 
       196 
185 
     | 
    
         
             
             * the buffer is a Ruby string pointer and not our memory to manage.
         
     | 
| 
       197 
186 
     | 
    
         
             
             */
         
     | 
| 
       198 
187 
     | 
    
         
             
            #define FREE_BINDS                                          \
         
     | 
| 
       199 
     | 
    
         
            -
              for (i = 0; i <  
     | 
| 
      
 188 
     | 
    
         
            +
              for (i = 0; i < bind_count; i++) {                        \
         
     | 
| 
       200 
189 
     | 
    
         
             
                if (bind_buffers[i].buffer && NIL_P(params_enc[i])) {   \
         
     | 
| 
       201 
190 
     | 
    
         
             
                  xfree(bind_buffers[i].buffer);                        \
         
     | 
| 
       202 
191 
     | 
    
         
             
                }                                                       \
         
     | 
| 
         @@ -211,6 +200,8 @@ static int my_big2ll(VALUE bignum, LONG_LONG *ptr) 
     | 
|
| 
       211 
200 
     | 
    
         
             
            {
         
     | 
| 
       212 
201 
     | 
    
         
             
              unsigned LONG_LONG num;
         
     | 
| 
       213 
202 
     | 
    
         
             
              size_t len;
         
     | 
| 
      
 203 
     | 
    
         
            +
            // rb_absint_size was added in 2.1.0. See:
         
     | 
| 
      
 204 
     | 
    
         
            +
            // https://github.com/ruby/ruby/commit/9fea875
         
     | 
| 
       214 
205 
     | 
    
         
             
            #ifdef HAVE_RB_ABSINT_SIZE
         
     | 
| 
       215 
206 
     | 
    
         
             
              int nlz_bits = 0;
         
     | 
| 
       216 
207 
     | 
    
         
             
              len = rb_absint_size(bignum, &nlz_bits);
         
     | 
| 
         @@ -229,16 +220,15 @@ static int my_big2ll(VALUE bignum, LONG_LONG *ptr) 
     | 
|
| 
       229 
220 
     | 
    
         
             
            #ifdef HAVE_RB_ABSINT_SIZE
         
     | 
| 
       230 
221 
     | 
    
         
             
                    nlz_bits == 0 &&
         
     | 
| 
       231 
222 
     | 
    
         
             
            #endif
         
     | 
| 
      
 223 
     | 
    
         
            +
            // rb_absint_singlebit_p was added in 2.1.0. See:
         
     | 
| 
      
 224 
     | 
    
         
            +
            // https://github.com/ruby/ruby/commit/e5ff9d5
         
     | 
| 
       232 
225 
     | 
    
         
             
            #if defined(HAVE_RB_ABSINT_SIZE) && defined(HAVE_RB_ABSINT_SINGLEBIT_P)
         
     | 
| 
       233 
226 
     | 
    
         
             
                    /* Optimized to avoid object allocation for Ruby 2.1+
         
     | 
| 
       234 
227 
     | 
    
         
             
                     * only -0x8000000000000000 is safe if `len == 8 && nlz_bits == 0`
         
     | 
| 
       235 
228 
     | 
    
         
             
                     */
         
     | 
| 
       236 
229 
     | 
    
         
             
                    !rb_absint_singlebit_p(bignum)
         
     | 
| 
       237 
     | 
    
         
            -
            #elif defined(HAVE_RB_BIG_CMP)
         
     | 
| 
       238 
     | 
    
         
            -
                    rb_big_cmp(bignum, LL2NUM(LLONG_MIN)) == INT2FIX(-1)
         
     | 
| 
       239 
230 
     | 
    
         
             
            #else
         
     | 
| 
       240 
     | 
    
         
            -
                     
     | 
| 
       241 
     | 
    
         
            -
                    rb_funcall(bignum, id_cmp, 1, LL2NUM(LLONG_MIN)) == INT2FIX(-1)
         
     | 
| 
      
 231 
     | 
    
         
            +
                    rb_big_cmp(bignum, LL2NUM(LLONG_MIN)) == INT2FIX(-1)
         
     | 
| 
       242 
232 
     | 
    
         
             
            #endif
         
     | 
| 
       243 
233 
     | 
    
         
             
                   ) {
         
     | 
| 
       244 
234 
     | 
    
         
             
                  goto overflow;
         
     | 
| 
         @@ -254,44 +244,45 @@ overflow: 
     | 
|
| 
       254 
244 
     | 
    
         
             
             *
         
     | 
| 
       255 
245 
     | 
    
         
             
             * Executes the current prepared statement, returns +result+.
         
     | 
| 
       256 
246 
     | 
    
         
             
             */
         
     | 
| 
       257 
     | 
    
         
            -
            static VALUE  
     | 
| 
      
 247 
     | 
    
         
            +
            static VALUE rb_mysql_stmt_execute(int argc, VALUE *argv, VALUE self) {
         
     | 
| 
       258 
248 
     | 
    
         
             
              MYSQL_BIND *bind_buffers = NULL;
         
     | 
| 
       259 
249 
     | 
    
         
             
              unsigned long *length_buffers = NULL;
         
     | 
| 
       260 
250 
     | 
    
         
             
              unsigned long bind_count;
         
     | 
| 
       261 
     | 
    
         
            -
              long i;
         
     | 
| 
      
 251 
     | 
    
         
            +
              unsigned long i;
         
     | 
| 
       262 
252 
     | 
    
         
             
              MYSQL_STMT *stmt;
         
     | 
| 
       263 
253 
     | 
    
         
             
              MYSQL_RES *metadata;
         
     | 
| 
      
 254 
     | 
    
         
            +
              VALUE opts;
         
     | 
| 
       264 
255 
     | 
    
         
             
              VALUE current;
         
     | 
| 
       265 
256 
     | 
    
         
             
              VALUE resultObj;
         
     | 
| 
       266 
     | 
    
         
            -
              VALUE *params_enc;
         
     | 
| 
      
 257 
     | 
    
         
            +
              VALUE *params_enc = NULL;
         
     | 
| 
       267 
258 
     | 
    
         
             
              int is_streaming;
         
     | 
| 
       268 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       269 
259 
     | 
    
         
             
              rb_encoding *conn_enc;
         
     | 
| 
       270 
     | 
    
         
            -
            #endif
         
     | 
| 
       271 
260 
     | 
    
         | 
| 
       272 
261 
     | 
    
         
             
              GET_STATEMENT(self);
         
     | 
| 
       273 
262 
     | 
    
         
             
              GET_CLIENT(stmt_wrapper->client);
         
     | 
| 
       274 
263 
     | 
    
         | 
| 
       275 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       276 
264 
     | 
    
         
             
              conn_enc = rb_to_encoding(wrapper->encoding);
         
     | 
| 
       277 
     | 
    
         
            -
            #endif
         
     | 
| 
       278 
     | 
    
         
            -
             
     | 
| 
       279 
     | 
    
         
            -
              /* Scratch space for string encoding exports, allocate on the stack. */
         
     | 
| 
       280 
     | 
    
         
            -
              params_enc = alloca(sizeof(VALUE) * argc);
         
     | 
| 
       281 
265 
     | 
    
         | 
| 
       282 
266 
     | 
    
         
             
              stmt = stmt_wrapper->stmt;
         
     | 
| 
       283 
     | 
    
         
            -
             
     | 
| 
       284 
267 
     | 
    
         
             
              bind_count = mysql_stmt_param_count(stmt);
         
     | 
| 
       285 
     | 
    
         
            -
             
     | 
| 
       286 
     | 
    
         
            -
             
     | 
| 
      
 268 
     | 
    
         
            +
             
     | 
| 
      
 269 
     | 
    
         
            +
              // Get count of ordinary arguments, and extract hash opts/keyword arguments
         
     | 
| 
      
 270 
     | 
    
         
            +
              // Use a local scope to avoid leaking the temporary count variable
         
     | 
| 
      
 271 
     | 
    
         
            +
              {
         
     | 
| 
      
 272 
     | 
    
         
            +
                int c = rb_scan_args(argc, argv, "*:", NULL, &opts);
         
     | 
| 
      
 273 
     | 
    
         
            +
                if (c != (long)bind_count) {
         
     | 
| 
      
 274 
     | 
    
         
            +
                  rb_raise(cMysql2Error, "Bind parameter count (%ld) doesn't match number of arguments (%d)", bind_count, c);
         
     | 
| 
      
 275 
     | 
    
         
            +
                }
         
     | 
| 
       287 
276 
     | 
    
         
             
              }
         
     | 
| 
       288 
277 
     | 
    
         | 
| 
       289 
278 
     | 
    
         
             
              // setup any bind variables in the query
         
     | 
| 
       290 
279 
     | 
    
         
             
              if (bind_count > 0) {
         
     | 
| 
      
 280 
     | 
    
         
            +
                // Scratch space for string encoding exports, allocate on the stack
         
     | 
| 
      
 281 
     | 
    
         
            +
                params_enc = alloca(sizeof(VALUE) * bind_count);
         
     | 
| 
       291 
282 
     | 
    
         
             
                bind_buffers = xcalloc(bind_count, sizeof(MYSQL_BIND));
         
     | 
| 
       292 
283 
     | 
    
         
             
                length_buffers = xcalloc(bind_count, sizeof(unsigned long));
         
     | 
| 
       293 
284 
     | 
    
         | 
| 
       294 
     | 
    
         
            -
                for (i = 0; i <  
     | 
| 
      
 285 
     | 
    
         
            +
                for (i = 0; i < bind_count; i++) {
         
     | 
| 
       295 
286 
     | 
    
         
             
                  bind_buffers[i].buffer = NULL;
         
     | 
| 
       296 
287 
     | 
    
         
             
                  params_enc[i] = Qnil;
         
     | 
| 
       297 
288 
     | 
    
         | 
| 
         @@ -319,12 +310,8 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       319 
310 
     | 
    
         
             
                          *(LONG_LONG*)(bind_buffers[i].buffer) = num;
         
     | 
| 
       320 
311 
     | 
    
         
             
                        } else {
         
     | 
| 
       321 
312 
     | 
    
         
             
                          /* The bignum was larger than we can fit in LONG_LONG, send it as a string */
         
     | 
| 
       322 
     | 
    
         
            -
                          VALUE rb_val_as_string = rb_big2str(argv[i], 10);
         
     | 
| 
       323 
313 
     | 
    
         
             
                          bind_buffers[i].buffer_type = MYSQL_TYPE_NEWDECIMAL;
         
     | 
| 
       324 
     | 
    
         
            -
                          params_enc[i] =  
     | 
| 
       325 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       326 
     | 
    
         
            -
                          params_enc[i] = rb_str_export_to_enc(params_enc[i], conn_enc);
         
     | 
| 
       327 
     | 
    
         
            -
            #endif
         
     | 
| 
      
 314 
     | 
    
         
            +
                          params_enc[i] = rb_str_export_to_enc(rb_big2str(argv[i], 10), conn_enc);
         
     | 
| 
       328 
315 
     | 
    
         
             
                          set_buffer_for_string(&bind_buffers[i], &length_buffers[i], params_enc[i]);
         
     | 
| 
       329 
316 
     | 
    
         
             
                        }
         
     | 
| 
       330 
317 
     | 
    
         
             
                      }
         
     | 
| 
         @@ -338,9 +325,7 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       338 
325 
     | 
    
         
             
                      bind_buffers[i].buffer_type = MYSQL_TYPE_STRING;
         
     | 
| 
       339 
326 
     | 
    
         | 
| 
       340 
327 
     | 
    
         
             
                      params_enc[i] = argv[i];
         
     | 
| 
       341 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       342 
328 
     | 
    
         
             
                      params_enc[i] = rb_str_export_to_enc(params_enc[i], conn_enc);
         
     | 
| 
       343 
     | 
    
         
            -
            #endif
         
     | 
| 
       344 
329 
     | 
    
         
             
                      set_buffer_for_string(&bind_buffers[i], &length_buffers[i], params_enc[i]);
         
     | 
| 
       345 
330 
     | 
    
         
             
                      break;
         
     | 
| 
       346 
331 
     | 
    
         
             
                    case T_TRUE:
         
     | 
| 
         @@ -405,9 +390,7 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       405 
390 
     | 
    
         
             
                        VALUE rb_val_as_string = rb_funcall(argv[i], intern_to_s, 0);
         
     | 
| 
       406 
391 
     | 
    
         | 
| 
       407 
392 
     | 
    
         
             
                        params_enc[i] = rb_val_as_string;
         
     | 
| 
       408 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       409 
393 
     | 
    
         
             
                        params_enc[i] = rb_str_export_to_enc(params_enc[i], conn_enc);
         
     | 
| 
       410 
     | 
    
         
            -
            #endif
         
     | 
| 
       411 
394 
     | 
    
         
             
                        set_buffer_for_string(&bind_buffers[i], &length_buffers[i], params_enc[i]);
         
     | 
| 
       412 
395 
     | 
    
         
             
                      }
         
     | 
| 
       413 
396 
     | 
    
         
             
                      break;
         
     | 
| 
         @@ -421,7 +404,40 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       421 
404 
     | 
    
         
             
                }
         
     | 
| 
       422 
405 
     | 
    
         
             
              }
         
     | 
| 
       423 
406 
     | 
    
         | 
| 
       424 
     | 
    
         
            -
               
     | 
| 
      
 407 
     | 
    
         
            +
              // Duplicate the options hash, merge! extra opts, put the copy into the Result object
         
     | 
| 
      
 408 
     | 
    
         
            +
              current = rb_hash_dup(rb_ivar_get(stmt_wrapper->client, intern_query_options));
         
     | 
| 
      
 409 
     | 
    
         
            +
              (void)RB_GC_GUARD(current);
         
     | 
| 
      
 410 
     | 
    
         
            +
              Check_Type(current, T_HASH);
         
     | 
| 
      
 411 
     | 
    
         
            +
             
     | 
| 
      
 412 
     | 
    
         
            +
              // Merge in hash opts/keyword arguments
         
     | 
| 
      
 413 
     | 
    
         
            +
              if (!NIL_P(opts)) {
         
     | 
| 
      
 414 
     | 
    
         
            +
                rb_funcall(current, intern_merge_bang, 1, opts);
         
     | 
| 
      
 415 
     | 
    
         
            +
              }
         
     | 
| 
      
 416 
     | 
    
         
            +
             
     | 
| 
      
 417 
     | 
    
         
            +
              is_streaming = (Qtrue == rb_hash_aref(current, sym_stream));
         
     | 
| 
      
 418 
     | 
    
         
            +
             
     | 
| 
      
 419 
     | 
    
         
            +
              // From stmt_execute to mysql_stmt_result_metadata to stmt_store_result, no
         
     | 
| 
      
 420 
     | 
    
         
            +
              // Ruby API calls are allowed so that GC is not invoked. If the connection is
         
     | 
| 
      
 421 
     | 
    
         
            +
              // in results-streaming-mode for Statement A, and in the middle Statement B
         
     | 
| 
      
 422 
     | 
    
         
            +
              // gets garbage collected, a message will be sent to the server notifying it
         
     | 
| 
      
 423 
     | 
    
         
            +
              // to release Statement B, resulting in the following error:
         
     | 
| 
      
 424 
     | 
    
         
            +
              //   Commands out of sync; you can't run this command now
         
     | 
| 
      
 425 
     | 
    
         
            +
              //
         
     | 
| 
      
 426 
     | 
    
         
            +
              // In streaming mode, statement execute must return a cursor because we
         
     | 
| 
      
 427 
     | 
    
         
            +
              // cannot prevent other Statement objects from being garbage collected
         
     | 
| 
      
 428 
     | 
    
         
            +
              // between fetches of each row of the result set. The following error
         
     | 
| 
      
 429 
     | 
    
         
            +
              // occurs if cursor mode is not set:
         
     | 
| 
      
 430 
     | 
    
         
            +
              //   Row retrieval was canceled by mysql_stmt_close
         
     | 
| 
      
 431 
     | 
    
         
            +
             
     | 
| 
      
 432 
     | 
    
         
            +
              if (is_streaming) {
         
     | 
| 
      
 433 
     | 
    
         
            +
                unsigned long type = CURSOR_TYPE_READ_ONLY;
         
     | 
| 
      
 434 
     | 
    
         
            +
                if (mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &type)) {
         
     | 
| 
      
 435 
     | 
    
         
            +
                  FREE_BINDS;
         
     | 
| 
      
 436 
     | 
    
         
            +
                  rb_raise(cMysql2Error, "Unable to stream prepared statement, could not set CURSOR_TYPE_READ_ONLY");
         
     | 
| 
      
 437 
     | 
    
         
            +
                }
         
     | 
| 
      
 438 
     | 
    
         
            +
              }
         
     | 
| 
      
 439 
     | 
    
         
            +
             
     | 
| 
      
 440 
     | 
    
         
            +
              if ((VALUE)rb_thread_call_without_gvl(nogvl_stmt_execute, stmt, RUBY_UBF_IO, 0) == Qfalse) {
         
     | 
| 
       425 
441 
     | 
    
         
             
                FREE_BINDS;
         
     | 
| 
       426 
442 
     | 
    
         
             
                rb_raise_mysql2_stmt_error(stmt_wrapper);
         
     | 
| 
       427 
443 
     | 
    
         
             
              }
         
     | 
| 
         @@ -439,11 +455,6 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       439 
455 
     | 
    
         
             
                return Qnil;
         
     | 
| 
       440 
456 
     | 
    
         
             
              }
         
     | 
| 
       441 
457 
     | 
    
         | 
| 
       442 
     | 
    
         
            -
              current = rb_hash_dup(rb_iv_get(stmt_wrapper->client, "@query_options"));
         
     | 
| 
       443 
     | 
    
         
            -
              (void)RB_GC_GUARD(current);
         
     | 
| 
       444 
     | 
    
         
            -
              Check_Type(current, T_HASH);
         
     | 
| 
       445 
     | 
    
         
            -
             
     | 
| 
       446 
     | 
    
         
            -
              is_streaming = (Qtrue == rb_hash_aref(current, sym_stream));
         
     | 
| 
       447 
458 
     | 
    
         
             
              if (!is_streaming) {
         
     | 
| 
       448 
459 
     | 
    
         
             
                // recieve the whole result set from the server
         
     | 
| 
       449 
460 
     | 
    
         
             
                if (mysql_stmt_store_result(stmt)) {
         
     | 
| 
         @@ -455,6 +466,8 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       455 
466 
     | 
    
         | 
| 
       456 
467 
     | 
    
         
             
              resultObj = rb_mysql_result_to_obj(stmt_wrapper->client, wrapper->encoding, current, metadata, self);
         
     | 
| 
       457 
468 
     | 
    
         | 
| 
      
 469 
     | 
    
         
            +
              rb_mysql_set_server_query_flags(wrapper->client, resultObj);
         
     | 
| 
      
 470 
     | 
    
         
            +
             
     | 
| 
       458 
471 
     | 
    
         
             
              if (!is_streaming) {
         
     | 
| 
       459 
472 
     | 
    
         
             
                // cache all result
         
     | 
| 
       460 
473 
     | 
    
         
             
                rb_funcall(resultObj, intern_each, 0);
         
     | 
| 
         @@ -467,27 +480,23 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       467 
480 
     | 
    
         
             
             *
         
     | 
| 
       468 
481 
     | 
    
         
             
             * Returns a list of fields that will be returned by this statement.
         
     | 
| 
       469 
482 
     | 
    
         
             
             */
         
     | 
| 
       470 
     | 
    
         
            -
            static VALUE  
     | 
| 
      
 483 
     | 
    
         
            +
            static VALUE rb_mysql_stmt_fields(VALUE self) {
         
     | 
| 
       471 
484 
     | 
    
         
             
              MYSQL_FIELD *fields;
         
     | 
| 
       472 
485 
     | 
    
         
             
              MYSQL_RES *metadata;
         
     | 
| 
       473 
486 
     | 
    
         
             
              unsigned int field_count;
         
     | 
| 
       474 
487 
     | 
    
         
             
              unsigned int i;
         
     | 
| 
       475 
488 
     | 
    
         
             
              VALUE field_list;
         
     | 
| 
       476 
489 
     | 
    
         
             
              MYSQL_STMT* stmt;
         
     | 
| 
       477 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       478 
490 
     | 
    
         
             
              rb_encoding *default_internal_enc, *conn_enc;
         
     | 
| 
       479 
     | 
    
         
            -
            #endif
         
     | 
| 
       480 
491 
     | 
    
         
             
              GET_STATEMENT(self);
         
     | 
| 
       481 
492 
     | 
    
         
             
              GET_CLIENT(stmt_wrapper->client);
         
     | 
| 
       482 
493 
     | 
    
         
             
              stmt = stmt_wrapper->stmt;
         
     | 
| 
       483 
494 
     | 
    
         | 
| 
       484 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       485 
495 
     | 
    
         
             
              default_internal_enc = rb_default_internal_encoding();
         
     | 
| 
       486 
496 
     | 
    
         
             
              {
         
     | 
| 
       487 
497 
     | 
    
         
             
                GET_CLIENT(stmt_wrapper->client);
         
     | 
| 
       488 
498 
     | 
    
         
             
                conn_enc = rb_to_encoding(wrapper->encoding);
         
     | 
| 
       489 
499 
     | 
    
         
             
              }
         
     | 
| 
       490 
     | 
    
         
            -
            #endif
         
     | 
| 
       491 
500 
     | 
    
         | 
| 
       492 
501 
     | 
    
         
             
              metadata = mysql_stmt_result_metadata(stmt);
         
     | 
| 
       493 
502 
     | 
    
         
             
              if (metadata == NULL) {
         
     | 
| 
         @@ -508,12 +517,10 @@ static VALUE fields(VALUE self) { 
     | 
|
| 
       508 
517 
     | 
    
         
             
                VALUE rb_field;
         
     | 
| 
       509 
518 
     | 
    
         | 
| 
       510 
519 
     | 
    
         
             
                rb_field = rb_str_new(fields[i].name, fields[i].name_length);
         
     | 
| 
       511 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       512 
520 
     | 
    
         
             
                rb_enc_associate(rb_field, conn_enc);
         
     | 
| 
       513 
521 
     | 
    
         
             
                if (default_internal_enc) {
         
     | 
| 
       514 
522 
     | 
    
         
             
                 rb_field = rb_str_export_to_enc(rb_field, default_internal_enc);
         
     | 
| 
       515 
523 
     | 
    
         
             
               }
         
     | 
| 
       516 
     | 
    
         
            -
            #endif
         
     | 
| 
       517 
524 
     | 
    
         | 
| 
       518 
525 
     | 
    
         
             
                rb_ary_store(field_list, (long)i, rb_field);
         
     | 
| 
       519 
526 
     | 
    
         
             
              }
         
     | 
| 
         @@ -564,12 +571,15 @@ static VALUE rb_mysql_stmt_close(VALUE self) { 
     | 
|
| 
       564 
571 
     | 
    
         
             
            }
         
     | 
| 
       565 
572 
     | 
    
         | 
| 
       566 
573 
     | 
    
         
             
            void init_mysql2_statement() {
         
     | 
| 
       567 
     | 
    
         
            -
               
     | 
| 
      
 574 
     | 
    
         
            +
              cDate = rb_const_get(rb_cObject, rb_intern("Date"));
         
     | 
| 
      
 575 
     | 
    
         
            +
              cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
         
     | 
| 
      
 576 
     | 
    
         
            +
              cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
         
     | 
| 
       568 
577 
     | 
    
         | 
| 
       569 
     | 
    
         
            -
               
     | 
| 
       570 
     | 
    
         
            -
              rb_define_method(cMysql2Statement, " 
     | 
| 
       571 
     | 
    
         
            -
              rb_define_method(cMysql2Statement, " 
     | 
| 
       572 
     | 
    
         
            -
              rb_define_method(cMysql2Statement, " 
     | 
| 
      
 578 
     | 
    
         
            +
              cMysql2Statement = rb_define_class_under(mMysql2, "Statement", rb_cObject);
         
     | 
| 
      
 579 
     | 
    
         
            +
              rb_define_method(cMysql2Statement, "param_count", rb_mysql_stmt_param_count, 0);
         
     | 
| 
      
 580 
     | 
    
         
            +
              rb_define_method(cMysql2Statement, "field_count", rb_mysql_stmt_field_count, 0);
         
     | 
| 
      
 581 
     | 
    
         
            +
              rb_define_method(cMysql2Statement, "_execute", rb_mysql_stmt_execute, -1);
         
     | 
| 
      
 582 
     | 
    
         
            +
              rb_define_method(cMysql2Statement, "fields", rb_mysql_stmt_fields, 0);
         
     | 
| 
       573 
583 
     | 
    
         
             
              rb_define_method(cMysql2Statement, "last_id", rb_mysql_stmt_last_id, 0);
         
     | 
| 
       574 
584 
     | 
    
         
             
              rb_define_method(cMysql2Statement, "affected_rows", rb_mysql_stmt_affected_rows, 0);
         
     | 
| 
       575 
585 
     | 
    
         
             
              rb_define_method(cMysql2Statement, "close", rb_mysql_stmt_close, 0);
         
     | 
| 
         @@ -589,7 +599,6 @@ void init_mysql2_statement() { 
     | 
|
| 
       589 
599 
     | 
    
         
             
              intern_year = rb_intern("year");
         
     | 
| 
       590 
600 
     | 
    
         | 
| 
       591 
601 
     | 
    
         
             
              intern_to_s = rb_intern("to_s");
         
     | 
| 
       592 
     | 
    
         
            -
             
     | 
| 
       593 
     | 
    
         
            -
               
     | 
| 
       594 
     | 
    
         
            -
            #endif
         
     | 
| 
      
 602 
     | 
    
         
            +
              intern_merge_bang = rb_intern("merge!");
         
     | 
| 
      
 603 
     | 
    
         
            +
              intern_query_options = rb_intern("@query_options");
         
     | 
| 
       595 
604 
     | 
    
         
             
            }
         
     |