[DRE-commits] [ruby-sqlite3] 01/04: New upstream version 1.3.13

Lucas Nussbaum lucas at moszumanska.debian.org
Sun Jul 2 12:27:39 UTC 2017


This is an automated email from the git hooks/post-receive script.

lucas pushed a commit to branch master
in repository ruby-sqlite3.

commit bad9452059054d52c1add4875771eb4a2ad21f1b
Author: Lucas Nussbaum <lucas at debian.org>
Date:   Sun Jul 2 13:19:23 2017 +0200

    New upstream version 1.3.13
---
 CHANGELOG.rdoc                 |   7 +-
 Gemfile                        |   7 +-
 README.rdoc                    |  25 ++-
 ext/sqlite3/database.c         |  95 ++++++++--
 ext/sqlite3/extconf.rb         |  25 ++-
 ext/sqlite3/sqlite3.c          |  55 ++++++
 lib/sqlite3.rb                 |   5 +
 lib/sqlite3/database.rb        |  21 ++-
 lib/sqlite3/pragmas.rb         | 402 ++++++++++++++++++++++++++++++++++++-----
 lib/sqlite3/version.rb         |   4 +-
 metadata.yml                   | 216 ----------------------
 sqlite3.gemspec                |  55 ++++++
 tasks/gem.rake                 |   2 +-
 test/test_database.rb          |  65 ++++++-
 test/test_database_readonly.rb |  11 +-
 test/test_integration.rb       |   4 +
 test/test_sqlite3.rb           |  12 ++
 test/test_statement.rb         |   2 +-
 18 files changed, 706 insertions(+), 307 deletions(-)

diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc
index 9ec805e..c9d42d5 100644
--- a/CHANGELOG.rdoc
+++ b/CHANGELOG.rdoc
@@ -1,3 +1,8 @@
+=== 1.3.12
+
+* Bugfixes:
+  * OS X install will default to homebrew if available. Fixes #195
+
 === 1.3.11 / 2015-10-10
 
 * Enhancements:
@@ -10,7 +15,7 @@
 === 1.3.10 / 2014-10-30
 
 * Enhancements:
-  * Windows: build against SQLite 3.8.6. Closes #135 [Hubro]
+  * Windows: build against SQLite 3.8.7.1. Closes #134, #135 [Hubro]
 
 === 1.3.9 / 2014-02-25
 
diff --git a/Gemfile b/Gemfile
index 486848a..38607c4 100644
--- a/Gemfile
+++ b/Gemfile
@@ -5,12 +5,11 @@
 source "https://rubygems.org/"
 
 
-gem "minitest", "~>5.8", :group => [:development, :test]
-gem "rdoc", "~>4.0", :group => [:development, :test]
+gem "minitest", "~>5.9", :group => [:development, :test]
 gem "rake-compiler", "~>0.9.3", :group => [:development, :test]
-gem "rake-compiler-dock", "~>0.4.3", :group => [:development, :test]
+gem "rake-compiler-dock", "~>0.5.2", :group => [:development, :test]
 gem "mini_portile", "~>0.6.2", :group => [:development, :test]
 gem "hoe-bundler", "~>1.0", :group => [:development, :test]
-gem "hoe", "~>3.14", :group => [:development, :test]
+gem "hoe", "~>3.15", :group => [:development, :test]
 
 # vim: syntax=ruby
diff --git a/README.rdoc b/README.rdoc
index 12e78df..89500ef 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -5,6 +5,8 @@
 * http://rubygems.org/gems/sqlite3
 * http://www.rubydoc.info/gems/sqlite3/frames
 
+{<img src="https://travis-ci.org/sparklemotion/sqlite3-ruby.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/sparklemotion/sqlite3-ruby]
+
 == DESCRIPTION
 
 This module allows Ruby programs to interface with the SQLite3
@@ -20,7 +22,7 @@ Note that this module is only compatible with SQLite 3.6.16 or newer.
   # Open a database
   db = SQLite3::Database.new "test.db"
   
-  # Create a database
+  # Create a table
   rows = db.execute <<-SQL
     create table numbers (
       name varchar(30),
@@ -36,12 +38,27 @@ Note that this module is only compatible with SQLite 3.6.16 or newer.
     db.execute "insert into numbers values ( ?, ? )", pair
   end
 
+  # Find a few rows
+  db.execute( "select * from numbers" ) do |row|
+    p row
+  end
+
+  # Create another table with multiple columns
+
+  db.execute <<-SQL
+    create table students (
+      name varchar(50),
+      email varchar(50),
+      grade varchar(5),
+      blog varchar(50)
+    );
+  SQL
+
   # Execute inserts with parameter markers
   db.execute("INSERT INTO students (name, email, grade, blog) 
-              VALUES (?, ?, ?, ?)", [@name, @email, @grade, @blog])
+              VALUES (?, ?, ?, ?)", ["Jane", "me at janedoe.com", "A", "http://blog.janedoe.com"])
   
-  # Find a few rows
-  db.execute( "select * from numbers" ) do |row|
+  db.execute( "select * from students" ) do |row|
     p row
   end
 
diff --git a/ext/sqlite3/database.c b/ext/sqlite3/database.c
index 35b8f97..21c8bc3 100644
--- a/ext/sqlite3/database.c
+++ b/ext/sqlite3/database.c
@@ -30,6 +30,8 @@ utf16_string_value_ptr(VALUE str)
   return RSTRING_PTR(str);
 }
 
+static VALUE sqlite3_rb_close(VALUE self);
+
 /* call-seq: SQLite3::Database.new(file, options = {})
  *
  * Create a new Database object that opens the given file. If utf16
@@ -44,6 +46,7 @@ static VALUE initialize(int argc, VALUE *argv, VALUE self)
   VALUE file;
   VALUE opts;
   VALUE zvfs;
+  VALUE flags;
 #ifdef HAVE_SQLITE3_OPEN_V2
   int mode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
 #endif
@@ -77,6 +80,11 @@ static VALUE initialize(int argc, VALUE *argv, VALUE self)
       }
 #endif
 
+      /* The three primary flag values for sqlite3_open_v2 are:
+       * SQLITE_OPEN_READONLY
+       * SQLITE_OPEN_READWRITE
+       * SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE -- always used for sqlite3_open and sqlite3_open16
+       */
       if (Qtrue == rb_hash_aref(opts, ID2SYM(rb_intern("readonly")))) {
 #ifdef HAVE_SQLITE3_OPEN_V2
         mode = SQLITE_OPEN_READONLY;
@@ -84,6 +92,27 @@ static VALUE initialize(int argc, VALUE *argv, VALUE self)
         rb_raise(rb_eNotImpError, "sqlite3-ruby was compiled against a version of sqlite that does not support readonly databases");
 #endif
       }
+      if (Qtrue == rb_hash_aref(opts, ID2SYM(rb_intern("readwrite")))) {
+#ifdef HAVE_SQLITE3_OPEN_V2
+        if (mode == SQLITE_OPEN_READONLY) {
+            rb_raise(rb_eRuntimeError, "conflicting options: readonly and readwrite");
+        }
+        mode = SQLITE_OPEN_READWRITE;
+#else
+        rb_raise(rb_eNotImpError, "sqlite3-ruby was compiled against a version of sqlite that does not support readwrite without create");
+#endif
+      }
+      flags = rb_hash_aref(opts, ID2SYM(rb_intern("flags")));
+      if (flags != Qnil) {
+#ifdef HAVE_SQLITE3_OPEN_V2
+        if ((mode & SQLITE_OPEN_CREATE) == 0) {
+            rb_raise(rb_eRuntimeError, "conflicting options: flags with readonly and/or readwrite");
+        }
+        mode = (int)NUM2INT(flags);
+#else
+        rb_raise(rb_eNotImpError, "sqlite3-ruby was compiled against a version of sqlite that does not support flags on open");
+#endif
+      }
 #ifdef HAVE_SQLITE3_OPEN_V2
       status = sqlite3_open_v2(
           StringValuePtr(file),
@@ -114,14 +143,13 @@ static VALUE initialize(int argc, VALUE *argv, VALUE self)
   rb_iv_set(self, "@results_as_hash", rb_hash_aref(opts, sym_results_as_hash));
   rb_iv_set(self, "@type_translation", rb_hash_aref(opts, sym_type_translation));
 #ifdef HAVE_SQLITE3_OPEN_V2
-  rb_iv_set(self, "@readonly", mode == SQLITE_OPEN_READONLY ? Qtrue : Qfalse);
+  rb_iv_set(self, "@readonly", (mode & SQLITE_OPEN_READONLY) ? Qtrue : Qfalse);
 #else
   rb_iv_set(self, "@readonly", Qfalse);
 #endif
 
   if(rb_block_given_p()) {
-    rb_yield(self);
-    rb_funcall(self, rb_intern("close"), 0);
+    rb_ensure(rb_yield, self, sqlite3_rb_close, self);
   }
 
   return self;
@@ -288,7 +316,14 @@ static VALUE sqlite3val2rb(sqlite3_value * val)
          which is what we want, as blobs are binary
        */
       int len = sqlite3_value_bytes(val);
+#ifdef HAVE_RUBY_ENCODING_H
       return rb_tainted_str_new((const char *)sqlite3_value_blob(val), len);
+#else
+      /* When encoding is not available, make it class SQLite3::Blob. */
+      VALUE strargv[1];
+      strargv[0] = rb_tainted_str_new((const char *)sqlite3_value_blob(val), len);
+      return rb_class_new_instance(1, strargv, cSqlite3Blob);
+#endif
       break;
     }
     case SQLITE_NULL:
@@ -322,12 +357,25 @@ static void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result)
       sqlite3_result_double(ctx, NUM2DBL(result));
       break;
     case T_STRING:
-      sqlite3_result_text(
-          ctx,
-          (const char *)StringValuePtr(result),
-          (int)RSTRING_LEN(result),
-          SQLITE_TRANSIENT
-      );
+      if(CLASS_OF(result) == cSqlite3Blob
+#ifdef HAVE_RUBY_ENCODING_H
+              || rb_enc_get_index(result) == rb_ascii8bit_encindex()
+#endif
+        ) {
+        sqlite3_result_blob(
+            ctx,
+            (const void *)StringValuePtr(result),
+            (int)RSTRING_LEN(result),
+            SQLITE_TRANSIENT
+        );
+      } else {
+        sqlite3_result_text(
+            ctx,
+            (const char *)StringValuePtr(result),
+            (int)RSTRING_LEN(result),
+            SQLITE_TRANSIENT
+        );
+      }
       break;
     default:
       rb_raise(rb_eRuntimeError, "can't return %s",
@@ -338,22 +386,18 @@ static void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result)
 static void rb_sqlite3_func(sqlite3_context * ctx, int argc, sqlite3_value **argv)
 {
   VALUE callable = (VALUE)sqlite3_user_data(ctx);
-  VALUE * params = NULL;
+  VALUE params = rb_ary_new2(argc);
   VALUE result;
   int i;
 
   if (argc > 0) {
-    params = xcalloc((size_t)argc, sizeof(VALUE *));
-
     for(i = 0; i < argc; i++) {
       VALUE param = sqlite3val2rb(argv[i]);
-      RB_GC_GUARD(param);
-      params[i] = param;
+      rb_ary_push(params, param);
     }
   }
 
-  result = rb_funcall2(callable, rb_intern("call"), argc, params);
-  xfree(params);
+  result = rb_apply(callable, rb_intern("call"), params);
 
   set_sqlite3_func_result(ctx, result);
 }
@@ -778,6 +822,24 @@ static VALUE transaction_active_p(VALUE self)
   return sqlite3_get_autocommit(ctx->db) ? Qfalse : Qtrue;
 }
 
+/* call-seq: db.db_filename(database_name)
+ *
+ * Returns the file associated with +database_name+.  Can return nil or an
+ * empty string if the database is temporary, or in-memory.
+ */
+static VALUE db_filename(VALUE self, VALUE db_name)
+{
+  sqlite3RubyPtr ctx;
+  const char * fname;
+  Data_Get_Struct(self, sqlite3Ruby, ctx);
+  REQUIRE_OPEN_DB(ctx);
+
+  fname = sqlite3_db_filename(ctx->db, StringValueCStr(db_name));
+
+  if(fname) return SQLITE3_UTF8_STR_NEW2(fname);
+  return Qnil;
+}
+
 void init_sqlite3_database()
 {
   ID id_utf16, id_results_as_hash, id_type_translation;
@@ -805,6 +867,7 @@ void init_sqlite3_database()
   rb_define_method(cSqlite3Database, "busy_handler", busy_handler, -1);
   rb_define_method(cSqlite3Database, "busy_timeout=", set_busy_timeout, 1);
   rb_define_method(cSqlite3Database, "transaction_active?", transaction_active_p, 0);
+  rb_define_private_method(cSqlite3Database, "db_filename", db_filename, 1);
 
 #ifdef HAVE_SQLITE3_LOAD_EXTENSION
   rb_define_method(cSqlite3Database, "load_extension", load_extension, 1);
diff --git a/ext/sqlite3/extconf.rb b/ext/sqlite3/extconf.rb
index 22abb89..9302f3f 100644
--- a/ext/sqlite3/extconf.rb
+++ b/ext/sqlite3/extconf.rb
@@ -6,8 +6,28 @@ require 'mkmf'
 
 RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
 
+
+
+ldflags = cppflags = nil
+if RbConfig::CONFIG["host_os"] =~ /darwin/
+  begin
+    brew_prefix = `brew --prefix sqlite3`.chomp
+    ldflags   = "#{brew_prefix}/lib"
+    cppflags  = "#{brew_prefix}/include"
+    pkg_conf  = "#{brew_prefix}/lib/pkgconfig"
+
+    # pkg_config should be less error prone than parsing compiler
+    # commandline options, but we need to set default ldflags and cpp flags
+    # in case the user doesn't have pkg-config installed
+    ENV['PKG_CONFIG_PATH'] ||= pkg_conf
+  rescue
+  end
+end
+
+pkg_config("sqlite3")
+
 # --with-sqlite3-{dir,include,lib}
-dir_config("sqlite3")
+dir_config("sqlite3", cppflags, ldflags)
 
 if RbConfig::CONFIG["host_os"] =~ /mswin/
   $CFLAGS << ' -W3'
@@ -19,7 +39,7 @@ def asplode missing
           "http://www.sqlite.org/ first."
   else
     abort <<-error
-#{missing} is missing. Try 'port install sqlite3 +universal',
+#{missing} is missing. Try 'brew install sqlite3',
 'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
 and check your shared library search path (the
 location where your sqlite3 shared library is located).
@@ -28,6 +48,7 @@ location where your sqlite3 shared library is located).
 end
 
 asplode('sqlite3.h')  unless find_header  'sqlite3.h'
+find_library 'pthread', 'pthread_create' # 1.8 support. *shrug*
 asplode('sqlite3') unless find_library 'sqlite3', 'sqlite3_libversion_number'
 
 # Functions defined in 1.9 but not 1.8
diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c
index 6faeaa2..dedfdf5 100644
--- a/ext/sqlite3/sqlite3.c
+++ b/ext/sqlite3/sqlite3.c
@@ -65,6 +65,59 @@ static VALUE libversion(VALUE UNUSED(klass))
   return INT2NUM(sqlite3_libversion_number());
 }
 
+/* Returns the compile time setting of the SQLITE_THREADSAFE flag.
+ * See: https://www.sqlite.org/c3ref/threadsafe.html
+ */
+static VALUE threadsafe_p(VALUE UNUSED(klass))
+{
+  return INT2NUM(sqlite3_threadsafe());
+}
+
+void init_sqlite3_constants()
+{
+  VALUE mSqlite3Constants;
+  VALUE mSqlite3Open;
+
+  mSqlite3Constants = rb_define_module_under(mSqlite3, "Constants");
+
+  /* sqlite3_open_v2 flags for Database::new */
+  mSqlite3Open = rb_define_module_under(mSqlite3Constants, "Open");
+
+  /* symbols = IO.readlines('sqlite3.h').map { |n| /\A#define\s+(SQLITE_OPEN_\w+)\s/ =~ n && $1 }.compact
+   * pad = symbols.map(&:length).max - 9
+   * symbols.each { |s| printf %Q{  rb_define_const(mSqlite3Open, %-#{pad}s INT2FIX(#{s}));\n}, '"' + s[12..-1] + '",' }
+   */
+  rb_define_const(mSqlite3Open, "READONLY",       INT2FIX(SQLITE_OPEN_READONLY));
+  rb_define_const(mSqlite3Open, "READWRITE",      INT2FIX(SQLITE_OPEN_READWRITE));
+  rb_define_const(mSqlite3Open, "CREATE",         INT2FIX(SQLITE_OPEN_CREATE));
+  rb_define_const(mSqlite3Open, "DELETEONCLOSE",  INT2FIX(SQLITE_OPEN_DELETEONCLOSE));
+  rb_define_const(mSqlite3Open, "EXCLUSIVE",      INT2FIX(SQLITE_OPEN_EXCLUSIVE));
+  rb_define_const(mSqlite3Open, "MAIN_DB",        INT2FIX(SQLITE_OPEN_MAIN_DB));
+  rb_define_const(mSqlite3Open, "TEMP_DB",        INT2FIX(SQLITE_OPEN_TEMP_DB));
+  rb_define_const(mSqlite3Open, "TRANSIENT_DB",   INT2FIX(SQLITE_OPEN_TRANSIENT_DB));
+  rb_define_const(mSqlite3Open, "MAIN_JOURNAL",   INT2FIX(SQLITE_OPEN_MAIN_JOURNAL));
+  rb_define_const(mSqlite3Open, "TEMP_JOURNAL",   INT2FIX(SQLITE_OPEN_TEMP_JOURNAL));
+  rb_define_const(mSqlite3Open, "SUBJOURNAL",     INT2FIX(SQLITE_OPEN_SUBJOURNAL));
+  rb_define_const(mSqlite3Open, "MASTER_JOURNAL", INT2FIX(SQLITE_OPEN_MASTER_JOURNAL));
+  rb_define_const(mSqlite3Open, "NOMUTEX",        INT2FIX(SQLITE_OPEN_NOMUTEX));
+  rb_define_const(mSqlite3Open, "FULLMUTEX",      INT2FIX(SQLITE_OPEN_FULLMUTEX));
+#ifdef SQLITE_OPEN_AUTOPROXY
+  /* SQLITE_VERSION_NUMBER>=3007002 */
+  rb_define_const(mSqlite3Open, "AUTOPROXY",      INT2FIX(SQLITE_OPEN_AUTOPROXY));
+  rb_define_const(mSqlite3Open, "SHAREDCACHE",    INT2FIX(SQLITE_OPEN_SHAREDCACHE));
+  rb_define_const(mSqlite3Open, "PRIVATECACHE",   INT2FIX(SQLITE_OPEN_PRIVATECACHE));
+  rb_define_const(mSqlite3Open, "WAL",            INT2FIX(SQLITE_OPEN_WAL));
+#endif
+#ifdef SQLITE_OPEN_URI
+  /* SQLITE_VERSION_NUMBER>=3007007 */
+  rb_define_const(mSqlite3Open, "URI",            INT2FIX(SQLITE_OPEN_URI));
+#endif
+#ifdef SQLITE_OPEN_MEMORY
+  /* SQLITE_VERSION_NUMBER>=3007013 */
+  rb_define_const(mSqlite3Open, "MEMORY",         INT2FIX(SQLITE_OPEN_MEMORY));
+#endif
+}
+
 void Init_sqlite3_native()
 {
   /*
@@ -85,6 +138,7 @@ void Init_sqlite3_native()
   sqlite3_initialize();
 #endif
 
+  init_sqlite3_constants();
   init_sqlite3_database();
   init_sqlite3_statement();
 #ifdef HAVE_SQLITE3_BACKUP_INIT
@@ -92,6 +146,7 @@ void Init_sqlite3_native()
 #endif
 
   rb_define_singleton_method(mSqlite3, "libversion", libversion, 0);
+  rb_define_singleton_method(mSqlite3, "threadsafe", threadsafe_p, 0);
   rb_define_const(mSqlite3, "SQLITE_VERSION", rb_str_new2(SQLITE_VERSION));
   rb_define_const(mSqlite3, "SQLITE_VERSION_NUMBER", INT2FIX(SQLITE_VERSION_NUMBER));
 }
diff --git a/lib/sqlite3.rb b/lib/sqlite3.rb
index 256b908..f6110e1 100644
--- a/lib/sqlite3.rb
+++ b/lib/sqlite3.rb
@@ -8,3 +8,8 @@ end
 
 require 'sqlite3/database'
 require 'sqlite3/version'
+
+module SQLite3
+  # Was sqlite3 compiled with thread safety on?
+  def self.threadsafe?; threadsafe > 0; end
+end
diff --git a/lib/sqlite3/database.rb b/lib/sqlite3/database.rb
index 0151988..c4f470b 100644
--- a/lib/sqlite3/database.rb
+++ b/lib/sqlite3/database.rb
@@ -98,6 +98,13 @@ in version 2.0.0.
       end
     end
 
+    # Returns the filename for the database named +db_name+.  +db_name+ defaults
+    # to "main".  Main return `nil` or an empty string if the database is
+    # temporary or in-memory.
+    def filename db_name = 'main'
+      db_filename db_name
+    end
+
     # Executes the given SQL statement. If additional parameters are given,
     # they are treated as bind variables, and are bound to the placeholders in
     # the query.
@@ -113,10 +120,6 @@ in version 2.0.0.
     # See also #execute2, #query, and #execute_batch for additional ways of
     # executing statements.
     def execute sql, bind_vars = [], *args, &block
-      # FIXME: This is a terrible hack and should be removed but is required
-      # for older versions of rails
-      hack = Object.const_defined?(:ActiveRecord) && sql =~ /^PRAGMA index_list/
-
       if bind_vars.nil? || !args.empty?
         if args.empty?
           bind_vars = []
@@ -147,12 +150,7 @@ Support for bind parameters as *args will be removed in 2.0.0.
         else
           if @results_as_hash
             stmt.map { |row|
-              h = type_translation ? row : ordered_map_for(columns, row)
-
-              # FIXME UGH TERRIBLE HACK!
-              h['unique'] = h['unique'].to_s if hack
-
-              h
+              type_translation ? row : ordered_map_for(columns, row)
             }
           else
             stmt.to_a
@@ -395,6 +393,9 @@ Support for this will be removed in version 2.0.0.
 
         def finalize
           super(@ctx)
+          result = @ctx.result
+          @ctx = FunctionProxy.new
+          result
         end
       })
       proxy.ctx = FunctionProxy.new
diff --git a/lib/sqlite3/pragmas.rb b/lib/sqlite3/pragmas.rb
index ce8fde5..a08e021 100644
--- a/lib/sqlite3/pragmas.rb
+++ b/lib/sqlite3/pragmas.rb
@@ -13,7 +13,6 @@ module SQLite3
     def get_boolean_pragma( name )
       get_first_value( "PRAGMA #{name}" ) != "0"
     end
-    private :get_boolean_pragma
 
     # Sets the given pragma to the given boolean value. The value itself
     # may be +true+ or +false+, or any other commonly used string or
@@ -39,7 +38,6 @@ module SQLite3
 
       execute( "PRAGMA #{name}=#{mode}" )
     end
-    private :set_boolean_pragma
 
     # Requests the given pragma (and parameters), and if the block is given,
     # each row of the result set will be yielded to it. Otherwise, the results
@@ -52,13 +50,11 @@ module SQLite3
         execute( "PRAGMA #{name}( #{args} )", &block )
       end
     end
-    private :get_query_pragma
 
     # Return the value of the given pragma.
     def get_enum_pragma( name )
       get_first_value( "PRAGMA #{name}" )
     end
-    private :get_enum_pragma
 
     # Set the value of the given pragma to +mode+. The +mode+ parameter must
     # conform to one of the values in the given +enum+ array. Each entry in
@@ -71,20 +67,17 @@ module SQLite3
         "unrecognized #{name} #{mode.inspect}" unless match
       execute( "PRAGMA #{name}='#{match.first.upcase}'" )
     end
-    private :set_enum_pragma
 
     # Returns the value of the given pragma as an integer.
     def get_int_pragma( name )
       get_first_value( "PRAGMA #{name}" ).to_i
     end
-    private :get_int_pragma
 
     # Set the value of the given pragma to the integer value of the +value+
     # parameter.
     def set_int_pragma( name, value )
       execute( "PRAGMA #{name}=#{value.to_i}" )
     end
-    private :set_int_pragma
 
     # The enumeration of valid synchronous modes.
     SYNCHRONOUS_MODES = [ [ 'full', 2 ], [ 'normal', 1 ], [ 'off', 0 ] ]
@@ -92,37 +85,52 @@ module SQLite3
     # The enumeration of valid temp store modes.
     TEMP_STORE_MODES  = [ [ 'default', 0 ], [ 'file', 1 ], [ 'memory', 2 ] ]
 
-    # Does an integrity check on the database. If the check fails, a
-    # SQLite3::Exception will be raised. Otherwise it
-    # returns silently.
-    def integrity_check
-      execute( "PRAGMA integrity_check" ) do |row|
-        raise Exception, row[0] if row[0] != "ok"
-      end
+    # The enumeration of valid auto vacuum modes.
+    AUTO_VACUUM_MODES  = [ [ 'none', 0 ], [ 'full', 1 ], [ 'incremental', 2 ] ]
+
+    # The list of valid journaling modes.
+    JOURNAL_MODES  = [ [ 'delete' ], [ 'truncate' ], [ 'persist' ], [ 'memory' ],
+                       [ 'wal' ], [ 'off' ] ]
+
+    # The list of valid locking modes.
+    LOCKING_MODES  = [ [ 'normal' ], [ 'exclusive' ] ]
+
+    # The list of valid encodings.
+    ENCODINGS = [ [ 'utf-8' ], [ 'utf-16' ], [ 'utf-16le' ], [ 'utf-16be ' ] ]
+
+    # The list of valid WAL checkpoints.
+    WAL_CHECKPOINTS = [ [ 'passive' ], [ 'full' ], [ 'restart' ], [ 'truncate' ] ]
+
+    def application_id
+      get_int_pragma "application_id"
+    end
+
+    def application_id=( integer )
+      set_int_pragma "application_id", integer
     end
 
     def auto_vacuum
-      get_boolean_pragma "auto_vacuum"
+      get_enum_pragma "auto_vacuum"
     end
 
     def auto_vacuum=( mode )
-      set_boolean_pragma "auto_vacuum", mode
+      set_enum_pragma "auto_vacuum", mode, AUTO_VACUUM_MODES
     end
 
-    def schema_cookie
-      get_int_pragma "schema_cookie"
+    def automatic_index
+      get_boolean_pragma "automatic_index"
     end
 
-    def schema_cookie=( cookie )
-      set_int_pragma "schema_cookie", cookie
+    def automatic_index=( mode )
+      set_boolean_pragma "automatic_index", mode
     end
 
-    def user_cookie
-      get_int_pragma "user_cookie"
+    def busy_timeout
+      get_int_pragma "busy_timeout"
     end
 
-    def user_cookie=( cookie )
-      set_int_pragma "user_cookie", cookie
+    def busy_timeout=( milliseconds )
+      set_int_pragma "busy_timeout", milliseconds
     end
 
     def cache_size
@@ -133,6 +141,58 @@ module SQLite3
       set_int_pragma "cache_size", size
     end
 
+    def cache_spill
+      get_boolean_pragma "cache_spill"
+    end
+
+    def cache_spill=( mode )
+      set_boolean_pragma "cache_spill", mode
+    end
+
+    def case_sensitive_like=( mode )
+      set_boolean_pragma "case_sensitive_like", mode
+    end
+
+    def cell_size_check
+      get_boolean_pragma "cell_size_check"
+    end
+
+    def cell_size_check=( mode )
+      set_boolean_pragma "cell_size_check", mode
+    end
+
+    def checkpoint_fullfsync
+      get_boolean_pragma "checkpoint_fullfsync"
+    end
+
+    def checkpoint_fullfsync=( mode )
+      set_boolean_pragma "checkpoint_fullfsync", mode
+    end
+
+    def collation_list( &block ) # :yields: row
+      get_query_pragma "collation_list", &block
+    end
+
+    def compile_options( &block ) # :yields: row
+      get_query_pragma "compile_options", &block
+    end
+
+    def count_changes
+      get_boolean_pragma "count_changes"
+    end
+
+    def count_changes=( mode )
+      set_boolean_pragma "count_changes", mode
+    end
+
+    def data_version
+      get_int_pragma "data_version"
+    end
+
+    def database_list( &block ) # :yields: row
+      get_query_pragma "database_list", &block
+    end
+
     def default_cache_size
       get_int_pragma "default_cache_size"
     end
@@ -149,14 +209,6 @@ module SQLite3
       set_enum_pragma "default_synchronous", mode, SYNCHRONOUS_MODES
     end
 
-    def synchronous
-      get_enum_pragma "synchronous"
-    end
-
-    def synchronous=( mode )
-      set_enum_pragma "synchronous", mode, SYNCHRONOUS_MODES
-    end
-
     def default_temp_store
       get_enum_pragma "default_temp_store"
     end
@@ -164,13 +216,41 @@ module SQLite3
     def default_temp_store=( mode )
       set_enum_pragma "default_temp_store", mode, TEMP_STORE_MODES
     end
-  
-    def temp_store
-      get_enum_pragma "temp_store"
+
+    def defer_foreign_keys
+      get_boolean_pragma "defer_foreign_keys"
     end
 
-    def temp_store=( mode )
-      set_enum_pragma "temp_store", mode, TEMP_STORE_MODES
+    def defer_foreign_keys=( mode )
+      set_boolean_pragma "defer_foreign_keys", mode
+    end
+
+    def encoding
+      get_enum_pragma "encoding"
+    end
+
+    def encoding=( mode )
+      set_enum_pragma "encoding", mode, ENCODINGS
+    end
+
+    def foreign_key_check( *table, &block ) # :yields: row
+      get_query_pragma "foreign_key_check", *table, &block
+    end
+
+    def foreign_key_list( table, &block ) # :yields: row
+      get_query_pragma "foreign_key_list", table, &block
+    end
+
+    def foreign_keys
+      get_boolean_pragma "foreign_keys"
+    end
+
+    def foreign_keys=( mode )
+      set_boolean_pragma "foreign_keys", mode
+    end
+
+    def freelist_count
+      get_int_pragma "freelist_count"
     end
 
     def full_column_names
@@ -181,14 +261,238 @@ module SQLite3
       set_boolean_pragma "full_column_names", mode
     end
   
-    def parser_trace
-      get_boolean_pragma "parser_trace"
+    def fullfsync
+      get_boolean_pragma "fullfsync"
+    end
+
+    def fullfsync=( mode )
+      set_boolean_pragma "fullfsync", mode
+    end
+
+    def ignore_check_constraints=( mode )
+      set_boolean_pragma "ignore_check_constraints", mode
+    end
+
+    def incremental_vacuum( pages, &block ) # :yields: row
+      get_query_pragma "incremental_vacuum", pages, &block
+    end
+
+    def index_info( index, &block ) # :yields: row
+      get_query_pragma "index_info", index, &block
+    end
+
+    def index_list( table, &block ) # :yields: row
+      get_query_pragma "index_list", table, &block
+    end
+
+    def index_xinfo( index, &block ) # :yields: row
+      get_query_pragma "index_xinfo", index, &block
+    end
+
+    def integrity_check( *num_errors, &block ) # :yields: row
+      get_query_pragma "integrity_check", *num_errors, &block
+    end
+
+    def journal_mode
+      get_enum_pragma "journal_mode"
+    end
+
+    def journal_mode=( mode )
+      set_enum_pragma "journal_mode", mode, JOURNAL_MODES
+    end
+
+    def journal_size_limit
+      get_int_pragma "journal_size_limit"
+    end
+
+    def journal_size_limit=( size )
+      set_int_pragma "journal_size_limit", size
+    end
+
+    def legacy_file_format
+      get_boolean_pragma "legacy_file_format"
+    end
+
+    def legacy_file_format=( mode )
+      set_boolean_pragma "legacy_file_format", mode
+    end
+
+    def locking_mode
+      get_enum_pragma "locking_mode"
+    end
+
+    def locking_mode=( mode )
+      set_enum_pragma "locking_mode", mode, LOCKING_MODES
+    end
+
+    def max_page_count
+      get_int_pragma "max_page_count"
+    end
+
+    def max_page_count=( size )
+      set_int_pragma "max_page_count", size
+    end
+
+    def mmap_size
+      get_int_pragma "mmap_size"
+    end
+
+    def mmap_size=( size )
+      set_int_pragma "mmap_size", size
+    end
+
+    def page_count
+      get_int_pragma "page_count"
+    end
+
+    def page_size
+      get_int_pragma "page_size"
+    end
+
+    def page_size=( size )
+      set_int_pragma "page_size", size
     end
 
     def parser_trace=( mode )
       set_boolean_pragma "parser_trace", mode
     end
   
+    def query_only
+      get_boolean_pragma "query_only"
+    end
+
+    def query_only=( mode )
+      set_boolean_pragma "query_only", mode
+    end
+
+    def quick_check( *num_errors, &block ) # :yields: row
+      get_query_pragma "quick_check", *num_errors, &block
+    end
+
+    def read_uncommitted
+      get_boolean_pragma "read_uncommitted"
+    end
+
+    def read_uncommitted=( mode )
+      set_boolean_pragma "read_uncommitted", mode
+    end
+
+    def recursive_triggers
+      get_boolean_pragma "recursive_triggers"
+    end
+
+    def recursive_triggers=( mode )
+      set_boolean_pragma "recursive_triggers", mode
+    end
+
+    def reverse_unordered_selects
+      get_boolean_pragma "reverse_unordered_selects"
+    end
+
+    def reverse_unordered_selects=( mode )
+      set_boolean_pragma "reverse_unordered_selects", mode
+    end
+
+    def schema_cookie
+      get_int_pragma "schema_cookie"
+    end
+
+    def schema_cookie=( cookie )
+      set_int_pragma "schema_cookie", cookie
+    end
+
+    def schema_version
+      get_int_pragma "schema_version"
+    end
+
+    def schema_version=( version )
+      set_int_pragma "schema_version", version
+    end
+
+    def secure_delete
+      get_boolean_pragma "secure_delete"
+    end
+
+    def secure_delete=( mode )
+      set_boolean_pragma "secure_delete", mode
+    end
+
+    def short_column_names
+      get_boolean_pragma "short_column_names"
+    end
+
+    def short_column_names=( mode )
+      set_boolean_pragma "short_column_names", mode
+    end
+
+    def shrink_memory
+      execute( "PRAGMA shrink_memory" )
+    end
+
+    def soft_heap_limit
+      get_int_pragma "soft_heap_limit"
+    end
+
+    def soft_heap_limit=( mode )
+      set_int_pragma "soft_heap_limit", mode
+    end
+
+    def stats( &block ) # :yields: row
+      get_query_pragma "stats", &block
+    end
+
+    def synchronous
+      get_enum_pragma "synchronous"
+    end
+
+    def synchronous=( mode )
+      set_enum_pragma "synchronous", mode, SYNCHRONOUS_MODES
+    end
+
+    def temp_store
+      get_enum_pragma "temp_store"
+    end
+
+    def temp_store=( mode )
+      set_enum_pragma "temp_store", mode, TEMP_STORE_MODES
+    end
+
+    def threads
+      get_int_pragma "threads"
+    end
+
+    def threads=( count )
+      set_int_pragma "threads", count
+    end
+
+    def user_cookie
+      get_int_pragma "user_cookie"
+    end
+
+    def user_cookie=( cookie )
+      set_int_pragma "user_cookie", cookie
+    end
+
+    def user_version
+      get_int_pragma "user_version"
+    end
+
+    def user_version=( version )
+      set_int_pragma "user_version", version
+    end
+
+    def vdbe_addoptrace=( mode )
+      set_boolean_pragma "vdbe_addoptrace", mode
+    end
+
+    def vdbe_debug=( mode )
+      set_boolean_pragma "vdbe_debug", mode
+    end
+
+    def vdbe_listing=( mode )
+      set_boolean_pragma "vdbe_listing", mode
+    end
+
     def vdbe_trace
       get_boolean_pragma "vdbe_trace"
     end
@@ -197,20 +501,24 @@ module SQLite3
       set_boolean_pragma "vdbe_trace", mode
     end
 
-    def database_list( &block ) # :yields: row
-      get_query_pragma "database_list", &block
+    def wal_autocheckpoint
+      get_int_pragma "wal_autocheckpoint"
     end
 
-    def foreign_key_list( table, &block ) # :yields: row
-      get_query_pragma "foreign_key_list", table, &block
+    def wal_autocheckpoint=( mode )
+      set_int_pragma "wal_autocheckpoint", mode
     end
 
-    def index_info( index, &block ) # :yields: row
-      get_query_pragma "index_info", index, &block
+    def wal_checkpoint
+      get_enum_pragma "wal_checkpoint"
     end
 
-    def index_list( table, &block ) # :yields: row
-      get_query_pragma "index_list", table, &block
+    def wal_checkpoint=( mode )
+      set_enum_pragma "wal_checkpoint", mode, WAL_CHECKPOINTS
+    end
+
+    def writable_schema=( mode )
+      set_boolean_pragma "writable_schema", mode
     end
 
     ###
diff --git a/lib/sqlite3/version.rb b/lib/sqlite3/version.rb
index 1c193d4..021aab0 100644
--- a/lib/sqlite3/version.rb
+++ b/lib/sqlite3/version.rb
@@ -1,12 +1,12 @@
 module SQLite3
 
-  VERSION = '1.3.11'
+  VERSION = '1.3.13'
 
   module VersionProxy
 
     MAJOR = 1
     MINOR = 3
-    TINY  = 11
+    TINY  = 13
     BUILD = nil
 
     STRING = [ MAJOR, MINOR, TINY, BUILD ].compact.join( "." )
diff --git a/metadata.yml b/metadata.yml
deleted file mode 100644
index a06ccd6..0000000
--- a/metadata.yml
+++ /dev/null
@@ -1,216 +0,0 @@
---- !ruby/object:Gem::Specification
-name: sqlite3
-version: !ruby/object:Gem::Version
-  version: 1.3.11
-platform: ruby
-authors:
-- Jamis Buck
-- Luis Lavena
-- Aaron Patterson
-autorequire: 
-bindir: bin
-cert_chain: []
-date: 2015-10-10 00:00:00.000000000 Z
-dependencies:
-- !ruby/object:Gem::Dependency
-  name: minitest
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '5.8'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '5.8'
-- !ruby/object:Gem::Dependency
-  name: rdoc
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '4.0'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '4.0'
-- !ruby/object:Gem::Dependency
-  name: rake-compiler
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: 0.9.3
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: 0.9.3
-- !ruby/object:Gem::Dependency
-  name: rake-compiler-dock
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: 0.4.3
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: 0.4.3
-- !ruby/object:Gem::Dependency
-  name: mini_portile
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: 0.6.2
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: 0.6.2
-- !ruby/object:Gem::Dependency
-  name: hoe-bundler
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.0'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.0'
-- !ruby/object:Gem::Dependency
-  name: hoe
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '3.14'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '3.14'
-description: |-
-  This module allows Ruby programs to interface with the SQLite3
-  database engine (http://www.sqlite.org).  You must have the
-  SQLite engine installed in order to build this module.
-
-  Note that this module is only compatible with SQLite 3.6.16 or newer.
-email:
-- jamis at 37signals.com
-- luislavena at gmail.com
-- aaron at tenderlovemaking.com
-executables: []
-extensions:
-- ext/sqlite3/extconf.rb
-extra_rdoc_files:
-- API_CHANGES.rdoc
-- CHANGELOG.rdoc
-- Manifest.txt
-- README.rdoc
-- ext/sqlite3/backup.c
-- ext/sqlite3/database.c
-- ext/sqlite3/exception.c
-- ext/sqlite3/sqlite3.c
-- ext/sqlite3/statement.c
-files:
-- API_CHANGES.rdoc
-- CHANGELOG.rdoc
-- ChangeLog.cvs
-- Gemfile
-- LICENSE
-- Manifest.txt
-- README.rdoc
-- Rakefile
-- ext/sqlite3/backup.c
-- ext/sqlite3/backup.h
-- ext/sqlite3/database.c
-- ext/sqlite3/database.h
-- ext/sqlite3/exception.c
-- ext/sqlite3/exception.h
-- ext/sqlite3/extconf.rb
-- ext/sqlite3/sqlite3.c
-- ext/sqlite3/sqlite3_ruby.h
-- ext/sqlite3/statement.c
-- ext/sqlite3/statement.h
-- faq/faq.rb
-- faq/faq.yml
-- lib/sqlite3.rb
-- lib/sqlite3/constants.rb
-- lib/sqlite3/database.rb
-- lib/sqlite3/errors.rb
-- lib/sqlite3/pragmas.rb
-- lib/sqlite3/resultset.rb
-- lib/sqlite3/statement.rb
-- lib/sqlite3/translator.rb
-- lib/sqlite3/value.rb
-- lib/sqlite3/version.rb
-- setup.rb
-- tasks/faq.rake
-- tasks/gem.rake
-- tasks/native.rake
-- tasks/vendor_sqlite3.rake
-- test/helper.rb
-- test/test_backup.rb
-- test/test_collation.rb
-- test/test_database.rb
-- test/test_database_readonly.rb
-- test/test_deprecated.rb
-- test/test_encoding.rb
-- test/test_integration.rb
-- test/test_integration_open_close.rb
-- test/test_integration_pending.rb
-- test/test_integration_resultset.rb
-- test/test_integration_statement.rb
-- test/test_result_set.rb
-- test/test_sqlite3.rb
-- test/test_statement.rb
-- test/test_statement_execute.rb
-homepage: https://github.com/sparklemotion/sqlite3-ruby
-licenses:
-- BSD-3
-metadata: {}
-post_install_message: 
-rdoc_options:
-- "--main"
-- README.rdoc
-require_paths:
-- lib
-required_ruby_version: !ruby/object:Gem::Requirement
-  requirements:
-  - - ">="
-    - !ruby/object:Gem::Version
-      version: 1.8.7
-required_rubygems_version: !ruby/object:Gem::Requirement
-  requirements:
-  - - ">="
-    - !ruby/object:Gem::Version
-      version: 1.3.5
-requirements: []
-rubyforge_project: 
-rubygems_version: 2.4.8
-signing_key: 
-specification_version: 4
-summary: This module allows Ruby programs to interface with the SQLite3 database engine
-  (http://www.sqlite.org)
-test_files: []
diff --git a/sqlite3.gemspec b/sqlite3.gemspec
new file mode 100644
index 0000000..277936b
--- /dev/null
+++ b/sqlite3.gemspec
@@ -0,0 +1,55 @@
+#########################################################
+# This file has been automatically generated by gem2tgz #
+#########################################################
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+  s.name = "sqlite3"
+  s.version = "1.3.13"
+
+  s.required_rubygems_version = Gem::Requirement.new(">= 1.3.5") if s.respond_to? :required_rubygems_version=
+  s.authors = ["Jamis Buck", "Luis Lavena", "Aaron Patterson"]
+  s.date = "2017-01-04"
+  s.description = "This module allows Ruby programs to interface with the SQLite3\ndatabase engine (http://www.sqlite.org).  You must have the\nSQLite engine installed in order to build this module.\n\nNote that this module is only compatible with SQLite 3.6.16 or newer."
+  s.email = ["jamis at 37signals.com", "luislavena at gmail.com", "aaron at tenderlovemaking.com"]
+  s.extensions = ["ext/sqlite3/extconf.rb"]
+  s.extra_rdoc_files = ["API_CHANGES.rdoc", "CHANGELOG.rdoc", "Manifest.txt", "README.rdoc", "ext/sqlite3/backup.c", "ext/sqlite3/database.c", "ext/sqlite3/exception.c", "ext/sqlite3/sqlite3.c", "ext/sqlite3/statement.c"]
+  s.files = ["API_CHANGES.rdoc", "CHANGELOG.rdoc", "ChangeLog.cvs", "Gemfile", "LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "ext/sqlite3/backup.c", "ext/sqlite3/backup.h", "ext/sqlite3/database.c", "ext/sqlite3/database.h", "ext/sqlite3/exception.c", "ext/sqlite3/exception.h", "ext/sqlite3/extconf.rb", "ext/sqlite3/sqlite3.c", "ext/sqlite3/sqlite3_ruby.h", "ext/sqlite3/statement.c", "ext/sqlite3/statement.h", "faq/faq.rb", "faq/faq.yml", "lib/sqlite3.rb", "lib/sqlite3/constants. [...]
+  s.homepage = "https://github.com/sparklemotion/sqlite3-ruby"
+  s.licenses = ["BSD-3"]
+  s.rdoc_options = ["--main", "README.rdoc"]
+  s.require_paths = ["lib"]
+  s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
+  s.rubygems_version = "1.8.23"
+  s.summary = "This module allows Ruby programs to interface with the SQLite3 database engine (http://www.sqlite.org)"
+
+  if s.respond_to? :specification_version then
+    s.specification_version = 4
+
+    if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+      s.add_development_dependency(%q<hoe>, ["~> 3.15"])
+      s.add_development_dependency(%q<hoe-bundler>, ["~> 1.0"])
+      s.add_development_dependency(%q<mini_portile>, ["~> 0.6.2"])
+      s.add_development_dependency(%q<minitest>, ["~> 5.9"])
+      s.add_development_dependency(%q<rake-compiler>, ["~> 0.9.3"])
+      s.add_development_dependency(%q<rake-compiler-dock>, ["~> 0.5.2"])
+      s.add_development_dependency(%q<rdoc>, ["~> 4.0"])
+    else
+      s.add_dependency(%q<hoe>, ["~> 3.15"])
+      s.add_dependency(%q<hoe-bundler>, ["~> 1.0"])
+      s.add_dependency(%q<mini_portile>, ["~> 0.6.2"])
+      s.add_dependency(%q<minitest>, ["~> 5.9"])
+      s.add_dependency(%q<rake-compiler>, ["~> 0.9.3"])
+      s.add_dependency(%q<rake-compiler-dock>, ["~> 0.5.2"])
+      s.add_dependency(%q<rdoc>, ["~> 4.0"])
+    end
+  else
+    s.add_dependency(%q<hoe>, ["~> 3.15"])
+    s.add_dependency(%q<hoe-bundler>, ["~> 1.0"])
+    s.add_dependency(%q<mini_portile>, ["~> 0.6.2"])
+    s.add_dependency(%q<minitest>, ["~> 5.9"])
+    s.add_dependency(%q<rake-compiler>, ["~> 0.9.3"])
+    s.add_dependency(%q<rake-compiler-dock>, ["~> 0.5.2"])
+    s.add_dependency(%q<rdoc>, ["~> 4.0"])
+  end
+end
diff --git a/tasks/gem.rake b/tasks/gem.rake
index 2d10de2..914eb17 100644
--- a/tasks/gem.rake
+++ b/tasks/gem.rake
@@ -25,7 +25,7 @@ HOE = Hoe.spec 'sqlite3' do
   spec_extras[:extensions] = ["ext/sqlite3/extconf.rb"]
 
   extra_dev_deps << ['rake-compiler', "~> 0.9.3"]
-  extra_dev_deps << ['rake-compiler-dock', "~> 0.4.3"]
+  extra_dev_deps << ['rake-compiler-dock', "~> 0.5.2"]
   extra_dev_deps << ["mini_portile", "~> 0.6.2"]
   extra_dev_deps << ["minitest", "~> 5.0"]
   extra_dev_deps << ["hoe-bundler", "~> 1.0"]
diff --git a/test/test_database.rb b/test/test_database.rb
index e37c15f..cb396ea 100644
--- a/test/test_database.rb
+++ b/test/test_database.rb
@@ -1,4 +1,6 @@
 require 'helper'
+require 'tempfile'
+require 'pathname'
 
 module SQLite3
   class TestDatabase < SQLite3::TestCase
@@ -6,12 +8,43 @@ module SQLite3
 
     def setup
       @db = SQLite3::Database.new(':memory:')
+      super
     end
 
     def test_segv
       assert_raises(TypeError) { SQLite3::Database.new 1 }
     end
 
+    def test_db_filename
+      tf = nil
+      assert_equal '', @db.filename('main')
+      tf = Tempfile.new 'thing'
+      @db = SQLite3::Database.new tf.path
+      assert_equal File.expand_path(tf.path), File.expand_path(@db.filename('main'))
+    ensure
+      tf.unlink if tf
+    end
+
+    def test_filename
+      tf = nil
+      assert_equal '', @db.filename
+      tf = Tempfile.new 'thing'
+      @db = SQLite3::Database.new tf.path
+      assert_equal File.expand_path(tf.path), File.expand_path(@db.filename)
+    ensure
+      tf.unlink if tf
+    end
+
+    def test_filename_with_attachment
+      tf = nil
+      assert_equal '', @db.filename
+      tf = Tempfile.new 'thing'
+      @db.execute "ATTACH DATABASE '#{tf.path}' AS 'testing'"
+      assert_equal File.expand_path(tf.path), File.expand_path(@db.filename('testing'))
+    ensure
+      tf.unlink if tf
+    end
+
     def test_bignum
       num = 4907021672125087844
       db.execute 'CREATE TABLE "employees" ("token" integer(8), "name" varchar(20) NOT NULL)'
@@ -109,6 +142,18 @@ module SQLite3
       assert thing.closed?
     end
 
+    def test_block_closes_self_even_raised
+      thing = nil
+      begin
+        SQLite3::Database.new(':memory:') do |db|
+          thing = db
+          raise
+        end
+      rescue
+      end
+      assert thing.closed?
+    end
+
     def test_prepare
       db = SQLite3::Database.new(':memory:')
       stmt = db.prepare('select "hello world"')
@@ -261,12 +306,30 @@ module SQLite3
     end
 
     def test_function_return_types
-      [10, 2.2, nil, "foo"].each do |thing|
+      [10, 2.2, nil, "foo", Blob.new("foo\0bar")].each do |thing|
         @db.define_function("hello") { |a| thing }
         assert_equal [thing], @db.execute("select hello('world')").first
       end
     end
 
+    def test_function_gc_segfault
+      @db.create_function("bug", -1) { |func, *values| func.result = values.join }
+      # With a lot of data and a lot of threads, try to induce a GC segfault.
+      params = Array.new(127, "?" * 28000)
+      proc = Proc.new {
+        db.execute("select bug(#{Array.new(params.length, "?").join(",")})", params)
+      }
+      m = Mutex.new
+      30.times.map { Thread.new { m.synchronize { proc.call } } }.each(&:join)
+    end
+
+    def test_function_return_type_round_trip
+      [10, 2.2, nil, "foo", Blob.new("foo\0bar")].each do |thing|
+        @db.define_function("hello") { |a| a }
+        assert_equal [thing], @db.execute("select hello(hello(?))", [thing]).first
+      end
+    end
+
     def test_define_function_closed
       @db.close
       assert_raise(SQLite3::Exception) do
diff --git a/test/test_database_readonly.rb b/test/test_database_readonly.rb
index bb35726..def34b2 100644
--- a/test/test_database_readonly.rb
+++ b/test/test_database_readonly.rb
@@ -3,7 +3,7 @@ require 'helper'
 module SQLite3
   class TestDatabaseReadonly < SQLite3::TestCase
     def setup
-      File.unlink 'test-readonly.db' if File.exists?('test-readonly.db')
+      File.unlink 'test-readonly.db' if File.exist?('test-readonly.db')
       @db = SQLite3::Database.new('test-readonly.db')
       @db.execute("CREATE TABLE foos (id integer)")
       @db.close
@@ -11,7 +11,7 @@ module SQLite3
 
     def teardown
       @db.close unless @db.closed?
-      File.unlink 'test-readonly.db'
+      File.unlink 'test-readonly.db' if File.exist?('test-readonly.db')
     end
 
     def test_open_readonly_database
@@ -19,6 +19,13 @@ module SQLite3
       assert @db.readonly?
     end
 
+    def test_open_readonly_not_exists_database
+      File.unlink 'test-readonly.db'
+      assert_raise(SQLite3::CantOpenException) do
+        @db = SQLite3::Database.new('test-readonly.db', :readonly => true)
+      end
+    end
+
     def test_insert_readonly_database
       @db = SQLite3::Database.new('test-readonly.db', :readonly => true)
       assert_raise(SQLite3::ReadOnlyException) do
diff --git a/test/test_integration.rb b/test/test_integration.rb
index 5f707af..9bd3c3a 100644
--- a/test/test_integration.rb
+++ b/test/test_integration.rb
@@ -499,6 +499,10 @@ class TC_Database_Integration < SQLite3::TestCase
 
     value = @db.get_first_value( "select accumulate(a) from foo" )
     assert_equal 6, value
+
+    # calling #get_first_value twice don't add up to the latest result
+    value = @db.get_first_value( "select accumulate(a) from foo" )
+    assert_equal 6, value
   end
 
   def test_create_aggregate_with_block
diff --git a/test/test_sqlite3.rb b/test/test_sqlite3.rb
index f397696..f5c7972 100644
--- a/test/test_sqlite3.rb
+++ b/test/test_sqlite3.rb
@@ -5,5 +5,17 @@ module SQLite3
     def test_libversion
       assert_not_nil SQLite3.libversion
     end
+
+    def test_threadsafe
+      assert_not_nil SQLite3.threadsafe
+    end
+
+    def test_threadsafe?
+      if SQLite3.threadsafe > 0
+        assert SQLite3.threadsafe?
+      else
+        refute SQLite3.threadsafe?
+      end
+    end
   end
 end
diff --git a/test/test_statement.rb b/test/test_statement.rb
index 31b4c6b..e92612b 100644
--- a/test/test_statement.rb
+++ b/test/test_statement.rb
@@ -34,7 +34,7 @@ module SQLite3
       #   UNIQUE constraint failed: *table_name*.*column_name*
       # Older versions of SQLite return:
       #   column *column_name* is not unique
-      assert_match /(column(s)? .* (is|are) not unique|UNIQUE constraint failed: .*)/, exception.message
+      assert_match(/(column(s)? .* (is|are) not unique|UNIQUE constraint failed: .*)/, exception.message)
     end
 
     ###

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-sqlite3.git



More information about the Pkg-ruby-extras-commits mailing list