sequel 5.106.0 → 5.109.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/bin/sequel +5 -5
- data/lib/sequel/adapters/ado.rb +1 -1
- data/lib/sequel/adapters/amalgalite.rb +34 -8
- data/lib/sequel/adapters/ibmdb.rb +2 -2
- data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -1
- data/lib/sequel/adapters/jdbc/mssql.rb +28 -5
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +14 -3
- data/lib/sequel/adapters/jdbc.rb +4 -3
- data/lib/sequel/adapters/mock.rb +1 -1
- data/lib/sequel/adapters/mysql.rb +7 -2
- data/lib/sequel/adapters/mysql2.rb +5 -4
- data/lib/sequel/adapters/postgres.rb +42 -39
- data/lib/sequel/adapters/shared/db2.rb +5 -2
- data/lib/sequel/adapters/shared/mssql.rb +11 -5
- data/lib/sequel/adapters/shared/mysql.rb +2 -2
- data/lib/sequel/adapters/shared/postgres.rb +80 -92
- data/lib/sequel/adapters/shared/sqlanywhere.rb +0 -32
- data/lib/sequel/adapters/shared/sqlite.rb +8 -7
- data/lib/sequel/adapters/sqlite.rb +13 -9
- data/lib/sequel/adapters/trilogy.rb +2 -1
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +11 -1
- data/lib/sequel/connection_pool/sharded_single.rb +1 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +7 -5
- data/lib/sequel/connection_pool/sharded_timed_queue.rb +3 -3
- data/lib/sequel/connection_pool/threaded.rb +9 -7
- data/lib/sequel/connection_pool/timed_queue.rb +2 -2
- data/lib/sequel/connection_pool.rb +3 -3
- data/lib/sequel/core.rb +44 -24
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/features.rb +1 -1
- data/lib/sequel/database/misc.rb +6 -11
- data/lib/sequel/database/query.rb +2 -2
- data/lib/sequel/database/schema_generator.rb +7 -5
- data/lib/sequel/database/schema_methods.rb +2 -2
- data/lib/sequel/database/transactions.rb +5 -7
- data/lib/sequel/dataset/actions.rb +2 -2
- data/lib/sequel/dataset/features.rb +4 -4
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/misc.rb +3 -3
- data/lib/sequel/dataset/prepared_statements.rb +2 -2
- data/lib/sequel/dataset/query.rb +8 -8
- data/lib/sequel/dataset/sql.rb +32 -13
- data/lib/sequel/dataset.rb +2 -2
- data/lib/sequel/deprecated.rb +2 -2
- data/lib/sequel/exceptions.rb +2 -2
- data/lib/sequel/extensions/_pretty_table.rb +1 -1
- data/lib/sequel/extensions/async_thread_pool.rb +3 -3
- data/lib/sequel/extensions/auto_cast_date_and_time.rb +2 -2
- data/lib/sequel/extensions/blank.rb +2 -2
- data/lib/sequel/extensions/constraint_validations.rb +1 -1
- data/lib/sequel/extensions/core_refinements.rb +7 -10
- data/lib/sequel/extensions/date_arithmetic.rb +1 -1
- data/lib/sequel/extensions/datetime_parse_to_time.rb +2 -2
- data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -3
- data/lib/sequel/extensions/graph_each.rb +1 -1
- data/lib/sequel/extensions/index_caching.rb +1 -1
- data/lib/sequel/extensions/inflector.rb +5 -5
- data/lib/sequel/extensions/is_distinct_from.rb +2 -2
- data/lib/sequel/extensions/lit_require_frozen.rb +20 -4
- data/lib/sequel/extensions/migration.rb +21 -7
- data/lib/sequel/extensions/named_timezones.rb +9 -9
- data/lib/sequel/extensions/pg_array.rb +10 -8
- data/lib/sequel/extensions/pg_array_ops.rb +69 -14
- data/lib/sequel/extensions/pg_auto_parameterize.rb +2 -2
- data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +3 -3
- data/lib/sequel/extensions/pg_enum.rb +2 -2
- data/lib/sequel/extensions/pg_extended_date_support.rb +5 -5
- data/lib/sequel/extensions/pg_extended_integer_support.rb +1 -1
- data/lib/sequel/extensions/pg_hstore.rb +2 -2
- data/lib/sequel/extensions/pg_hstore_ops.rb +5 -5
- data/lib/sequel/extensions/pg_inet.rb +2 -2
- data/lib/sequel/extensions/pg_inet_ops.rb +2 -2
- data/lib/sequel/extensions/pg_interval.rb +6 -6
- data/lib/sequel/extensions/pg_json.rb +4 -4
- data/lib/sequel/extensions/pg_json_ops.rb +15 -13
- data/lib/sequel/extensions/pg_range.rb +6 -6
- data/lib/sequel/extensions/pg_range_ops.rb +7 -7
- data/lib/sequel/extensions/pg_row.rb +4 -4
- data/lib/sequel/extensions/pg_row_ops.rb +6 -6
- data/lib/sequel/extensions/provenance.rb +2 -2
- data/lib/sequel/extensions/query.rb +2 -2
- data/lib/sequel/extensions/s.rb +6 -10
- data/lib/sequel/extensions/schema_dumper.rb +10 -6
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +2 -0
- data/lib/sequel/extensions/sql_comments.rb +1 -1
- data/lib/sequel/extensions/sql_log_normalizer.rb +1 -1
- data/lib/sequel/extensions/sqlite_json_ops.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +5 -5
- data/lib/sequel/extensions/symbol_aref.rb +12 -32
- data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -5
- data/lib/sequel/extensions/symbol_as.rb +1 -2
- data/lib/sequel/extensions/symbol_as_refinement.rb +1 -5
- data/lib/sequel/extensions/transaction_connection_validator.rb +1 -1
- data/lib/sequel/model/associations.rb +17 -17
- data/lib/sequel/model/base.rb +18 -15
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model/plugins.rb +2 -2
- data/lib/sequel/model.rb +2 -2
- data/lib/sequel/plugins/association_pks.rb +1 -1
- data/lib/sequel/plugins/association_proxies.rb +4 -4
- data/lib/sequel/plugins/auto_restrict_eager_graph.rb +2 -0
- data/lib/sequel/plugins/caching.rb +28 -3
- data/lib/sequel/plugins/class_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/column_encryption.rb +10 -10
- data/lib/sequel/plugins/concurrent_eager_loading.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +9 -20
- data/lib/sequel/plugins/deprecated_associations.rb +2 -2
- data/lib/sequel/plugins/eager_each.rb +1 -1
- data/lib/sequel/plugins/finder.rb +1 -1
- data/lib/sequel/plugins/forbid_lazy_load.rb +3 -3
- data/lib/sequel/plugins/insert_conflict.rb +1 -1
- data/lib/sequel/plugins/insert_returning_select.rb +1 -1
- data/lib/sequel/plugins/instance_filters.rb +8 -0
- data/lib/sequel/plugins/instance_hooks.rb +19 -0
- data/lib/sequel/plugins/json_serializer.rb +4 -4
- data/lib/sequel/plugins/lazy_attributes.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +9 -0
- data/lib/sequel/plugins/optimistic_locking.rb +12 -2
- data/lib/sequel/plugins/optimistic_locking_base.rb +14 -0
- data/lib/sequel/plugins/pg_array_associations.rb +4 -4
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +3 -3
- data/lib/sequel/plugins/pg_eager_any_typed_array.rb +2 -2
- data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +11 -2
- data/lib/sequel/plugins/prepared_statements.rb +2 -2
- data/lib/sequel/plugins/select_on_skipped_update.rb +63 -0
- data/lib/sequel/plugins/serialization.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +21 -3
- data/lib/sequel/plugins/skip_saving_columns.rb +2 -2
- data/lib/sequel/plugins/split_values.rb +1 -1
- data/lib/sequel/plugins/sql_comments.rb +8 -8
- data/lib/sequel/plugins/subclasses.rb +6 -6
- data/lib/sequel/plugins/subset_conditions.rb +5 -16
- data/lib/sequel/plugins/tactical_eager_loading.rb +1 -1
- data/lib/sequel/plugins/throw_failures.rb +3 -3
- data/lib/sequel/plugins/unused_associations.rb +5 -5
- data/lib/sequel/plugins/validate_associated.rb +7 -1
- data/lib/sequel/plugins/validate_associated_context.rb +52 -0
- data/lib/sequel/plugins/validation_helpers.rb +1 -1
- data/lib/sequel/plugins/xml_serializer.rb +2 -0
- data/lib/sequel/sql.rb +120 -116
- data/lib/sequel/version.rb +1 -1
- metadata +5 -3
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
module Plugins
|
|
5
|
+
# This plugin changes the default model behavior so that for existing
|
|
6
|
+
# objects, if Model#save_changes skips the save as the object is not
|
|
7
|
+
# modified, or if the UPDATE query is skipped as there were no columns
|
|
8
|
+
# to update, Sequel will issue a SELECT query to make sure the object
|
|
9
|
+
# still exists. This is only done if require_modification is set for
|
|
10
|
+
# the object, so that these cases will raise the same error that
|
|
11
|
+
# Sequel would raise if the UPDATE require was run but did not modify
|
|
12
|
+
# a row.
|
|
13
|
+
#
|
|
14
|
+
# class Item < Sequel::Model
|
|
15
|
+
# plugin :select_on_skipped_update
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# item = Item[1]
|
|
19
|
+
#
|
|
20
|
+
# # Delete the item from the database
|
|
21
|
+
# Item.where(id: 1).delete
|
|
22
|
+
#
|
|
23
|
+
# # By default, this would return nil, but with the plugin,
|
|
24
|
+
# # this raises Sequel::NoExistingRow.
|
|
25
|
+
# item.save_changes
|
|
26
|
+
#
|
|
27
|
+
# # By default, this would return the object without issuing the
|
|
28
|
+
# # UPDATE query (as the columns to update is empty. With the plugin,
|
|
29
|
+
# # this raises Sequel::NoExistingRow.
|
|
30
|
+
# item.save(columns: [])
|
|
31
|
+
module SelectOnSkippedUpdate
|
|
32
|
+
COUNT = Sequel.function(:count).*.as(:count)
|
|
33
|
+
private_constant :COUNT
|
|
34
|
+
|
|
35
|
+
module InstanceMethods
|
|
36
|
+
# If an UPDATE statement was skipped as the object wasn't modified, run a SELECT query.
|
|
37
|
+
def save_changes(opts=OPTS)
|
|
38
|
+
ret = super
|
|
39
|
+
run_select_on_skipped_update if ret.nil? && require_modification
|
|
40
|
+
ret
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
# If an UPDATE statement was skipped as there were no columns to update, run a SELECT query.
|
|
46
|
+
def _update_columns(columns)
|
|
47
|
+
ret = super
|
|
48
|
+
run_select_on_skipped_update if ret.nil? && columns.empty? && require_modification
|
|
49
|
+
ret
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Run a SELECT query on the dataset to determine whether the object still exists in the database.
|
|
53
|
+
# This will result in an exception if a single row is not modified.
|
|
54
|
+
def run_select_on_skipped_update
|
|
55
|
+
ds = _update_dataset
|
|
56
|
+
unless ds.select(COUNT).single_value! == 1
|
|
57
|
+
raise(NoMatchingRow, "Attempt to select object did not result in a single row modification")
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -154,7 +154,7 @@ module Sequel
|
|
|
154
154
|
|
|
155
155
|
private
|
|
156
156
|
|
|
157
|
-
# Add serializated attribute
|
|
157
|
+
# Add serializated attribute accessor methods to the serialization_module
|
|
158
158
|
def define_serialized_attribute_accessor(serializer, deserializer, *columns)
|
|
159
159
|
m = self
|
|
160
160
|
include(@serialization_module ||= Sequel.set_temp_name(Module.new){"#{name}::@serialization_module"}) unless @serialization_module
|
|
@@ -6,7 +6,7 @@ module Sequel
|
|
|
6
6
|
# in the following ways:
|
|
7
7
|
#
|
|
8
8
|
# * It automatically saves model instances back to the
|
|
9
|
-
# shard they were
|
|
9
|
+
# shard they were retrieved from.
|
|
10
10
|
# * It makes model associations use the same shard as the model object.
|
|
11
11
|
# * It adds a slightly nicer API for creating model instances on
|
|
12
12
|
# specific shards.
|
|
@@ -12,6 +12,11 @@ module Sequel
|
|
|
12
12
|
# argument to the plugin) holds the class name as a string. However,
|
|
13
13
|
# you can override this by using the <tt>:model_map</tt> option and/or
|
|
14
14
|
# the <tt>:key_map</tt> option.
|
|
15
|
+
#
|
|
16
|
+
# The +sti_key+ column can be set via mass assignment, just like any
|
|
17
|
+
# non-primary key column. Make sure to follow the recommendations in the
|
|
18
|
+
# {mass assignment guide}[rdoc-ref:doc/mass_assignment.rdoc]
|
|
19
|
+
# to ensure this column is not set with untrusted data.
|
|
15
20
|
#
|
|
16
21
|
# You should only load this plugin in the parent class, not in the subclasses.
|
|
17
22
|
#
|
|
@@ -84,6 +89,7 @@ module Sequel
|
|
|
84
89
|
@sti_key_array = nil
|
|
85
90
|
@sti_key = key
|
|
86
91
|
@sti_dataset = dataset
|
|
92
|
+
@sti_root_class = self
|
|
87
93
|
@sti_model_map = opts[:model_map] || lambda{|v| v if v && v != ''}
|
|
88
94
|
@sti_key_map = if km = opts[:key_map]
|
|
89
95
|
if km.is_a?(Hash)
|
|
@@ -150,7 +156,7 @@ module Sequel
|
|
|
150
156
|
# This defaults to a lookup in the key map.
|
|
151
157
|
attr_reader :sti_key_chooser
|
|
152
158
|
|
|
153
|
-
Plugins.inherited_instance_variables(self, :@sti_dataset=>nil, :@sti_key=>nil, :@sti_key_map=>nil, :@sti_model_map=>nil, :@sti_key_chooser=>nil)
|
|
159
|
+
Plugins.inherited_instance_variables(self, :@sti_dataset=>nil, :@sti_key=>nil, :@sti_key_map=>nil, :@sti_model_map=>nil, :@sti_key_chooser=>nil, :@sti_root_class=>nil)
|
|
154
160
|
|
|
155
161
|
# Freeze STI information when freezing model class. Note that
|
|
156
162
|
# because of how STI works, you should not freeze an STI subclass
|
|
@@ -194,7 +200,7 @@ module Sequel
|
|
|
194
200
|
end
|
|
195
201
|
|
|
196
202
|
# Copy the necessary attributes to the subclasses, and filter the
|
|
197
|
-
# subclass's dataset based on the
|
|
203
|
+
# subclass's dataset based on the sti_key_map entry for the class.
|
|
198
204
|
def inherited(subclass)
|
|
199
205
|
super
|
|
200
206
|
key = Array(sti_key_map[subclass]).dup
|
|
@@ -221,11 +227,23 @@ module Sequel
|
|
|
221
227
|
# Return a class object. If a class is given, return it directly.
|
|
222
228
|
# Treat strings and symbols as class names. If nil is given or
|
|
223
229
|
# an invalid class name string or symbol is used, return self.
|
|
230
|
+
# If the class is valid but is not a subclass of the class that
|
|
231
|
+
# loaded the single_table_inheritance plugin, use the class that
|
|
232
|
+
# loaded the plugin.
|
|
224
233
|
# Raise an error for other types.
|
|
225
234
|
def sti_class(v)
|
|
226
235
|
case v
|
|
227
236
|
when String, Symbol
|
|
228
|
-
|
|
237
|
+
begin
|
|
238
|
+
klass = constantize(v)
|
|
239
|
+
if Class === klass && @sti_root_class >= klass
|
|
240
|
+
klass
|
|
241
|
+
else
|
|
242
|
+
@sti_root_class
|
|
243
|
+
end
|
|
244
|
+
rescue
|
|
245
|
+
self
|
|
246
|
+
end
|
|
229
247
|
when nil
|
|
230
248
|
self
|
|
231
249
|
when Class
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Sequel
|
|
4
4
|
module Plugins
|
|
5
|
-
# The
|
|
5
|
+
# The skip_saving_columns plugin allows skipping specific columns when
|
|
6
6
|
# saving. By default, it skips columns that the database schema
|
|
7
7
|
# indicates are generated columns:
|
|
8
8
|
#
|
|
@@ -90,7 +90,7 @@ module Sequel
|
|
|
90
90
|
|
|
91
91
|
# Skip the columns the model has marked to skip when updating
|
|
92
92
|
# only changed columns.
|
|
93
|
-
def
|
|
93
|
+
def _save_update_changed_columns_hash
|
|
94
94
|
_save_removed_skipped_columns(super)
|
|
95
95
|
end
|
|
96
96
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Sequel
|
|
4
4
|
module Plugins
|
|
5
|
-
# The split_values plugin splits the values hash
|
|
5
|
+
# The split_values plugin splits the values hash retrieved from the
|
|
6
6
|
# database, and moves keys from the values hash that are not columns
|
|
7
7
|
# in the model's dataset to a separate hash. This makes it so the
|
|
8
8
|
# values hash only stores columns from the model's dataset.
|
|
@@ -63,9 +63,9 @@ module Sequel
|
|
|
63
63
|
super(*a, &block)
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
|
-
# :
|
|
66
|
+
# simplecov:disable
|
|
67
67
|
mod.send(:ruby2_keywords, meth) if mod.respond_to?(:ruby2_keywords, true)
|
|
68
|
-
# :
|
|
68
|
+
# simplecov:enable
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def self.apply(model)
|
|
@@ -101,9 +101,9 @@ module Sequel
|
|
|
101
101
|
super(*a, &block)
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
|
-
# :
|
|
104
|
+
# simplecov:disable
|
|
105
105
|
ruby2_keywords(meth) if respond_to?(:ruby2_keywords, true)
|
|
106
|
-
# :
|
|
106
|
+
# simplecov:enable
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
private
|
|
@@ -133,9 +133,9 @@ module Sequel
|
|
|
133
133
|
super(*a, &block)
|
|
134
134
|
end
|
|
135
135
|
end
|
|
136
|
-
# :
|
|
136
|
+
# simplecov:disable
|
|
137
137
|
ruby2_keywords(meth) if respond_to?(:ruby2_keywords, true)
|
|
138
|
-
# :
|
|
138
|
+
# simplecov:enable
|
|
139
139
|
end
|
|
140
140
|
|
|
141
141
|
private
|
|
@@ -163,9 +163,9 @@ module Sequel
|
|
|
163
163
|
super(*a, &block)
|
|
164
164
|
end
|
|
165
165
|
end
|
|
166
|
-
# :
|
|
166
|
+
# simplecov:disable
|
|
167
167
|
ruby2_keywords(meth) if respond_to?(:ruby2_keywords, true)
|
|
168
|
-
# :
|
|
168
|
+
# simplecov:enable
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
private
|
|
@@ -40,9 +40,9 @@ module Sequel
|
|
|
40
40
|
|
|
41
41
|
# Initialize the subclasses instance variable for the model.
|
|
42
42
|
def self.apply(model, &block)
|
|
43
|
-
# :
|
|
43
|
+
# simplecov:disable
|
|
44
44
|
model.instance_variable_set(:@subclasses, []) if NEED_SUBCLASSES
|
|
45
|
-
# :
|
|
45
|
+
# simplecov:enable
|
|
46
46
|
model.instance_variable_set(:@on_subclass, block)
|
|
47
47
|
end
|
|
48
48
|
|
|
@@ -51,13 +51,13 @@ module Sequel
|
|
|
51
51
|
# class created.
|
|
52
52
|
attr_reader :on_subclass
|
|
53
53
|
|
|
54
|
-
# :
|
|
54
|
+
# simplecov:disable
|
|
55
55
|
if NEED_SUBCLASSES
|
|
56
56
|
# All subclasses for the current model. Does not
|
|
57
57
|
# include the model itself.
|
|
58
58
|
attr_reader :subclasses
|
|
59
59
|
end
|
|
60
|
-
# :
|
|
60
|
+
# simplecov:enable
|
|
61
61
|
|
|
62
62
|
# All descendent classes of this model.
|
|
63
63
|
def descendants
|
|
@@ -85,9 +85,9 @@ module Sequel
|
|
|
85
85
|
# in the subclass.
|
|
86
86
|
def inherited(subclass)
|
|
87
87
|
super
|
|
88
|
-
# :
|
|
88
|
+
# simplecov:disable
|
|
89
89
|
Sequel.synchronize{subclasses << subclass} if NEED_SUBCLASSES
|
|
90
|
-
# :
|
|
90
|
+
# simplecov:enable
|
|
91
91
|
on_subclass.call(subclass) if on_subclass
|
|
92
92
|
end
|
|
93
93
|
end
|
|
@@ -105,22 +105,11 @@ module Sequel
|
|
|
105
105
|
|
|
106
106
|
private
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
where(name, Sequel.send(meth, *args.map{|a| self.instance_method(:"#{a}_conditions").bind(ds).call}))
|
|
114
|
-
end
|
|
115
|
-
else
|
|
116
|
-
# Cannot bind module method to arbitrary objects in Ruby 1.9.
|
|
117
|
-
# :nocov:
|
|
118
|
-
def _where_any_all(meth, name, args)
|
|
119
|
-
ds = model.dataset.clone
|
|
120
|
-
ds.extend(self)
|
|
121
|
-
where(name, Sequel.send(meth, *args.map{|a| ds.send(:"#{a}_conditions")}))
|
|
122
|
-
end
|
|
123
|
-
# :nocov:
|
|
108
|
+
# Backbone of #where_any and #where_all
|
|
109
|
+
def _where_any_all(meth, name, args)
|
|
110
|
+
ds = model.dataset
|
|
111
|
+
# #bind used here because the dataset module may not yet be included in the model's dataset
|
|
112
|
+
where(name, Sequel.send(meth, *args.map{|a| self.instance_method(:"#{a}_conditions").bind(ds).call}))
|
|
124
113
|
end
|
|
125
114
|
end
|
|
126
115
|
end
|
|
@@ -162,7 +162,7 @@ module Sequel
|
|
|
162
162
|
end
|
|
163
163
|
|
|
164
164
|
# Filter the objects used when tactical eager loading.
|
|
165
|
-
# By default, this removes frozen objects and objects that
|
|
165
|
+
# By default, this removes frozen objects and objects that already have the association loaded,
|
|
166
166
|
# as well as objects where the reflection for the association is not the same as the receiver's
|
|
167
167
|
# reflection for the association.
|
|
168
168
|
def _filter_tactical_eager_load_objects(opts)
|
|
@@ -64,7 +64,7 @@ module Sequel
|
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
if RUBY_VERSION >= '2.2' && (!defined?(JRUBY_VERSION) || JRUBY_VERSION > '9.1')
|
|
67
|
+
if RUBY_VERSION >= '2.2' && (!defined?(JRUBY_VERSION) || JRUBY_VERSION.to_r > Rational('9.1'))
|
|
68
68
|
# Throw HookFailed with the generated error. If the throw is not
|
|
69
69
|
# caught, just return the originally generated error.
|
|
70
70
|
def hook_failed_error(msg)
|
|
@@ -86,7 +86,7 @@ module Sequel
|
|
|
86
86
|
# UncaughtThrowError was added in Ruby 2.2. Older Ruby versions
|
|
87
87
|
# used ArgumentError with "uncaught throw" at the start of the message
|
|
88
88
|
|
|
89
|
-
# :
|
|
89
|
+
# simplecov:disable
|
|
90
90
|
def hook_failed_error(msg)
|
|
91
91
|
e = super
|
|
92
92
|
throw HookFailed, e
|
|
@@ -102,7 +102,7 @@ module Sequel
|
|
|
102
102
|
raise e2 unless e2.message.start_with?('uncaught throw')
|
|
103
103
|
e
|
|
104
104
|
end
|
|
105
|
-
# :
|
|
105
|
+
# simplecov:enable
|
|
106
106
|
end
|
|
107
107
|
end
|
|
108
108
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen-string-literal: true
|
|
2
2
|
|
|
3
|
-
# :
|
|
3
|
+
# simplecov:disable
|
|
4
4
|
|
|
5
5
|
# This entire file is excluded from coverage testing. This is because it
|
|
6
6
|
# requires coverage testing to work, and if you've already loaded Sequel
|
|
@@ -67,7 +67,7 @@ module Sequel
|
|
|
67
67
|
#
|
|
68
68
|
# You can use the output of the +unused_associations+ method to determine
|
|
69
69
|
# which associations are not used at all in your application, and can
|
|
70
|
-
# be
|
|
70
|
+
# be eliminated.
|
|
71
71
|
#
|
|
72
72
|
# You can also take that unused association data and pass it to the
|
|
73
73
|
# +unused_association_options+ method, which will return an array of
|
|
@@ -131,7 +131,7 @@ module Sequel
|
|
|
131
131
|
# = Automatic Usage of Unused Association Data
|
|
132
132
|
#
|
|
133
133
|
# Since it can be a pain to manually update all of your code
|
|
134
|
-
# to remove unused
|
|
134
|
+
# to remove unused associations or add options to prevent the
|
|
135
135
|
# definition of unused associations, the unused_associations
|
|
136
136
|
# plugin comes with support to take previously saved unused
|
|
137
137
|
# association data, and use it to not create unused associations,
|
|
@@ -265,7 +265,7 @@ module Sequel
|
|
|
265
265
|
module ClassMethods
|
|
266
266
|
# Only the data is copied to subclasses, to allow the :modify_associations
|
|
267
267
|
# plugin option to affect them. The :file and :coverage_file are not copied
|
|
268
|
-
# to subclasses, as users are expected
|
|
268
|
+
# to subclasses, as users are expected to call methods such as
|
|
269
269
|
# unused_associations only on the class that is loading the plugin.
|
|
270
270
|
Plugins.inherited_instance_variables(self, :@unused_associations_data=>nil)
|
|
271
271
|
|
|
@@ -526,4 +526,4 @@ module Sequel
|
|
|
526
526
|
end
|
|
527
527
|
end
|
|
528
528
|
end
|
|
529
|
-
# :
|
|
529
|
+
# simplecov:enable
|
|
@@ -43,6 +43,12 @@ module Sequel
|
|
|
43
43
|
module InstanceMethods
|
|
44
44
|
private
|
|
45
45
|
|
|
46
|
+
# Whether the associated object is valid. By default, the same as calling
|
|
47
|
+
# +valid?+ on the object, but exists so it can be overridden.
|
|
48
|
+
def associated_object_valid?(reflection, obj)
|
|
49
|
+
obj.valid?
|
|
50
|
+
end
|
|
51
|
+
|
|
46
52
|
# Delay validating the associated object until validating the current object.
|
|
47
53
|
def delay_validate_associated_object(reflection, obj)
|
|
48
54
|
after_validation_hook{validate_associated_object(reflection, obj)}
|
|
@@ -62,7 +68,7 @@ module Sequel
|
|
|
62
68
|
end
|
|
63
69
|
end
|
|
64
70
|
|
|
65
|
-
unless obj
|
|
71
|
+
unless associated_object_valid?(reflection, obj)
|
|
66
72
|
if ignore_key_errors
|
|
67
73
|
# Ignore errors on the key column in the associated object. This column
|
|
68
74
|
# will be set when saving to a presumably valid value using a column
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
module Plugins
|
|
5
|
+
# The validate_associated_context plugin extends the validate_associated
|
|
6
|
+
# plugin to work with the validation_contexts plugin. It ensures associated
|
|
7
|
+
# objects are validated using the validation context of the current object.
|
|
8
|
+
#
|
|
9
|
+
# This plugin loads the validate_associated and validation_contexts plugins.
|
|
10
|
+
# The associated model must also use the validation_contexts plugin in order
|
|
11
|
+
# to access the validation context.
|
|
12
|
+
#
|
|
13
|
+
# class Album < Sequel::Model
|
|
14
|
+
# plugin :validate_associated_context
|
|
15
|
+
# many_to_one :artist
|
|
16
|
+
#
|
|
17
|
+
# def validate
|
|
18
|
+
# super
|
|
19
|
+
# validate_associated_object(model.association_reflection(:artist), artist) if artist
|
|
20
|
+
# end
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# class Artist < Sequel::Model
|
|
24
|
+
# plugin :validation_contexts
|
|
25
|
+
# def validate
|
|
26
|
+
# super
|
|
27
|
+
# errors.add(:name, 'not present') if name.nil? && validation_context == :publish
|
|
28
|
+
# end
|
|
29
|
+
# end
|
|
30
|
+
#
|
|
31
|
+
# album = Album.new(artist: Artist.new)
|
|
32
|
+
# album.valid? # => true
|
|
33
|
+
# album.valid?(validation_context: :publish) # => false
|
|
34
|
+
module ValidateAssociatedContext
|
|
35
|
+
# Depend on the validate_associated and validation_contexts plugins.
|
|
36
|
+
def self.apply(model)
|
|
37
|
+
model.plugin :validate_associated
|
|
38
|
+
model.plugin :validation_contexts
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
module InstanceMethods
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
# Whether the associated object is valid, using the validation context
|
|
45
|
+
# of the current object.
|
|
46
|
+
def associated_object_valid?(reflection, obj)
|
|
47
|
+
obj.valid?(:validation_context=>validation_context)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -39,7 +39,7 @@ module Sequel
|
|
|
39
39
|
# :skip_invalid :: Do not try to validate columns that are already invalid.
|
|
40
40
|
#
|
|
41
41
|
# The default validation options for all models can be modified by
|
|
42
|
-
#
|
|
42
|
+
# overriding the Model#default_validation_helpers_options private method.
|
|
43
43
|
# By changing the default options, you can setup internationalization of the
|
|
44
44
|
# error messages. For example, you would modify the default options:
|
|
45
45
|
#
|