sequel 5.87.0 → 5.90.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/sequel/adapters/ibmdb.rb +1 -0
- data/lib/sequel/adapters/mysql2.rb +8 -1
- data/lib/sequel/adapters/shared/access.rb +1 -0
- data/lib/sequel/adapters/shared/mssql.rb +1 -0
- data/lib/sequel/adapters/shared/oracle.rb +1 -0
- data/lib/sequel/adapters/shared/postgres.rb +34 -4
- data/lib/sequel/core.rb +15 -0
- data/lib/sequel/database/dataset_defaults.rb +3 -3
- data/lib/sequel/database/misc.rb +5 -1
- data/lib/sequel/database/schema_generator.rb +8 -0
- data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +1 -1
- data/lib/sequel/dataset/prepared_statements.rb +2 -1
- data/lib/sequel/dataset/query.rb +2 -2
- data/lib/sequel/dataset/sql.rb +6 -1
- data/lib/sequel/extensions/connection_validator.rb +15 -10
- data/lib/sequel/extensions/migration.rb +19 -3
- data/lib/sequel/extensions/null_dataset.rb +2 -2
- data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +9 -4
- data/lib/sequel/extensions/pg_enum.rb +3 -3
- data/lib/sequel/extensions/pg_row.rb +3 -1
- data/lib/sequel/extensions/query_blocker.rb +172 -0
- data/lib/sequel/extensions/string_agg.rb +2 -2
- data/lib/sequel/extensions/virtual_row_method_block.rb +1 -0
- data/lib/sequel/model/associations.rb +19 -2
- data/lib/sequel/model/base.rb +29 -12
- data/lib/sequel/plugins/composition.rb +1 -1
- data/lib/sequel/plugins/enum.rb +1 -1
- data/lib/sequel/plugins/inverted_subsets.rb +1 -0
- data/lib/sequel/plugins/lazy_attributes.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +1 -1
- data/lib/sequel/plugins/pg_eager_any_typed_array.rb +95 -0
- data/lib/sequel/plugins/rcte_tree.rb +1 -1
- data/lib/sequel/plugins/serialization.rb +11 -5
- data/lib/sequel/plugins/sql_comments.rb +7 -2
- data/lib/sequel/plugins/static_cache_cache.rb +50 -13
- data/lib/sequel/plugins/subset_conditions.rb +1 -0
- data/lib/sequel/plugins/subset_static_cache.rb +263 -0
- data/lib/sequel/sql.rb +8 -1
- data/lib/sequel/version.rb +1 -1
- metadata +6 -6
@@ -693,6 +693,9 @@ module Sequel
|
|
693
693
|
|
694
694
|
# The predicate condition to use for the eager_loader.
|
695
695
|
def eager_loading_predicate_condition(keys)
|
696
|
+
if transform = self[:eager_loading_predicate_transform]
|
697
|
+
keys = transform.call(keys, self)
|
698
|
+
end
|
696
699
|
{predicate_key=>keys}
|
697
700
|
end
|
698
701
|
|
@@ -759,7 +762,15 @@ module Sequel
|
|
759
762
|
def placeholder_eager_loader
|
760
763
|
cached_fetch(:placeholder_eager_loader) do
|
761
764
|
eager_loading_dataset.placeholder_literalizer_loader do |pl, ds|
|
762
|
-
|
765
|
+
arg = pl.arg
|
766
|
+
|
767
|
+
if transform = self[:eager_loading_predicate_transform]
|
768
|
+
arg = arg.transform do |v|
|
769
|
+
transform.call(v, self)
|
770
|
+
end
|
771
|
+
end
|
772
|
+
|
773
|
+
apply_eager_limit_strategy(ds.where(predicate_key=>arg), eager_limit_strategy)
|
763
774
|
end
|
764
775
|
end
|
765
776
|
end
|
@@ -1707,6 +1718,9 @@ module Sequel
|
|
1707
1718
|
# record should be populated.
|
1708
1719
|
# :eager_loader_key :: A symbol for the key column to use to populate the key_hash
|
1709
1720
|
# for the eager loader. Can be set to nil to not populate the key_hash.
|
1721
|
+
# :eager_loading_predicate_transform :: A callable object with which to transform the predicate key values used
|
1722
|
+
# when eager loading. Called with two arguments, the array of predicate key
|
1723
|
+
# values, and a the reflection for the association being eager loaded.
|
1710
1724
|
# :extend :: A module or array of modules to extend the dataset with.
|
1711
1725
|
# :filter_limit_strategy :: Determines the strategy used for enforcing limits and offsets when filtering by
|
1712
1726
|
# limited associations. Possible options are :window_function, :distinct_on, or
|
@@ -1769,6 +1783,9 @@ module Sequel
|
|
1769
1783
|
# Set to nil to not define a setter method for the association.
|
1770
1784
|
# :subqueries_per_union :: The number of subqueries to use in each UNION query, for eager
|
1771
1785
|
# loading limited associations using the default :union strategy.
|
1786
|
+
# :use_placeholder_loader :: Whether to use a placeholder loader when eager loading the
|
1787
|
+
# association. Can be set to false to disable the use of a placeholder
|
1788
|
+
# loader if one would be used by default.
|
1772
1789
|
# :validate :: Set to false to not validate when implicitly saving any associated object.
|
1773
1790
|
# === :many_to_one
|
1774
1791
|
# :key :: foreign key in current model's table that references
|
@@ -1891,7 +1908,7 @@ module Sequel
|
|
1891
1908
|
raise(Error, "cannot clone an association to an association of different type (association #{name} with type #{type} cloning #{opts[:clone]} with type #{cloned_assoc[:type]})")
|
1892
1909
|
end
|
1893
1910
|
|
1894
|
-
opts[:use_placeholder_loader] = !opts[:instance_specific] && !opts[:eager_graph]
|
1911
|
+
opts[:use_placeholder_loader] = !opts[:instance_specific] && !opts[:eager_graph] unless opts.include?(:use_placeholder_loader)
|
1895
1912
|
opts[:eager_block] = opts[:block] unless opts.include?(:eager_block)
|
1896
1913
|
opts[:graph_join_type] ||= :left_outer
|
1897
1914
|
opts[:order_eager_graph] = true unless opts.include?(:order_eager_graph)
|
data/lib/sequel/model/base.rb
CHANGED
@@ -184,7 +184,7 @@ module Sequel
|
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
187
|
-
klass = Class.new(self)
|
187
|
+
klass = Sequel.set_temp_name(Class.new(self)){"Sequel::_Model(#{source.inspect})"}
|
188
188
|
|
189
189
|
if source.is_a?(::Sequel::Database)
|
190
190
|
klass.db = source
|
@@ -762,22 +762,36 @@ module Sequel
|
|
762
762
|
end
|
763
763
|
end
|
764
764
|
end
|
765
|
+
|
766
|
+
# Module that the class methods that call dataset methods are kept in.
|
767
|
+
# This allows the methods to be overridden and call super with the
|
768
|
+
# default behavior.
|
769
|
+
def dataset_methods_module
|
770
|
+
return @dataset_methods_module if defined?(@dataset_methods_module)
|
771
|
+
mod_name = "#{name}::@dataset_methods_module"
|
772
|
+
Sequel.synchronize{@dataset_methods_module ||= Sequel.set_temp_name(Module.new){mod_name}}
|
773
|
+
extend(@dataset_methods_module)
|
774
|
+
@dataset_methods_module
|
775
|
+
end
|
765
776
|
|
766
|
-
# Define a model method that calls the dataset method with the same name
|
767
|
-
# only used for methods with names that can't be represented directly in
|
768
|
-
# ruby code.
|
777
|
+
# Define a model method that calls the dataset method with the same name.
|
769
778
|
def def_model_dataset_method(meth)
|
770
779
|
return if respond_to?(meth, true)
|
771
780
|
|
781
|
+
mod = dataset_methods_module
|
782
|
+
|
772
783
|
if meth.to_s =~ /\A[A-Za-z_][A-Za-z0-9_]*\z/
|
773
|
-
|
784
|
+
mod.module_eval(<<END, __FILE__, __LINE__ + 1)
|
785
|
+
def #{meth}(*args, &block); dataset.#{meth}(*args, &block) end
|
786
|
+
ruby2_keywords :#{meth} if respond_to?(:ruby2_keywords, true)
|
787
|
+
END
|
774
788
|
else
|
775
|
-
|
789
|
+
mod.send(:define_method, meth){|*args, &block| dataset.public_send(meth, *args, &block)}
|
790
|
+
# :nocov:
|
791
|
+
mod.send(:ruby2_keywords, meth) if respond_to?(:ruby2_keywords, true)
|
792
|
+
# :nocov:
|
776
793
|
end
|
777
|
-
|
778
|
-
# :nocov:
|
779
|
-
singleton_class.send(:ruby2_keywords, meth) if respond_to?(:ruby2_keywords, true)
|
780
|
-
# :nocov:
|
794
|
+
mod.send(:alias_method, meth, meth)
|
781
795
|
end
|
782
796
|
|
783
797
|
# Get the schema from the database, fall back on checking the columns
|
@@ -943,7 +957,10 @@ module Sequel
|
|
943
957
|
# Module that the class includes that holds methods the class adds for column accessors and
|
944
958
|
# associations so that the methods can be overridden with +super+.
|
945
959
|
def overridable_methods_module
|
946
|
-
|
960
|
+
return @overridable_methods_module if defined?(@overridable_methods_module)
|
961
|
+
mod_name = "#{name}::@overridable_methods_module"
|
962
|
+
Sequel.synchronize{@overridable_methods_module ||= Sequel.set_temp_name(Module.new){mod_name}}
|
963
|
+
include(@overridable_methods_module)
|
947
964
|
@overridable_methods_module
|
948
965
|
end
|
949
966
|
|
@@ -1597,7 +1614,7 @@ module Sequel
|
|
1597
1614
|
@skip_validation_on_next_save = true
|
1598
1615
|
end
|
1599
1616
|
|
1600
|
-
# Returns
|
1617
|
+
# Returns naked dataset that should return only the row related to this instance.
|
1601
1618
|
#
|
1602
1619
|
# Artist[1].this
|
1603
1620
|
# # SELECT * FROM artists WHERE (id = 1) LIMIT 1
|
data/lib/sequel/plugins/enum.rb
CHANGED
@@ -32,6 +32,7 @@ module Sequel
|
|
32
32
|
def self.apply(model, &block)
|
33
33
|
model.instance_exec do
|
34
34
|
@dataset_module_class = Class.new(@dataset_module_class) do
|
35
|
+
Sequel.set_temp_name(self){"#{model.name}::@dataset_module_class(InvertedSubsets)"}
|
35
36
|
include DatasetModuleMethods
|
36
37
|
if block
|
37
38
|
define_method(:inverted_subset_name, &block)
|
@@ -64,7 +64,7 @@ module Sequel
|
|
64
64
|
# :dataset :: The base dataset to use for the lazy attribute lookup
|
65
65
|
# :table :: The table name to use to qualify the attribute and primary key columns.
|
66
66
|
def define_lazy_attribute_getter(a, opts=OPTS)
|
67
|
-
include(@lazy_attributes_module ||= Module.new) unless @lazy_attributes_module
|
67
|
+
include(@lazy_attributes_module ||= Sequel.set_temp_name(Module.new){"#{name}::@lazy_attributes_module"}) unless @lazy_attributes_module
|
68
68
|
@lazy_attributes_module.class_eval do
|
69
69
|
define_method(a) do
|
70
70
|
if !values.has_key?(a) && !new?
|
@@ -129,7 +129,7 @@ module Sequel
|
|
129
129
|
#
|
130
130
|
# If a block is provided, it is used to set the :reject_if option.
|
131
131
|
def nested_attributes(*associations, &block)
|
132
|
-
include(@nested_attributes_module ||= Module.new) unless @nested_attributes_module
|
132
|
+
include(@nested_attributes_module ||= Sequel.set_temp_name(Module.new){"#{name}::@nested_attributes_module"}) unless @nested_attributes_module
|
133
133
|
opts = associations.last.is_a?(Hash) ? associations.pop : OPTS
|
134
134
|
reflections = associations.map{|a| association_reflection(a) || raise(Error, "no association named #{a} for #{self}")}
|
135
135
|
reflections.each do |r|
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Sequel
|
4
|
+
module Plugins
|
5
|
+
# The pg_eager_any_typed_array plugin automatically converts
|
6
|
+
# the predicate expressions used for eager loading from:
|
7
|
+
#
|
8
|
+
# table.column IN (value_list)
|
9
|
+
#
|
10
|
+
# to:
|
11
|
+
#
|
12
|
+
# table.column = ANY(array_expr::type[])
|
13
|
+
#
|
14
|
+
# This makes it easier to use the pg_auto_parameterize_in_array
|
15
|
+
# extension with the :treat_string_list_as_text_array option,
|
16
|
+
# when using foreign keys with non-text database types that are represented
|
17
|
+
# by Ruby strings, such as enum and uuid types.
|
18
|
+
#
|
19
|
+
# Most association types that ship with Sequel have their predicate
|
20
|
+
# expressions converted by this plugin. Here are the exceptions:
|
21
|
+
#
|
22
|
+
# * associations using composite predicate keys
|
23
|
+
# * many_to_pg_array associations
|
24
|
+
# * many_to_many/one_through_one associations using :join_table_db option
|
25
|
+
# * many_through_many/one_through_many associations using
|
26
|
+
# :separate_table_per_query option
|
27
|
+
#
|
28
|
+
# To avoid predicate conversion for particular associations, set the
|
29
|
+
# :eager_loading_predicate_transform association option to nil/false.
|
30
|
+
#
|
31
|
+
# This plugin loads the pg_array extension into the model's Database.
|
32
|
+
module PgEagerAnyTypedArray
|
33
|
+
# Add the pg_array extension to the database
|
34
|
+
def self.apply(model)
|
35
|
+
model.db.extension(:pg_array)
|
36
|
+
end
|
37
|
+
|
38
|
+
module ClassMethods
|
39
|
+
TRANSFORM = proc do |values, ref|
|
40
|
+
type = ref.send(:cached_fetch, :_pg_eager_any_typed_array_type) do
|
41
|
+
key = ref.predicate_key
|
42
|
+
next if key.is_a?(Array)
|
43
|
+
|
44
|
+
while key.is_a?(SQL::QualifiedIdentifier)
|
45
|
+
key = key.column
|
46
|
+
end
|
47
|
+
|
48
|
+
# :nocov:
|
49
|
+
# many_to_pg_array association type does not need changes, as it
|
50
|
+
# already converts the values to a typed postgres array, it does
|
51
|
+
# not call the code that uses :eager_loading_predicate_transform.
|
52
|
+
#
|
53
|
+
# No association type that ships with Sequel can reach this code
|
54
|
+
# unless it is one of these types, but external association types
|
55
|
+
# could potentially reach it.
|
56
|
+
sch = case ref[:type]
|
57
|
+
# :nocov:
|
58
|
+
when :many_to_one, :one_to_one, :one_to_many, :pg_array_to_many
|
59
|
+
ref.associated_class.db_schema
|
60
|
+
when :many_to_many, :one_through_one
|
61
|
+
# Not compatible with the :join_table_db option, but that option
|
62
|
+
# does not call into this code.
|
63
|
+
Hash[ref.associated_class.db.schema(ref.join_table_source)]
|
64
|
+
when :many_through_many, :one_through_many
|
65
|
+
# Not compatible with the :separate_query_per_table option, but
|
66
|
+
# that option does not call into this code.
|
67
|
+
Hash[ref.associated_class.db.schema(ref[:through][0][:table])]
|
68
|
+
end
|
69
|
+
|
70
|
+
if sch && (sch = sch[key])
|
71
|
+
sch[:db_type]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
if type
|
76
|
+
Sequel.function(:ANY, Sequel.pg_array(values, type))
|
77
|
+
else
|
78
|
+
values
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Set the :eager_loading_predicate_transform option if not already set
|
83
|
+
def associate(type, name, opts = OPTS, &block)
|
84
|
+
res = super
|
85
|
+
|
86
|
+
unless res.has_key?(:eager_loading_predicate_transform)
|
87
|
+
res[:eager_loading_predicate_transform] = TRANSFORM
|
88
|
+
end
|
89
|
+
|
90
|
+
res
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -81,7 +81,7 @@ module Sequel
|
|
81
81
|
|
82
82
|
opts = opts.dup
|
83
83
|
opts[:class] = model
|
84
|
-
opts[:methods_module] = Module.new
|
84
|
+
opts[:methods_module] = Sequel.set_temp_name(Module.new){"#{model.name}::_rcte_tree[:methods_module]"}
|
85
85
|
opts[:union_all] = opts[:union_all].nil? ? true : opts[:union_all]
|
86
86
|
model.send(:include, opts[:methods_module])
|
87
87
|
|
@@ -37,7 +37,8 @@ module Sequel
|
|
37
37
|
#
|
38
38
|
# # Register custom serializer/deserializer pair, if desired
|
39
39
|
# require 'sequel/plugins/serialization'
|
40
|
-
#
|
40
|
+
# require 'base64'
|
41
|
+
# Sequel::Plugins::Serialization.register_format(:base64, Base64.method(:encode64), Base64.method(:decode64))
|
41
42
|
#
|
42
43
|
# class User < Sequel::Model
|
43
44
|
# # Built-in format support when loading the plugin
|
@@ -48,10 +49,10 @@ module Sequel
|
|
48
49
|
# serialize_attributes :marshal, :permissions
|
49
50
|
#
|
50
51
|
# # Use custom registered serialization format just like built-in format
|
51
|
-
# serialize_attributes :
|
52
|
+
# serialize_attributes :base64, :password
|
52
53
|
#
|
53
54
|
# # Use a custom serializer/deserializer pair without registering
|
54
|
-
# serialize_attributes [:
|
55
|
+
# serialize_attributes [ Base64.method(:encode64), Base64.method(:decode64)], :password
|
55
56
|
# end
|
56
57
|
# user = User.create
|
57
58
|
# user.permissions = {global: 'read-only'}
|
@@ -123,7 +124,12 @@ module Sequel
|
|
123
124
|
end
|
124
125
|
|
125
126
|
# Create instance level reader that deserializes column values on request,
|
126
|
-
# and instance level writer that stores new deserialized values.
|
127
|
+
# and instance level writer that stores new deserialized values. If +format+
|
128
|
+
# is a symbol, it should correspond to a previously-registered format using +register_format+.
|
129
|
+
# Otherwise, +format+ is expected to be a 2-element array of callables,
|
130
|
+
# with the first element being the serializer, used to convert the value used by the application
|
131
|
+
# to the value that will be stored in the database, and the second element being the deserializer,
|
132
|
+
# used to convert the value stored the database to the value used by the application.
|
127
133
|
def serialize_attributes(format, *columns)
|
128
134
|
if format.is_a?(Symbol)
|
129
135
|
unless format = Sequel.synchronize{REGISTERED_FORMATS[format]}
|
@@ -140,7 +146,7 @@ module Sequel
|
|
140
146
|
# Add serializated attribute acessor methods to the serialization_module
|
141
147
|
def define_serialized_attribute_accessor(serializer, deserializer, *columns)
|
142
148
|
m = self
|
143
|
-
include(@serialization_module ||= Module.new) unless @serialization_module
|
149
|
+
include(@serialization_module ||= Sequel.set_temp_name(Module.new){"#{name}::@serialization_module"}) unless @serialization_module
|
144
150
|
@serialization_module.class_eval do
|
145
151
|
columns.each do |column|
|
146
152
|
m.serialization_map[column] = serializer
|
@@ -40,7 +40,8 @@ module Sequel
|
|
40
40
|
# Album.sql_comments_dataset_methods :to_csv # csv_serializer plugin
|
41
41
|
#
|
42
42
|
# In order for the sql_comments plugin to work, the sql_comments
|
43
|
-
# Database extension must be loaded into the model's database
|
43
|
+
# Database extension must be loaded into the model's database, so
|
44
|
+
# loading the plugin does this automatically.
|
44
45
|
#
|
45
46
|
# Note that in order to make sure SQL comments are included, some
|
46
47
|
# optimizations are disabled if this plugin is loaded.
|
@@ -67,6 +68,10 @@ module Sequel
|
|
67
68
|
# :nocov:
|
68
69
|
end
|
69
70
|
|
71
|
+
def self.apply(model)
|
72
|
+
model.db.extension(:sql_comments)
|
73
|
+
end
|
74
|
+
|
70
75
|
def self.configure(model)
|
71
76
|
model.send(:reset_fast_pk_lookup_sql)
|
72
77
|
end
|
@@ -85,7 +90,7 @@ module Sequel
|
|
85
90
|
# Use automatic SQL comments for the given dataset methods.
|
86
91
|
def sql_comments_dataset_methods(*meths)
|
87
92
|
unless @_sql_comments_dataset_module
|
88
|
-
dataset_module(@_sql_comments_dataset_module = Module.new)
|
93
|
+
dataset_module(@_sql_comments_dataset_module = Sequel.set_temp_name(Module.new){"#{name}::@_sql_comments_dataset_module"})
|
89
94
|
end
|
90
95
|
_sql_comments_methods(@_sql_comments_dataset_module, :dataset, meths)
|
91
96
|
end
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
module Sequel
|
4
4
|
module Plugins
|
5
|
-
# The static_cache_cache plugin allows for caching the row content for
|
6
|
-
# that use the
|
7
|
-
# can avoid the need to query the database every time loading
|
8
|
-
#
|
9
|
-
# plugin.
|
5
|
+
# The static_cache_cache plugin allows for caching the row content for the current
|
6
|
+
# class and subclasses that use the static_cache or subset_static_cache plugins.
|
7
|
+
# Using this plugin can avoid the need to query the database every time loading
|
8
|
+
# the static_cache plugin into a model (static_cache plugin) or using the
|
9
|
+
# cache_subset method (subset_static_cache plugin).
|
10
10
|
#
|
11
11
|
# Usage:
|
12
12
|
#
|
@@ -26,11 +26,7 @@ module Sequel
|
|
26
26
|
module ClassMethods
|
27
27
|
# Dump the in-memory cached rows to the cache file.
|
28
28
|
def dump_static_cache_cache
|
29
|
-
|
30
|
-
@static_cache_cache.sort.each do |k, v|
|
31
|
-
static_cache_cache[k] = v
|
32
|
-
end
|
33
|
-
File.open(@static_cache_cache_file, 'wb'){|f| f.write(Marshal.dump(static_cache_cache))}
|
29
|
+
File.open(@static_cache_cache_file, 'wb'){|f| f.write(Marshal.dump(sort_static_cache_hash(@static_cache_cache)))}
|
34
30
|
nil
|
35
31
|
end
|
36
32
|
|
@@ -38,16 +34,57 @@ module Sequel
|
|
38
34
|
|
39
35
|
private
|
40
36
|
|
37
|
+
# Sort the given static cache hash in a deterministic way, so that
|
38
|
+
# the same static cache values will result in the same marshal file.
|
39
|
+
def sort_static_cache_hash(cache)
|
40
|
+
cache = cache.sort do |a, b|
|
41
|
+
a, = a
|
42
|
+
b, = b
|
43
|
+
if a.is_a?(Array)
|
44
|
+
if b.is_a?(Array)
|
45
|
+
a_name, a_meth = a
|
46
|
+
b_name, b_meth = b
|
47
|
+
x = a_name <=> b_name
|
48
|
+
if x.zero?
|
49
|
+
x = a_meth <=> b_meth
|
50
|
+
end
|
51
|
+
x
|
52
|
+
else
|
53
|
+
1
|
54
|
+
end
|
55
|
+
elsif b.is_a?(Array)
|
56
|
+
-1
|
57
|
+
else
|
58
|
+
a <=> b
|
59
|
+
end
|
60
|
+
end
|
61
|
+
Hash[cache]
|
62
|
+
end
|
63
|
+
|
41
64
|
# Load the rows for the model from the cache if available.
|
42
65
|
# If not available, load the rows from the database, and
|
43
66
|
# then update the cache with the raw rows.
|
44
67
|
def load_static_cache_rows
|
45
|
-
|
68
|
+
_load_static_cache_rows(dataset, name)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Load the rows for the subset from the cache if available.
|
72
|
+
# If not available, load the rows from the database, and
|
73
|
+
# then update the cache with the raw rows.
|
74
|
+
def load_subset_static_cache_rows(ds, meth)
|
75
|
+
_load_static_cache_rows(ds, [name, meth].freeze)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Check the cache first for the key, and return rows without a database
|
79
|
+
# query if present. Otherwise, get all records in the provided dataset,
|
80
|
+
# and update the cache with them.
|
81
|
+
def _load_static_cache_rows(ds, key)
|
82
|
+
if rows = Sequel.synchronize{@static_cache_cache[key]}
|
46
83
|
rows.map{|row| call(row)}.freeze
|
47
84
|
else
|
48
|
-
rows =
|
85
|
+
rows = ds.all.freeze
|
49
86
|
raw_rows = rows.map(&:values)
|
50
|
-
Sequel.synchronize{@static_cache_cache[
|
87
|
+
Sequel.synchronize{@static_cache_cache[key] = raw_rows}
|
51
88
|
rows
|
52
89
|
end
|
53
90
|
end
|
@@ -48,6 +48,7 @@ module Sequel
|
|
48
48
|
def self.apply(model, &block)
|
49
49
|
model.instance_exec do
|
50
50
|
@dataset_module_class = Class.new(@dataset_module_class) do
|
51
|
+
Sequel.set_temp_name(self){"#{model.name}::@dataset_module_class(SubsetConditions)"}
|
51
52
|
include DatasetModuleMethods
|
52
53
|
end
|
53
54
|
end
|