diff --git a/.rdoc_options b/.rdoc_options index 1f489341..0d2ded97 100644 --- a/.rdoc_options +++ b/.rdoc_options @@ -17,6 +17,7 @@ exclude: - "vendor" - "ports" - "tmp" +- "pkg" hyperlink_all: false line_numbers: false locale: diff --git a/ext/sqlite3/database.c b/ext/sqlite3/database.c index 621dc7aa..724c4c2f 100644 --- a/ext/sqlite3/database.c +++ b/ext/sqlite3/database.c @@ -771,14 +771,8 @@ collation(VALUE self, VALUE name, VALUE comparator) } #ifdef HAVE_SQLITE3_LOAD_EXTENSION -/* call-seq: db.load_extension(file) - * - * Loads an SQLite extension library from the named file. Extension - * loading must be enabled using db.enable_load_extension(true) prior - * to calling this API. - */ static VALUE -load_extension(VALUE self, VALUE file) +load_extension_internal(VALUE self, VALUE file) { sqlite3RubyPtr ctx; int status; @@ -997,7 +991,7 @@ init_sqlite3_database(void) rb_define_private_method(cSqlite3Database, "db_filename", db_filename, 1); #ifdef HAVE_SQLITE3_LOAD_EXTENSION - rb_define_method(cSqlite3Database, "load_extension", load_extension, 1); + rb_define_private_method(cSqlite3Database, "load_extension_internal", load_extension_internal, 1); #endif #ifdef HAVE_SQLITE3_ENABLE_LOAD_EXTENSION diff --git a/lib/sqlite3/database.rb b/lib/sqlite3/database.rb index 1cf9e62e..8c10df35 100644 --- a/lib/sqlite3/database.rb +++ b/lib/sqlite3/database.rb @@ -658,6 +658,37 @@ def busy_handler_timeout=(milliseconds) end end + # call-seq: + # load_extension(extension_specifier) -> Database + # + # Loads an SQLite extension library from the named file. Extension loading must be enabled using + # Database#enable_load_extension prior to using this method. + # + # See also: https://www.sqlite.org/loadext.html + # + # [Parameters] + # - extension_specifier (String | +_ExtensionSpecifier+) If a String, it is the filesystem path + # to the sqlite extension file. If an object that responds to #sqlite_extension_path, the + # return value of that method is used as the filesystem path to the sqlite extension file. + # + # +_ExtensionSpecifier+ describes the following interface: + # + # interface _ExtensionSpecifier + # def sqlite_extension_path: () → String + # end + # + # For example, the +sqlean+ ruby gem offers a set of classes that implement this interface, + # allowing a calling convention like: + # + # db.load_extension(SQLean::VSV) + # + def load_extension(extension_specifier) + if extension_specifier.respond_to?(:sqlite_extension_path) + extension_specifier = extension_specifier.sqlite_extension_path + end + load_extension_internal(extension_specifier) + end + # A helper class for dealing with custom functions (see #create_function, # #create_aggregate, and #create_aggregate_handler). It encapsulates the # opaque function object that represents the current invocation. It also diff --git a/lib/sqlite3/version.rb b/lib/sqlite3/version.rb index 5ffba7ed..ccecebfa 100644 --- a/lib/sqlite3/version.rb +++ b/lib/sqlite3/version.rb @@ -1,4 +1,4 @@ module SQLite3 # (String) the version of the sqlite3 gem, e.g. "2.1.1" - VERSION = "2.3.0" + VERSION = "2.4.0.dev" end diff --git a/test/test_database.rb b/test/test_database.rb index 27f0479a..58df7060 100644 --- a/test/test_database.rb +++ b/test/test_database.rb @@ -653,10 +653,31 @@ def test_strict_mode def test_load_extension_with_nonstring_argument db = SQLite3::Database.new(":memory:") skip("extensions are not enabled") unless db.respond_to?(:load_extension) + assert_raises(TypeError) { db.load_extension(1) } assert_raises(TypeError) { db.load_extension(Pathname.new("foo.so")) } end + def test_load_extension_with_an_extension_descriptor + extension_descriptor = Class.new do + def sqlite_extension_path + "path/to/extension" + end + end.new + + class << db + attr_reader :load_extension_internal_path + + def load_extension_internal(path) + @load_extension_internal_path = path + end + end + + db.load_extension(extension_descriptor) + + assert_equal("path/to/extension", db.load_extension_internal_path) + end + def test_load_extension_error db = SQLite3::Database.new(":memory:") assert_raises(SQLite3::Exception) { db.load_extension("path/to/foo.so") }