mysql2_bigint 0.2.6.1
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/CHANGELOG.md +120 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +248 -0
- data/Rakefile +5 -0
- data/benchmark/active_record.rb +51 -0
- data/benchmark/allocations.rb +33 -0
- data/benchmark/escape.rb +36 -0
- data/benchmark/query_with_mysql_casting.rb +80 -0
- data/benchmark/query_without_mysql_casting.rb +47 -0
- data/benchmark/sequel.rb +37 -0
- data/benchmark/setup_db.rb +119 -0
- data/examples/eventmachine.rb +21 -0
- data/examples/threaded.rb +20 -0
- data/ext/mysql2/client.c +768 -0
- data/ext/mysql2/client.h +41 -0
- data/ext/mysql2/extconf.rb +69 -0
- data/ext/mysql2/mysql2_ext.c +12 -0
- data/ext/mysql2/mysql2_ext.h +38 -0
- data/ext/mysql2/result.c +488 -0
- data/ext/mysql2/result.h +20 -0
- data/lib/active_record/connection_adapters/em_mysql2_adapter.rb +64 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +654 -0
- data/lib/active_record/fiber_patches.rb +104 -0
- data/lib/arel/engines/sql/compilers/mysql2_compiler.rb +11 -0
- data/lib/mysql2.rb +16 -0
- data/lib/mysql2/client.rb +240 -0
- data/lib/mysql2/em.rb +37 -0
- data/lib/mysql2/em_fiber.rb +31 -0
- data/lib/mysql2/error.rb +15 -0
- data/lib/mysql2/result.rb +5 -0
- data/lib/mysql2/version.rb +3 -0
- data/lib/mysql2_bigint.rb +1 -0
- data/mysql2_bigint.gemspec +32 -0
- data/spec/em/em_fiber_spec.rb +22 -0
- data/spec/em/em_spec.rb +49 -0
- data/spec/mysql2/client_spec.rb +385 -0
- data/spec/mysql2/error_spec.rb +25 -0
- data/spec/mysql2/result_spec.rb +328 -0
- data/spec/rcov.opts +3 -0
- data/spec/spec_helper.rb +66 -0
- data/tasks/benchmarks.rake +20 -0
- data/tasks/compile.rake +53 -0
- data/tasks/rspec.rake +16 -0
- data/tasks/vendor_mysql.rake +41 -0
- metadata +199 -0
    
        data/ext/mysql2/client.h
    ADDED
    
    | @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            #ifndef MYSQL2_CLIENT_H
         | 
| 2 | 
            +
            #define MYSQL2_CLIENT_H
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            /*
         | 
| 5 | 
            +
             * partial emulation of the 1.9 rb_thread_blocking_region under 1.8,
         | 
| 6 | 
            +
             * this is enough for dealing with blocking I/O functions in the
         | 
| 7 | 
            +
             * presence of threads.
         | 
| 8 | 
            +
             */
         | 
| 9 | 
            +
            #ifndef HAVE_RB_THREAD_BLOCKING_REGION
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            #include <rubysig.h>
         | 
| 12 | 
            +
            #define RUBY_UBF_IO ((rb_unblock_function_t *)-1)
         | 
| 13 | 
            +
            typedef void rb_unblock_function_t(void *);
         | 
| 14 | 
            +
            typedef VALUE rb_blocking_function_t(void *);
         | 
| 15 | 
            +
            static VALUE
         | 
| 16 | 
            +
            rb_thread_blocking_region(
         | 
| 17 | 
            +
              rb_blocking_function_t *func, void *data1,
         | 
| 18 | 
            +
              RB_MYSQL_UNUSED rb_unblock_function_t *ubf,
         | 
| 19 | 
            +
              RB_MYSQL_UNUSED void *data2)
         | 
| 20 | 
            +
            {
         | 
| 21 | 
            +
              VALUE rv;
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              TRAP_BEG;
         | 
| 24 | 
            +
              rv = func(data1);
         | 
| 25 | 
            +
              TRAP_END;
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              return rv;
         | 
| 28 | 
            +
            }
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            #endif /* ! HAVE_RB_THREAD_BLOCKING_REGION */
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            void init_mysql2_client();
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            typedef struct {
         | 
| 35 | 
            +
              VALUE encoding;
         | 
| 36 | 
            +
              char active;
         | 
| 37 | 
            +
              char closed;
         | 
| 38 | 
            +
              MYSQL *client;
         | 
| 39 | 
            +
            } mysql_client_wrapper;
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            #endif
         | 
| @@ -0,0 +1,69 @@ | |
| 1 | 
            +
            # encoding: UTF-8
         | 
| 2 | 
            +
            require 'mkmf'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            def asplode lib
         | 
| 5 | 
            +
              abort "-----\n#{lib} is missing.  please check your installation of mysql and try again.\n-----"
         | 
| 6 | 
            +
            end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            # 1.9-only
         | 
| 9 | 
            +
            have_func('rb_thread_blocking_region')
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            # borrowed from mysqlplus
         | 
| 12 | 
            +
            # http://github.com/oldmoe/mysqlplus/blob/master/ext/extconf.rb
         | 
| 13 | 
            +
            dirs = ENV['PATH'].split(File::PATH_SEPARATOR) + %w[
         | 
| 14 | 
            +
              /opt
         | 
| 15 | 
            +
              /opt/local
         | 
| 16 | 
            +
              /opt/local/mysql
         | 
| 17 | 
            +
              /opt/local/lib/mysql5
         | 
| 18 | 
            +
              /usr
         | 
| 19 | 
            +
              /usr/local
         | 
| 20 | 
            +
              /usr/local/mysql
         | 
| 21 | 
            +
              /usr/local/mysql-*
         | 
| 22 | 
            +
              /usr/local/lib/mysql5
         | 
| 23 | 
            +
            ].map{|dir| "#{dir}/bin" }
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5}"
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            if RUBY_PLATFORM =~ /mswin|mingw/
         | 
| 28 | 
            +
              inc, lib = dir_config('mysql')
         | 
| 29 | 
            +
              exit 1 unless have_library("libmysql")
         | 
| 30 | 
            +
            elsif mc = (with_config('mysql-config') || Dir[GLOB].first) then
         | 
| 31 | 
            +
              mc = Dir[GLOB].first if mc == true
         | 
| 32 | 
            +
              cflags = `#{mc} --cflags`.chomp
         | 
| 33 | 
            +
              exit 1 if $? != 0
         | 
| 34 | 
            +
              libs = `#{mc} --libs`.chomp
         | 
| 35 | 
            +
              exit 1 if $? != 0
         | 
| 36 | 
            +
              $CPPFLAGS += ' ' + cflags
         | 
| 37 | 
            +
              $libs = libs + " " + $libs
         | 
| 38 | 
            +
            else
         | 
| 39 | 
            +
              inc, lib = dir_config('mysql', '/usr/local')
         | 
| 40 | 
            +
              libs = ['m', 'z', 'socket', 'nsl', 'mygcc']
         | 
| 41 | 
            +
              while not find_library('mysqlclient', 'mysql_query', lib, "#{lib}/mysql") do
         | 
| 42 | 
            +
                exit 1 if libs.empty?
         | 
| 43 | 
            +
                have_library(libs.shift)
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
            end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            if have_header('mysql.h') then
         | 
| 48 | 
            +
              prefix = nil
         | 
| 49 | 
            +
            elsif have_header('mysql/mysql.h') then
         | 
| 50 | 
            +
              prefix = 'mysql'
         | 
| 51 | 
            +
            else
         | 
| 52 | 
            +
              asplode 'mysql.h'
         | 
| 53 | 
            +
            end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            %w{ errmsg.h mysqld_error.h }.each do |h|
         | 
| 56 | 
            +
              header = [prefix, h].compact.join '/'
         | 
| 57 | 
            +
              asplode h unless have_header h
         | 
| 58 | 
            +
            end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            unless RUBY_PLATFORM =~ /mswin/ or RUBY_PLATFORM =~ /sparc/
         | 
| 61 | 
            +
              $CFLAGS << ' -Wall -funroll-loops'
         | 
| 62 | 
            +
            end
         | 
| 63 | 
            +
            # $CFLAGS << ' -O0 -ggdb3 -Wextra'
         | 
| 64 | 
            +
             | 
| 65 | 
            +
            if hard_mysql_path = $libs[%r{-L(/[^ ]+)}, 1]
         | 
| 66 | 
            +
            	$LDFLAGS << " -Wl,-rpath,#{hard_mysql_path}"
         | 
| 67 | 
            +
            end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            create_makefile('mysql2/mysql2')
         | 
| @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            #include <mysql2_ext.h>
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            VALUE mMysql2, cMysql2Error;
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            /* Ruby Extension initializer */
         | 
| 6 | 
            +
            void Init_mysql2() {
         | 
| 7 | 
            +
              mMysql2      = rb_define_module("Mysql2");
         | 
| 8 | 
            +
              cMysql2Error = rb_const_get(mMysql2, rb_intern("Error"));
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              init_mysql2_client();
         | 
| 11 | 
            +
              init_mysql2_result();
         | 
| 12 | 
            +
            }
         | 
| @@ -0,0 +1,38 @@ | |
| 1 | 
            +
            #ifndef MYSQL2_EXT
         | 
| 2 | 
            +
            #define MYSQL2_EXT
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            #include <ruby.h>
         | 
| 5 | 
            +
            #include <fcntl.h>
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            #ifndef HAVE_UINT
         | 
| 8 | 
            +
            #define HAVE_UINT
         | 
| 9 | 
            +
            typedef unsigned short    ushort;
         | 
| 10 | 
            +
            typedef unsigned int    uint;
         | 
| 11 | 
            +
            #endif
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            #ifdef HAVE_MYSQL_H
         | 
| 14 | 
            +
            #include <mysql.h>
         | 
| 15 | 
            +
            #include <mysql_com.h>
         | 
| 16 | 
            +
            #include <errmsg.h>
         | 
| 17 | 
            +
            #include <mysqld_error.h>
         | 
| 18 | 
            +
            #else
         | 
| 19 | 
            +
            #include <mysql/mysql.h>
         | 
| 20 | 
            +
            #include <mysql/mysql_com.h>
         | 
| 21 | 
            +
            #include <mysql/errmsg.h>
         | 
| 22 | 
            +
            #include <mysql/mysqld_error.h>
         | 
| 23 | 
            +
            #endif
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 26 | 
            +
            #include <ruby/encoding.h>
         | 
| 27 | 
            +
            #endif
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            #if defined(__GNUC__) && (__GNUC__ >= 3)
         | 
| 30 | 
            +
            #define RB_MYSQL_UNUSED __attribute__ ((unused))
         | 
| 31 | 
            +
            #else
         | 
| 32 | 
            +
            #define RB_MYSQL_UNUSED
         | 
| 33 | 
            +
            #endif
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            #include <client.h>
         | 
| 36 | 
            +
            #include <result.h>
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            #endif
         | 
    
        data/ext/mysql2/result.c
    ADDED
    
    | @@ -0,0 +1,488 @@ | |
| 1 | 
            +
            #include <mysql2_ext.h>
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 4 | 
            +
            rb_encoding *binaryEncoding;
         | 
| 5 | 
            +
            #endif
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            #define MYSQL2_MAX_YEAR 2058
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            #ifdef NEGATIVE_TIME_T
         | 
| 10 | 
            +
              /* 1901-12-13 20:45:52 UTC : The oldest time in 32-bit signed time_t. */
         | 
| 11 | 
            +
            #define MYSQL2_MIN_YEAR 1902
         | 
| 12 | 
            +
            #else
         | 
| 13 | 
            +
             /* 1970-01-01 00:00:00 UTC : The Unix epoch - the oldest time in portable time_t. */
         | 
| 14 | 
            +
            #define MYSQL2_MIN_YEAR 1970
         | 
| 15 | 
            +
            #endif
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            VALUE cMysql2Result;
         | 
| 18 | 
            +
            VALUE cBigDecimal, cDate, cDateTime;
         | 
| 19 | 
            +
            VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month, opt_utc_offset;
         | 
| 20 | 
            +
            extern VALUE mMysql2, cMysql2Client, cMysql2Error;
         | 
| 21 | 
            +
            static VALUE intern_encoding_from_charset;
         | 
| 22 | 
            +
            static ID intern_new, intern_utc, intern_local, intern_encoding_from_charset_code,
         | 
| 23 | 
            +
                      intern_localtime, intern_local_offset, intern_civil, intern_new_offset;
         | 
| 24 | 
            +
            static ID sym_symbolize_keys, sym_as, sym_array, sym_database_timezone, sym_application_timezone,
         | 
| 25 | 
            +
                      sym_local, sym_utc, sym_cast_booleans, sym_cache_rows;
         | 
| 26 | 
            +
            static ID intern_merge;
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            static void rb_mysql_result_mark(void * wrapper) {
         | 
| 29 | 
            +
              mysql2_result_wrapper * w = wrapper;
         | 
| 30 | 
            +
              if (w) {
         | 
| 31 | 
            +
                rb_gc_mark(w->fields);
         | 
| 32 | 
            +
                rb_gc_mark(w->rows);
         | 
| 33 | 
            +
                rb_gc_mark(w->encoding);
         | 
| 34 | 
            +
              }
         | 
| 35 | 
            +
            }
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            /* this may be called manually or during GC */
         | 
| 38 | 
            +
            static void rb_mysql_result_free_result(mysql2_result_wrapper * wrapper) {
         | 
| 39 | 
            +
              if (wrapper && wrapper->resultFreed != 1) {
         | 
| 40 | 
            +
                mysql_free_result(wrapper->result);
         | 
| 41 | 
            +
                wrapper->resultFreed = 1;
         | 
| 42 | 
            +
              }
         | 
| 43 | 
            +
            }
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            /* this is called during GC */
         | 
| 46 | 
            +
            static void rb_mysql_result_free(void * wrapper) {
         | 
| 47 | 
            +
              mysql2_result_wrapper * w = wrapper;
         | 
| 48 | 
            +
              /* FIXME: this may call flush_use_result, which can hit the socket */
         | 
| 49 | 
            +
              rb_mysql_result_free_result(w);
         | 
| 50 | 
            +
              xfree(wrapper);
         | 
| 51 | 
            +
            }
         | 
| 52 | 
            +
             | 
| 53 | 
            +
            /*
         | 
| 54 | 
            +
             * for small results, this won't hit the network, but there's no
         | 
| 55 | 
            +
             * reliable way for us to tell this so we'll always release the GVL
         | 
| 56 | 
            +
             * to be safe
         | 
| 57 | 
            +
             */
         | 
| 58 | 
            +
            static VALUE nogvl_fetch_row(void *ptr) {
         | 
| 59 | 
            +
              MYSQL_RES *result = ptr;
         | 
| 60 | 
            +
             | 
| 61 | 
            +
              return (VALUE)mysql_fetch_row(result);
         | 
| 62 | 
            +
            }
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, short int symbolize_keys) {
         | 
| 65 | 
            +
              mysql2_result_wrapper * wrapper;
         | 
| 66 | 
            +
              VALUE rb_field;
         | 
| 67 | 
            +
              GetMysql2Result(self, wrapper);
         | 
| 68 | 
            +
             | 
| 69 | 
            +
              if (wrapper->fields == Qnil) {
         | 
| 70 | 
            +
                wrapper->numberOfFields = mysql_num_fields(wrapper->result);
         | 
| 71 | 
            +
                wrapper->fields = rb_ary_new2(wrapper->numberOfFields);
         | 
| 72 | 
            +
              }
         | 
| 73 | 
            +
             | 
| 74 | 
            +
              rb_field = rb_ary_entry(wrapper->fields, idx);
         | 
| 75 | 
            +
              if (rb_field == Qnil) {
         | 
| 76 | 
            +
                MYSQL_FIELD *field = NULL;
         | 
| 77 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 78 | 
            +
                rb_encoding *default_internal_enc = rb_default_internal_encoding();
         | 
| 79 | 
            +
                rb_encoding *conn_enc = rb_to_encoding(wrapper->encoding);
         | 
| 80 | 
            +
            #endif
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                field = mysql_fetch_field_direct(wrapper->result, idx);
         | 
| 83 | 
            +
                if (symbolize_keys) {
         | 
| 84 | 
            +
                  char buf[field->name_length+1];
         | 
| 85 | 
            +
                  memcpy(buf, field->name, field->name_length);
         | 
| 86 | 
            +
                  buf[field->name_length] = 0;
         | 
| 87 | 
            +
                  rb_field = ID2SYM(rb_intern(buf));
         | 
| 88 | 
            +
                } else {
         | 
| 89 | 
            +
                  rb_field = rb_str_new(field->name, field->name_length);
         | 
| 90 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 91 | 
            +
                  rb_enc_associate(rb_field, conn_enc);
         | 
| 92 | 
            +
                  if (default_internal_enc) {
         | 
| 93 | 
            +
                    rb_field = rb_str_export_to_enc(rb_field, default_internal_enc);
         | 
| 94 | 
            +
                  }
         | 
| 95 | 
            +
            #endif
         | 
| 96 | 
            +
                }
         | 
| 97 | 
            +
                rb_ary_store(wrapper->fields, idx, rb_field);
         | 
| 98 | 
            +
              }
         | 
| 99 | 
            +
             | 
| 100 | 
            +
              return rb_field;
         | 
| 101 | 
            +
            }
         | 
| 102 | 
            +
             | 
| 103 | 
            +
            static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezone, int symbolizeKeys, int asArray, int castBool) {
         | 
| 104 | 
            +
              VALUE rowVal;
         | 
| 105 | 
            +
              mysql2_result_wrapper * wrapper;
         | 
| 106 | 
            +
              MYSQL_ROW row;
         | 
| 107 | 
            +
              MYSQL_FIELD * fields = NULL;
         | 
| 108 | 
            +
              unsigned int i = 0;
         | 
| 109 | 
            +
              unsigned long * fieldLengths;
         | 
| 110 | 
            +
              void * ptr;
         | 
| 111 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 112 | 
            +
              rb_encoding *default_internal_enc;
         | 
| 113 | 
            +
              rb_encoding *conn_enc;
         | 
| 114 | 
            +
            #endif
         | 
| 115 | 
            +
              GetMysql2Result(self, wrapper);
         | 
| 116 | 
            +
             | 
| 117 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 118 | 
            +
              default_internal_enc = rb_default_internal_encoding();
         | 
| 119 | 
            +
              conn_enc = rb_to_encoding(wrapper->encoding);
         | 
| 120 | 
            +
            #endif
         | 
| 121 | 
            +
             | 
| 122 | 
            +
              ptr = wrapper->result;
         | 
| 123 | 
            +
              row = (MYSQL_ROW)rb_thread_blocking_region(nogvl_fetch_row, ptr, RUBY_UBF_IO, 0);
         | 
| 124 | 
            +
              if (row == NULL) {
         | 
| 125 | 
            +
                return Qnil;
         | 
| 126 | 
            +
              }
         | 
| 127 | 
            +
             | 
| 128 | 
            +
              if (asArray) {
         | 
| 129 | 
            +
                rowVal = rb_ary_new2(wrapper->numberOfFields);
         | 
| 130 | 
            +
              } else {
         | 
| 131 | 
            +
                rowVal = rb_hash_new();
         | 
| 132 | 
            +
              }
         | 
| 133 | 
            +
              fields = mysql_fetch_fields(wrapper->result);
         | 
| 134 | 
            +
              fieldLengths = mysql_fetch_lengths(wrapper->result);
         | 
| 135 | 
            +
              if (wrapper->fields == Qnil) {
         | 
| 136 | 
            +
                wrapper->numberOfFields = mysql_num_fields(wrapper->result);
         | 
| 137 | 
            +
                wrapper->fields = rb_ary_new2(wrapper->numberOfFields);
         | 
| 138 | 
            +
              }
         | 
| 139 | 
            +
             | 
| 140 | 
            +
              for (i = 0; i < wrapper->numberOfFields; i++) {
         | 
| 141 | 
            +
                VALUE field = rb_mysql_result_fetch_field(self, i, symbolizeKeys);
         | 
| 142 | 
            +
                if (row[i]) {
         | 
| 143 | 
            +
                  VALUE val = Qnil;
         | 
| 144 | 
            +
                  switch(fields[i].type) {
         | 
| 145 | 
            +
                    case MYSQL_TYPE_NULL:       // NULL-type field
         | 
| 146 | 
            +
                      val = Qnil;
         | 
| 147 | 
            +
                      break;
         | 
| 148 | 
            +
                    case MYSQL_TYPE_BIT:        // BIT field (MySQL 5.0.3 and up)
         | 
| 149 | 
            +
                      val = rb_str_new(row[i], fieldLengths[i]);
         | 
| 150 | 
            +
                      break;
         | 
| 151 | 
            +
                    case MYSQL_TYPE_TINY:       // TINYINT field
         | 
| 152 | 
            +
                      if (castBool && fields[i].length == 1) {
         | 
| 153 | 
            +
                        val = *row[i] == '1' ? Qtrue : Qfalse;
         | 
| 154 | 
            +
                        break;
         | 
| 155 | 
            +
                      }
         | 
| 156 | 
            +
                    case MYSQL_TYPE_SHORT:      // SMALLINT field
         | 
| 157 | 
            +
                    case MYSQL_TYPE_LONG:       // INTEGER field
         | 
| 158 | 
            +
                    case MYSQL_TYPE_INT24:      // MEDIUMINT field
         | 
| 159 | 
            +
                    case MYSQL_TYPE_LONGLONG:   // BIGINT field
         | 
| 160 | 
            +
                    case MYSQL_TYPE_YEAR:       // YEAR field
         | 
| 161 | 
            +
                      val = rb_cstr2inum(row[i], 10);
         | 
| 162 | 
            +
                      break;
         | 
| 163 | 
            +
                    case MYSQL_TYPE_DECIMAL:    // DECIMAL or NUMERIC field
         | 
| 164 | 
            +
                    case MYSQL_TYPE_NEWDECIMAL: // Precision math DECIMAL or NUMERIC field (MySQL 5.0.3 and up)
         | 
| 165 | 
            +
                      if (strtod(row[i], NULL) == 0.000000){
         | 
| 166 | 
            +
                        val = rb_funcall(cBigDecimal, intern_new, 1, opt_decimal_zero);
         | 
| 167 | 
            +
                      }else{
         | 
| 168 | 
            +
                        val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new(row[i], fieldLengths[i]));
         | 
| 169 | 
            +
                      }
         | 
| 170 | 
            +
                      break;
         | 
| 171 | 
            +
                    case MYSQL_TYPE_FLOAT:      // FLOAT field
         | 
| 172 | 
            +
                    case MYSQL_TYPE_DOUBLE: {     // DOUBLE or REAL field
         | 
| 173 | 
            +
                      double column_to_double;
         | 
| 174 | 
            +
                      column_to_double = strtod(row[i], NULL);
         | 
| 175 | 
            +
                      if (column_to_double == 0.000000){
         | 
| 176 | 
            +
                        val = opt_float_zero;
         | 
| 177 | 
            +
                      }else{
         | 
| 178 | 
            +
                        val = rb_float_new(column_to_double);
         | 
| 179 | 
            +
                      }
         | 
| 180 | 
            +
                      break;
         | 
| 181 | 
            +
                    }
         | 
| 182 | 
            +
                    case MYSQL_TYPE_TIME: {     // TIME field
         | 
| 183 | 
            +
                      int hour, min, sec, tokens;
         | 
| 184 | 
            +
                      tokens = sscanf(row[i], "%2d:%2d:%2d", &hour, &min, &sec);
         | 
| 185 | 
            +
                      val = rb_funcall(rb_cTime, db_timezone, 6, opt_time_year, opt_time_month, opt_time_month, INT2NUM(hour), INT2NUM(min), INT2NUM(sec));
         | 
| 186 | 
            +
                      if (!NIL_P(app_timezone)) {
         | 
| 187 | 
            +
                        if (app_timezone == intern_local) {
         | 
| 188 | 
            +
                          val = rb_funcall(val, intern_localtime, 0);
         | 
| 189 | 
            +
                        } else { // utc
         | 
| 190 | 
            +
                          val = rb_funcall(val, intern_utc, 0);
         | 
| 191 | 
            +
                        }
         | 
| 192 | 
            +
                      }
         | 
| 193 | 
            +
                      break;
         | 
| 194 | 
            +
                    }
         | 
| 195 | 
            +
                    case MYSQL_TYPE_TIMESTAMP:  // TIMESTAMP field
         | 
| 196 | 
            +
                    case MYSQL_TYPE_DATETIME: { // DATETIME field
         | 
| 197 | 
            +
                      int year, month, day, hour, min, sec, tokens;
         | 
| 198 | 
            +
                      tokens = sscanf(row[i], "%4d-%2d-%2d %2d:%2d:%2d", &year, &month, &day, &hour, &min, &sec);
         | 
| 199 | 
            +
                      if (year+month+day+hour+min+sec == 0) {
         | 
| 200 | 
            +
                        val = Qnil;
         | 
| 201 | 
            +
                      } else {
         | 
| 202 | 
            +
                        if (month < 1 || day < 1) {
         | 
| 203 | 
            +
                          rb_raise(cMysql2Error, "Invalid date: %s", row[i]);
         | 
| 204 | 
            +
                          val = Qnil;
         | 
| 205 | 
            +
                        } else {
         | 
| 206 | 
            +
                          if (year < MYSQL2_MIN_YEAR || year+month+day > MYSQL2_MAX_YEAR) { // use DateTime instead
         | 
| 207 | 
            +
                            VALUE offset = INT2NUM(0);
         | 
| 208 | 
            +
                            if (db_timezone == intern_local) {
         | 
| 209 | 
            +
                              offset = rb_funcall(cMysql2Client, intern_local_offset, 0);
         | 
| 210 | 
            +
                            }
         | 
| 211 | 
            +
                            val = rb_funcall(cDateTime, intern_civil, 7, INT2NUM(year), INT2NUM(month), INT2NUM(day), INT2NUM(hour), INT2NUM(min), INT2NUM(sec), offset);
         | 
| 212 | 
            +
                            if (!NIL_P(app_timezone)) {
         | 
| 213 | 
            +
                              if (app_timezone == intern_local) {
         | 
| 214 | 
            +
                                offset = rb_funcall(cMysql2Client, intern_local_offset, 0);
         | 
| 215 | 
            +
                                val = rb_funcall(val, intern_new_offset, 1, offset);
         | 
| 216 | 
            +
                              } else { // utc
         | 
| 217 | 
            +
                                val = rb_funcall(val, intern_new_offset, 1, opt_utc_offset);
         | 
| 218 | 
            +
                              }
         | 
| 219 | 
            +
                            }
         | 
| 220 | 
            +
                          } else {
         | 
| 221 | 
            +
                            val = rb_funcall(rb_cTime, db_timezone, 6, INT2NUM(year), INT2NUM(month), INT2NUM(day), INT2NUM(hour), INT2NUM(min), INT2NUM(sec));
         | 
| 222 | 
            +
                            if (!NIL_P(app_timezone)) {
         | 
| 223 | 
            +
                              if (app_timezone == intern_local) {
         | 
| 224 | 
            +
                                val = rb_funcall(val, intern_localtime, 0);
         | 
| 225 | 
            +
                              } else { // utc
         | 
| 226 | 
            +
                                val = rb_funcall(val, intern_utc, 0);
         | 
| 227 | 
            +
                              }
         | 
| 228 | 
            +
                            }
         | 
| 229 | 
            +
                          }
         | 
| 230 | 
            +
                        }
         | 
| 231 | 
            +
                      }
         | 
| 232 | 
            +
                      break;
         | 
| 233 | 
            +
                    }
         | 
| 234 | 
            +
                    case MYSQL_TYPE_DATE:       // DATE field
         | 
| 235 | 
            +
                    case MYSQL_TYPE_NEWDATE: {  // Newer const used > 5.0
         | 
| 236 | 
            +
                      int year, month, day, tokens;
         | 
| 237 | 
            +
                      tokens = sscanf(row[i], "%4d-%2d-%2d", &year, &month, &day);
         | 
| 238 | 
            +
                      if (year+month+day == 0) {
         | 
| 239 | 
            +
                        val = Qnil;
         | 
| 240 | 
            +
                      } else {
         | 
| 241 | 
            +
                        if (month < 1 || day < 1) {
         | 
| 242 | 
            +
                          rb_raise(cMysql2Error, "Invalid date: %s", row[i]);
         | 
| 243 | 
            +
                          val = Qnil;
         | 
| 244 | 
            +
                        } else {
         | 
| 245 | 
            +
                          val = rb_funcall(cDate, intern_new, 3, INT2NUM(year), INT2NUM(month), INT2NUM(day));
         | 
| 246 | 
            +
                        }
         | 
| 247 | 
            +
                      }
         | 
| 248 | 
            +
                      break;
         | 
| 249 | 
            +
                    }
         | 
| 250 | 
            +
                    case MYSQL_TYPE_TINY_BLOB:
         | 
| 251 | 
            +
                    case MYSQL_TYPE_MEDIUM_BLOB:
         | 
| 252 | 
            +
                    case MYSQL_TYPE_LONG_BLOB:
         | 
| 253 | 
            +
                    case MYSQL_TYPE_BLOB:
         | 
| 254 | 
            +
                    case MYSQL_TYPE_VAR_STRING:
         | 
| 255 | 
            +
                    case MYSQL_TYPE_VARCHAR:
         | 
| 256 | 
            +
                    case MYSQL_TYPE_STRING:     // CHAR or BINARY field
         | 
| 257 | 
            +
                    case MYSQL_TYPE_SET:        // SET field
         | 
| 258 | 
            +
                    case MYSQL_TYPE_ENUM:       // ENUM field
         | 
| 259 | 
            +
                    case MYSQL_TYPE_GEOMETRY:   // Spatial fielda
         | 
| 260 | 
            +
                    default:
         | 
| 261 | 
            +
                      val = rb_str_new(row[i], fieldLengths[i]);
         | 
| 262 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 263 | 
            +
                      // if binary flag is set, respect it's wishes
         | 
| 264 | 
            +
                      if (fields[i].flags & BINARY_FLAG && fields[i].charsetnr == 63) {
         | 
| 265 | 
            +
                        rb_enc_associate(val, binaryEncoding);
         | 
| 266 | 
            +
                      } else {
         | 
| 267 | 
            +
                        // lookup the encoding configured on this field
         | 
| 268 | 
            +
                        VALUE new_encoding = rb_funcall(cMysql2Client, intern_encoding_from_charset_code, 1, INT2NUM(fields[i].charsetnr));
         | 
| 269 | 
            +
                        if (new_encoding != Qnil) {
         | 
| 270 | 
            +
                          // use the field encoding we were able to match
         | 
| 271 | 
            +
                          rb_encoding *enc = rb_to_encoding(new_encoding);
         | 
| 272 | 
            +
                          rb_enc_associate(val, enc);
         | 
| 273 | 
            +
                        } else {
         | 
| 274 | 
            +
                          // otherwise fall-back to the connection's encoding
         | 
| 275 | 
            +
                          rb_enc_associate(val, conn_enc);
         | 
| 276 | 
            +
                        }
         | 
| 277 | 
            +
                        if (default_internal_enc) {
         | 
| 278 | 
            +
                          val = rb_str_export_to_enc(val, default_internal_enc);
         | 
| 279 | 
            +
                        }
         | 
| 280 | 
            +
                      }
         | 
| 281 | 
            +
            #endif
         | 
| 282 | 
            +
                      break;
         | 
| 283 | 
            +
                  }
         | 
| 284 | 
            +
                  if (asArray) {
         | 
| 285 | 
            +
                    rb_ary_push(rowVal, val);
         | 
| 286 | 
            +
                  } else {
         | 
| 287 | 
            +
                    rb_hash_aset(rowVal, field, val);
         | 
| 288 | 
            +
                  }
         | 
| 289 | 
            +
                } else {
         | 
| 290 | 
            +
                  if (asArray) {
         | 
| 291 | 
            +
                    rb_ary_push(rowVal, Qnil);
         | 
| 292 | 
            +
                  } else {
         | 
| 293 | 
            +
                    rb_hash_aset(rowVal, field, Qnil);
         | 
| 294 | 
            +
                  }
         | 
| 295 | 
            +
                }
         | 
| 296 | 
            +
              }
         | 
| 297 | 
            +
              return rowVal;
         | 
| 298 | 
            +
            }
         | 
| 299 | 
            +
             | 
| 300 | 
            +
            static VALUE rb_mysql_result_fetch_fields(VALUE self) {
         | 
| 301 | 
            +
              mysql2_result_wrapper * wrapper;
         | 
| 302 | 
            +
              unsigned int i = 0;
         | 
| 303 | 
            +
              short int symbolizeKeys = 0;
         | 
| 304 | 
            +
              VALUE defaults;
         | 
| 305 | 
            +
             | 
| 306 | 
            +
              GetMysql2Result(self, wrapper);
         | 
| 307 | 
            +
             | 
| 308 | 
            +
              defaults = rb_iv_get(self, "@query_options");
         | 
| 309 | 
            +
              if (rb_hash_aref(defaults, sym_symbolize_keys) == Qtrue) {
         | 
| 310 | 
            +
                symbolizeKeys = 1;
         | 
| 311 | 
            +
              }
         | 
| 312 | 
            +
             | 
| 313 | 
            +
              if (wrapper->fields == Qnil) {
         | 
| 314 | 
            +
                wrapper->numberOfFields = mysql_num_fields(wrapper->result);
         | 
| 315 | 
            +
                wrapper->fields = rb_ary_new2(wrapper->numberOfFields);
         | 
| 316 | 
            +
              }
         | 
| 317 | 
            +
             | 
| 318 | 
            +
              if (RARRAY_LEN(wrapper->fields) != wrapper->numberOfFields) {
         | 
| 319 | 
            +
                for (i=0; i<wrapper->numberOfFields; i++) {
         | 
| 320 | 
            +
                  rb_mysql_result_fetch_field(self, i, symbolizeKeys);
         | 
| 321 | 
            +
                }
         | 
| 322 | 
            +
              }
         | 
| 323 | 
            +
             | 
| 324 | 
            +
              return wrapper->fields;
         | 
| 325 | 
            +
            }
         | 
| 326 | 
            +
             | 
| 327 | 
            +
            static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
         | 
| 328 | 
            +
              VALUE defaults, opts, block;
         | 
| 329 | 
            +
              ID db_timezone, app_timezone, dbTz, appTz;
         | 
| 330 | 
            +
              mysql2_result_wrapper * wrapper;
         | 
| 331 | 
            +
              unsigned long i;
         | 
| 332 | 
            +
              int symbolizeKeys = 0, asArray = 0, castBool = 0, cacheRows = 1;
         | 
| 333 | 
            +
             | 
| 334 | 
            +
              GetMysql2Result(self, wrapper);
         | 
| 335 | 
            +
             | 
| 336 | 
            +
              defaults = rb_iv_get(self, "@query_options");
         | 
| 337 | 
            +
              if (rb_scan_args(argc, argv, "01&", &opts, &block) == 1) {
         | 
| 338 | 
            +
                opts = rb_funcall(defaults, intern_merge, 1, opts);
         | 
| 339 | 
            +
              } else {
         | 
| 340 | 
            +
                opts = defaults;
         | 
| 341 | 
            +
              }
         | 
| 342 | 
            +
             | 
| 343 | 
            +
              if (rb_hash_aref(opts, sym_symbolize_keys) == Qtrue) {
         | 
| 344 | 
            +
                symbolizeKeys = 1;
         | 
| 345 | 
            +
              }
         | 
| 346 | 
            +
             | 
| 347 | 
            +
              if (rb_hash_aref(opts, sym_as) == sym_array) {
         | 
| 348 | 
            +
                asArray = 1;
         | 
| 349 | 
            +
              }
         | 
| 350 | 
            +
             | 
| 351 | 
            +
              if (rb_hash_aref(opts, sym_cast_booleans) == Qtrue) {
         | 
| 352 | 
            +
                castBool = 1;
         | 
| 353 | 
            +
              }
         | 
| 354 | 
            +
             | 
| 355 | 
            +
              if (rb_hash_aref(opts, sym_cache_rows) == Qfalse) {
         | 
| 356 | 
            +
                cacheRows = 0;
         | 
| 357 | 
            +
              }
         | 
| 358 | 
            +
             | 
| 359 | 
            +
              dbTz = rb_hash_aref(opts, sym_database_timezone);
         | 
| 360 | 
            +
              if (dbTz == sym_local) {
         | 
| 361 | 
            +
                db_timezone = intern_local;
         | 
| 362 | 
            +
              } else if (dbTz == sym_utc) {
         | 
| 363 | 
            +
                db_timezone = intern_utc;
         | 
| 364 | 
            +
              } else {
         | 
| 365 | 
            +
                if (!NIL_P(dbTz)) {
         | 
| 366 | 
            +
                  rb_warn(":database_timezone option must be :utc or :local - defaulting to :local");
         | 
| 367 | 
            +
                }
         | 
| 368 | 
            +
                db_timezone = intern_local;
         | 
| 369 | 
            +
              }
         | 
| 370 | 
            +
             | 
| 371 | 
            +
              appTz = rb_hash_aref(opts, sym_application_timezone);
         | 
| 372 | 
            +
              if (appTz == sym_local) {
         | 
| 373 | 
            +
                app_timezone = intern_local;
         | 
| 374 | 
            +
              } else if (appTz == sym_utc) {
         | 
| 375 | 
            +
                app_timezone = intern_utc;
         | 
| 376 | 
            +
              } else {
         | 
| 377 | 
            +
                app_timezone = Qnil;
         | 
| 378 | 
            +
              }
         | 
| 379 | 
            +
             | 
| 380 | 
            +
              if (wrapper->lastRowProcessed == 0) {
         | 
| 381 | 
            +
                wrapper->numberOfRows = mysql_num_rows(wrapper->result);
         | 
| 382 | 
            +
                if (wrapper->numberOfRows == 0) {
         | 
| 383 | 
            +
                  wrapper->rows = rb_ary_new();
         | 
| 384 | 
            +
                  return wrapper->rows;
         | 
| 385 | 
            +
                }
         | 
| 386 | 
            +
                wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
         | 
| 387 | 
            +
              }
         | 
| 388 | 
            +
             | 
| 389 | 
            +
              if (cacheRows && wrapper->lastRowProcessed == wrapper->numberOfRows) {
         | 
| 390 | 
            +
                // we've already read the entire dataset from the C result into our
         | 
| 391 | 
            +
                // internal array. Lets hand that over to the user since it's ready to go
         | 
| 392 | 
            +
                for (i = 0; i < wrapper->numberOfRows; i++) {
         | 
| 393 | 
            +
                  rb_yield(rb_ary_entry(wrapper->rows, i));
         | 
| 394 | 
            +
                }
         | 
| 395 | 
            +
              } else {
         | 
| 396 | 
            +
                unsigned long rowsProcessed = 0;
         | 
| 397 | 
            +
                rowsProcessed = RARRAY_LEN(wrapper->rows);
         | 
| 398 | 
            +
                for (i = 0; i < wrapper->numberOfRows; i++) {
         | 
| 399 | 
            +
                  VALUE row;
         | 
| 400 | 
            +
                  if (cacheRows && i < rowsProcessed) {
         | 
| 401 | 
            +
                    row = rb_ary_entry(wrapper->rows, i);
         | 
| 402 | 
            +
                  } else {
         | 
| 403 | 
            +
                    row = rb_mysql_result_fetch_row(self, db_timezone, app_timezone, symbolizeKeys, asArray, castBool);
         | 
| 404 | 
            +
                    if (cacheRows) {
         | 
| 405 | 
            +
                      rb_ary_store(wrapper->rows, i, row);
         | 
| 406 | 
            +
                    }
         | 
| 407 | 
            +
                    wrapper->lastRowProcessed++;
         | 
| 408 | 
            +
                  }
         | 
| 409 | 
            +
             | 
| 410 | 
            +
                  if (row == Qnil) {
         | 
| 411 | 
            +
                    // we don't need the mysql C dataset around anymore, peace it
         | 
| 412 | 
            +
                    rb_mysql_result_free_result(wrapper);
         | 
| 413 | 
            +
                    return Qnil;
         | 
| 414 | 
            +
                  }
         | 
| 415 | 
            +
             | 
| 416 | 
            +
                  if (block != Qnil) {
         | 
| 417 | 
            +
                    rb_yield(row);
         | 
| 418 | 
            +
                  }
         | 
| 419 | 
            +
                }
         | 
| 420 | 
            +
                if (wrapper->lastRowProcessed == wrapper->numberOfRows) {
         | 
| 421 | 
            +
                  // we don't need the mysql C dataset around anymore, peace it
         | 
| 422 | 
            +
                  rb_mysql_result_free_result(wrapper);
         | 
| 423 | 
            +
                }
         | 
| 424 | 
            +
              }
         | 
| 425 | 
            +
             | 
| 426 | 
            +
              return wrapper->rows;
         | 
| 427 | 
            +
            }
         | 
| 428 | 
            +
             | 
| 429 | 
            +
            /* Mysql2::Result */
         | 
| 430 | 
            +
            VALUE rb_mysql_result_to_obj(MYSQL_RES * r) {
         | 
| 431 | 
            +
              VALUE obj;
         | 
| 432 | 
            +
              mysql2_result_wrapper * wrapper;
         | 
| 433 | 
            +
              obj = Data_Make_Struct(cMysql2Result, mysql2_result_wrapper, rb_mysql_result_mark, rb_mysql_result_free, wrapper);
         | 
| 434 | 
            +
              wrapper->numberOfFields = 0;
         | 
| 435 | 
            +
              wrapper->numberOfRows = 0;
         | 
| 436 | 
            +
              wrapper->lastRowProcessed = 0;
         | 
| 437 | 
            +
              wrapper->resultFreed = 0;
         | 
| 438 | 
            +
              wrapper->result = r;
         | 
| 439 | 
            +
              wrapper->fields = Qnil;
         | 
| 440 | 
            +
              wrapper->rows = Qnil;
         | 
| 441 | 
            +
              wrapper->encoding = Qnil;
         | 
| 442 | 
            +
              rb_obj_call_init(obj, 0, NULL);
         | 
| 443 | 
            +
              return obj;
         | 
| 444 | 
            +
            }
         | 
| 445 | 
            +
             | 
| 446 | 
            +
            void init_mysql2_result() {
         | 
| 447 | 
            +
              cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
         | 
| 448 | 
            +
              cDate = rb_const_get(rb_cObject, rb_intern("Date"));
         | 
| 449 | 
            +
              cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
         | 
| 450 | 
            +
             | 
| 451 | 
            +
              cMysql2Result = rb_define_class_under(mMysql2, "Result", rb_cObject);
         | 
| 452 | 
            +
              rb_define_method(cMysql2Result, "each", rb_mysql_result_each, -1);
         | 
| 453 | 
            +
              rb_define_method(cMysql2Result, "fields", rb_mysql_result_fetch_fields, 0);
         | 
| 454 | 
            +
             | 
| 455 | 
            +
              intern_encoding_from_charset = rb_intern("encoding_from_charset");
         | 
| 456 | 
            +
              intern_encoding_from_charset_code = rb_intern("encoding_from_charset_code");
         | 
| 457 | 
            +
             | 
| 458 | 
            +
              intern_new          = rb_intern("new");
         | 
| 459 | 
            +
              intern_utc          = rb_intern("utc");
         | 
| 460 | 
            +
              intern_local        = rb_intern("local");
         | 
| 461 | 
            +
              intern_merge        = rb_intern("merge");
         | 
| 462 | 
            +
              intern_localtime    = rb_intern("localtime");
         | 
| 463 | 
            +
              intern_local_offset = rb_intern("local_offset");
         | 
| 464 | 
            +
              intern_civil        = rb_intern("civil");
         | 
| 465 | 
            +
              intern_new_offset   = rb_intern("new_offset");
         | 
| 466 | 
            +
             | 
| 467 | 
            +
              sym_symbolize_keys  = ID2SYM(rb_intern("symbolize_keys"));
         | 
| 468 | 
            +
              sym_as              = ID2SYM(rb_intern("as"));
         | 
| 469 | 
            +
              sym_array           = ID2SYM(rb_intern("array"));
         | 
| 470 | 
            +
              sym_local           = ID2SYM(rb_intern("local"));
         | 
| 471 | 
            +
              sym_utc             = ID2SYM(rb_intern("utc"));
         | 
| 472 | 
            +
              sym_cast_booleans   = ID2SYM(rb_intern("cast_booleans"));
         | 
| 473 | 
            +
              sym_database_timezone     = ID2SYM(rb_intern("database_timezone"));
         | 
| 474 | 
            +
              sym_application_timezone  = ID2SYM(rb_intern("application_timezone"));
         | 
| 475 | 
            +
              sym_cache_rows     = ID2SYM(rb_intern("cache_rows"));
         | 
| 476 | 
            +
             | 
| 477 | 
            +
              opt_decimal_zero = rb_str_new2("0.0");
         | 
| 478 | 
            +
              rb_global_variable(&opt_decimal_zero); //never GC
         | 
| 479 | 
            +
              opt_float_zero = rb_float_new((double)0);
         | 
| 480 | 
            +
              rb_global_variable(&opt_float_zero);
         | 
| 481 | 
            +
              opt_time_year = INT2NUM(2000);
         | 
| 482 | 
            +
              opt_time_month = INT2NUM(1);
         | 
| 483 | 
            +
              opt_utc_offset = INT2NUM(0);
         | 
| 484 | 
            +
             | 
| 485 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 486 | 
            +
              binaryEncoding = rb_enc_find("binary");
         | 
| 487 | 
            +
            #endif
         | 
| 488 | 
            +
            }
         |