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