sequel 4.46.0 → 4.49.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/CHANGELOG +210 -0
- data/Rakefile +1 -1
- data/doc/advanced_associations.rdoc +1 -1
- data/doc/opening_databases.rdoc +3 -2
- data/doc/release_notes/4.47.0.txt +56 -0
- data/doc/release_notes/4.48.0.txt +293 -0
- data/doc/release_notes/4.49.0.txt +222 -0
- data/lib/sequel/adapters/ado/access.rb +2 -1
- data/lib/sequel/adapters/do/postgres.rb +5 -2
- data/lib/sequel/adapters/ibmdb.rb +30 -8
- data/lib/sequel/adapters/jdbc/as400.rb +1 -1
- data/lib/sequel/adapters/jdbc/db2.rb +12 -3
- data/lib/sequel/adapters/jdbc/derby.rb +4 -5
- data/lib/sequel/adapters/jdbc/h2.rb +10 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +46 -20
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +20 -6
- data/lib/sequel/adapters/jdbc.rb +39 -23
- data/lib/sequel/adapters/mock.rb +27 -19
- data/lib/sequel/adapters/mysql.rb +17 -16
- data/lib/sequel/adapters/mysql2.rb +5 -6
- data/lib/sequel/adapters/oracle.rb +5 -9
- data/lib/sequel/adapters/postgres.rb +91 -103
- data/lib/sequel/adapters/shared/db2.rb +22 -6
- data/lib/sequel/adapters/shared/mssql.rb +5 -4
- data/lib/sequel/adapters/shared/mysql.rb +79 -25
- data/lib/sequel/adapters/shared/oracle.rb +26 -3
- data/lib/sequel/adapters/shared/postgres.rb +199 -95
- data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
- data/lib/sequel/adapters/shared/sqlite.rb +72 -82
- data/lib/sequel/adapters/sqlanywhere.rb +4 -1
- data/lib/sequel/adapters/sqlite.rb +5 -3
- data/lib/sequel/adapters/swift/postgres.rb +5 -2
- data/lib/sequel/adapters/tinytds.rb +0 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/adapters/utils/pg_types.rb +2 -76
- data/lib/sequel/ast_transformer.rb +1 -1
- data/lib/sequel/connection_pool/sharded_single.rb +1 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +1 -1
- data/lib/sequel/connection_pool/single.rb +2 -2
- data/lib/sequel/connection_pool/threaded.rb +2 -2
- data/lib/sequel/connection_pool.rb +9 -2
- data/lib/sequel/core.rb +2 -2
- data/lib/sequel/database/connecting.rb +8 -8
- data/lib/sequel/database/dataset.rb +6 -3
- data/lib/sequel/database/dataset_defaults.rb +14 -1
- data/lib/sequel/database/misc.rb +1 -1
- data/lib/sequel/database/query.rb +3 -0
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset/actions.rb +72 -10
- data/lib/sequel/dataset/dataset_module.rb +58 -0
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/misc.rb +1 -0
- data/lib/sequel/dataset/prepared_statements.rb +3 -3
- data/lib/sequel/dataset/query.rb +22 -11
- data/lib/sequel/dataset.rb +1 -1
- data/lib/sequel/exceptions.rb +8 -0
- data/lib/sequel/extensions/_model_pg_row.rb +5 -2
- data/lib/sequel/extensions/core_extensions.rb +4 -1
- data/lib/sequel/extensions/current_datetime_timestamp.rb +2 -1
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -3
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
- data/lib/sequel/extensions/filter_having.rb +2 -0
- data/lib/sequel/extensions/freeze_datasets.rb +2 -0
- data/lib/sequel/extensions/from_block.rb +1 -1
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/hash_aliases.rb +2 -0
- data/lib/sequel/extensions/identifier_mangling.rb +0 -7
- data/lib/sequel/extensions/meta_def.rb +2 -0
- data/lib/sequel/extensions/migration.rb +11 -8
- data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/null_dataset.rb +1 -0
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +207 -130
- data/lib/sequel/extensions/pg_hstore.rb +38 -20
- data/lib/sequel/extensions/pg_inet.rb +18 -6
- data/lib/sequel/extensions/pg_interval.rb +19 -12
- data/lib/sequel/extensions/pg_json.rb +25 -14
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/extensions/pg_range.rb +133 -100
- data/lib/sequel/extensions/pg_range_ops.rb +4 -3
- data/lib/sequel/extensions/pg_row.rb +68 -39
- data/lib/sequel/extensions/pg_row_ops.rb +11 -5
- data/lib/sequel/extensions/query_literals.rb +2 -0
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
- data/lib/sequel/extensions/s.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +29 -25
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
- data/lib/sequel/extensions/server_block.rb +32 -15
- data/lib/sequel/extensions/set_overrides.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +0 -1
- data/lib/sequel/extensions/symbol_aref.rb +0 -4
- data/lib/sequel/model/associations.rb +35 -7
- data/lib/sequel/model/base.rb +113 -87
- data/lib/sequel/model/dataset_module.rb +5 -43
- data/lib/sequel/model/errors.rb +2 -1
- data/lib/sequel/model/inflections.rb +17 -5
- data/lib/sequel/model.rb +26 -58
- data/lib/sequel/plugins/active_model.rb +2 -2
- data/lib/sequel/plugins/association_autoreloading.rb +2 -0
- data/lib/sequel/plugins/association_dependencies.rb +3 -3
- data/lib/sequel/plugins/association_pks.rb +73 -46
- data/lib/sequel/plugins/association_proxies.rb +1 -1
- data/lib/sequel/plugins/auto_validations.rb +6 -2
- data/lib/sequel/plugins/boolean_readers.rb +2 -2
- data/lib/sequel/plugins/boolean_subsets.rb +1 -1
- data/lib/sequel/plugins/caching.rb +19 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +24 -13
- data/lib/sequel/plugins/column_conflicts.rb +7 -2
- data/lib/sequel/plugins/column_select.rb +3 -3
- data/lib/sequel/plugins/composition.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +8 -8
- data/lib/sequel/plugins/dataset_associations.rb +25 -13
- data/lib/sequel/plugins/defaults_setter.rb +13 -1
- data/lib/sequel/plugins/eager_each.rb +1 -1
- data/lib/sequel/plugins/force_encoding.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +9 -12
- data/lib/sequel/plugins/identifier_columns.rb +2 -0
- data/lib/sequel/plugins/instance_filters.rb +3 -1
- data/lib/sequel/plugins/instance_hooks.rb +17 -9
- data/lib/sequel/plugins/json_serializer.rb +19 -12
- data/lib/sequel/plugins/lazy_attributes.rb +8 -7
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +2 -0
- data/lib/sequel/plugins/modification_detection.rb +3 -0
- data/lib/sequel/plugins/nested_attributes.rb +6 -2
- data/lib/sequel/plugins/pg_array_associations.rb +5 -0
- data/lib/sequel/plugins/pg_row.rb +4 -2
- data/lib/sequel/plugins/pg_typecast_on_load.rb +2 -0
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/plugins/rcte_tree.rb +4 -24
- data/lib/sequel/plugins/serialization.rb +9 -15
- data/lib/sequel/plugins/single_table_inheritance.rb +8 -3
- data/lib/sequel/plugins/split_values.rb +6 -5
- data/lib/sequel/plugins/static_cache.rb +31 -25
- data/lib/sequel/plugins/subset_conditions.rb +3 -1
- data/lib/sequel/plugins/table_select.rb +1 -1
- data/lib/sequel/plugins/touch.rb +4 -2
- data/lib/sequel/plugins/validation_class_methods.rb +5 -6
- data/lib/sequel/plugins/validation_helpers.rb +14 -8
- data/lib/sequel/plugins/xml_serializer.rb +4 -4
- data/lib/sequel/sql.rb +18 -9
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +115 -14
- data/spec/adapters/mssql_spec.rb +4 -4
- data/spec/adapters/mysql_spec.rb +83 -29
- data/spec/adapters/oracle_spec.rb +28 -24
- data/spec/adapters/postgres_spec.rb +40 -24
- data/spec/adapters/sqlanywhere_spec.rb +88 -86
- data/spec/adapters/sqlite_spec.rb +29 -24
- data/spec/bin_spec.rb +7 -1
- data/spec/core/connection_pool_spec.rb +45 -14
- data/spec/core/database_spec.rb +155 -0
- data/spec/core/dataset_spec.rb +219 -36
- data/spec/core/schema_spec.rb +16 -0
- data/spec/core/spec_helper.rb +1 -0
- data/spec/core_extensions_spec.rb +6 -2
- data/spec/extensions/active_model_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +34 -2
- data/spec/extensions/auto_literal_strings_spec.rb +5 -1
- data/spec/extensions/auto_validations_spec.rb +2 -0
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +106 -19
- data/spec/extensions/column_conflicts_spec.rb +11 -0
- data/spec/extensions/column_select_spec.rb +1 -0
- data/spec/extensions/composition_spec.rb +13 -0
- data/spec/extensions/connection_validator_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +20 -8
- data/spec/extensions/defaults_setter_spec.rb +15 -1
- data/spec/extensions/filter_having_spec.rb +5 -3
- data/spec/extensions/hash_aliases_spec.rb +3 -1
- data/spec/extensions/identifier_columns_spec.rb +3 -1
- data/spec/extensions/implicit_subquery_spec.rb +4 -2
- data/spec/extensions/json_serializer_spec.rb +18 -0
- data/spec/extensions/lazy_attributes_spec.rb +3 -3
- data/spec/extensions/many_through_many_spec.rb +4 -4
- data/spec/extensions/meta_def_spec.rb +9 -0
- data/spec/extensions/migration_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +14 -3
- data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/pg_array_associations_spec.rb +29 -18
- data/spec/extensions/pg_array_spec.rb +44 -25
- data/spec/extensions/pg_hstore_spec.rb +10 -0
- data/spec/extensions/pg_inet_spec.rb +26 -0
- data/spec/extensions/pg_interval_spec.rb +20 -0
- data/spec/extensions/pg_json_spec.rb +24 -0
- data/spec/extensions/pg_range_spec.rb +98 -14
- data/spec/extensions/pg_row_spec.rb +14 -4
- data/spec/extensions/pg_typecast_on_load_spec.rb +11 -9
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +3 -1
- data/spec/extensions/schema_dumper_spec.rb +108 -94
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
- data/spec/extensions/serialization_spec.rb +1 -1
- data/spec/extensions/server_block_spec.rb +7 -0
- data/spec/extensions/single_table_inheritance_spec.rb +17 -1
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/static_cache_spec.rb +75 -24
- data/spec/extensions/string_agg_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +9 -0
- data/spec/extensions/validation_helpers_spec.rb +10 -5
- data/spec/extensions/whitelist_security_spec.rb +26 -0
- data/spec/integration/associations_test.rb +8 -0
- data/spec/integration/dataset_test.rb +45 -44
- data/spec/integration/model_test.rb +53 -4
- data/spec/integration/plugin_test.rb +28 -4
- data/spec/integration/prepared_statement_test.rb +3 -0
- data/spec/integration/schema_test.rb +21 -1
- data/spec/integration/transaction_test.rb +40 -40
- data/spec/model/association_reflection_spec.rb +43 -1
- data/spec/model/associations_spec.rb +29 -9
- data/spec/model/class_dataset_methods_spec.rb +20 -4
- data/spec/model/dataset_methods_spec.rb +12 -3
- data/spec/model/eager_loading_spec.rb +8 -8
- data/spec/model/model_spec.rb +45 -1
- data/spec/model/plugins_spec.rb +34 -0
- data/spec/model/record_spec.rb +1 -1
- data/spec/spec_config.rb +2 -0
- metadata +11 -4
- data/spec/adapters/firebird_spec.rb +0 -405
- data/spec/adapters/informix_spec.rb +0 -100
|
@@ -12,26 +12,6 @@ module Sequel
|
|
|
12
12
|
# level (where level 1 is children, level 2 is children and grandchildren
|
|
13
13
|
# etc.) in a single query.
|
|
14
14
|
#
|
|
15
|
-
# = Background
|
|
16
|
-
#
|
|
17
|
-
# There are two types of common models for storing tree structured data
|
|
18
|
-
# in an SQL database, the adjacency list model and the nested set model.
|
|
19
|
-
# Before recursive common table expressions (or similar capabilities such
|
|
20
|
-
# as CONNECT BY for Oracle), the nested set model was the only easy way
|
|
21
|
-
# to retrieve all ancestors and descendants in a single query. However,
|
|
22
|
-
# it has significant performance corner cases.
|
|
23
|
-
#
|
|
24
|
-
# On PostgreSQL 8.4, with a significant number of rows, the nested set
|
|
25
|
-
# model is almost 500 times slower than using a recursive common table
|
|
26
|
-
# expression with the adjacency list model to get all descendants, and
|
|
27
|
-
# almost 24,000 times slower to get all descendants to a given level.
|
|
28
|
-
#
|
|
29
|
-
# Considering that the nested set model requires more difficult management
|
|
30
|
-
# than the adjacency list model, it's almost always better to use the
|
|
31
|
-
# adjacency list model if your database supports common table expressions.
|
|
32
|
-
# See http://explainextended.com/2009/09/24/adjacency-list-vs-nested-sets-postgresql/
|
|
33
|
-
# for detailed analysis.
|
|
34
|
-
#
|
|
35
15
|
# = Usage
|
|
36
16
|
#
|
|
37
17
|
# The rcte_tree plugin adds four associations to the model: parent, children, ancestors, and
|
|
@@ -153,7 +133,7 @@ module Sequel
|
|
|
153
133
|
base_ds = model.where(prkey_array.zip(key_array.map{|k| get_column_value(k)}))
|
|
154
134
|
recursive_ds = model.join(t, key_array.zip(prkey_array))
|
|
155
135
|
if c = a[:conditions]
|
|
156
|
-
(base_ds, recursive_ds) = [base_ds, recursive_ds].
|
|
136
|
+
(base_ds, recursive_ds) = [base_ds, recursive_ds].map do |ds|
|
|
157
137
|
(c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.where(*c) : ds.where(c)
|
|
158
138
|
end
|
|
159
139
|
end
|
|
@@ -201,7 +181,7 @@ module Sequel
|
|
|
201
181
|
recursive_case = model.join(t, key_array.zip(prkey_array)).
|
|
202
182
|
select(*recursive_case_columns)
|
|
203
183
|
if c = r[:conditions]
|
|
204
|
-
(base_case, recursive_case) = [base_case, recursive_case].
|
|
184
|
+
(base_case, recursive_case) = [base_case, recursive_case].map do |ds|
|
|
205
185
|
(c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.where(*c) : ds.where(c)
|
|
206
186
|
end
|
|
207
187
|
end
|
|
@@ -248,7 +228,7 @@ module Sequel
|
|
|
248
228
|
base_ds = model.where(key_array.zip(prkey_array.map{|k| get_column_value(k)}))
|
|
249
229
|
recursive_ds = model.join(t, prkey_array.zip(key_array))
|
|
250
230
|
if c = d[:conditions]
|
|
251
|
-
(base_ds, recursive_ds) = [base_ds, recursive_ds].
|
|
231
|
+
(base_ds, recursive_ds) = [base_ds, recursive_ds].map do |ds|
|
|
252
232
|
(c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.where(*c) : ds.where(c)
|
|
253
233
|
end
|
|
254
234
|
end
|
|
@@ -299,7 +279,7 @@ module Sequel
|
|
|
299
279
|
recursive_case = model.join(t, prkey_array.zip(key_array)).
|
|
300
280
|
select(*recursive_case_columns)
|
|
301
281
|
if c = r[:conditions]
|
|
302
|
-
(base_case, recursive_case) = [base_case, recursive_case].
|
|
282
|
+
(base_case, recursive_case) = [base_case, recursive_case].map do |ds|
|
|
303
283
|
(c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.where(*c) : ds.where(c)
|
|
304
284
|
end
|
|
305
285
|
end
|
|
@@ -7,11 +7,11 @@ module Sequel
|
|
|
7
7
|
# when you call an accessor.
|
|
8
8
|
#
|
|
9
9
|
# This plugin works by keeping the serialized value in the values, and
|
|
10
|
-
# adding a
|
|
11
|
-
# will check the
|
|
12
|
-
# or deserialized the entry in
|
|
13
|
-
# set the
|
|
14
|
-
# that serializes all
|
|
10
|
+
# adding a deserialized_values hash. The reader method for serialized columns
|
|
11
|
+
# will check the deserialized_values for the value, return it if present,
|
|
12
|
+
# or deserialized the entry in values and return it. The writer method will
|
|
13
|
+
# set the deserialized_values entry. This plugin adds a before_save hook
|
|
14
|
+
# that serializes all deserialized_values to values.
|
|
15
15
|
#
|
|
16
16
|
# You can specify the serialization format as a pair of serializer/deserializer
|
|
17
17
|
# callable objects. You can also specify the serialization format as a single
|
|
@@ -97,16 +97,9 @@ module Sequel
|
|
|
97
97
|
end
|
|
98
98
|
register_format(:marshal, lambda{|v| [Marshal.dump(v)].pack('m')},
|
|
99
99
|
lambda do |v|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
begin
|
|
104
|
-
# Backwards compatibility for unpacked marshal output.
|
|
105
|
-
Marshal.load(v)
|
|
106
|
-
rescue
|
|
107
|
-
raise e
|
|
108
|
-
end
|
|
109
|
-
end
|
|
100
|
+
# Handle unpacked marshalled data for backwards compat
|
|
101
|
+
v = v.unpack('m')[0] unless v[0..1] == "\x04\x08"
|
|
102
|
+
Marshal.load(v)
|
|
110
103
|
end)
|
|
111
104
|
register_format(:yaml, lambda(&:to_yaml), lambda{|v| YAML.load(v)})
|
|
112
105
|
register_format(:json, lambda{|v| Sequel.object_to_json(v)}, lambda{|v| Sequel.parse_json(v)})
|
|
@@ -156,6 +149,7 @@ module Sequel
|
|
|
156
149
|
# The columns that will be serialized. This is only for
|
|
157
150
|
# backwards compatibility, use serialization_map in new code.
|
|
158
151
|
def serialized_columns
|
|
152
|
+
Sequel::Deprecation.deprecate("#{self}.serialized_columns in the serialization plugin", "Use #{self}.serialization_map.keys instead")
|
|
159
153
|
serialization_map.keys
|
|
160
154
|
end
|
|
161
155
|
|
|
@@ -95,7 +95,7 @@ module Sequel
|
|
|
95
95
|
end
|
|
96
96
|
end
|
|
97
97
|
km.each do |k,v|
|
|
98
|
-
h[k.to_s] = [
|
|
98
|
+
h[k.to_s] = [] unless h.key?(k.to_s)
|
|
99
99
|
h[k.to_s].push( *Array(v) )
|
|
100
100
|
end
|
|
101
101
|
h
|
|
@@ -111,7 +111,7 @@ module Sequel
|
|
|
111
111
|
end
|
|
112
112
|
end
|
|
113
113
|
sti_model_map.each do |k,v|
|
|
114
|
-
h[v.to_s] = [
|
|
114
|
+
h[v.to_s] = [] unless h.key?(v.to_s)
|
|
115
115
|
h[v.to_s] << k
|
|
116
116
|
end
|
|
117
117
|
h
|
|
@@ -182,7 +182,12 @@ module Sequel
|
|
|
182
182
|
# Return an instance of the class specified by sti_key,
|
|
183
183
|
# used by the row_proc.
|
|
184
184
|
def sti_load(r)
|
|
185
|
-
|
|
185
|
+
sti_class_from_sti_key(r[sti_key]).call(r)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Return the sti class based on one of the keys from sti_model_map.
|
|
189
|
+
def sti_class_from_sti_key(key)
|
|
190
|
+
sti_class(sti_model_map[key])
|
|
186
191
|
end
|
|
187
192
|
|
|
188
193
|
# Make sure that all subclasses of the parent class correctly include
|
|
@@ -57,11 +57,12 @@ module Sequel
|
|
|
57
57
|
# Check all entries in the values hash. If any of the keys are not columns,
|
|
58
58
|
# move the entry into the noncolumn_values hash.
|
|
59
59
|
def split_noncolumn_values
|
|
60
|
-
@values.keys
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
cols = (@values.keys - columns)
|
|
61
|
+
return self if cols.empty?
|
|
62
|
+
|
|
63
|
+
nc = @noncolumn_values ||= {}
|
|
64
|
+
vals = @values
|
|
65
|
+
cols.each{|k| nc[k] = vals.delete(k)}
|
|
65
66
|
self
|
|
66
67
|
end
|
|
67
68
|
end
|
|
@@ -26,6 +26,7 @@ module Sequel
|
|
|
26
26
|
# * Model.each
|
|
27
27
|
# * Model.count (without an argument or block)
|
|
28
28
|
# * Model.map
|
|
29
|
+
# * Model.as_hash
|
|
29
30
|
# * Model.to_hash
|
|
30
31
|
# * Model.to_hash_groups
|
|
31
32
|
#
|
|
@@ -127,41 +128,46 @@ module Sequel
|
|
|
127
128
|
Plugins.inherited_instance_variables(self, :@static_cache_frozen=>nil)
|
|
128
129
|
|
|
129
130
|
# Use the cache instead of a query to get the results.
|
|
130
|
-
def
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
def as_hash(key_column = nil, value_column = nil, opts = OPTS)
|
|
132
|
+
if key_column.nil? && value_column.nil?
|
|
133
|
+
if @static_cache_frozen && !opts[:hash]
|
|
134
|
+
return Hash[cache]
|
|
135
|
+
else
|
|
136
|
+
key_column = primary_key
|
|
137
|
+
end
|
|
136
138
|
end
|
|
137
|
-
end
|
|
138
139
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
140
|
+
h = opts[:hash] || {}
|
|
141
|
+
if value_column
|
|
142
|
+
if value_column.is_a?(Array)
|
|
143
|
+
if key_column.is_a?(Array)
|
|
144
|
+
@all.each{|r| h[r.values.values_at(*key_column)] = r.values.values_at(*value_column)}
|
|
145
|
+
else
|
|
146
|
+
@all.each{|r| h[r[key_column]] = r.values.values_at(*value_column)}
|
|
147
|
+
end
|
|
144
148
|
else
|
|
145
|
-
|
|
149
|
+
if key_column.is_a?(Array)
|
|
150
|
+
@all.each{|r| h[r.values.values_at(*key_column)] = r[value_column]}
|
|
151
|
+
else
|
|
152
|
+
@all.each{|r| h[r[key_column]] = r[value_column]}
|
|
153
|
+
end
|
|
146
154
|
end
|
|
155
|
+
elsif key_column.is_a?(Array)
|
|
156
|
+
@all.each{|r| h[r.values.values_at(*key_column)] = static_cache_object(r)}
|
|
147
157
|
else
|
|
148
|
-
|
|
149
|
-
@all.each{|r| h[r.values.values_at(*key_column)] = r[value_column]}
|
|
150
|
-
else
|
|
151
|
-
@all.each{|r| h[r[key_column]] = r[value_column]}
|
|
152
|
-
end
|
|
158
|
+
@all.each{|r| h[r[key_column]] = static_cache_object(r)}
|
|
153
159
|
end
|
|
154
|
-
|
|
155
|
-
@all.each{|r| h[r.values.values_at(*key_column)] = static_cache_object(r)}
|
|
156
|
-
else
|
|
157
|
-
@all.each{|r| h[r[key_column]] = static_cache_object(r)}
|
|
160
|
+
h
|
|
158
161
|
end
|
|
159
|
-
|
|
162
|
+
|
|
163
|
+
# Alias of as_hash for backwards compatibility.
|
|
164
|
+
def to_hash(*a)
|
|
165
|
+
as_hash(*a)
|
|
160
166
|
end
|
|
161
167
|
|
|
162
168
|
# Use the cache instead of a query to get the results
|
|
163
|
-
def to_hash_groups(key_column, value_column = nil)
|
|
164
|
-
h = {}
|
|
169
|
+
def to_hash_groups(key_column, value_column = nil, opts = OPTS)
|
|
170
|
+
h = opts[:hash] || {}
|
|
165
171
|
if value_column
|
|
166
172
|
if value_column.is_a?(Array)
|
|
167
173
|
if key_column.is_a?(Array)
|
|
@@ -13,7 +13,9 @@ module Sequel
|
|
|
13
13
|
# Album.plugin :subset_conditions
|
|
14
14
|
#
|
|
15
15
|
# # This will now create a published_conditions method
|
|
16
|
-
# Album.
|
|
16
|
+
# Album.dataset_module do
|
|
17
|
+
# subset :published, :published => true
|
|
18
|
+
# end
|
|
17
19
|
#
|
|
18
20
|
# Album.where(Album.published_conditions).sql
|
|
19
21
|
# # SELECT * FROM albums WHERE (published IS TRUE)
|
|
@@ -32,7 +32,7 @@ module Sequel
|
|
|
32
32
|
# has no explicit selection, select table.* from that table.
|
|
33
33
|
def convert_input_dataset(ds)
|
|
34
34
|
ds = super
|
|
35
|
-
if !ds.opts[:select] && (from = ds.opts[:from]) && from.length == 1 && !ds.opts[:join]
|
|
35
|
+
if !ds.opts[:select] && (from = ds.opts[:from]) && from.length == 1 && !ds.opts[:join] # SEQUEL5: Only !ds.opts[:select]
|
|
36
36
|
ds = ds.select_all(ds.first_source)
|
|
37
37
|
end
|
|
38
38
|
ds
|
data/lib/sequel/plugins/touch.rb
CHANGED
|
@@ -31,6 +31,7 @@ module Sequel
|
|
|
31
31
|
module Touch
|
|
32
32
|
# The default column to update when touching
|
|
33
33
|
TOUCH_COLUMN_DEFAULT = :updated_at
|
|
34
|
+
Sequel::Deprecation.deprecate_constant(self, :TOUCH_COLUMN_DEFAULT)
|
|
34
35
|
|
|
35
36
|
def self.apply(model, opts=OPTS)
|
|
36
37
|
model.instance_variable_set(:@touched_associations, {})
|
|
@@ -46,7 +47,7 @@ module Sequel
|
|
|
46
47
|
# If a hash is used, the value is used as the column to update.
|
|
47
48
|
# :column :: The column to modify when touching a model instance.
|
|
48
49
|
def self.configure(model, opts=OPTS)
|
|
49
|
-
model.touch_column = opts[:column] ||
|
|
50
|
+
model.touch_column = opts[:column] || :updated_at if opts[:column] || !model.touch_column
|
|
50
51
|
model.touch_associations(opts[:associations]) if opts[:associations]
|
|
51
52
|
end
|
|
52
53
|
|
|
@@ -136,10 +137,11 @@ module Sequel
|
|
|
136
137
|
# Can't update all values at once, so update each instance individually.
|
|
137
138
|
# Instead if doing a simple save, update via the instance's dataset,
|
|
138
139
|
# to avoid going into an infinite loop in some cases.
|
|
139
|
-
send(
|
|
140
|
+
send(assoc).each{|x| x.this.update(column=>touch_association_value)}
|
|
140
141
|
else
|
|
141
142
|
# Update all values at once for performance reasons.
|
|
142
143
|
ds.update(column=>touch_association_value)
|
|
144
|
+
associations.delete(assoc)
|
|
143
145
|
end
|
|
144
146
|
end
|
|
145
147
|
end
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# frozen-string-literal: true
|
|
2
2
|
|
|
3
3
|
module Sequel
|
|
4
|
-
extension :blank
|
|
5
|
-
|
|
6
4
|
module Plugins
|
|
7
5
|
# Sequel's built-in validation_class_methods plugin adds backwards compatibility
|
|
8
6
|
# for the legacy class-level validation methods (e.g. validates_presence_of :column).
|
|
@@ -11,7 +9,7 @@ module Sequel
|
|
|
11
9
|
# as it is less complex and more flexible. However, this plugin provides reflection
|
|
12
10
|
# support, since it is class-level, while the instance-level validation_helpers
|
|
13
11
|
# plugin does not.
|
|
14
|
-
#
|
|
12
|
+
#
|
|
15
13
|
# Usage:
|
|
16
14
|
#
|
|
17
15
|
# # Add the validation class methods to all model subclasses (called before loading subclasses)
|
|
@@ -118,7 +116,7 @@ module Sequel
|
|
|
118
116
|
validations.each do |att, procs|
|
|
119
117
|
v = case att
|
|
120
118
|
when Array
|
|
121
|
-
att.
|
|
119
|
+
att.map{|a| o.get_column_value(a)}
|
|
122
120
|
else
|
|
123
121
|
o.get_column_value(att)
|
|
124
122
|
end
|
|
@@ -194,11 +192,12 @@ module Sequel
|
|
|
194
192
|
# :tag :: The tag to use for this validation.
|
|
195
193
|
def validates_each(*atts, &block)
|
|
196
194
|
opts = extract_options!(atts)
|
|
195
|
+
blank_meth = db.method(:blank_object?).to_proc
|
|
197
196
|
blk = if (i = opts[:if]) || (am = opts[:allow_missing]) || (an = opts[:allow_nil]) || (ab = opts[:allow_blank])
|
|
198
197
|
proc do |o,a,v|
|
|
199
198
|
next if i && !validation_if_proc(o, i)
|
|
200
199
|
next if an && Array(v).all?(&:nil?)
|
|
201
|
-
next if ab && Array(v).all?(
|
|
200
|
+
next if ab && Array(v).all?(&blank_meth)
|
|
202
201
|
next if am && Array(a).all?{|x| !o.values.has_key?(x)}
|
|
203
202
|
block.call(o,a,v)
|
|
204
203
|
end
|
|
@@ -317,7 +316,7 @@ module Sequel
|
|
|
317
316
|
reflect_validation(:presence, opts, atts)
|
|
318
317
|
atts << opts
|
|
319
318
|
validates_each(*atts) do |o, a, v|
|
|
320
|
-
o.errors.add(a, opts[:message]) if
|
|
319
|
+
o.errors.add(a, opts[:message]) if db.send(:blank_object?, v) && v != false
|
|
321
320
|
end
|
|
322
321
|
end
|
|
323
322
|
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module Sequel
|
|
4
4
|
module Plugins
|
|
5
|
-
# The validation_helpers plugin contains
|
|
6
|
-
#
|
|
5
|
+
# The validation_helpers plugin contains validate_* methods designed to be called inside Model#validate
|
|
6
|
+
# to perform validations:
|
|
7
7
|
#
|
|
8
8
|
# Sequel::Model.plugin :validation_helpers
|
|
9
9
|
# class Album < Sequel::Model
|
|
@@ -19,9 +19,7 @@ module Sequel
|
|
|
19
19
|
# atts :: Single attribute symbol or an array of attribute symbols specifying the
|
|
20
20
|
# attribute(s) to validate.
|
|
21
21
|
# Options:
|
|
22
|
-
# :allow_blank :: Whether to skip the validation if the value is blank.
|
|
23
|
-
# make sure all objects respond to blank if you use this option, which you can do by:
|
|
24
|
-
# Sequel.extension :blank
|
|
22
|
+
# :allow_blank :: Whether to skip the validation if the value is blank.
|
|
25
23
|
# :allow_missing :: Whether to skip the validation if the attribute isn't a key in the
|
|
26
24
|
# values hash. This is different from allow_nil, because Sequel only sends the attributes
|
|
27
25
|
# in the values when doing an insert or update. If the attribute is not present, Sequel
|
|
@@ -92,6 +90,8 @@ module Sequel
|
|
|
92
90
|
:presence=>{:message=>lambda{"is not present"}},
|
|
93
91
|
:unique=>{:message=>lambda{'is already taken'}}
|
|
94
92
|
}
|
|
93
|
+
DEFAULT__OPTIONS = DEFAULT_OPTIONS
|
|
94
|
+
Sequel::Deprecation.deprecate_constant(self, :DEFAULT_OPTIONS)
|
|
95
95
|
|
|
96
96
|
module InstanceMethods
|
|
97
97
|
# Check that the attribute values are the given exact length.
|
|
@@ -131,7 +131,13 @@ module Sequel
|
|
|
131
131
|
# Accepts a :nil_message option that is the error message to use when the
|
|
132
132
|
# value is nil instead of being too long.
|
|
133
133
|
def validates_max_length(max, atts, opts=OPTS)
|
|
134
|
-
validatable_attributes_for_type(:max_length, atts, opts)
|
|
134
|
+
validatable_attributes_for_type(:max_length, atts, opts) do |a,v,m|
|
|
135
|
+
if v.nil?
|
|
136
|
+
validation_error_message(opts[:nil_message] || default_validation_helpers_options(:max_length)[:nil_message])
|
|
137
|
+
elsif v.length > max
|
|
138
|
+
validation_error_message(m, max)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
135
141
|
end
|
|
136
142
|
|
|
137
143
|
# Check that the attribute values are not shorter than the given min length.
|
|
@@ -270,7 +276,7 @@ module Sequel
|
|
|
270
276
|
# The hash return must include a :message option that is either a
|
|
271
277
|
# proc or string.
|
|
272
278
|
def default_validation_helpers_options(type)
|
|
273
|
-
|
|
279
|
+
DEFAULT__OPTIONS[type]
|
|
274
280
|
end
|
|
275
281
|
|
|
276
282
|
# Skip validating any attribute that matches one of the allow_* options.
|
|
@@ -284,7 +290,7 @@ module Sequel
|
|
|
284
290
|
next if am && !values.has_key?(a)
|
|
285
291
|
v = from_values ? values[a] : get_column_value(a)
|
|
286
292
|
next if an && v.nil?
|
|
287
|
-
next if ab &&
|
|
293
|
+
next if ab && model.db.send(:blank_object?, v)
|
|
288
294
|
if message = yield(a, v, m)
|
|
289
295
|
errors.add(a, message)
|
|
290
296
|
end
|
|
@@ -158,7 +158,7 @@ module Sequel
|
|
|
158
158
|
opts[:builder]
|
|
159
159
|
else
|
|
160
160
|
builder_opts = if opts[:builder_opts]
|
|
161
|
-
opts[:builder_opts]
|
|
161
|
+
Hash[opts[:builder_opts]]
|
|
162
162
|
else
|
|
163
163
|
{}
|
|
164
164
|
end
|
|
@@ -234,10 +234,10 @@ module Sequel
|
|
|
234
234
|
if assocs = opts[:associations]
|
|
235
235
|
assocs = case assocs
|
|
236
236
|
when Symbol
|
|
237
|
-
{assocs=>
|
|
237
|
+
{assocs=>OPTS}
|
|
238
238
|
when Array
|
|
239
239
|
assocs_tmp = {}
|
|
240
|
-
assocs.each{|v| assocs_tmp[v] =
|
|
240
|
+
assocs.each{|v| assocs_tmp[v] = OPTS}
|
|
241
241
|
assocs_tmp
|
|
242
242
|
when Hash
|
|
243
243
|
assocs
|
|
@@ -347,7 +347,7 @@ module Sequel
|
|
|
347
347
|
cols.each do |c|
|
|
348
348
|
attrs = {}
|
|
349
349
|
if types
|
|
350
|
-
attrs[:type] = db_schema.fetch(c,
|
|
350
|
+
attrs[:type] = db_schema.fetch(c, OPTS)[:type]
|
|
351
351
|
end
|
|
352
352
|
v = vals[c]
|
|
353
353
|
if v.nil?
|
data/lib/sequel/sql.rb
CHANGED
|
@@ -1030,10 +1030,13 @@ module Sequel
|
|
|
1030
1030
|
# The expression to alias
|
|
1031
1031
|
attr_reader :expression
|
|
1032
1032
|
|
|
1033
|
-
# The alias to use for the expression
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1033
|
+
# The alias to use for the expression
|
|
1034
|
+
attr_reader :alias
|
|
1035
|
+
|
|
1036
|
+
def aliaz
|
|
1037
|
+
Sequel::Deprecation.deprecate("Sequel::SQL::AliasedExpression#aliaz", "Use #alias instead")
|
|
1038
|
+
self.alias
|
|
1039
|
+
end
|
|
1037
1040
|
|
|
1038
1041
|
# The columns aliases to use, for when the aliased expression is
|
|
1039
1042
|
# a record or set of records (such as a dataset).
|
|
@@ -1042,7 +1045,7 @@ module Sequel
|
|
|
1042
1045
|
# Create an object with the given expression and alias.
|
|
1043
1046
|
def initialize(expression, aliaz, columns=nil)
|
|
1044
1047
|
@expression = expression
|
|
1045
|
-
@
|
|
1048
|
+
@alias = aliaz
|
|
1046
1049
|
@columns = columns
|
|
1047
1050
|
freeze
|
|
1048
1051
|
end
|
|
@@ -1150,7 +1153,7 @@ module Sequel
|
|
|
1150
1153
|
when BooleanExpression
|
|
1151
1154
|
case op = ce.op
|
|
1152
1155
|
when :AND, :OR
|
|
1153
|
-
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.
|
|
1156
|
+
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.map{|a| BooleanExpression.invert(a)})
|
|
1154
1157
|
else
|
|
1155
1158
|
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.dup)
|
|
1156
1159
|
end
|
|
@@ -1359,7 +1362,11 @@ module Sequel
|
|
|
1359
1362
|
|
|
1360
1363
|
# The SQL function to call
|
|
1361
1364
|
attr_reader :name
|
|
1362
|
-
|
|
1365
|
+
|
|
1366
|
+
def f
|
|
1367
|
+
Sequel::Deprecation.deprecate("Sequel::SQL::Function#f", "Use #name instead")
|
|
1368
|
+
name
|
|
1369
|
+
end
|
|
1363
1370
|
|
|
1364
1371
|
# The array of arguments to pass to the function (may be blank)
|
|
1365
1372
|
attr_reader :args
|
|
@@ -1764,7 +1771,7 @@ module Sequel
|
|
|
1764
1771
|
def self.like(l, *ces)
|
|
1765
1772
|
l, lre, lci = like_element(l)
|
|
1766
1773
|
lci = (ces.last.is_a?(Hash) ? ces.pop : {})[:case_insensitive] ? true : lci
|
|
1767
|
-
ces.
|
|
1774
|
+
ces.map! do |ce|
|
|
1768
1775
|
r, rre, rci = like_element(ce)
|
|
1769
1776
|
BooleanExpression.new(LIKE_MAP[[lre||rre, lci||rci]], l, r)
|
|
1770
1777
|
end
|
|
@@ -1917,7 +1924,9 @@ module Sequel
|
|
|
1917
1924
|
# For a more detailed explanation, see the {Virtual Rows guide}[rdoc-ref:doc/virtual_rows.rdoc].
|
|
1918
1925
|
class VirtualRow < BasicObject
|
|
1919
1926
|
QUESTION_MARK = LiteralString.new('?').freeze
|
|
1927
|
+
Sequel::Deprecation.deprecate_constant(self, :QUESTION_MARK)
|
|
1920
1928
|
DOUBLE_UNDERSCORE = '__'.freeze
|
|
1929
|
+
Sequel::Deprecation.deprecate_constant(self, :DOUBLE_UNDERSCORE)
|
|
1921
1930
|
|
|
1922
1931
|
include OperatorBuilders
|
|
1923
1932
|
|
|
@@ -1972,7 +1981,7 @@ module Sequel
|
|
|
1972
1981
|
end
|
|
1973
1982
|
elsif args.empty?
|
|
1974
1983
|
if split = Sequel.split_symbols?
|
|
1975
|
-
table, column = m.to_s.split(
|
|
1984
|
+
table, column = m.to_s.split('__', 2)
|
|
1976
1985
|
if column && split == :deprecated
|
|
1977
1986
|
Sequel::Deprecation.deprecate("Splitting virtual row method names", "Either set Sequel.split_symbols = true, or change #{m.inspect} to #{table}[:#{column}]")
|
|
1978
1987
|
end
|
data/lib/sequel/version.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Sequel
|
|
|
5
5
|
MAJOR = 4
|
|
6
6
|
# The minor version of Sequel. Bumped for every non-patch level
|
|
7
7
|
# release, generally around once a month.
|
|
8
|
-
MINOR =
|
|
8
|
+
MINOR = 49
|
|
9
9
|
# The tiny version of Sequel. Usually 0, only bumped for bugfix
|
|
10
10
|
# releases that fix regressions from previous versions.
|
|
11
11
|
TINY = 0
|