sqlite3 1.3.5 → 1.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.rdoc +84 -0
- data/Gemfile +15 -0
- data/Manifest.txt +2 -0
- data/README.rdoc +29 -6
- data/ext/sqlite3/database.c +131 -27
- data/ext/sqlite3/extconf.rb +31 -7
- data/ext/sqlite3/sqlite3.c +112 -0
- data/ext/sqlite3/sqlite3_ruby.h +12 -4
- data/ext/sqlite3/statement.c +33 -22
- data/faq/faq.yml +1 -1
- data/lib/sqlite3.rb +6 -1
- data/lib/sqlite3/database.rb +36 -24
- data/lib/sqlite3/pragmas.rb +357 -49
- data/lib/sqlite3/resultset.rb +94 -25
- data/lib/sqlite3/statement.rb +13 -17
- data/lib/sqlite3/version.rb +2 -2
- data/setup.rb +2 -2
- data/tasks/gem.rake +12 -6
- data/tasks/native.rake +22 -7
- data/tasks/vendor_sqlite3.rake +69 -20
- data/test/helper.rb +17 -2
- data/test/test_backup.rb +2 -2
- data/test/test_collation.rb +1 -1
- data/test/test_database.rb +102 -7
- data/test/test_database_readonly.rb +10 -3
- data/test/test_deprecated.rb +8 -1
- data/test/test_encoding.rb +35 -1
- data/test/test_integration.rb +36 -15
- data/test/test_integration_open_close.rb +1 -1
- data/test/test_integration_pending.rb +2 -2
- data/test/test_integration_resultset.rb +6 -3
- data/test/test_integration_statement.rb +2 -2
- data/test/test_result_set.rb +37 -0
- data/test/test_sqlite3.rb +13 -1
- data/test/test_statement.rb +26 -4
- data/test/test_statement_execute.rb +1 -1
- metadata +125 -121
- data/.gemtest +0 -0
    
        data/ext/sqlite3/extconf.rb
    CHANGED
    
    | @@ -6,14 +6,29 @@ require 'mkmf' | |
| 6 6 |  | 
| 7 7 | 
             
            RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
         | 
| 8 8 |  | 
| 9 | 
            -
            # --with-sqlite3-{dir,include,lib}
         | 
| 10 | 
            -
            dir_config("sqlite3")
         | 
| 11 9 |  | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 10 | 
            +
             | 
| 11 | 
            +
            ldflags = cppflags = nil
         | 
| 12 | 
            +
            if RbConfig::CONFIG["host_os"] =~ /darwin/
         | 
| 13 | 
            +
              begin
         | 
| 14 | 
            +
                brew_prefix = `brew --prefix sqlite3`.chomp
         | 
| 15 | 
            +
                ldflags   = "#{brew_prefix}/lib"
         | 
| 16 | 
            +
                cppflags  = "#{brew_prefix}/include"
         | 
| 17 | 
            +
                pkg_conf  = "#{brew_prefix}/lib/pkgconfig"
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                # pkg_config should be less error prone than parsing compiler
         | 
| 20 | 
            +
                # commandline options, but we need to set default ldflags and cpp flags
         | 
| 21 | 
            +
                # in case the user doesn't have pkg-config installed
         | 
| 22 | 
            +
                ENV['PKG_CONFIG_PATH'] ||= pkg_conf
         | 
| 23 | 
            +
              rescue
         | 
| 24 | 
            +
              end
         | 
| 15 25 | 
             
            end
         | 
| 16 26 |  | 
| 27 | 
            +
            pkg_config("sqlite3")
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            # --with-sqlite3-{dir,include,lib}
         | 
| 30 | 
            +
            dir_config("sqlite3", cppflags, ldflags)
         | 
| 31 | 
            +
             | 
| 17 32 | 
             
            if RbConfig::CONFIG["host_os"] =~ /mswin/
         | 
| 18 33 | 
             
              $CFLAGS << ' -W3'
         | 
| 19 34 | 
             
            end
         | 
| @@ -24,24 +39,33 @@ def asplode missing | |
| 24 39 | 
             
                      "http://www.sqlite.org/ first."
         | 
| 25 40 | 
             
              else
         | 
| 26 41 | 
             
                abort <<-error
         | 
| 27 | 
            -
            #{missing} is missing. Try ' | 
| 28 | 
            -
             | 
| 42 | 
            +
            #{missing} is missing. Try 'brew install sqlite3',
         | 
| 43 | 
            +
            'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
         | 
| 44 | 
            +
            and check your shared library search path (the
         | 
| 29 45 | 
             
            location where your sqlite3 shared library is located).
         | 
| 30 46 | 
             
                error
         | 
| 31 47 | 
             
              end
         | 
| 32 48 | 
             
            end
         | 
| 33 49 |  | 
| 34 50 | 
             
            asplode('sqlite3.h')  unless find_header  'sqlite3.h'
         | 
| 51 | 
            +
            find_library 'pthread', 'pthread_create' # 1.8 support. *shrug*
         | 
| 35 52 | 
             
            asplode('sqlite3') unless find_library 'sqlite3', 'sqlite3_libversion_number'
         | 
| 36 53 |  | 
| 37 54 | 
             
            # Functions defined in 1.9 but not 1.8
         | 
| 38 55 | 
             
            have_func('rb_proc_arity')
         | 
| 39 56 |  | 
| 57 | 
            +
            # Functions defined in 2.1 but not 2.0
         | 
| 58 | 
            +
            have_func('rb_integer_pack')
         | 
| 59 | 
            +
             | 
| 40 60 | 
             
            # These functions may not be defined
         | 
| 41 61 | 
             
            have_func('sqlite3_initialize')
         | 
| 42 62 | 
             
            have_func('sqlite3_backup_init')
         | 
| 43 63 | 
             
            have_func('sqlite3_column_database_name')
         | 
| 44 64 | 
             
            have_func('sqlite3_enable_load_extension')
         | 
| 45 65 | 
             
            have_func('sqlite3_load_extension')
         | 
| 66 | 
            +
            have_func('sqlite3_open_v2')
         | 
| 67 | 
            +
            have_func('sqlite3_prepare_v2')
         | 
| 68 | 
            +
            have_type('sqlite3_int64', 'sqlite3.h')
         | 
| 69 | 
            +
            have_type('sqlite3_uint64', 'sqlite3.h')
         | 
| 46 70 |  | 
| 47 71 | 
             
            create_makefile('sqlite3/sqlite3_native')
         | 
    
        data/ext/sqlite3/sqlite3.c
    CHANGED
    
    | @@ -3,11 +3,121 @@ | |
| 3 3 | 
             
            VALUE mSqlite3;
         | 
| 4 4 | 
             
            VALUE cSqlite3Blob;
         | 
| 5 5 |  | 
| 6 | 
            +
            int bignum_to_int64(VALUE value, sqlite3_int64 *result)
         | 
| 7 | 
            +
            {
         | 
| 8 | 
            +
            #ifdef HAVE_RB_INTEGER_PACK
         | 
| 9 | 
            +
              const int nails = 0;
         | 
| 10 | 
            +
              int t = rb_integer_pack(value, result, 1, sizeof(*result), nails,
         | 
| 11 | 
            +
            			  INTEGER_PACK_NATIVE_BYTE_ORDER|
         | 
| 12 | 
            +
            			  INTEGER_PACK_2COMP);
         | 
| 13 | 
            +
              switch (t) {
         | 
| 14 | 
            +
              case -2: case +2:
         | 
| 15 | 
            +
                return 0;
         | 
| 16 | 
            +
              case +1:
         | 
| 17 | 
            +
                if (!nails) {
         | 
| 18 | 
            +
                  if (*result < 0) return 0;
         | 
| 19 | 
            +
                }
         | 
| 20 | 
            +
                break;
         | 
| 21 | 
            +
              case -1:
         | 
| 22 | 
            +
                if (!nails) {
         | 
| 23 | 
            +
                  if (*result >= 0) return 0;
         | 
| 24 | 
            +
                }
         | 
| 25 | 
            +
                else {
         | 
| 26 | 
            +
                  *result += INT64_MIN;
         | 
| 27 | 
            +
                }
         | 
| 28 | 
            +
                break;
         | 
| 29 | 
            +
              }
         | 
| 30 | 
            +
              return 1;
         | 
| 31 | 
            +
            #else
         | 
| 32 | 
            +
            # ifndef RBIGNUM_LEN
         | 
| 33 | 
            +
            #   define RBIGNUM_LEN(x) RBIGNUM(x)->len
         | 
| 34 | 
            +
            # endif
         | 
| 35 | 
            +
              const long len = RBIGNUM_LEN(value);
         | 
| 36 | 
            +
              if (len == 0) {
         | 
| 37 | 
            +
                *result = 0;
         | 
| 38 | 
            +
                return 1;
         | 
| 39 | 
            +
              }
         | 
| 40 | 
            +
              if (len > 63 / (SIZEOF_BDIGITS * CHAR_BIT) + 1) return 0;
         | 
| 41 | 
            +
              if (len == 63 / (SIZEOF_BDIGITS * CHAR_BIT) + 1) {
         | 
| 42 | 
            +
                const BDIGIT *digits = RBIGNUM_DIGITS(value);
         | 
| 43 | 
            +
                BDIGIT blast = digits[len-1];
         | 
| 44 | 
            +
                BDIGIT bmax = (BDIGIT)1UL << (63 % (CHAR_BIT * SIZEOF_BDIGITS));
         | 
| 45 | 
            +
                if (blast > bmax) return 0;
         | 
| 46 | 
            +
                if (blast == bmax) {
         | 
| 47 | 
            +
                  if (RBIGNUM_POSITIVE_P(value)) {
         | 
| 48 | 
            +
            	return 0;
         | 
| 49 | 
            +
                  }
         | 
| 50 | 
            +
                  else {
         | 
| 51 | 
            +
            	long i = len-1;
         | 
| 52 | 
            +
            	while (i) {
         | 
| 53 | 
            +
            	  if (digits[--i]) return 0;
         | 
| 54 | 
            +
            	}
         | 
| 55 | 
            +
                  }
         | 
| 56 | 
            +
                }
         | 
| 57 | 
            +
              }
         | 
| 58 | 
            +
              *result = (sqlite3_int64)NUM2LL(value);
         | 
| 59 | 
            +
              return 1;
         | 
| 60 | 
            +
            #endif
         | 
| 61 | 
            +
            }
         | 
| 62 | 
            +
             | 
| 6 63 | 
             
            static VALUE libversion(VALUE UNUSED(klass))
         | 
| 7 64 | 
             
            {
         | 
| 8 65 | 
             
              return INT2NUM(sqlite3_libversion_number());
         | 
| 9 66 | 
             
            }
         | 
| 10 67 |  | 
| 68 | 
            +
            /* Returns the compile time setting of the SQLITE_THREADSAFE flag.
         | 
| 69 | 
            +
             * See: https://www.sqlite.org/c3ref/threadsafe.html
         | 
| 70 | 
            +
             */
         | 
| 71 | 
            +
            static VALUE threadsafe_p(VALUE UNUSED(klass))
         | 
| 72 | 
            +
            {
         | 
| 73 | 
            +
              return INT2NUM(sqlite3_threadsafe());
         | 
| 74 | 
            +
            }
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            void init_sqlite3_constants()
         | 
| 77 | 
            +
            {
         | 
| 78 | 
            +
              VALUE mSqlite3Constants;
         | 
| 79 | 
            +
              VALUE mSqlite3Open;
         | 
| 80 | 
            +
             | 
| 81 | 
            +
              mSqlite3Constants = rb_define_module_under(mSqlite3, "Constants");
         | 
| 82 | 
            +
             | 
| 83 | 
            +
              /* sqlite3_open_v2 flags for Database::new */
         | 
| 84 | 
            +
              mSqlite3Open = rb_define_module_under(mSqlite3Constants, "Open");
         | 
| 85 | 
            +
             | 
| 86 | 
            +
              /* symbols = IO.readlines('sqlite3.h').map { |n| /\A#define\s+(SQLITE_OPEN_\w+)\s/ =~ n && $1 }.compact
         | 
| 87 | 
            +
               * pad = symbols.map(&:length).max - 9
         | 
| 88 | 
            +
               * symbols.each { |s| printf %Q{  rb_define_const(mSqlite3Open, %-#{pad}s INT2FIX(#{s}));\n}, '"' + s[12..-1] + '",' }
         | 
| 89 | 
            +
               */
         | 
| 90 | 
            +
              rb_define_const(mSqlite3Open, "READONLY",       INT2FIX(SQLITE_OPEN_READONLY));
         | 
| 91 | 
            +
              rb_define_const(mSqlite3Open, "READWRITE",      INT2FIX(SQLITE_OPEN_READWRITE));
         | 
| 92 | 
            +
              rb_define_const(mSqlite3Open, "CREATE",         INT2FIX(SQLITE_OPEN_CREATE));
         | 
| 93 | 
            +
              rb_define_const(mSqlite3Open, "DELETEONCLOSE",  INT2FIX(SQLITE_OPEN_DELETEONCLOSE));
         | 
| 94 | 
            +
              rb_define_const(mSqlite3Open, "EXCLUSIVE",      INT2FIX(SQLITE_OPEN_EXCLUSIVE));
         | 
| 95 | 
            +
              rb_define_const(mSqlite3Open, "MAIN_DB",        INT2FIX(SQLITE_OPEN_MAIN_DB));
         | 
| 96 | 
            +
              rb_define_const(mSqlite3Open, "TEMP_DB",        INT2FIX(SQLITE_OPEN_TEMP_DB));
         | 
| 97 | 
            +
              rb_define_const(mSqlite3Open, "TRANSIENT_DB",   INT2FIX(SQLITE_OPEN_TRANSIENT_DB));
         | 
| 98 | 
            +
              rb_define_const(mSqlite3Open, "MAIN_JOURNAL",   INT2FIX(SQLITE_OPEN_MAIN_JOURNAL));
         | 
| 99 | 
            +
              rb_define_const(mSqlite3Open, "TEMP_JOURNAL",   INT2FIX(SQLITE_OPEN_TEMP_JOURNAL));
         | 
| 100 | 
            +
              rb_define_const(mSqlite3Open, "SUBJOURNAL",     INT2FIX(SQLITE_OPEN_SUBJOURNAL));
         | 
| 101 | 
            +
              rb_define_const(mSqlite3Open, "MASTER_JOURNAL", INT2FIX(SQLITE_OPEN_MASTER_JOURNAL));
         | 
| 102 | 
            +
              rb_define_const(mSqlite3Open, "NOMUTEX",        INT2FIX(SQLITE_OPEN_NOMUTEX));
         | 
| 103 | 
            +
              rb_define_const(mSqlite3Open, "FULLMUTEX",      INT2FIX(SQLITE_OPEN_FULLMUTEX));
         | 
| 104 | 
            +
            #ifdef SQLITE_OPEN_AUTOPROXY
         | 
| 105 | 
            +
              /* SQLITE_VERSION_NUMBER>=3007002 */
         | 
| 106 | 
            +
              rb_define_const(mSqlite3Open, "AUTOPROXY",      INT2FIX(SQLITE_OPEN_AUTOPROXY));
         | 
| 107 | 
            +
              rb_define_const(mSqlite3Open, "SHAREDCACHE",    INT2FIX(SQLITE_OPEN_SHAREDCACHE));
         | 
| 108 | 
            +
              rb_define_const(mSqlite3Open, "PRIVATECACHE",   INT2FIX(SQLITE_OPEN_PRIVATECACHE));
         | 
| 109 | 
            +
              rb_define_const(mSqlite3Open, "WAL",            INT2FIX(SQLITE_OPEN_WAL));
         | 
| 110 | 
            +
            #endif
         | 
| 111 | 
            +
            #ifdef SQLITE_OPEN_URI
         | 
| 112 | 
            +
              /* SQLITE_VERSION_NUMBER>=3007007 */
         | 
| 113 | 
            +
              rb_define_const(mSqlite3Open, "URI",            INT2FIX(SQLITE_OPEN_URI));
         | 
| 114 | 
            +
            #endif
         | 
| 115 | 
            +
            #ifdef SQLITE_OPEN_MEMORY
         | 
| 116 | 
            +
              /* SQLITE_VERSION_NUMBER>=3007013 */
         | 
| 117 | 
            +
              rb_define_const(mSqlite3Open, "MEMORY",         INT2FIX(SQLITE_OPEN_MEMORY));
         | 
| 118 | 
            +
            #endif
         | 
| 119 | 
            +
            }
         | 
| 120 | 
            +
             | 
| 11 121 | 
             
            void Init_sqlite3_native()
         | 
| 12 122 | 
             
            {
         | 
| 13 123 | 
             
              /*
         | 
| @@ -28,6 +138,7 @@ void Init_sqlite3_native() | |
| 28 138 | 
             
              sqlite3_initialize();
         | 
| 29 139 | 
             
            #endif
         | 
| 30 140 |  | 
| 141 | 
            +
              init_sqlite3_constants();
         | 
| 31 142 | 
             
              init_sqlite3_database();
         | 
| 32 143 | 
             
              init_sqlite3_statement();
         | 
| 33 144 | 
             
            #ifdef HAVE_SQLITE3_BACKUP_INIT
         | 
| @@ -35,6 +146,7 @@ void Init_sqlite3_native() | |
| 35 146 | 
             
            #endif
         | 
| 36 147 |  | 
| 37 148 | 
             
              rb_define_singleton_method(mSqlite3, "libversion", libversion, 0);
         | 
| 149 | 
            +
              rb_define_singleton_method(mSqlite3, "threadsafe", threadsafe_p, 0);
         | 
| 38 150 | 
             
              rb_define_const(mSqlite3, "SQLITE_VERSION", rb_str_new2(SQLITE_VERSION));
         | 
| 39 151 | 
             
              rb_define_const(mSqlite3, "SQLITE_VERSION_NUMBER", INT2FIX(SQLITE_VERSION_NUMBER));
         | 
| 40 152 | 
             
            }
         | 
    
        data/ext/sqlite3/sqlite3_ruby.h
    CHANGED
    
    | @@ -12,15 +12,13 @@ | |
| 12 12 | 
             
            # define UNUSED(x) x
         | 
| 13 13 | 
             
            #endif
         | 
| 14 14 |  | 
| 15 | 
            -
            #ifndef RBIGNUM_LEN
         | 
| 16 | 
            -
            #define RBIGNUM_LEN(x) RBIGNUM(x)->len
         | 
| 17 | 
            -
            #endif
         | 
| 18 | 
            -
             | 
| 19 15 | 
             
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 20 16 | 
             
            #include <ruby/encoding.h>
         | 
| 21 17 |  | 
| 18 | 
            +
            #define USASCII_P(_obj) (rb_enc_get_index(_obj) == rb_usascii_encindex())
         | 
| 22 19 | 
             
            #define UTF8_P(_obj) (rb_enc_get_index(_obj) == rb_utf8_encindex())
         | 
| 23 20 | 
             
            #define UTF16_LE_P(_obj) (rb_enc_get_index(_obj) == rb_enc_find_index("UTF-16LE"))
         | 
| 21 | 
            +
            #define UTF16_BE_P(_obj) (rb_enc_get_index(_obj) == rb_enc_find_index("UTF-16BE"))
         | 
| 24 22 | 
             
            #define SQLITE3_UTF8_STR_NEW2(_obj) \
         | 
| 25 23 | 
             
                (rb_enc_associate_index(rb_str_new2(_obj), rb_utf8_encindex()))
         | 
| 26 24 |  | 
| @@ -33,6 +31,14 @@ | |
| 33 31 |  | 
| 34 32 | 
             
            #include <sqlite3.h>
         | 
| 35 33 |  | 
| 34 | 
            +
            #ifndef HAVE_TYPE_SQLITE3_INT64
         | 
| 35 | 
            +
            typedef sqlite_int64 sqlite3_int64;
         | 
| 36 | 
            +
            #endif
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            #ifndef HAVE_TYPE_SQLITE3_UINT64
         | 
| 39 | 
            +
            typedef sqlite_uint64 sqlite3_uint64;
         | 
| 40 | 
            +
            #endif
         | 
| 41 | 
            +
             | 
| 36 42 | 
             
            extern VALUE mSqlite3;
         | 
| 37 43 | 
             
            extern VALUE cSqlite3Blob;
         | 
| 38 44 |  | 
| @@ -41,4 +47,6 @@ extern VALUE cSqlite3Blob; | |
| 41 47 | 
             
            #include <exception.h>
         | 
| 42 48 | 
             
            #include <backup.h>
         | 
| 43 49 |  | 
| 50 | 
            +
            int bignum_to_int64(VALUE big, sqlite3_int64 *result);
         | 
| 51 | 
            +
             | 
| 44 52 | 
             
            #endif
         | 
    
        data/ext/sqlite3/statement.c
    CHANGED
    
    | @@ -49,7 +49,11 @@ static VALUE initialize(VALUE self, VALUE db, VALUE sql) | |
| 49 49 | 
             
              }
         | 
| 50 50 | 
             
            #endif
         | 
| 51 51 |  | 
| 52 | 
            +
            #ifdef HAVE_SQLITE3_PREPARE_V2
         | 
| 52 53 | 
             
              status = sqlite3_prepare_v2(
         | 
| 54 | 
            +
            #else
         | 
| 55 | 
            +
              status = sqlite3_prepare(
         | 
| 56 | 
            +
            #endif
         | 
| 53 57 | 
             
                  db_ctx->db,
         | 
| 54 58 | 
             
                  (const char *)StringValuePtr(sql),
         | 
| 55 59 | 
             
                  (int)RSTRING_LEN(sql),
         | 
| @@ -75,15 +79,12 @@ static VALUE initialize(VALUE self, VALUE db, VALUE sql) | |
| 75 79 | 
             
            static VALUE sqlite3_rb_close(VALUE self)
         | 
| 76 80 | 
             
            {
         | 
| 77 81 | 
             
              sqlite3StmtRubyPtr ctx;
         | 
| 78 | 
            -
              sqlite3 * db;
         | 
| 79 82 |  | 
| 80 83 | 
             
              Data_Get_Struct(self, sqlite3StmtRuby, ctx);
         | 
| 81 84 |  | 
| 82 85 | 
             
              REQUIRE_OPEN_STMT(ctx);
         | 
| 83 86 |  | 
| 84 | 
            -
               | 
| 85 | 
            -
              CHECK(db, sqlite3_finalize(ctx->st));
         | 
| 86 | 
            -
             | 
| 87 | 
            +
              sqlite3_finalize(ctx->st);
         | 
| 87 88 | 
             
              ctx->st = NULL;
         | 
| 88 89 |  | 
| 89 90 | 
             
              return self;
         | 
| @@ -111,7 +112,6 @@ static VALUE step(VALUE self) | |
| 111 112 | 
             
              VALUE list;
         | 
| 112 113 | 
             
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 113 114 | 
             
              rb_encoding * internal_encoding;
         | 
| 114 | 
            -
              int enc_index;
         | 
| 115 115 | 
             
            #endif
         | 
| 116 116 |  | 
| 117 117 | 
             
              Data_Get_Struct(self, sqlite3StmtRuby, ctx);
         | 
| @@ -123,8 +123,7 @@ static VALUE step(VALUE self) | |
| 123 123 | 
             
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 124 124 | 
             
              {
         | 
| 125 125 | 
             
                  VALUE db          = rb_iv_get(self, "@connection");
         | 
| 126 | 
            -
                   | 
| 127 | 
            -
                  enc_index = NIL_P(encoding) ? rb_utf8_encindex() : rb_to_encoding_index(encoding);
         | 
| 126 | 
            +
                  rb_funcall(db, rb_intern("encoding"), 0);
         | 
| 128 127 | 
             
                  internal_encoding = rb_default_internal_encoding();
         | 
| 129 128 | 
             
              }
         | 
| 130 129 | 
             
            #endif
         | 
| @@ -154,7 +153,7 @@ static VALUE step(VALUE self) | |
| 154 153 | 
             
                                (long)sqlite3_column_bytes(stmt, i)
         | 
| 155 154 | 
             
                            );
         | 
| 156 155 | 
             
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 157 | 
            -
                            rb_enc_associate_index(str,  | 
| 156 | 
            +
                            rb_enc_associate_index(str, rb_utf8_encindex());
         | 
| 158 157 | 
             
                            if(internal_encoding)
         | 
| 159 158 | 
             
                              str = rb_str_export_to_enc(str, internal_encoding);
         | 
| 160 159 | 
             
            #endif
         | 
| @@ -184,6 +183,8 @@ static VALUE step(VALUE self) | |
| 184 183 | 
             
                  return Qnil;
         | 
| 185 184 | 
             
                  break;
         | 
| 186 185 | 
             
                default:
         | 
| 186 | 
            +
                  sqlite3_reset(stmt);
         | 
| 187 | 
            +
                  ctx->done_p = 0;
         | 
| 187 188 | 
             
                  CHECK(sqlite3_db_handle(ctx->st), value);
         | 
| 188 189 | 
             
              }
         | 
| 189 190 |  | 
| @@ -236,15 +237,22 @@ static VALUE bind_param(VALUE self, VALUE key, VALUE value) | |
| 236 237 | 
             
                        SQLITE_TRANSIENT
         | 
| 237 238 | 
             
                        );
         | 
| 238 239 | 
             
                  } else {
         | 
| 240 | 
            +
             | 
| 241 | 
            +
             | 
| 239 242 | 
             
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 240 | 
            -
                    if( | 
| 241 | 
            -
             | 
| 242 | 
            -
                           | 
| 243 | 
            -
                           | 
| 244 | 
            -
                           | 
| 243 | 
            +
                    if (UTF16_LE_P(value) || UTF16_BE_P(value)) {
         | 
| 244 | 
            +
                      status = sqlite3_bind_text16(
         | 
| 245 | 
            +
                          ctx->st,
         | 
| 246 | 
            +
                          index,
         | 
| 247 | 
            +
                          (const char *)StringValuePtr(value),
         | 
| 248 | 
            +
                          (int)RSTRING_LEN(value),
         | 
| 249 | 
            +
                          SQLITE_TRANSIENT
         | 
| 250 | 
            +
                          );
         | 
| 251 | 
            +
                    } else {
         | 
| 252 | 
            +
                      if (!UTF8_P(value) || !USASCII_P(value)) {
         | 
| 253 | 
            +
                          value = rb_str_encode(value, rb_enc_from_encoding(rb_utf8_encoding()), 0, Qnil);
         | 
| 245 254 | 
             
                      }
         | 
| 246 255 | 
             
            #endif
         | 
| 247 | 
            -
             | 
| 248 256 | 
             
                    status = sqlite3_bind_text(
         | 
| 249 257 | 
             
                        ctx->st,
         | 
| 250 258 | 
             
                        index,
         | 
| @@ -252,13 +260,18 @@ static VALUE bind_param(VALUE self, VALUE key, VALUE value) | |
| 252 260 | 
             
                        (int)RSTRING_LEN(value),
         | 
| 253 261 | 
             
                        SQLITE_TRANSIENT
         | 
| 254 262 | 
             
                        );
         | 
| 263 | 
            +
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| 264 | 
            +
                    }
         | 
| 265 | 
            +
            #endif
         | 
| 255 266 | 
             
                  }
         | 
| 256 267 | 
             
                  break;
         | 
| 257 | 
            -
                case T_BIGNUM:
         | 
| 258 | 
            -
                   | 
| 259 | 
            -
             | 
| 268 | 
            +
                case T_BIGNUM: {
         | 
| 269 | 
            +
                  sqlite3_int64 num64;
         | 
| 270 | 
            +
                  if (bignum_to_int64(value, &num64)) {
         | 
| 271 | 
            +
                      status = sqlite3_bind_int64(ctx->st, index, num64);
         | 
| 260 272 | 
             
                      break;
         | 
| 261 273 | 
             
                  }
         | 
| 274 | 
            +
                }
         | 
| 262 275 | 
             
                case T_FLOAT:
         | 
| 263 276 | 
             
                  status = sqlite3_bind_double(ctx->st, index, NUM2DBL(value));
         | 
| 264 277 | 
             
                  break;
         | 
| @@ -287,12 +300,11 @@ static VALUE bind_param(VALUE self, VALUE key, VALUE value) | |
| 287 300 | 
             
            static VALUE reset_bang(VALUE self)
         | 
| 288 301 | 
             
            {
         | 
| 289 302 | 
             
              sqlite3StmtRubyPtr ctx;
         | 
| 290 | 
            -
              int status;
         | 
| 291 303 |  | 
| 292 304 | 
             
              Data_Get_Struct(self, sqlite3StmtRuby, ctx);
         | 
| 293 305 | 
             
              REQUIRE_OPEN_STMT(ctx);
         | 
| 294 306 |  | 
| 295 | 
            -
               | 
| 307 | 
            +
              sqlite3_reset(ctx->st);
         | 
| 296 308 |  | 
| 297 309 | 
             
              ctx->done_p = 0;
         | 
| 298 310 |  | 
| @@ -307,12 +319,11 @@ static VALUE reset_bang(VALUE self) | |
| 307 319 | 
             
            static VALUE clear_bindings(VALUE self)
         | 
| 308 320 | 
             
            {
         | 
| 309 321 | 
             
              sqlite3StmtRubyPtr ctx;
         | 
| 310 | 
            -
              int status;
         | 
| 311 322 |  | 
| 312 323 | 
             
              Data_Get_Struct(self, sqlite3StmtRuby, ctx);
         | 
| 313 324 | 
             
              REQUIRE_OPEN_STMT(ctx);
         | 
| 314 325 |  | 
| 315 | 
            -
               | 
| 326 | 
            +
              sqlite3_clear_bindings(ctx->st);
         | 
| 316 327 |  | 
| 317 328 | 
             
              ctx->done_p = 0;
         | 
| 318 329 |  | 
| @@ -359,7 +370,7 @@ static VALUE column_name(VALUE self, VALUE index) | |
| 359 370 |  | 
| 360 371 | 
             
              name = sqlite3_column_name(ctx->st, (int)NUM2INT(index));
         | 
| 361 372 |  | 
| 362 | 
            -
              if(name) return  | 
| 373 | 
            +
              if(name) return SQLITE3_UTF8_STR_NEW2(name);
         | 
| 363 374 | 
             
              return Qnil;
         | 
| 364 375 | 
             
            }
         | 
| 365 376 |  | 
    
        data/faq/faq.yml
    CHANGED
    
    
    
        data/lib/sqlite3.rb
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            # support multiple ruby version (fat binaries under windows)
         | 
| 2 2 | 
             
            begin
         | 
| 3 | 
            -
              RUBY_VERSION =~ /(\d | 
| 3 | 
            +
              RUBY_VERSION =~ /(\d+\.\d+)/
         | 
| 4 4 | 
             
              require "sqlite3/#{$1}/sqlite3_native"
         | 
| 5 5 | 
             
            rescue LoadError
         | 
| 6 6 | 
             
              require 'sqlite3/sqlite3_native'
         | 
| @@ -8,3 +8,8 @@ end | |
| 8 8 |  | 
| 9 9 | 
             
            require 'sqlite3/database'
         | 
| 10 10 | 
             
            require 'sqlite3/version'
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            module SQLite3
         | 
| 13 | 
            +
              # Was sqlite3 compiled with thread safety on?
         | 
| 14 | 
            +
              def self.threadsafe?; threadsafe > 0; end
         | 
| 15 | 
            +
            end
         | 
    
        data/lib/sqlite3/database.rb
    CHANGED
    
    | @@ -94,10 +94,17 @@ in version 2.0.0. | |
| 94 94 | 
             
                  begin
         | 
| 95 95 | 
             
                    yield stmt
         | 
| 96 96 | 
             
                  ensure
         | 
| 97 | 
            -
                    stmt.close
         | 
| 97 | 
            +
                    stmt.close unless stmt.closed?
         | 
| 98 98 | 
             
                  end
         | 
| 99 99 | 
             
                end
         | 
| 100 100 |  | 
| 101 | 
            +
                # Returns the filename for the database named +db_name+.  +db_name+ defaults
         | 
| 102 | 
            +
                # to "main".  Main return `nil` or an empty string if the database is
         | 
| 103 | 
            +
                # temporary or in-memory.
         | 
| 104 | 
            +
                def filename db_name = 'main'
         | 
| 105 | 
            +
                  db_filename db_name
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
             | 
| 101 108 | 
             
                # Executes the given SQL statement. If additional parameters are given,
         | 
| 102 109 | 
             
                # they are treated as bind variables, and are bound to the placeholders in
         | 
| 103 110 | 
             
                # the query.
         | 
| @@ -113,10 +120,6 @@ in version 2.0.0. | |
| 113 120 | 
             
                # See also #execute2, #query, and #execute_batch for additional ways of
         | 
| 114 121 | 
             
                # executing statements.
         | 
| 115 122 | 
             
                def execute sql, bind_vars = [], *args, &block
         | 
| 116 | 
            -
                  # FIXME: This is a terrible hack and should be removed but is required
         | 
| 117 | 
            -
                  # for older versions of rails
         | 
| 118 | 
            -
                  hack = Object.const_defined?(:ActiveRecord) && sql =~ /^PRAGMA index_list/
         | 
| 119 | 
            -
             | 
| 120 123 | 
             
                  if bind_vars.nil? || !args.empty?
         | 
| 121 124 | 
             
                    if args.empty?
         | 
| 122 125 | 
             
                      bind_vars = []
         | 
| @@ -147,12 +150,7 @@ Support for bind parameters as *args will be removed in 2.0.0. | |
| 147 150 | 
             
                    else
         | 
| 148 151 | 
             
                      if @results_as_hash
         | 
| 149 152 | 
             
                        stmt.map { |row|
         | 
| 150 | 
            -
                           | 
| 151 | 
            -
             | 
| 152 | 
            -
                          # FIXME UGH TERRIBLE HACK!
         | 
| 153 | 
            -
                          h['unique'] = h['unique'].to_s if hack
         | 
| 154 | 
            -
             | 
| 155 | 
            -
                          h
         | 
| 153 | 
            +
                          type_translation ? row : ordered_map_for(columns, row)
         | 
| 156 154 | 
             
                        }
         | 
| 157 155 | 
             
                      else
         | 
| 158 156 | 
             
                        stmt.to_a
         | 
| @@ -221,22 +219,25 @@ Support for this behavior will be removed in version 2.0.0. | |
| 221 219 | 
             
                  sql = sql.strip
         | 
| 222 220 | 
             
                  until sql.empty? do
         | 
| 223 221 | 
             
                    prepare( sql ) do |stmt|
         | 
| 224 | 
            -
                       | 
| 225 | 
            -
             | 
| 226 | 
            -
             | 
| 227 | 
            -
                        stmt. | 
| 222 | 
            +
                      unless stmt.closed?
         | 
| 223 | 
            +
                        # FIXME: this should probably use sqlite3's api for batch execution
         | 
| 224 | 
            +
                        # This implementation requires stepping over the results.
         | 
| 225 | 
            +
                        if bind_vars.length == stmt.bind_parameter_count
         | 
| 226 | 
            +
                          stmt.bind_params(bind_vars)
         | 
| 227 | 
            +
                        end
         | 
| 228 | 
            +
                        stmt.step
         | 
| 228 229 | 
             
                      end
         | 
| 229 | 
            -
                      stmt.step
         | 
| 230 230 | 
             
                      sql = stmt.remainder.strip
         | 
| 231 231 | 
             
                    end
         | 
| 232 232 | 
             
                  end
         | 
| 233 | 
            +
                  # FIXME: we should not return `nil` as a success return value
         | 
| 233 234 | 
             
                  nil
         | 
| 234 235 | 
             
                end
         | 
| 235 236 |  | 
| 236 237 | 
             
                # This is a convenience method for creating a statement, binding
         | 
| 237 238 | 
             
                # paramters to it, and calling execute:
         | 
| 238 239 | 
             
                #
         | 
| 239 | 
            -
                #   result = db.query( "select * from foo where a=?", 5 | 
| 240 | 
            +
                #   result = db.query( "select * from foo where a=?", [5])
         | 
| 240 241 | 
             
                #   # is the same as
         | 
| 241 242 | 
             
                #   result = db.prepare( "select * from foo where a=?" ).execute( 5 )
         | 
| 242 243 | 
             
                #
         | 
| @@ -250,7 +251,7 @@ Support for this behavior will be removed in version 2.0.0. | |
| 250 251 | 
             
                    if args.empty?
         | 
| 251 252 | 
             
                      bind_vars = []
         | 
| 252 253 | 
             
                    else
         | 
| 253 | 
            -
                      bind_vars = [ | 
| 254 | 
            +
                      bind_vars = [bind_vars] + args
         | 
| 254 255 | 
             
                    end
         | 
| 255 256 |  | 
| 256 257 | 
             
                    warn(<<-eowarn) if $VERBOSE
         | 
| @@ -392,6 +393,9 @@ Support for this will be removed in version 2.0.0. | |
| 392 393 |  | 
| 393 394 | 
             
                    def finalize
         | 
| 394 395 | 
             
                      super(@ctx)
         | 
| 396 | 
            +
                      result = @ctx.result
         | 
| 397 | 
            +
                      @ctx = FunctionProxy.new
         | 
| 398 | 
            +
                      result
         | 
| 395 399 | 
             
                    end
         | 
| 396 400 | 
             
                  })
         | 
| 397 401 | 
             
                  proxy.ctx = FunctionProxy.new
         | 
| @@ -428,6 +432,7 @@ Support for this will be removed in version 2.0.0. | |
| 428 432 | 
             
                #
         | 
| 429 433 | 
             
                #   class LengthsAggregateHandler
         | 
| 430 434 | 
             
                #     def self.arity; 1; end
         | 
| 435 | 
            +
                #     def self.name; 'lengths'; end
         | 
| 431 436 | 
             
                #
         | 
| 432 437 | 
             
                #     def initialize
         | 
| 433 438 | 
             
                #       @total = 0
         | 
| @@ -446,21 +451,28 @@ Support for this will be removed in version 2.0.0. | |
| 446 451 | 
             
                #   puts db.get_first_value( "select lengths(name) from A" )
         | 
| 447 452 | 
             
                def create_aggregate_handler( handler )
         | 
| 448 453 | 
             
                  proxy = Class.new do
         | 
| 449 | 
            -
                    def initialize  | 
| 450 | 
            -
                      @ | 
| 451 | 
            -
                      @fp | 
| 454 | 
            +
                    def initialize klass
         | 
| 455 | 
            +
                      @klass = klass
         | 
| 456 | 
            +
                      @fp    = FunctionProxy.new
         | 
| 452 457 | 
             
                    end
         | 
| 453 458 |  | 
| 454 459 | 
             
                    def step( *args )
         | 
| 455 | 
            -
                       | 
| 460 | 
            +
                      instance.step(@fp, *args)
         | 
| 456 461 | 
             
                    end
         | 
| 457 462 |  | 
| 458 463 | 
             
                    def finalize
         | 
| 459 | 
            -
                       | 
| 464 | 
            +
                      instance.finalize @fp
         | 
| 465 | 
            +
                      @instance = nil
         | 
| 460 466 | 
             
                      @fp.result
         | 
| 461 467 | 
             
                    end
         | 
| 468 | 
            +
             | 
| 469 | 
            +
                    private
         | 
| 470 | 
            +
             | 
| 471 | 
            +
                    def instance
         | 
| 472 | 
            +
                      @instance ||= @klass.new
         | 
| 473 | 
            +
                    end
         | 
| 462 474 | 
             
                  end
         | 
| 463 | 
            -
                  define_aggregator(handler.name, proxy.new(handler | 
| 475 | 
            +
                  define_aggregator(handler.name, proxy.new(handler))
         | 
| 464 476 | 
             
                  self
         | 
| 465 477 | 
             
                end
         | 
| 466 478 |  |