Skip to content

Commit

Permalink
Allow Data{base,set}#extension to not require files if the extension …
Browse files Browse the repository at this point in the history
…is already registered

This is how model plugins work, and it makes it easier for applications
to use custom extensions without messing with the load path.
  • Loading branch information
jeremyevans committed Nov 7, 2024
1 parent a966aac commit c6c9588
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
=== master

* Allow Data{base,set}#extension to not require files if the extension is already registered (jeremyevans) (#2246)

* Do not limit imports to 40 rows at a time if using pg_auto_parameterize extension with the no_auto_parameterize method (davekaro) (#2242)

=== 5.86.0 (2024-11-01)
Expand Down
8 changes: 6 additions & 2 deletions lib/sequel/database/misc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,13 @@ def cast_type_literal(type)
# extension does not have specific support for Database objects, an Error will be raised.
# Returns self.
def extension(*exts)
Sequel.extension(*exts)
exts.each do |ext|
if pr = Sequel.synchronize{EXTENSIONS[ext]}
unless pr = Sequel.synchronize{EXTENSIONS[ext]}
Sequel.extension(ext)
pr = Sequel.synchronize{EXTENSIONS[ext]}
end

if pr
if Sequel.synchronize{@loaded_extensions.include?(ext) ? false : (@loaded_extensions << ext)}
pr.call(self)
end
Expand Down
10 changes: 7 additions & 3 deletions lib/sequel/dataset/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ def exclude_having(*cond, &block)
# If no related extension file exists or the extension does not have
# specific support for Dataset objects, an error will be raised.
def extension(*exts)
Sequel.extension(*exts)
exts.each{|ext| Sequel.extension(ext) unless Sequel.synchronize{EXTENSIONS[ext]}}
mods = exts.map{|ext| Sequel.synchronize{EXTENSION_MODULES[ext]}}
if mods.all?
with_extend(*mods)
Expand Down Expand Up @@ -1359,9 +1359,13 @@ def simple_select_all?
unless TRUE_FREEZE
# Load the extensions into the receiver, without checking if the receiver is frozen.
def _extension!(exts)
Sequel.extension(*exts)
exts.each do |ext|
if pr = Sequel.synchronize{EXTENSIONS[ext]}
unless pr = Sequel.synchronize{EXTENSIONS[ext]}
Sequel.extension(ext)
pr = Sequel.synchronize{EXTENSIONS[ext]}
end

if pr
pr.call(self)
else
raise(Error, "Extension #{ext} does not have specific support handling individual datasets (try: Sequel.extension #{ext.inspect})")
Expand Down
17 changes: 17 additions & 0 deletions spec/core/database_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3043,6 +3043,21 @@ def min_max(type, db_type, opts={})
end
end

describe "Database extensions without files" do
before do
@db = Sequel.mock
@_extensions = Sequel::Database::EXTENSIONS.dup
end
after do
Sequel::Database::EXTENSIONS.replace(@_extensions)
end

it "should work if they are already registered" do
Sequel::Database.register_extension(:foo, Module.new{def a; 1; end})
@db.extension(:foo).a.must_equal 1
end
end

describe "Database extensions" do
before(:all) do
class << Sequel
Expand All @@ -3057,8 +3072,10 @@ class << Sequel
end
before do
@db = Sequel.mock
@_extensions = Sequel::Database::EXTENSIONS.dup
end
after do
Sequel::Database::EXTENSIONS.replace(@_extensions)
Sequel::Database.instance_variable_set(:@initialize_hook, proc{|db| })
end

Expand Down
12 changes: 12 additions & 0 deletions spec/core/dataset_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5454,6 +5454,18 @@ def complex_expression_sql_append(sql, op, args)
end
end

describe "Dataset extensions without files" do
after do
Sequel::Dataset::EXTENSIONS.delete(:foo)
Sequel::Dataset.const_get(:EXTENSION_MODULES).delete(:foo)
end

it "should work if they are already registered" do
Sequel::Dataset.register_extension(:foo, Module.new{def a; 1; end})
Sequel.mock.dataset.extension(:foo).a.must_equal 1
end
end

describe "Dataset extensions" do
before(:all) do
class << Sequel
Expand Down

0 comments on commit c6c9588

Please sign in to comment.