Hello community, here is the log from the commit of package rubygem-sqlite3 for openSUSE:Factory checked in at 2016-10-18 10:40:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-sqlite3 (Old) and /work/SRC/openSUSE:Factory/.rubygem-sqlite3.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-sqlite3" Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-sqlite3/rubygem-sqlite3.changes 2015-10-14 16:44:55.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.rubygem-sqlite3.new/rubygem-sqlite3.changes 2016-10-18 10:40:34.000000000 +0200 @@ -1,0 +2,11 @@ +Sun Oct 9 04:36:48 UTC 2016 - [email protected] + +- updated to version 1.3.12 + see installed CHANGELOG.rdoc + + === 1.3.12 + + * Bugfixes: + * OS X install will default to homebrew if available. Fixes #195 + +------------------------------------------------------------------- Old: ---- sqlite3-1.3.11.gem New: ---- sqlite3-1.3.12.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-sqlite3.spec ++++++ --- /var/tmp/diff_new_pack.DtPEeJ/_old 2016-10-18 10:40:35.000000000 +0200 +++ /var/tmp/diff_new_pack.DtPEeJ/_new 2016-10-18 10:40:35.000000000 +0200 @@ -1,7 +1,7 @@ # # spec file for package rubygem-sqlite3 # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -24,7 +24,7 @@ # Name: rubygem-sqlite3 -Version: 1.3.11 +Version: 1.3.12 Release: 0 %define mod_name sqlite3 %define mod_full_name %{mod_name}-%{version} ++++++ sqlite3-1.3.11.gem -> sqlite3-1.3.12.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/CHANGELOG.rdoc new/CHANGELOG.rdoc --- old/CHANGELOG.rdoc 2015-10-10 23:20:32.000000000 +0200 +++ new/CHANGELOG.rdoc 2016-10-09 03:02:02.000000000 +0200 @@ -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: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Gemfile new/Gemfile --- old/Gemfile 2015-10-10 23:20:32.000000000 +0200 +++ new/Gemfile 2016-10-09 03:02:02.000000000 +0200 @@ -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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/README.rdoc new/README.rdoc --- old/README.rdoc 2015-10-10 23:20:32.000000000 +0200 +++ new/README.rdoc 2016-10-09 03:02:02.000000000 +0200 @@ -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 @@ # 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 @@ 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", "[email protected]", "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 Files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ext/sqlite3/database.c new/ext/sqlite3/database.c --- old/ext/sqlite3/database.c 2015-10-10 23:20:32.000000000 +0200 +++ new/ext/sqlite3/database.c 2016-10-09 03:02:02.000000000 +0200 @@ -30,6 +30,8 @@ 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 @@ -45,6 +47,7 @@ VALUE opts; VALUE zvfs; #ifdef HAVE_SQLITE3_OPEN_V2 + VALUE flags; int mode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; #endif int status; @@ -77,6 +80,11 @@ } #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 @@ 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 @@ 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 @@ 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 @@ 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 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 @@ 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 @@ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ext/sqlite3/extconf.rb new/ext/sqlite3/extconf.rb --- old/ext/sqlite3/extconf.rb 2015-10-10 23:20:32.000000000 +0200 +++ new/ext/sqlite3/extconf.rb 2016-10-09 03:02:02.000000000 +0200 @@ -6,8 +6,28 @@ RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC'] + + +ldflags = cppflags = nil +if RbConfig::CONFIG["host_os"] =~ /darwin/ + begin + brew_info = `brew info sqlite3` + ldflags = brew_info[/LDFLAGS.*$/].split(/-L/).last + cppflags = brew_info[/CPPFLAGS.*$/].split(/-I/).last + pkg_conf = brew_info[/PKG_CONFIG_PATH.*$/].split(": ").last + + # 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 @@ "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 @@ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ext/sqlite3/sqlite3.c new/ext/sqlite3/sqlite3.c --- old/ext/sqlite3/sqlite3.c 2015-10-10 23:20:32.000000000 +0200 +++ new/ext/sqlite3/sqlite3.c 2016-10-09 03:02:02.000000000 +0200 @@ -65,6 +65,59 @@ 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 @@ sqlite3_initialize(); #endif + init_sqlite3_constants(); init_sqlite3_database(); init_sqlite3_statement(); #ifdef HAVE_SQLITE3_BACKUP_INIT @@ -92,6 +146,7 @@ #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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/sqlite3/database.rb new/lib/sqlite3/database.rb --- old/lib/sqlite3/database.rb 2015-10-10 23:20:32.000000000 +0200 +++ new/lib/sqlite3/database.rb 2016-10-09 03:02:02.000000000 +0200 @@ -98,6 +98,13 @@ 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 @@ # 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 @@ 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 @@ def finalize super(@ctx) + result = @ctx.result + @ctx = FunctionProxy.new + result end }) proxy.ctx = FunctionProxy.new diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/sqlite3/pragmas.rb new/lib/sqlite3/pragmas.rb --- old/lib/sqlite3/pragmas.rb 2015-10-10 23:20:32.000000000 +0200 +++ new/lib/sqlite3/pragmas.rb 2016-10-09 03:02:02.000000000 +0200 @@ -13,7 +13,6 @@ 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 @@ 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 @@ 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 @@ "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,6 +85,22 @@ # The enumeration of valid temp store modes. TEMP_STORE_MODES = [ [ 'default', 0 ], [ 'file', 1 ], [ 'memory', 2 ] ] + # 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' ] ] + # Does an integrity check on the database. If the check fails, a # SQLite3::Exception will be raised. Otherwise it # returns silently. @@ -101,28 +110,36 @@ end end + 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 +150,58 @@ 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 +218,6 @@ 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 +225,41 @@ 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 +270,238 @@ 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 +510,24 @@ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/sqlite3/version.rb new/lib/sqlite3/version.rb --- old/lib/sqlite3/version.rb 2015-10-10 23:20:32.000000000 +0200 +++ new/lib/sqlite3/version.rb 2016-10-09 03:02:02.000000000 +0200 @@ -1,12 +1,12 @@ module SQLite3 - VERSION = '1.3.11' + VERSION = '1.3.12' module VersionProxy MAJOR = 1 MINOR = 3 - TINY = 11 + TINY = 12 BUILD = nil STRING = [ MAJOR, MINOR, TINY, BUILD ].compact.join( "." ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/sqlite3.rb new/lib/sqlite3.rb --- old/lib/sqlite3.rb 2015-10-10 23:20:32.000000000 +0200 +++ new/lib/sqlite3.rb 2016-10-09 03:02:02.000000000 +0200 @@ -8,3 +8,8 @@ require 'sqlite3/database' require 'sqlite3/version' + +module SQLite3 + # Was sqlite3 compiled with thread safety on? + def self.threadsafe?; threadsafe > 0; end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2015-10-10 23:20:32.000000000 +0200 +++ new/metadata 2016-10-09 03:02:02.000000000 +0200 @@ -1,7 +1,7 @@ --- !ruby/object:Gem::Specification name: sqlite3 version: !ruby/object:Gem::Version - version: 1.3.11 + version: 1.3.12 platform: ruby authors: - Jamis Buck @@ -10,7 +10,7 @@ autorequire: bindir: bin cert_chain: [] -date: 2015-10-10 00:00:00.000000000 Z +date: 2016-10-09 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: minitest @@ -18,14 +18,14 @@ requirements: - - "~>" - !ruby/object:Gem::Version - version: '5.8' + version: '5.9' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version - version: '5.8' + version: '5.9' - !ruby/object:Gem::Dependency name: rdoc requirement: !ruby/object:Gem::Requirement @@ -60,14 +60,14 @@ requirements: - - "~>" - !ruby/object:Gem::Version - version: 0.4.3 + version: 0.5.2 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version - version: 0.4.3 + version: 0.5.2 - !ruby/object:Gem::Dependency name: mini_portile requirement: !ruby/object:Gem::Requirement @@ -102,14 +102,14 @@ requirements: - - "~>" - !ruby/object:Gem::Version - version: '3.14' + version: '3.15' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version - version: '3.14' + version: '3.15' description: |- This module allows Ruby programs to interface with the SQLite3 database engine (http://www.sqlite.org). You must have the @@ -208,7 +208,7 @@ version: 1.3.5 requirements: [] rubyforge_project: -rubygems_version: 2.4.8 +rubygems_version: 2.5.1 signing_key: specification_version: 4 summary: This module allows Ruby programs to interface with the SQLite3 database engine diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tasks/gem.rake new/tasks/gem.rake --- old/tasks/gem.rake 2015-10-10 23:20:32.000000000 +0200 +++ new/tasks/gem.rake 2016-10-09 03:02:02.000000000 +0200 @@ -25,7 +25,7 @@ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/test_database.rb new/test/test_database.rb --- old/test/test_database.rb 2015-10-10 23:20:32.000000000 +0200 +++ new/test/test_database.rb 2016-10-09 03:02:02.000000000 +0200 @@ -1,4 +1,5 @@ require 'helper' +require 'tempfile' module SQLite3 class TestDatabase < SQLite3::TestCase @@ -6,12 +7,43 @@ 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 tf.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 tf.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 tf.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 +141,18 @@ 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 +305,30 @@ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/test_database_readonly.rb new/test/test_database_readonly.rb --- old/test/test_database_readonly.rb 2015-10-10 23:20:32.000000000 +0200 +++ new/test/test_database_readonly.rb 2016-10-09 03:02:02.000000000 +0200 @@ -3,7 +3,7 @@ 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 @@ 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 @@ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/test_integration.rb new/test/test_integration.rb --- old/test/test_integration.rb 2015-10-10 23:20:32.000000000 +0200 +++ new/test/test_integration.rb 2016-10-09 03:02:02.000000000 +0200 @@ -499,6 +499,10 @@ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/test_sqlite3.rb new/test/test_sqlite3.rb --- old/test/test_sqlite3.rb 2015-10-10 23:20:32.000000000 +0200 +++ new/test/test_sqlite3.rb 2016-10-09 03:02:02.000000000 +0200 @@ -5,5 +5,17 @@ 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
