sequel 3.47.0 → 3.48.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +230 -0
- data/README.rdoc +31 -40
- data/Rakefile +1 -14
- data/doc/active_record.rdoc +29 -29
- data/doc/association_basics.rdoc +4 -13
- data/doc/cheat_sheet.rdoc +8 -6
- data/doc/code_order.rdoc +89 -0
- data/doc/core_extensions.rdoc +3 -3
- data/doc/dataset_basics.rdoc +7 -8
- data/doc/dataset_filtering.rdoc +7 -2
- data/doc/mass_assignment.rdoc +2 -3
- data/doc/migration.rdoc +8 -8
- data/doc/model_hooks.rdoc +11 -7
- data/doc/object_model.rdoc +2 -2
- data/doc/opening_databases.rdoc +5 -14
- data/doc/prepared_statements.rdoc +5 -9
- data/doc/querying.rdoc +23 -28
- data/doc/reflection.rdoc +11 -0
- data/doc/release_notes/3.48.0.txt +477 -0
- data/doc/schema_modification.rdoc +12 -5
- data/doc/security.rdoc +2 -2
- data/doc/sharding.rdoc +1 -2
- data/doc/sql.rdoc +10 -13
- data/doc/testing.rdoc +8 -4
- data/doc/transactions.rdoc +2 -2
- data/doc/validations.rdoc +40 -17
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado.rb +25 -20
- data/lib/sequel/adapters/ado/access.rb +1 -0
- data/lib/sequel/adapters/ado/mssql.rb +1 -0
- data/lib/sequel/adapters/db2.rb +9 -7
- data/lib/sequel/adapters/dbi.rb +16 -16
- data/lib/sequel/adapters/do.rb +17 -18
- data/lib/sequel/adapters/do/mysql.rb +1 -0
- data/lib/sequel/adapters/do/postgres.rb +2 -0
- data/lib/sequel/adapters/do/sqlite.rb +1 -0
- data/lib/sequel/adapters/firebird.rb +5 -7
- data/lib/sequel/adapters/ibmdb.rb +23 -20
- data/lib/sequel/adapters/informix.rb +8 -2
- data/lib/sequel/adapters/jdbc.rb +39 -35
- data/lib/sequel/adapters/jdbc/as400.rb +1 -0
- data/lib/sequel/adapters/jdbc/cubrid.rb +1 -0
- data/lib/sequel/adapters/jdbc/db2.rb +1 -0
- data/lib/sequel/adapters/jdbc/derby.rb +1 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +1 -0
- data/lib/sequel/adapters/jdbc/h2.rb +1 -0
- data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -0
- data/lib/sequel/adapters/jdbc/informix.rb +1 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +1 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +1 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +2 -0
- data/lib/sequel/adapters/jdbc/progress.rb +1 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +1 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -0
- data/lib/sequel/adapters/mock.rb +30 -31
- data/lib/sequel/adapters/mysql.rb +6 -7
- data/lib/sequel/adapters/mysql2.rb +5 -6
- data/lib/sequel/adapters/odbc.rb +22 -20
- data/lib/sequel/adapters/odbc/mssql.rb +1 -0
- data/lib/sequel/adapters/openbase.rb +4 -1
- data/lib/sequel/adapters/oracle.rb +10 -8
- data/lib/sequel/adapters/postgres.rb +12 -10
- data/lib/sequel/adapters/shared/access.rb +6 -0
- data/lib/sequel/adapters/shared/cubrid.rb +2 -0
- data/lib/sequel/adapters/shared/db2.rb +2 -0
- data/lib/sequel/adapters/shared/firebird.rb +2 -0
- data/lib/sequel/adapters/shared/informix.rb +2 -0
- data/lib/sequel/adapters/shared/mssql.rb +14 -8
- data/lib/sequel/adapters/shared/mysql.rb +6 -0
- data/lib/sequel/adapters/shared/oracle.rb +2 -0
- data/lib/sequel/adapters/shared/postgres.rb +14 -4
- data/lib/sequel/adapters/shared/progress.rb +1 -0
- data/lib/sequel/adapters/shared/sqlite.rb +4 -3
- data/lib/sequel/adapters/sqlite.rb +6 -7
- data/lib/sequel/adapters/swift.rb +20 -21
- data/lib/sequel/adapters/swift/mysql.rb +1 -0
- data/lib/sequel/adapters/swift/postgres.rb +2 -0
- data/lib/sequel/adapters/swift/sqlite.rb +1 -0
- data/lib/sequel/adapters/tinytds.rb +5 -6
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +68 -0
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +57 -50
- data/lib/sequel/database/connecting.rb +9 -10
- data/lib/sequel/database/dataset.rb +11 -6
- data/lib/sequel/database/dataset_defaults.rb +61 -69
- data/lib/sequel/database/features.rb +21 -0
- data/lib/sequel/database/misc.rb +23 -3
- data/lib/sequel/database/query.rb +13 -7
- data/lib/sequel/database/schema_methods.rb +6 -6
- data/lib/sequel/database/transactions.rb +1 -0
- data/lib/sequel/dataset/actions.rb +51 -38
- data/lib/sequel/dataset/features.rb +1 -0
- data/lib/sequel/dataset/graph.rb +9 -33
- data/lib/sequel/dataset/misc.rb +30 -5
- data/lib/sequel/dataset/mutation.rb +2 -3
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/dataset/query.rb +91 -27
- data/lib/sequel/dataset/sql.rb +40 -6
- data/lib/sequel/deprecated.rb +74 -0
- data/lib/sequel/deprecated_core_extensions.rb +135 -0
- data/lib/sequel/extensions/columns_introspection.rb +1 -5
- data/lib/sequel/extensions/core_extensions.rb +10 -3
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +33 -0
- data/lib/sequel/extensions/filter_having.rb +58 -0
- data/lib/sequel/extensions/graph_each.rb +63 -0
- data/lib/sequel/extensions/hash_aliases.rb +44 -0
- data/lib/sequel/extensions/looser_typecasting.rb +14 -3
- data/lib/sequel/extensions/migration.rb +2 -3
- data/lib/sequel/extensions/named_timezones.rb +14 -1
- data/lib/sequel/extensions/null_dataset.rb +7 -1
- data/lib/sequel/extensions/pagination.rb +15 -5
- data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +48 -14
- data/lib/sequel/extensions/pg_json.rb +7 -7
- data/lib/sequel/extensions/pg_range_ops.rb +8 -2
- data/lib/sequel/extensions/pg_statement_cache.rb +1 -0
- data/lib/sequel/extensions/pretty_table.rb +13 -4
- data/lib/sequel/extensions/query.rb +21 -4
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +22 -0
- data/lib/sequel/extensions/schema_caching.rb +10 -7
- data/lib/sequel/extensions/schema_dumper.rb +35 -48
- data/lib/sequel/extensions/select_remove.rb +13 -4
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +117 -0
- data/lib/sequel/extensions/set_overrides.rb +43 -0
- data/lib/sequel/extensions/to_dot.rb +6 -0
- data/lib/sequel/model.rb +12 -6
- data/lib/sequel/model/associations.rb +80 -38
- data/lib/sequel/model/base.rb +137 -52
- data/lib/sequel/model/errors.rb +7 -2
- data/lib/sequel/plugins/active_model.rb +13 -0
- data/lib/sequel/plugins/after_initialize.rb +43 -0
- data/lib/sequel/plugins/association_proxies.rb +63 -7
- data/lib/sequel/plugins/auto_validations.rb +56 -16
- data/lib/sequel/plugins/blacklist_security.rb +63 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +9 -0
- data/lib/sequel/plugins/constraint_validations.rb +50 -8
- data/lib/sequel/plugins/dataset_associations.rb +2 -0
- data/lib/sequel/plugins/hook_class_methods.rb +7 -1
- data/lib/sequel/plugins/identity_map.rb +4 -0
- data/lib/sequel/plugins/json_serializer.rb +32 -13
- data/lib/sequel/plugins/optimistic_locking.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +4 -4
- data/lib/sequel/plugins/scissors.rb +33 -0
- data/lib/sequel/plugins/serialization.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +6 -0
- data/lib/sequel/plugins/tree.rb +5 -1
- data/lib/sequel/plugins/validation_class_methods.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +15 -11
- data/lib/sequel/plugins/xml_serializer.rb +12 -3
- data/lib/sequel/sql.rb +12 -2
- data/lib/sequel/timezones.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/lib/sequel_core.rb +1 -0
- data/lib/sequel_model.rb +1 -0
- data/spec/adapters/mssql_spec.rb +24 -57
- data/spec/adapters/postgres_spec.rb +27 -55
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +1 -1
- data/spec/bin_spec.rb +251 -0
- data/spec/core/database_spec.rb +46 -32
- data/spec/core/dataset_spec.rb +233 -181
- data/spec/core/deprecated_spec.rb +78 -0
- data/spec/core/expression_filters_spec.rb +3 -4
- data/spec/core/mock_adapter_spec.rb +9 -9
- data/spec/core/object_graph_spec.rb +9 -19
- data/spec/core/schema_spec.rb +3 -1
- data/spec/core/spec_helper.rb +19 -0
- data/spec/core_extensions_spec.rb +80 -30
- data/spec/extensions/after_initialize_spec.rb +24 -0
- data/spec/extensions/association_proxies_spec.rb +37 -1
- data/spec/extensions/auto_validations_spec.rb +20 -4
- data/spec/extensions/blacklist_security_spec.rb +87 -0
- data/spec/extensions/boolean_readers_spec.rb +2 -1
- data/spec/extensions/class_table_inheritance_spec.rb +7 -0
- data/spec/extensions/columns_introspection_spec.rb +3 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +83 -5
- data/spec/extensions/core_refinements_spec.rb +7 -7
- data/spec/extensions/dataset_associations_spec.rb +2 -2
- data/spec/extensions/date_arithmetic_spec.rb +1 -1
- data/spec/extensions/defaults_setter_spec.rb +2 -1
- data/spec/extensions/empty_array_ignore_nulls_spec.rb +24 -0
- data/spec/extensions/filter_having_spec.rb +40 -0
- data/spec/extensions/graph_each_spec.rb +109 -0
- data/spec/extensions/hash_aliases_spec.rb +16 -0
- data/spec/extensions/hook_class_methods_spec.rb +2 -2
- data/spec/extensions/identity_map_spec.rb +3 -3
- data/spec/extensions/json_serializer_spec.rb +19 -19
- data/spec/extensions/lazy_attributes_spec.rb +1 -0
- data/spec/extensions/list_spec.rb +13 -13
- data/spec/extensions/looser_typecasting_spec.rb +10 -3
- data/spec/extensions/many_through_many_spec.rb +1 -1
- data/spec/extensions/migration_spec.rb +7 -7
- data/spec/extensions/named_timezones_spec.rb +6 -0
- data/spec/extensions/nested_attributes_spec.rb +2 -2
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/pagination_spec.rb +2 -2
- data/spec/extensions/pg_hstore_ops_spec.rb +75 -0
- data/spec/extensions/pg_range_ops_spec.rb +4 -2
- data/spec/extensions/pg_row_plugin_spec.rb +1 -1
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +3 -3
- data/spec/extensions/schema_caching_spec.rb +3 -3
- data/spec/extensions/schema_dumper_spec.rb +27 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/scissors_spec.rb +26 -0
- data/spec/extensions/select_remove_spec.rb +1 -1
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +102 -0
- data/spec/extensions/set_overrides_spec.rb +45 -0
- data/spec/extensions/single_table_inheritance_spec.rb +10 -0
- data/spec/extensions/spec_helper.rb +24 -1
- data/spec/extensions/static_cache_spec.rb +1 -1
- data/spec/extensions/string_stripper_spec.rb +2 -1
- data/spec/extensions/to_dot_spec.rb +1 -1
- data/spec/extensions/typecast_on_load_spec.rb +3 -2
- data/spec/extensions/update_primary_key_spec.rb +2 -2
- data/spec/extensions/validation_class_methods_spec.rb +19 -19
- data/spec/extensions/validation_helpers_spec.rb +30 -21
- data/spec/extensions/xml_serializer_spec.rb +5 -5
- data/spec/integration/associations_test.rb +10 -30
- data/spec/integration/dataset_test.rb +20 -24
- data/spec/integration/eager_loader_test.rb +5 -5
- data/spec/integration/model_test.rb +3 -3
- data/spec/integration/plugin_test.rb +7 -39
- data/spec/integration/schema_test.rb +4 -38
- data/spec/integration/spec_helper.rb +2 -1
- data/spec/model/association_reflection_spec.rb +70 -5
- data/spec/model/associations_spec.rb +11 -11
- data/spec/model/base_spec.rb +25 -8
- data/spec/model/class_dataset_methods_spec.rb +143 -0
- data/spec/model/dataset_methods_spec.rb +1 -1
- data/spec/model/eager_loading_spec.rb +25 -25
- data/spec/model/hooks_spec.rb +1 -1
- data/spec/model/model_spec.rb +22 -7
- data/spec/model/plugins_spec.rb +1 -6
- data/spec/model/record_spec.rb +37 -29
- data/spec/model/spec_helper.rb +23 -1
- data/spec/model/validations_spec.rb +15 -17
- metadata +32 -3
@@ -13,6 +13,7 @@ module Sequel
|
|
13
13
|
elsif db.respond_to?(:quote_identifiers?)
|
14
14
|
@quote_identifiers = db.quote_identifiers?
|
15
15
|
else
|
16
|
+
Sequel::Deprecation.deprecate('Calling Dataset#quote_identifiers? for a dataset where the database doesn\'t implement quote_identifiers? will raise a NoMethodError in Sequel 4.')
|
16
17
|
@quote_identifiers = false
|
17
18
|
end
|
18
19
|
end
|
data/lib/sequel/dataset/graph.rb
CHANGED
@@ -13,42 +13,18 @@ module Sequel
|
|
13
13
|
#
|
14
14
|
# DB[:table].add_graph_aliases(:some_alias=>[:table, :column])
|
15
15
|
# # SELECT ..., table.column AS some_alias
|
16
|
-
# # => {:table=>{:column=>some_alias_value, ...}, ...}
|
17
16
|
def add_graph_aliases(graph_aliases)
|
17
|
+
unless ga = opts[:graph_aliases]
|
18
|
+
unless opts[:graph] && (ga = opts[:graph][:column_aliases])
|
19
|
+
Sequel::Deprecation.deprecate('Calling Dataset#add_graph_aliases before #graph or #set_graph_aliases', 'Please call it after #graph or #set_graph_aliases')
|
20
|
+
end
|
21
|
+
end
|
18
22
|
columns, graph_aliases = graph_alias_columns(graph_aliases)
|
19
|
-
|
20
|
-
ds.opts[:graph_aliases] = (ds.opts[:graph_aliases] || (ds.opts[:graph][:column_aliases] rescue {}) || {}).merge(graph_aliases)
|
21
|
-
ds
|
23
|
+
select_more(*columns).clone(:graph_aliases => ga.merge(graph_aliases))
|
22
24
|
end
|
23
25
|
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
# This differs from the usual usage of join, which returns the result set
|
28
|
-
# as a single hash. For example:
|
29
|
-
#
|
30
|
-
# # CREATE TABLE artists (id INTEGER, name TEXT);
|
31
|
-
# # CREATE TABLE albums (id INTEGER, name TEXT, artist_id INTEGER);
|
32
|
-
#
|
33
|
-
# DB[:artists].left_outer_join(:albums, :artist_id=>:id).first
|
34
|
-
# #=> {:id=>albums.id, :name=>albums.name, :artist_id=>albums.artist_id}
|
35
|
-
#
|
36
|
-
# DB[:artists].graph(:albums, :artist_id=>:id).first
|
37
|
-
# #=> {:artists=>{:id=>artists.id, :name=>artists.name}, :albums=>{:id=>albums.id, :name=>albums.name, :artist_id=>albums.artist_id}}
|
38
|
-
#
|
39
|
-
# Using a join such as left_outer_join, the attribute names that are shared between
|
40
|
-
# the tables are combined in the single return hash. You can get around that by
|
41
|
-
# using +select+ with correct aliases for all of the columns, but it is simpler to
|
42
|
-
# use +graph+ and have the result set split for you. In addition, +graph+ respects
|
43
|
-
# any +row_proc+ of the current dataset and the datasets you use with +graph+.
|
44
|
-
#
|
45
|
-
# If you are graphing a table and all columns for that table are nil, this
|
46
|
-
# indicates that no matching rows existed in the table, so graph will return nil
|
47
|
-
# instead of a hash with all nil values:
|
48
|
-
#
|
49
|
-
# # If the artist doesn't have any albums
|
50
|
-
# DB[:artists].graph(:albums, :artist_id=>:id).first
|
51
|
-
# => {:artists=>{:id=>artists.id, :name=>artists.name}, :albums=>nil}
|
26
|
+
# Similar to Dataset#join_table, but uses unambiguous aliases for selected
|
27
|
+
# columns and keeps metadata about the aliases for use in other methods.
|
52
28
|
#
|
53
29
|
# Arguments:
|
54
30
|
# dataset :: Can be a symbol (specifying a table), another dataset,
|
@@ -226,7 +202,6 @@ module Sequel
|
|
226
202
|
# :album_name=>[:albums, :name],
|
227
203
|
# :forty_two=>[:albums, :fourtwo, 42]).first
|
228
204
|
# # SELECT artists.name, albums.name AS album_name, 42 AS forty_two ...
|
229
|
-
# # => {:artists=>{:name=>artists.name}, :albums=>{:name=>albums.name, :fourtwo=>42}}
|
230
205
|
def set_graph_aliases(graph_aliases)
|
231
206
|
columns, graph_aliases = graph_alias_columns(graph_aliases)
|
232
207
|
ds = select(*columns)
|
@@ -262,6 +237,7 @@ module Sequel
|
|
262
237
|
# tranform and run the row_proc on each part (if applicable),
|
263
238
|
# and yield a hash of the parts.
|
264
239
|
def graph_each
|
240
|
+
Sequel::Deprecation.deprecate('Dataset#graph_each', 'Load the graph_each extension if you want to continue using it')
|
265
241
|
# Reject tables with nil datasets, as they are excluded from
|
266
242
|
# the result set
|
267
243
|
datasets = @opts[:graph][:table_aliases].to_a.reject{|ta,ds| ds.nil?}
|
data/lib/sequel/dataset/misc.rb
CHANGED
@@ -12,11 +12,32 @@ module Sequel
|
|
12
12
|
|
13
13
|
# The database related to this dataset. This is the Database instance that
|
14
14
|
# will execute all of this dataset's queries.
|
15
|
-
|
15
|
+
attr_reader :db
|
16
16
|
|
17
17
|
# The hash of options for this dataset, keys are symbols.
|
18
|
-
|
19
|
-
|
18
|
+
attr_reader :opts
|
19
|
+
|
20
|
+
# REMOVE40
|
21
|
+
def db=(v)
|
22
|
+
Sequel::Deprecation.deprecate('Dataset#db=', 'Please load the sequel_3_dataset_methods extension to continue using it')
|
23
|
+
@db = v
|
24
|
+
end
|
25
|
+
def opts=(v)
|
26
|
+
Sequel::Deprecation.deprecate('Dataset#opts=', 'Please load the sequel_3_dataset_methods extension to continue using it')
|
27
|
+
@opts = v
|
28
|
+
end
|
29
|
+
|
30
|
+
module DeprecateModifyHash
|
31
|
+
%w'[]= merge! update clear delete delete_if keep_if reject! select! shift store'.each do |meth|
|
32
|
+
class_eval(<<-END, __FILE__, __LINE__+1)
|
33
|
+
def #{meth}(*)
|
34
|
+
Sequel::Deprecation.deprecate('Modifying the initial dataset opts hash is deprecated. Please dup the hash.')
|
35
|
+
super
|
36
|
+
end
|
37
|
+
END
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
20
41
|
# Constructs a new Dataset instance with an associated database and
|
21
42
|
# options. Datasets are usually constructed by invoking the Database#[] method:
|
22
43
|
#
|
@@ -25,9 +46,11 @@ module Sequel
|
|
25
46
|
# Sequel::Dataset is an abstract class that is not useful by itself. Each
|
26
47
|
# database adapter provides a subclass of Sequel::Dataset, and has
|
27
48
|
# the Database#dataset method return an instance of that subclass.
|
28
|
-
def initialize(db, opts = nil)
|
49
|
+
def initialize(db, opts = (no_arg_given=true; nil))
|
29
50
|
@db = db
|
30
|
-
|
51
|
+
# REMOVE40
|
52
|
+
Sequel::Deprecation.deprecate('Passing the opts argument to Database#dataset or Dataset#initialize', 'Clone the dataset afterward to change the opts') unless no_arg_given
|
53
|
+
@opts = opts || {}.extend(DeprecateModifyHash)
|
31
54
|
end
|
32
55
|
|
33
56
|
# Define a hash value such that datasets with the same DB, opts, and SQL
|
@@ -127,6 +150,7 @@ module Sequel
|
|
127
150
|
elsif db.respond_to?(:identifier_input_method)
|
128
151
|
@identifier_input_method = db.identifier_input_method
|
129
152
|
else
|
153
|
+
Sequel::Deprecation.deprecate('Calling Dataset#identifier_input_method for a dataset where the database doesn\'t implement identifier_input_method will raise a NoMethodError in Sequel 4.')
|
130
154
|
@identifier_input_method = nil
|
131
155
|
end
|
132
156
|
end
|
@@ -139,6 +163,7 @@ module Sequel
|
|
139
163
|
elsif db.respond_to?(:identifier_output_method)
|
140
164
|
@identifier_output_method = db.identifier_output_method
|
141
165
|
else
|
166
|
+
Sequel::Deprecation.deprecate('Calling Dataset#identifier_output_method for a dataset where the database doesn\'t implement identifier_output_method will raise a NoMethodError in Sequel 4.')
|
142
167
|
@identifier_output_method = nil
|
143
168
|
end
|
144
169
|
end
|
@@ -58,7 +58,7 @@ module Sequel
|
|
58
58
|
|
59
59
|
# Avoid self-referential dataset by cloning.
|
60
60
|
def from_self!(*args, &block)
|
61
|
-
@opts
|
61
|
+
@opts = clone.from_self(*args, &block).opts
|
62
62
|
self
|
63
63
|
end
|
64
64
|
|
@@ -74,8 +74,7 @@ module Sequel
|
|
74
74
|
# to the receiver and merging the options of the resulting dataset into
|
75
75
|
# the receiver's options.
|
76
76
|
def mutation_method(meth, *args, &block)
|
77
|
-
|
78
|
-
@opts.merge!(copy.opts)
|
77
|
+
@opts = send(meth, *args, &block).opts
|
79
78
|
self
|
80
79
|
end
|
81
80
|
end
|
@@ -29,7 +29,7 @@ module Sequel
|
|
29
29
|
# Override the given *_sql method based on the type, and
|
30
30
|
# cache the result of the sql.
|
31
31
|
def prepared_sql
|
32
|
-
return @prepared_sql if
|
32
|
+
return @prepared_sql if @prepared_sql
|
33
33
|
@prepared_args ||= []
|
34
34
|
@prepared_sql = super
|
35
35
|
@opts[:sql] = @prepared_sql
|
data/lib/sequel/dataset/query.rb
CHANGED
@@ -41,6 +41,7 @@ module Sequel
|
|
41
41
|
set_defaults set_graph_aliases set_overrides unfiltered ungraphed ungrouped union
|
42
42
|
unlimited unordered where with with_recursive with_sql
|
43
43
|
METHS
|
44
|
+
# REMOVE40: query paginate set_defaults set_overrides
|
44
45
|
|
45
46
|
# Register an extension callback for Dataset objects. ext should be the
|
46
47
|
# extension name symbol, and mod should either be a Module that the
|
@@ -69,18 +70,30 @@ module Sequel
|
|
69
70
|
#
|
70
71
|
# DB[:table].filter(:a).and(:b) # SELECT * FROM table WHERE a AND b
|
71
72
|
def and(*cond, &block)
|
72
|
-
|
73
|
-
|
73
|
+
unless @opts[:having] || @opts[:where]
|
74
|
+
Sequel::Deprecation.deprecate('Dataset#and will no longer raise for an unfilered dataset starting in Sequel 4.')
|
75
|
+
raise(InvalidOperation, "No existing filter found.")
|
76
|
+
end
|
77
|
+
if @opts[:having]
|
78
|
+
Sequel::Deprecation.deprecate('Dataset#and will no longer modify the HAVING clause starting in Sequel 4. Switch to using Dataset#having or use the filter_having extension.')
|
79
|
+
having(*cond, &block)
|
80
|
+
else
|
81
|
+
where(*cond, &block)
|
82
|
+
end
|
74
83
|
end
|
75
84
|
|
76
85
|
# Returns a new clone of the dataset with with the given options merged.
|
77
86
|
# If the options changed include options in COLUMN_CHANGE_OPTS, the cached
|
78
87
|
# columns are deleted. This method should generally not be called
|
79
88
|
# directly by user code.
|
80
|
-
def clone(opts =
|
89
|
+
def clone(opts = nil)
|
81
90
|
c = super()
|
82
|
-
|
83
|
-
|
91
|
+
if opts
|
92
|
+
c.instance_variable_set(:@opts, @opts.merge(opts))
|
93
|
+
c.instance_variable_set(:@columns, nil) if @columns && !opts.each_key{|o| break if COLUMN_CHANGE_OPTS.include?(o)}
|
94
|
+
else
|
95
|
+
c.instance_variable_set(:@opts, @opts.dup)
|
96
|
+
end
|
84
97
|
c
|
85
98
|
end
|
86
99
|
|
@@ -116,7 +129,10 @@ module Sequel
|
|
116
129
|
# DB[:items].except(DB[:other_items], :alias=>:i)
|
117
130
|
# # SELECT * FROM (SELECT * FROM items EXCEPT SELECT * FROM other_items) AS i
|
118
131
|
def except(dataset, opts={})
|
119
|
-
|
132
|
+
unless opts.is_a?(Hash)
|
133
|
+
Sequel::Deprecation.deprecate('Passing a non-hash as the second argument to Dataset#except', "Please switch to an options hash with the :all option")
|
134
|
+
opts = {:all=>opts}
|
135
|
+
end
|
120
136
|
raise(InvalidOperation, "EXCEPT not supported") unless supports_intersect_except?
|
121
137
|
raise(InvalidOperation, "EXCEPT ALL not supported") if opts[:all] && !supports_intersect_except_all?
|
122
138
|
compound_clone(:except, dataset, opts)
|
@@ -131,6 +147,7 @@ module Sequel
|
|
131
147
|
# DB[:items].exclude(:category => 'software', :id=>3)
|
132
148
|
# # SELECT * FROM items WHERE ((category != 'software') OR (id != 3))
|
133
149
|
def exclude(*cond, &block)
|
150
|
+
Sequel::Deprecation.deprecate('Dataset#exclude will no longer modify the HAVING clause starting in Sequel 4. Switch to using Dataset#exclude_having or use the filter_having extension.') if @opts[:having]
|
134
151
|
_filter_or_exclude(true, @opts[:having] ? :having : :where, *cond, &block)
|
135
152
|
end
|
136
153
|
|
@@ -214,6 +231,7 @@ module Sequel
|
|
214
231
|
#
|
215
232
|
# See the the {"Dataset Filtering" guide}[link:files/doc/dataset_filtering_rdoc.html] for more examples and details.
|
216
233
|
def filter(*cond, &block)
|
234
|
+
Sequel::Deprecation.deprecate('Dataset#filter will no longer modify the HAVING clause starting in Sequel 4. Switch to using Dataset#having or use the filter_having extension.') if @opts[:having]
|
217
235
|
_filter(@opts[:having] ? :having : :where, *cond, &block)
|
218
236
|
end
|
219
237
|
|
@@ -238,6 +256,7 @@ module Sequel
|
|
238
256
|
source.each do |s|
|
239
257
|
case s
|
240
258
|
when Hash
|
259
|
+
Sequel::Deprecation.deprecate('Dataset#from will no longer treat an input hash as an alias specifier. Switch to aliasing using Sequel.as or use the hash_aliases extension.')
|
241
260
|
s.each{|k,v| sources << SQL::AliasedExpression.new(k,v)}
|
242
261
|
when Dataset
|
243
262
|
if hoist_cte?(s)
|
@@ -406,7 +425,10 @@ module Sequel
|
|
406
425
|
# DB[:items].intersect(DB[:other_items], :alias=>:i)
|
407
426
|
# # SELECT * FROM (SELECT * FROM items INTERSECT SELECT * FROM other_items) AS i
|
408
427
|
def intersect(dataset, opts={})
|
409
|
-
|
428
|
+
unless opts.is_a?(Hash)
|
429
|
+
Sequel::Deprecation.deprecate('Passing a non-hash as the second argument to Dataset#intersect', "Please switch to an options hash with the :all option")
|
430
|
+
opts = {:all=>opts}
|
431
|
+
end
|
410
432
|
raise(InvalidOperation, "INTERSECT not supported") unless supports_intersect_except?
|
411
433
|
raise(InvalidOperation, "INTERSECT ALL not supported") if opts[:all] && !supports_intersect_except_all?
|
412
434
|
compound_clone(:intersect, dataset, opts)
|
@@ -421,7 +443,10 @@ module Sequel
|
|
421
443
|
# # SELECT * FROM items WHERE ((category != 'software') OR (id != 3))
|
422
444
|
def invert
|
423
445
|
having, where = @opts[:having], @opts[:where]
|
424
|
-
|
446
|
+
unless having || where
|
447
|
+
Sequel::Deprecation.deprecate('Dataset#invert will no longer raise for an unfilered dataset starting in Sequel 4.')
|
448
|
+
raise(Error, "No current filter")
|
449
|
+
end
|
425
450
|
o = {}
|
426
451
|
o[:having] = SQL::BooleanExpression.invert(having) if having
|
427
452
|
o[:where] = SQL::BooleanExpression.invert(where) if where
|
@@ -464,7 +489,8 @@ module Sequel
|
|
464
489
|
# the last joined or primary table is used.
|
465
490
|
# * :qualify - Can be set to false to not do any implicit qualification. Can be set
|
466
491
|
# to :deep to use the Qualifier AST Transformer, which will attempt to qualify
|
467
|
-
# subexpressions of the expression tree.
|
492
|
+
# subexpressions of the expression tree. Defaults to the value of
|
493
|
+
# default_join_table_qualification.
|
468
494
|
# * block - The block argument should only be given if a JOIN with an ON clause is used,
|
469
495
|
# in which case it yields the table alias/name for the table currently being joined,
|
470
496
|
# the table alias/name for the last joined (or first table), and an array of previous
|
@@ -505,13 +531,14 @@ module Sequel
|
|
505
531
|
last_alias = options[:implicit_qualifier]
|
506
532
|
qualify_type = options[:qualify]
|
507
533
|
when Symbol, String, SQL::Identifier
|
534
|
+
Sequel::Deprecation.deprecate('Passing a non-hash as the options hash to Dataset#join_table', "Please switch to an options hash with the :table_alias option")
|
508
535
|
table_alias = options
|
509
536
|
last_alias = nil
|
510
537
|
else
|
511
538
|
raise Error, "invalid options format for join_table: #{options.inspect}"
|
512
539
|
end
|
513
540
|
|
514
|
-
if Dataset
|
541
|
+
if table.is_a?(Dataset)
|
515
542
|
if table_alias.nil?
|
516
543
|
table_alias_num = (@opts[:num_dataset_sources] || 0) + 1
|
517
544
|
table_alias = dataset_alias(table_alias_num)
|
@@ -532,6 +559,7 @@ module Sequel
|
|
532
559
|
last_alias ||= @opts[:last_joined_table] || first_source_alias
|
533
560
|
if Sequel.condition_specifier?(expr)
|
534
561
|
expr = expr.collect do |k, v|
|
562
|
+
qualify_type = default_join_table_qualification if qualify_type.nil?
|
535
563
|
case qualify_type
|
536
564
|
when false
|
537
565
|
nil # Do no qualification
|
@@ -578,7 +606,7 @@ module Sequel
|
|
578
606
|
def limit(l, o = (no_offset = true; nil))
|
579
607
|
return from_self.limit(l, o) if @opts[:sql]
|
580
608
|
|
581
|
-
if Range
|
609
|
+
if l.is_a?(Range)
|
582
610
|
o = l.first
|
583
611
|
l = l.last - l.first + (l.exclude_end? ? 0 : 1)
|
584
612
|
end
|
@@ -630,9 +658,17 @@ module Sequel
|
|
630
658
|
# DB[:items].filter(:a).or(:b) # SELECT * FROM items WHERE a OR b
|
631
659
|
def or(*cond, &block)
|
632
660
|
clause = (@opts[:having] ? :having : :where)
|
633
|
-
|
661
|
+
unless @opts[clause]
|
662
|
+
Sequel::Deprecation.deprecate('Dataset#or will no longer raise for an unfilered dataset starting in Sequel 4.')
|
663
|
+
raise(InvalidOperation, "No existing filter found.")
|
664
|
+
end
|
665
|
+
Sequel::Deprecation.deprecate('Dataset#or will no longer modify the HAVING clause starting in Sequel 4. You can use the filter_having extension to continue to use the current behavior.') if clause == :having
|
634
666
|
cond = cond.first if cond.size == 1
|
635
|
-
|
667
|
+
if cond.respond_to?(:empty?) && cond.empty? && !block
|
668
|
+
clone
|
669
|
+
else
|
670
|
+
clone(clause => SQL::BooleanExpression.new(:OR, @opts[clause], filter_expr(cond, &block)))
|
671
|
+
end
|
636
672
|
end
|
637
673
|
|
638
674
|
# Returns a copy of the dataset with the order changed. If the dataset has an
|
@@ -692,7 +728,14 @@ module Sequel
|
|
692
728
|
# DB[:items].filter(:id=>1).qualify(:i)
|
693
729
|
# # SELECT i.* FROM items WHERE (i.id = 1)
|
694
730
|
def qualify(table=first_source)
|
695
|
-
|
731
|
+
o = @opts
|
732
|
+
return clone if o[:sql]
|
733
|
+
h = {}
|
734
|
+
(o.keys & QUALIFY_KEYS).each do |k|
|
735
|
+
h[k] = qualified_expression(o[k], table)
|
736
|
+
end
|
737
|
+
h[:select] = [SQL::ColumnAll.new(table)] if !o[:select] || o[:select].empty?
|
738
|
+
clone(h)
|
696
739
|
end
|
697
740
|
|
698
741
|
# Return a copy of the dataset with unqualified identifiers in the
|
@@ -703,14 +746,8 @@ module Sequel
|
|
703
746
|
# DB[:items].filter(:id=>1).qualify_to(:i)
|
704
747
|
# # SELECT i.* FROM items WHERE (i.id = 1)
|
705
748
|
def qualify_to(table)
|
706
|
-
|
707
|
-
|
708
|
-
h = {}
|
709
|
-
(o.keys & QUALIFY_KEYS).each do |k|
|
710
|
-
h[k] = qualified_expression(o[k], table)
|
711
|
-
end
|
712
|
-
h[:select] = [SQL::ColumnAll.new(table)] if !o[:select] || o[:select].empty?
|
713
|
-
clone(h)
|
749
|
+
Sequel::Deprecation.deprecate('Dataset#qualify_to', 'Switch to Dataset#qualify or use the sequel_3_dataset_methods extension')
|
750
|
+
qualify(table)
|
714
751
|
end
|
715
752
|
|
716
753
|
# Qualify the dataset to its current first source. This is useful
|
@@ -722,7 +759,8 @@ module Sequel
|
|
722
759
|
# DB[:items].filter(:id=>1).qualify_to_first_source
|
723
760
|
# # SELECT items.* FROM items WHERE (items.id = 1)
|
724
761
|
def qualify_to_first_source
|
725
|
-
|
762
|
+
Sequel::Deprecation.deprecate('Dataset#qualify_to_first_source', 'Switch to Dataset#qualify or use the sequel_3_dataset_methods extension')
|
763
|
+
qualify
|
726
764
|
end
|
727
765
|
|
728
766
|
# Modify the RETURNING clause, only supported on a few databases. If returning
|
@@ -765,7 +803,12 @@ module Sequel
|
|
765
803
|
virtual_row_columns(columns, block)
|
766
804
|
m = []
|
767
805
|
columns.each do |i|
|
768
|
-
i.is_a?(Hash)
|
806
|
+
if i.is_a?(Hash)
|
807
|
+
Sequel::Deprecation.deprecate('Dataset#select will no longer treat an input hash as an alias specifier. Switch to aliasing using Sequel.as or use the hash_aliases extension.')
|
808
|
+
m.concat(i.map{|k, v| SQL::AliasedExpression.new(k,v)})
|
809
|
+
else
|
810
|
+
m << i
|
811
|
+
end
|
769
812
|
end
|
770
813
|
clone(:select => m)
|
771
814
|
end
|
@@ -825,7 +868,11 @@ module Sequel
|
|
825
868
|
# DB[:items].select(:a).select_more(:b) # SELECT a, b FROM items
|
826
869
|
# DB[:items].select_more(:b) # SELECT b FROM items
|
827
870
|
def select_more(*columns, &block)
|
828
|
-
|
871
|
+
if @opts[:select]
|
872
|
+
columns = @opts[:select] + columns
|
873
|
+
else
|
874
|
+
Sequel::Deprecation.deprecate('Dataset#select_more will no longer remove the wildcard selection from the Dataset starting in Sequel 4. Switch to using Dataset#select if you want that behavior.')
|
875
|
+
end
|
829
876
|
select(*columns, &block)
|
830
877
|
end
|
831
878
|
|
@@ -849,6 +896,7 @@ module Sequel
|
|
849
896
|
# DB[:items].set_defaults(:a=>'a', :c=>'c').insert(:a=>'d', :b=>'b')
|
850
897
|
# # INSERT INTO items (a, c, b) VALUES ('d', 'c', 'b')
|
851
898
|
def set_defaults(hash)
|
899
|
+
Sequel::Deprecation.deprecate('Dataset#set_defaults', 'Please use the dataset_set_overrides extension if you want to continue using it')
|
852
900
|
clone(:defaults=>(@opts[:defaults]||{}).merge(hash))
|
853
901
|
end
|
854
902
|
|
@@ -859,6 +907,7 @@ module Sequel
|
|
859
907
|
# DB[:items].set_overrides(:a=>'a', :c=>'c').insert(:a=>'d', :b=>'b')
|
860
908
|
# # INSERT INTO items (a, c, b) VALUES ('a', 'c', 'b')
|
861
909
|
def set_overrides(hash)
|
910
|
+
Sequel::Deprecation.deprecate('Dataset#set_overrides', 'Please use the dataset_set_overrides extension if you want to continue using it')
|
862
911
|
clone(:overrides=>hash.merge(@opts[:overrides]||{}))
|
863
912
|
end
|
864
913
|
|
@@ -911,7 +960,10 @@ module Sequel
|
|
911
960
|
# DB[:items].union(DB[:other_items], :alias=>:i)
|
912
961
|
# # SELECT * FROM (SELECT * FROM items UNION SELECT * FROM other_items) AS i
|
913
962
|
def union(dataset, opts={})
|
914
|
-
|
963
|
+
unless opts.is_a?(Hash)
|
964
|
+
Sequel::Deprecation.deprecate('Passing a non-hash as the second argument to Dataset#union', "Please switch to an options hash with the :all option")
|
965
|
+
opts = {:all=>opts}
|
966
|
+
end
|
915
967
|
compound_clone(:union, dataset, opts)
|
916
968
|
end
|
917
969
|
|
@@ -1051,6 +1103,11 @@ module Sequel
|
|
1051
1103
|
_filter_or_exclude(false, clause, *cond, &block)
|
1052
1104
|
end
|
1053
1105
|
|
1106
|
+
# The default :qualify option to use for join tables if one is not specified.
|
1107
|
+
def default_join_table_qualification
|
1108
|
+
:symbol
|
1109
|
+
end
|
1110
|
+
|
1054
1111
|
# SQL expression object based on the expr type. See +filter+.
|
1055
1112
|
def filter_expr(expr = nil, &block)
|
1056
1113
|
expr = nil if expr == []
|
@@ -1129,7 +1186,14 @@ module Sequel
|
|
1129
1186
|
# Treat the +block+ as a virtual_row block if not +nil+ and
|
1130
1187
|
# add the resulting columns to the +columns+ array (modifies +columns+).
|
1131
1188
|
def virtual_row_columns(columns, block)
|
1132
|
-
|
1189
|
+
if block
|
1190
|
+
v = Sequel.virtual_row(&block)
|
1191
|
+
if v.is_a?(Array)
|
1192
|
+
columns.concat(v)
|
1193
|
+
else
|
1194
|
+
columns << v
|
1195
|
+
end
|
1196
|
+
end
|
1133
1197
|
end
|
1134
1198
|
end
|
1135
1199
|
end
|