sequel 4.41.0 → 4.42.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 +98 -0
- data/README.rdoc +23 -10
- data/doc/active_record.rdoc +4 -4
- data/doc/advanced_associations.rdoc +2 -2
- data/doc/association_basics.rdoc +5 -2
- data/doc/cheat_sheet.rdoc +3 -3
- data/doc/core_extensions.rdoc +2 -2
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/dataset_filtering.rdoc +1 -1
- data/doc/migration.rdoc +19 -1
- data/doc/prepared_statements.rdoc +2 -2
- data/doc/release_notes/4.42.0.txt +221 -0
- data/doc/testing.rdoc +3 -1
- data/lib/sequel/adapters/ado/access.rb +0 -1
- data/lib/sequel/adapters/ado/mssql.rb +0 -1
- data/lib/sequel/adapters/do/mysql.rb +0 -1
- data/lib/sequel/adapters/do/postgres.rb +0 -1
- data/lib/sequel/adapters/do/sqlite3.rb +0 -1
- data/lib/sequel/adapters/ibmdb.rb +21 -25
- data/lib/sequel/adapters/jdbc.rb +8 -16
- data/lib/sequel/adapters/jdbc/as400.rb +0 -1
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -1
- data/lib/sequel/adapters/jdbc/db2.rb +0 -1
- data/lib/sequel/adapters/jdbc/derby.rb +0 -1
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -1
- data/lib/sequel/adapters/jdbc/h2.rb +0 -1
- data/lib/sequel/adapters/jdbc/hsqldb.rb +0 -1
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -1
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -1
- data/lib/sequel/adapters/jdbc/jtds.rb +0 -1
- data/lib/sequel/adapters/jdbc/mssql.rb +0 -1
- data/lib/sequel/adapters/jdbc/mysql.rb +0 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +0 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -13
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +0 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -1
- data/lib/sequel/adapters/jdbc/sqlserver.rb +3 -4
- data/lib/sequel/adapters/mock.rb +54 -12
- data/lib/sequel/adapters/mysql.rb +1 -1
- data/lib/sequel/adapters/mysql2.rb +11 -17
- data/lib/sequel/adapters/odbc/mssql.rb +0 -1
- data/lib/sequel/adapters/oracle.rb +8 -20
- data/lib/sequel/adapters/postgres.rb +11 -29
- data/lib/sequel/adapters/shared/access.rb +5 -12
- data/lib/sequel/adapters/shared/cubrid.rb +4 -13
- data/lib/sequel/adapters/shared/db2.rb +4 -2
- data/lib/sequel/adapters/shared/firebird.rb +2 -4
- data/lib/sequel/adapters/shared/informix.rb +4 -2
- data/lib/sequel/adapters/shared/mssql.rb +3 -5
- data/lib/sequel/adapters/shared/mysql.rb +4 -14
- data/lib/sequel/adapters/shared/oracle.rb +1 -3
- data/lib/sequel/adapters/shared/postgres.rb +16 -38
- data/lib/sequel/adapters/shared/progress.rb +0 -2
- data/lib/sequel/adapters/shared/sqlanywhere.rb +0 -2
- data/lib/sequel/adapters/shared/sqlite.rb +20 -16
- data/lib/sequel/adapters/sqlite.rb +8 -20
- data/lib/sequel/adapters/swift/mysql.rb +0 -1
- data/lib/sequel/adapters/swift/postgres.rb +0 -1
- data/lib/sequel/adapters/swift/sqlite.rb +0 -1
- data/lib/sequel/adapters/tinytds.rb +4 -12
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -2
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +11 -34
- data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +26 -0
- data/lib/sequel/ast_transformer.rb +2 -2
- data/lib/sequel/database/dataset.rb +1 -1
- data/lib/sequel/database/dataset_defaults.rb +0 -66
- data/lib/sequel/database/features.rb +6 -0
- data/lib/sequel/database/misc.rb +31 -17
- data/lib/sequel/database/query.rb +7 -4
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset.rb +8 -8
- data/lib/sequel/dataset/actions.rb +140 -46
- data/lib/sequel/dataset/features.rb +1 -5
- data/lib/sequel/dataset/graph.rb +7 -8
- data/lib/sequel/dataset/misc.rb +127 -56
- data/lib/sequel/dataset/mutation.rb +9 -20
- data/lib/sequel/dataset/placeholder_literalizer.rb +10 -1
- data/lib/sequel/dataset/prepared_statements.rb +102 -46
- data/lib/sequel/dataset/query.rb +155 -72
- data/lib/sequel/dataset/sql.rb +26 -9
- data/lib/sequel/extensions/columns_introspection.rb +3 -1
- data/lib/sequel/extensions/core_extensions.rb +5 -5
- data/lib/sequel/extensions/core_refinements.rb +5 -5
- data/lib/sequel/extensions/duplicate_columns_handler.rb +4 -2
- data/lib/sequel/extensions/freeze_datasets.rb +69 -0
- data/lib/sequel/extensions/identifier_mangling.rb +196 -0
- data/lib/sequel/extensions/looser_typecasting.rb +11 -7
- data/lib/sequel/extensions/migration.rb +1 -1
- data/lib/sequel/extensions/null_dataset.rb +5 -2
- data/lib/sequel/extensions/pagination.rb +42 -23
- data/lib/sequel/extensions/pg_enum.rb +3 -3
- data/lib/sequel/extensions/query.rb +3 -3
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +15 -8
- data/lib/sequel/model/associations.rb +25 -8
- data/lib/sequel/model/base.rb +88 -29
- data/lib/sequel/model/dataset_module.rb +37 -0
- data/lib/sequel/plugins/association_pks.rb +4 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/constraint_validations.rb +1 -2
- data/lib/sequel/plugins/csv_serializer.rb +2 -2
- data/lib/sequel/plugins/dataset_associations.rb +8 -8
- data/lib/sequel/plugins/eager_each.rb +2 -2
- data/lib/sequel/plugins/instance_filters.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +2 -2
- data/lib/sequel/plugins/lazy_attributes.rb +1 -1
- data/lib/sequel/plugins/list.rb +4 -4
- data/lib/sequel/plugins/prepared_statements.rb +2 -4
- data/lib/sequel/plugins/prepared_statements_associations.rb +1 -3
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +13 -13
- data/lib/sequel/plugins/sharding.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +9 -4
- data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/plugins/validation_helpers.rb +1 -1
- data/lib/sequel/plugins/xml_serializer.rb +2 -2
- data/lib/sequel/sql.rb +69 -36
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +10 -0
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +4 -5
- data/spec/adapters/mysql_spec.rb +9 -9
- data/spec/adapters/postgres_spec.rb +67 -68
- data/spec/adapters/spec_helper.rb +6 -1
- data/spec/adapters/sqlite_spec.rb +29 -15
- data/spec/core/connection_pool_spec.rb +14 -14
- data/spec/core/database_spec.rb +38 -180
- data/spec/core/dataset_mutation_spec.rb +253 -0
- data/spec/core/dataset_spec.rb +394 -537
- data/spec/core/expression_filters_spec.rb +34 -32
- data/spec/core/mock_adapter_spec.rb +27 -35
- data/spec/core/placeholder_literalizer_spec.rb +2 -4
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +1 -2
- data/spec/core_extensions_spec.rb +22 -29
- data/spec/extensions/active_model_spec.rb +6 -6
- data/spec/extensions/association_dependencies_spec.rb +2 -2
- data/spec/extensions/blacklist_security_spec.rb +3 -3
- data/spec/extensions/boolean_readers_spec.rb +12 -12
- data/spec/extensions/caching_spec.rb +13 -10
- data/spec/extensions/class_table_inheritance_spec.rb +38 -43
- data/spec/extensions/column_conflicts_spec.rb +1 -3
- data/spec/extensions/columns_introspection_spec.rb +2 -3
- data/spec/extensions/composition_spec.rb +5 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +5 -5
- data/spec/extensions/constraint_validations_spec.rb +14 -8
- data/spec/extensions/core_refinements_spec.rb +22 -29
- data/spec/extensions/csv_serializer_spec.rb +7 -6
- data/spec/extensions/date_arithmetic_spec.rb +15 -15
- data/spec/extensions/defaults_setter_spec.rb +2 -2
- data/spec/extensions/delay_add_association_spec.rb +1 -1
- data/spec/extensions/dirty_spec.rb +19 -10
- data/spec/extensions/duplicate_columns_handler_spec.rb +12 -18
- data/spec/extensions/eager_each_spec.rb +12 -16
- data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
- data/spec/extensions/eval_inspect_spec.rb +4 -3
- data/spec/extensions/force_encoding_spec.rb +12 -12
- data/spec/extensions/freeze_datasets_spec.rb +31 -0
- data/spec/extensions/graph_each_spec.rb +6 -18
- data/spec/extensions/hook_class_methods_spec.rb +7 -7
- data/spec/extensions/identifier_mangling_spec.rb +307 -0
- data/spec/extensions/instance_filters_spec.rb +5 -6
- data/spec/extensions/instance_hooks_spec.rb +12 -12
- data/spec/extensions/json_serializer_spec.rb +12 -15
- data/spec/extensions/lazy_attributes_spec.rb +4 -4
- data/spec/extensions/list_spec.rb +19 -21
- data/spec/extensions/many_through_many_spec.rb +108 -163
- data/spec/extensions/meta_def_spec.rb +7 -2
- data/spec/extensions/migration_spec.rb +10 -12
- data/spec/extensions/mssql_optimistic_locking_spec.rb +4 -3
- data/spec/extensions/named_timezones_spec.rb +4 -3
- data/spec/extensions/nested_attributes_spec.rb +2 -2
- data/spec/extensions/null_dataset_spec.rb +17 -12
- data/spec/extensions/optimistic_locking_spec.rb +4 -5
- data/spec/extensions/pagination_spec.rb +8 -10
- data/spec/extensions/pg_array_associations_spec.rb +28 -27
- data/spec/extensions/pg_array_ops_spec.rb +2 -1
- data/spec/extensions/pg_array_spec.rb +6 -2
- data/spec/extensions/pg_enum_spec.rb +5 -3
- data/spec/extensions/pg_hstore_ops_spec.rb +3 -1
- data/spec/extensions/pg_hstore_spec.rb +7 -6
- data/spec/extensions/pg_inet_ops_spec.rb +2 -1
- data/spec/extensions/pg_inet_spec.rb +2 -1
- data/spec/extensions/pg_interval_spec.rb +2 -1
- data/spec/extensions/pg_json_ops_spec.rb +2 -1
- data/spec/extensions/pg_json_spec.rb +6 -3
- data/spec/extensions/pg_loose_count_spec.rb +1 -0
- data/spec/extensions/pg_range_ops_spec.rb +3 -1
- data/spec/extensions/pg_range_spec.rb +9 -5
- data/spec/extensions/pg_row_ops_spec.rb +2 -1
- data/spec/extensions/pg_row_plugin_spec.rb +4 -6
- data/spec/extensions/pg_row_spec.rb +5 -3
- data/spec/extensions/pg_static_cache_updater_spec.rb +2 -1
- data/spec/extensions/pg_typecast_on_load_spec.rb +1 -1
- data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
- data/spec/extensions/prepared_statements_spec.rb +12 -11
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +8 -5
- data/spec/extensions/rcte_tree_spec.rb +39 -39
- data/spec/extensions/round_timestamps_spec.rb +2 -2
- data/spec/extensions/schema_dumper_spec.rb +3 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/scissors_spec.rb +1 -2
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +30 -17
- data/spec/extensions/serialization_modification_detection_spec.rb +2 -2
- data/spec/extensions/serialization_spec.rb +15 -13
- data/spec/extensions/set_overrides_spec.rb +14 -8
- data/spec/extensions/sharding_spec.rb +9 -18
- data/spec/extensions/shared_caching_spec.rb +3 -4
- data/spec/extensions/single_table_inheritance_spec.rb +11 -11
- data/spec/extensions/skip_create_refresh_spec.rb +2 -1
- data/spec/extensions/spec_helper.rb +1 -1
- data/spec/extensions/split_values_spec.rb +2 -2
- data/spec/extensions/sql_comments_spec.rb +6 -0
- data/spec/extensions/static_cache_spec.rb +7 -9
- data/spec/extensions/string_agg_spec.rb +30 -29
- data/spec/extensions/tactical_eager_loading_spec.rb +4 -5
- data/spec/extensions/thread_local_timezones_spec.rb +2 -2
- data/spec/extensions/timestamps_spec.rb +28 -3
- data/spec/extensions/to_dot_spec.rb +1 -2
- data/spec/extensions/tree_spec.rb +33 -29
- data/spec/extensions/typecast_on_load_spec.rb +1 -1
- data/spec/extensions/unlimited_update_spec.rb +1 -0
- data/spec/extensions/update_primary_key_spec.rb +11 -7
- data/spec/extensions/update_refresh_spec.rb +1 -1
- data/spec/extensions/uuid_spec.rb +0 -1
- data/spec/extensions/validate_associated_spec.rb +1 -1
- data/spec/extensions/validation_class_methods_spec.rb +10 -10
- data/spec/extensions/validation_helpers_spec.rb +10 -10
- data/spec/extensions/xml_serializer_spec.rb +7 -3
- data/spec/integration/associations_test.rb +31 -31
- data/spec/integration/dataset_test.rb +17 -19
- data/spec/integration/eager_loader_test.rb +24 -24
- data/spec/integration/model_test.rb +6 -6
- data/spec/integration/plugin_test.rb +43 -43
- data/spec/integration/prepared_statement_test.rb +6 -6
- data/spec/integration/schema_test.rb +63 -52
- data/spec/integration/spec_helper.rb +6 -1
- data/spec/integration/transaction_test.rb +13 -13
- data/spec/model/association_reflection_spec.rb +17 -17
- data/spec/model/associations_spec.rb +101 -96
- data/spec/model/base_spec.rb +175 -49
- data/spec/model/class_dataset_methods_spec.rb +5 -9
- data/spec/model/dataset_methods_spec.rb +5 -5
- data/spec/model/eager_loading_spec.rb +209 -235
- data/spec/model/hooks_spec.rb +15 -15
- data/spec/model/model_spec.rb +28 -21
- data/spec/model/plugins_spec.rb +4 -5
- data/spec/model/record_spec.rb +59 -57
- data/spec/model/spec_helper.rb +1 -1
- data/spec/model/validations_spec.rb +6 -6
- data/spec/spec_config.rb +1 -1
- metadata +10 -2
|
@@ -71,11 +71,11 @@ module Sequel
|
|
|
71
71
|
lambda do
|
|
72
72
|
h = {}
|
|
73
73
|
lk.zip(lpk).each{|k, pk| h[k] = get_column_value(pk)}
|
|
74
|
-
_join_table_dataset(opts).
|
|
74
|
+
_join_table_dataset(opts).where(h).select_map(rk)
|
|
75
75
|
end
|
|
76
76
|
else
|
|
77
77
|
lambda do
|
|
78
|
-
_join_table_dataset(opts).
|
|
78
|
+
_join_table_dataset(opts).where(lk=>get_column_value(lpk)).select_map(rk)
|
|
79
79
|
end
|
|
80
80
|
end
|
|
81
81
|
|
|
@@ -91,7 +91,7 @@ module Sequel
|
|
|
91
91
|
lpkv = get_column_value(lpk)
|
|
92
92
|
cond = {lk=>lpkv}
|
|
93
93
|
end
|
|
94
|
-
ds = _join_table_dataset(opts).
|
|
94
|
+
ds = _join_table_dataset(opts).where(cond)
|
|
95
95
|
ds.exclude(rk=>pks).delete
|
|
96
96
|
pks -= ds.select_map(rk)
|
|
97
97
|
lpkv = Array(lpkv)
|
|
@@ -139,7 +139,7 @@ module Sequel
|
|
|
139
139
|
|
|
140
140
|
checked_transaction do
|
|
141
141
|
ds = send(opts.dataset_method)
|
|
142
|
-
ds.unfiltered.
|
|
142
|
+
ds.unfiltered.where(pkh).update(h)
|
|
143
143
|
ds.exclude(pkh).update(nh)
|
|
144
144
|
end
|
|
145
145
|
end
|
|
@@ -280,7 +280,7 @@ module Sequel
|
|
|
280
280
|
@sti_dataset = ds.join(table, pk=>pk).select_append(*sel_app)
|
|
281
281
|
set_dataset(@sti_dataset)
|
|
282
282
|
set_columns(self.columns)
|
|
283
|
-
dataset
|
|
283
|
+
@dataset = @dataset.with_row_proc(lambda{|r| subclass.sti_load(r)})
|
|
284
284
|
(columns - [pk]).each{|a| define_lazy_attribute_getter(a, :dataset=>dataset, :table=>table)}
|
|
285
285
|
|
|
286
286
|
@cti_models += [self]
|
|
@@ -323,7 +323,7 @@ module Sequel
|
|
|
323
323
|
private
|
|
324
324
|
|
|
325
325
|
def cti_this(model)
|
|
326
|
-
use_server(model.cti_instance_dataset.
|
|
326
|
+
use_server(model.cti_instance_dataset.where(model.primary_key_hash(pk)))
|
|
327
327
|
end
|
|
328
328
|
|
|
329
329
|
# Set the sti_key column based on the sti_key_map.
|
|
@@ -117,8 +117,7 @@ module Sequel
|
|
|
117
117
|
end
|
|
118
118
|
|
|
119
119
|
if @dataset
|
|
120
|
-
ds = @dataset.
|
|
121
|
-
ds.quote_identifiers = false
|
|
120
|
+
ds = @dataset.with_quote_identifiers(false)
|
|
122
121
|
table_name = ds.literal(ds.first_source_table)
|
|
123
122
|
reflections = {}
|
|
124
123
|
@constraint_validations = (Sequel.synchronize{hash[table_name]} || []).map{|r| constraint_validation_array(r, reflections)}
|
|
@@ -31,7 +31,7 @@ module Sequel
|
|
|
31
31
|
# all objects in the dataset:
|
|
32
32
|
#
|
|
33
33
|
# Album.to_csv
|
|
34
|
-
# Album.
|
|
34
|
+
# Album.where(:artist_id=>1).to_csv
|
|
35
35
|
#
|
|
36
36
|
# If you have an existing array of model instance you want to convert to
|
|
37
37
|
# CSV, you can call the class to_csv method with the :array option:
|
|
@@ -48,7 +48,7 @@ module Sequel
|
|
|
48
48
|
# The array_from_csv class method exists to parse arrays of model instances
|
|
49
49
|
# from CSV:
|
|
50
50
|
#
|
|
51
|
-
# csv = Album.
|
|
51
|
+
# csv = Album.where(:artist_id=>1).to_csv
|
|
52
52
|
# albums = Album.array_from_csv(csv)
|
|
53
53
|
#
|
|
54
54
|
# These do not necessarily round trip, since doing so would let users
|
|
@@ -12,7 +12,7 @@ module Sequel
|
|
|
12
12
|
# plugin :dataset_associations
|
|
13
13
|
# one_to_many :albums
|
|
14
14
|
# end
|
|
15
|
-
# Artist.
|
|
15
|
+
# Artist.where(id=>1..100).albums
|
|
16
16
|
# # SELECT * FROM albums
|
|
17
17
|
# # WHERE (albums.artist_id IN (
|
|
18
18
|
# # SELECT id FROM artists
|
|
@@ -27,7 +27,7 @@ module Sequel
|
|
|
27
27
|
# As the dataset methods return datasets, you can easily chain the
|
|
28
28
|
# methods to get associated datasets of associated datasets:
|
|
29
29
|
#
|
|
30
|
-
# Artist.
|
|
30
|
+
# Artist.where(id=>1..100).albums.where{name < 'M'}.tags
|
|
31
31
|
# # SELECT tags.* FROM tags
|
|
32
32
|
# # WHERE (tags.id IN (
|
|
33
33
|
# # SELECT albums_tags.tag_id FROM albums
|
|
@@ -83,15 +83,15 @@ module Sequel
|
|
|
83
83
|
sds = opts[:limit] ? self : unordered
|
|
84
84
|
ds = case r[:type]
|
|
85
85
|
when :many_to_one
|
|
86
|
-
ds.
|
|
86
|
+
ds.where(r.qualified_primary_key=>sds.select(*Array(r[:qualified_key])))
|
|
87
87
|
when :one_to_one, :one_to_many
|
|
88
|
-
r.send(:apply_filter_by_associations_limit_strategy, ds.
|
|
88
|
+
r.send(:apply_filter_by_associations_limit_strategy, ds.where(r.qualified_key=>sds.select(*Array(r.qualified_primary_key))))
|
|
89
89
|
when :many_to_many, :one_through_one
|
|
90
90
|
mds = r.associated_class.dataset.
|
|
91
91
|
join(r[:join_table], r[:right_keys].zip(r.right_primary_keys)).
|
|
92
92
|
select(*Array(r.qualified_right_key)).
|
|
93
93
|
where(r.qualify(r.join_table_alias, r[:left_keys])=>sds.select(*r.qualify(model.table_name, r[:left_primary_key_columns])))
|
|
94
|
-
ds.
|
|
94
|
+
ds.where(r.qualified_right_primary_key=>r.send(:apply_filter_by_associations_limit_strategy, mds))
|
|
95
95
|
when :many_through_many, :one_through_many
|
|
96
96
|
fe, *edges = r.edges
|
|
97
97
|
edges << r.final_edge
|
|
@@ -109,11 +109,11 @@ module Sequel
|
|
|
109
109
|
select(*Array(r.qualify(table, left))).
|
|
110
110
|
where(r.qualify(fe[:table], fe[:right])=>sds.select(*r.qualify(model.table_name, r[:left_primary_key_columns])))
|
|
111
111
|
edges.each{|e| mds = mds.join(e[:table], Array(e[:right]).zip(Array(e[:left])))}
|
|
112
|
-
ds.
|
|
112
|
+
ds.where(r.qualified_right_primary_key=>r.send(:apply_filter_by_associations_limit_strategy, mds))
|
|
113
113
|
when :pg_array_to_many
|
|
114
|
-
ds.
|
|
114
|
+
ds.where(Sequel[r.primary_key=>sds.select{Sequel.pg_array_op(r.qualify(r[:model].table_name, r[:key])).unnest}])
|
|
115
115
|
when :many_to_pg_array
|
|
116
|
-
ds.
|
|
116
|
+
ds.where(Sequel.function(:coalesce, Sequel.pg_array_op(r[:key]).overlaps(sds.select{array_agg(r.qualify(r[:model].table_name, r.primary_key))}), false))
|
|
117
117
|
else
|
|
118
118
|
raise Error, "unrecognized association type for association #{name.inspect}: #{r[:type].inspect}"
|
|
119
119
|
end
|
|
@@ -30,9 +30,9 @@ module Sequel
|
|
|
30
30
|
module EagerEach
|
|
31
31
|
module DatasetMethods
|
|
32
32
|
# Don't call #all when attempting to load the columns.
|
|
33
|
-
def columns
|
|
33
|
+
def columns!
|
|
34
34
|
if use_eager_all?
|
|
35
|
-
clone(:all_called=>true).columns
|
|
35
|
+
clone(:all_called=>true).columns!
|
|
36
36
|
else
|
|
37
37
|
super
|
|
38
38
|
end
|
|
@@ -100,7 +100,7 @@ module Sequel
|
|
|
100
100
|
|
|
101
101
|
# Apply the instance filters to the given dataset
|
|
102
102
|
def apply_instance_filters(ds)
|
|
103
|
-
instance_filters.inject(ds){|ds1, i| ds1.
|
|
103
|
+
instance_filters.inject(ds){|ds1, i| ds1.where(*i[0], &i[1])}
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
# Clear the instance filters.
|
|
@@ -55,7 +55,7 @@ module Sequel
|
|
|
55
55
|
# of which return all objects in the dataset:
|
|
56
56
|
#
|
|
57
57
|
# Album.to_json
|
|
58
|
-
# Album.
|
|
58
|
+
# Album.where(:artist_id=>1).to_json(:include=>:tags)
|
|
59
59
|
#
|
|
60
60
|
# If you have an existing array of model instances you want to convert to
|
|
61
61
|
# JSON, you can call the class to_json method with the :array option:
|
|
@@ -72,7 +72,7 @@ module Sequel
|
|
|
72
72
|
# The array_from_json class method exists to parse arrays of model instances
|
|
73
73
|
# from json:
|
|
74
74
|
#
|
|
75
|
-
# json = Album.
|
|
75
|
+
# json = Album.where(:artist_id=>1).to_json
|
|
76
76
|
# albums = Album.array_from_json(json)
|
|
77
77
|
#
|
|
78
78
|
# These does not necessarily round trip, since doing so would let users
|
data/lib/sequel/plugins/list.rb
CHANGED
|
@@ -62,10 +62,10 @@ module Sequel
|
|
|
62
62
|
model.scope_proc = case scope = opts[:scope]
|
|
63
63
|
when Symbol
|
|
64
64
|
model.dataset = model.dataset.order_prepend(scope)
|
|
65
|
-
proc{|obj| obj.model.
|
|
65
|
+
proc{|obj| obj.model.where(scope=>obj.send(scope))}
|
|
66
66
|
when Array
|
|
67
67
|
model.dataset = model.dataset.order_prepend(*scope)
|
|
68
|
-
proc{|obj| obj.model.
|
|
68
|
+
proc{|obj| obj.model.where(scope.map{|s| [s, obj.get_column_value(s)]})}
|
|
69
69
|
else
|
|
70
70
|
scope
|
|
71
71
|
end
|
|
@@ -123,11 +123,11 @@ module Sequel
|
|
|
123
123
|
ds = list_dataset
|
|
124
124
|
op, ds = if target < current
|
|
125
125
|
target = 1 if target < 1
|
|
126
|
-
[:+, ds.
|
|
126
|
+
[:+, ds.where(position_field=>target...current)]
|
|
127
127
|
else
|
|
128
128
|
lp ||= last_position
|
|
129
129
|
target = lp if target > lp
|
|
130
|
-
[:-, ds.
|
|
130
|
+
[:-, ds.where(position_field=>(current + 1)..target)]
|
|
131
131
|
end
|
|
132
132
|
ds.update(position_field => Sequel::SQL::NumericExpression.new(op, position_field, 1))
|
|
133
133
|
update(position_field => target)
|
|
@@ -67,9 +67,7 @@ module Sequel
|
|
|
67
67
|
# Create a prepared statement based on the given dataset with a unique name for the given
|
|
68
68
|
# type of query and values.
|
|
69
69
|
def prepare_statement(ds, type, vals=OPTS)
|
|
70
|
-
|
|
71
|
-
ps.log_sql = true
|
|
72
|
-
ps
|
|
70
|
+
ds.clone(:log_sql=>true).prepare(type, :"smpsp_#{NEXT.call}", vals)
|
|
73
71
|
end
|
|
74
72
|
|
|
75
73
|
# Return a sorted array of columns for use as a hash key.
|
|
@@ -102,7 +100,7 @@ module Sequel
|
|
|
102
100
|
|
|
103
101
|
# Return a prepared statement that can be used to refresh a row to get new column values after insertion.
|
|
104
102
|
def prepared_refresh
|
|
105
|
-
cached_prepared_statement(:fixed, :refresh){prepare_explicit_statement(naked.clone(:server=>dataset.opts.fetch(:server, :default)).
|
|
103
|
+
cached_prepared_statement(:fixed, :refresh){prepare_explicit_statement(naked.clone(:server=>dataset.opts.fetch(:server, :default)).where(prepared_statement_key_array(primary_key)), :first)}
|
|
106
104
|
end
|
|
107
105
|
|
|
108
106
|
# Return an array of two element arrays with the column symbol as the first entry and the
|
|
@@ -77,9 +77,7 @@ module Sequel
|
|
|
77
77
|
end
|
|
78
78
|
ds = ds.bind(h)
|
|
79
79
|
end
|
|
80
|
-
|
|
81
|
-
ps.log_sql = true
|
|
82
|
-
ps
|
|
80
|
+
ds.clone(:log_sql=>true).prepare(opts.returns_array? ? :select : :first, :"smpsap_#{NEXT.call}")
|
|
83
81
|
end
|
|
84
82
|
end
|
|
85
83
|
end
|
|
@@ -33,7 +33,7 @@ module Sequel
|
|
|
33
33
|
# Return a prepared statement that can be used to lookup a row given a dataset for the row matching
|
|
34
34
|
# the primary key.
|
|
35
35
|
def prepared_lookup_dataset(ds)
|
|
36
|
-
cached_prepared_statement(:lookup_sql, ds.sql){prepare_statement(ds.
|
|
36
|
+
cached_prepared_statement(:lookup_sql, ds.sql){prepare_statement(ds.where(prepared_statement_key_array(primary_key).map{|k, v| [SQL::QualifiedIdentifier.new(ds.model.table_name, k), v]}), :first)}
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -56,12 +56,12 @@ module Sequel
|
|
|
56
56
|
#
|
|
57
57
|
# # Eager loading - also populates the :parent and children associations
|
|
58
58
|
# # for all ancestors and descendants
|
|
59
|
-
# Model.
|
|
59
|
+
# Model.where(:id=>[1, 2]).eager(:ancestors, :descendants).all
|
|
60
60
|
#
|
|
61
61
|
# # Eager loading children and grand children
|
|
62
|
-
# Model.
|
|
62
|
+
# Model.where(:id=>[1, 2]).eager(:descendants=>2).all
|
|
63
63
|
# # Eager loading children, grand children, and great grand children
|
|
64
|
-
# Model.
|
|
64
|
+
# Model.where(:id=>[1, 2]).eager(:descendants=>3).all
|
|
65
65
|
#
|
|
66
66
|
# = Options
|
|
67
67
|
#
|
|
@@ -150,11 +150,11 @@ module Sequel
|
|
|
150
150
|
a[:read_only] = true unless a.has_key?(:read_only)
|
|
151
151
|
a[:eager_loader_key] = key
|
|
152
152
|
a[:dataset] ||= proc do
|
|
153
|
-
base_ds = model.
|
|
153
|
+
base_ds = model.where(prkey_array.zip(key_array.map{|k| get_column_value(k)}))
|
|
154
154
|
recursive_ds = model.join(t, key_array.zip(prkey_array))
|
|
155
155
|
if c = a[:conditions]
|
|
156
156
|
(base_ds, recursive_ds) = [base_ds, recursive_ds].collect do |ds|
|
|
157
|
-
(c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.
|
|
157
|
+
(c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.where(*c) : ds.where(c)
|
|
158
158
|
end
|
|
159
159
|
end
|
|
160
160
|
table_alias = model.dataset.schema_and_table(model.table_name)[1].to_sym
|
|
@@ -196,13 +196,13 @@ module Sequel
|
|
|
196
196
|
obj.associations[parent] = nil
|
|
197
197
|
end
|
|
198
198
|
r = model.association_reflection(ancestors)
|
|
199
|
-
base_case = model.
|
|
199
|
+
base_case = model.where(prkey=>id_map.keys).
|
|
200
200
|
select(*ancestor_base_case_columns)
|
|
201
201
|
recursive_case = model.join(t, key_array.zip(prkey_array)).
|
|
202
202
|
select(*recursive_case_columns)
|
|
203
203
|
if c = r[:conditions]
|
|
204
204
|
(base_case, recursive_case) = [base_case, recursive_case].collect do |ds|
|
|
205
|
-
(c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.
|
|
205
|
+
(c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.where(*c) : ds.where(c)
|
|
206
206
|
end
|
|
207
207
|
end
|
|
208
208
|
table_alias = model.dataset.schema_and_table(model.table_name)[1].to_sym
|
|
@@ -245,11 +245,11 @@ module Sequel
|
|
|
245
245
|
d[:read_only] = true unless d.has_key?(:read_only)
|
|
246
246
|
la = d[:level_alias] ||= :x_level_x
|
|
247
247
|
d[:dataset] ||= proc do
|
|
248
|
-
base_ds = model.
|
|
248
|
+
base_ds = model.where(key_array.zip(prkey_array.map{|k| get_column_value(k)}))
|
|
249
249
|
recursive_ds = model.join(t, prkey_array.zip(key_array))
|
|
250
250
|
if c = d[:conditions]
|
|
251
251
|
(base_ds, recursive_ds) = [base_ds, recursive_ds].collect do |ds|
|
|
252
|
-
(c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.
|
|
252
|
+
(c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.where(*c) : ds.where(c)
|
|
253
253
|
end
|
|
254
254
|
end
|
|
255
255
|
table_alias = model.dataset.schema_and_table(model.table_name)[1].to_sym
|
|
@@ -294,21 +294,21 @@ module Sequel
|
|
|
294
294
|
obj.associations[childrena] = []
|
|
295
295
|
end
|
|
296
296
|
r = model.association_reflection(descendants)
|
|
297
|
-
base_case = model.
|
|
297
|
+
base_case = model.where(key=>id_map.keys).
|
|
298
298
|
select(*descendant_base_case_columns)
|
|
299
299
|
recursive_case = model.join(t, prkey_array.zip(key_array)).
|
|
300
300
|
select(*recursive_case_columns)
|
|
301
301
|
if c = r[:conditions]
|
|
302
302
|
(base_case, recursive_case) = [base_case, recursive_case].collect do |ds|
|
|
303
|
-
(c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.
|
|
303
|
+
(c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.where(*c) : ds.where(c)
|
|
304
304
|
end
|
|
305
305
|
end
|
|
306
306
|
if associations.is_a?(Integer)
|
|
307
307
|
level = associations
|
|
308
308
|
no_cache_level = level - 1
|
|
309
309
|
associations = {}
|
|
310
|
-
base_case = base_case.
|
|
311
|
-
recursive_case = recursive_case.
|
|
310
|
+
base_case = base_case.select_append(SQL::AliasedExpression.new(Sequel.cast(0, Integer), la))
|
|
311
|
+
recursive_case = recursive_case.select_append(SQL::AliasedExpression.new(SQL::QualifiedIdentifier.new(t, la) + 1, la)).where(SQL::QualifiedIdentifier.new(t, la) < level - 1)
|
|
312
312
|
end
|
|
313
313
|
table_alias = model.dataset.schema_and_table(model.table_name)[1].to_sym
|
|
314
314
|
ds = model.from(SQL::AliasedExpression.new(t, table_alias)).
|
|
@@ -119,7 +119,8 @@ module Sequel
|
|
|
119
119
|
lambda{|klass| klass.name.to_s}
|
|
120
120
|
end
|
|
121
121
|
@sti_key_chooser = opts[:key_chooser] || lambda{|inst| Array(inst.model.sti_key_map[inst.model]).last }
|
|
122
|
-
|
|
122
|
+
|
|
123
|
+
@dataset = @dataset.with_row_proc(model.method(:sti_load))
|
|
123
124
|
end
|
|
124
125
|
end
|
|
125
126
|
|
|
@@ -158,9 +159,9 @@ module Sequel
|
|
|
158
159
|
key = Array(sti_key_map[subclass]).dup
|
|
159
160
|
sti_subclass_added(key)
|
|
160
161
|
rp = dataset.row_proc
|
|
161
|
-
subclass.set_dataset(sti_dataset.
|
|
162
|
+
subclass.set_dataset(sti_dataset.where(SQL::QualifiedIdentifier.new(sti_dataset.first_source_alias, sti_key)=>Sequel.delay{key}), :inherited=>true)
|
|
162
163
|
subclass.instance_eval do
|
|
163
|
-
dataset
|
|
164
|
+
@dataset = @dataset.with_row_proc(rp)
|
|
164
165
|
@sti_key_array = key
|
|
165
166
|
self.simple_table = nil
|
|
166
167
|
end
|
|
@@ -187,7 +188,11 @@ module Sequel
|
|
|
187
188
|
# If calling set_dataset manually, make sure to set the dataset
|
|
188
189
|
# row proc to one that handles inheritance correctly.
|
|
189
190
|
def set_dataset_row_proc(ds)
|
|
190
|
-
|
|
191
|
+
if @dataset
|
|
192
|
+
ds.with_row_proc(@dataset.row_proc)
|
|
193
|
+
else
|
|
194
|
+
super
|
|
195
|
+
end
|
|
191
196
|
end
|
|
192
197
|
|
|
193
198
|
# Return a class object. If a class is given, return it directly.
|
|
@@ -16,7 +16,7 @@ module Sequel
|
|
|
16
16
|
#
|
|
17
17
|
# Basically, this allows the following code to issue only two queries:
|
|
18
18
|
#
|
|
19
|
-
# Album.
|
|
19
|
+
# Album.where{id<100}.all do |a|
|
|
20
20
|
# a.artists
|
|
21
21
|
# end
|
|
22
22
|
# # SELECT * FROM albums WHERE (id < 100)
|
|
@@ -30,7 +30,7 @@ module Sequel
|
|
|
30
30
|
# objects that the current object was retrieved with:
|
|
31
31
|
#
|
|
32
32
|
# # SELECT * FROM albums WHERE (id < 100)
|
|
33
|
-
# albums = Album.
|
|
33
|
+
# albums = Album.where{id<100}.all
|
|
34
34
|
#
|
|
35
35
|
# # Eagerly load all artists for these albums
|
|
36
36
|
# # SELECT * FROM artists WHERE id IN (...)
|
|
@@ -45,7 +45,7 @@ module Sequel
|
|
|
45
45
|
# You can also use the :eager option to specify dependent associations
|
|
46
46
|
# to eager load:
|
|
47
47
|
#
|
|
48
|
-
# albums = Album.
|
|
48
|
+
# albums = Album.where{id<100}.all
|
|
49
49
|
#
|
|
50
50
|
# # Eager load all artists for these albums, and all albums for those artists
|
|
51
51
|
# # SELECT * FROM artists WHERE id IN (...)
|
|
@@ -54,7 +54,7 @@ module Sequel
|
|
|
54
54
|
#
|
|
55
55
|
# You can also use :eager to specify an eager callback. For example:
|
|
56
56
|
#
|
|
57
|
-
# albums = Album.
|
|
57
|
+
# albums = Album.where{id<100}.all
|
|
58
58
|
#
|
|
59
59
|
# # Eagerly load all artists whose name starts with A-M for these albums
|
|
60
60
|
# # SELECT * FROM artists WHERE name > 'N' AND id IN (...)
|
|
@@ -204,7 +204,7 @@ module Sequel
|
|
|
204
204
|
# must be unique. So if you are doing a soft delete of records, in which
|
|
205
205
|
# the name must be unique, but only for active records:
|
|
206
206
|
#
|
|
207
|
-
# validates_unique(:name){|ds| ds.
|
|
207
|
+
# validates_unique(:name){|ds| ds.where(:active)}
|
|
208
208
|
#
|
|
209
209
|
# You should also add a unique index in the
|
|
210
210
|
# database, as this suffers from a fairly obvious race condition.
|
|
@@ -63,7 +63,7 @@ module Sequel
|
|
|
63
63
|
# of which return all objects in the dataset:
|
|
64
64
|
#
|
|
65
65
|
# Album.to_xml
|
|
66
|
-
# Album.
|
|
66
|
+
# Album.where(:artist_id=>1).to_xml(:include=>:tags)
|
|
67
67
|
#
|
|
68
68
|
# If you have an existing array of model instances you want to convert to
|
|
69
69
|
# XML, you can call the class to_xml method with the :array option:
|
|
@@ -80,7 +80,7 @@ module Sequel
|
|
|
80
80
|
# The array_from_xml class method exists to parse arrays of model instances
|
|
81
81
|
# from xml:
|
|
82
82
|
#
|
|
83
|
-
# xml = Album.
|
|
83
|
+
# xml = Album.where(:artist_id=>1).to_xml
|
|
84
84
|
# albums = Album.array_from_xml(xml)
|
|
85
85
|
#
|
|
86
86
|
# These does not necessarily round trip, since doing so would let users
|