sequel 4.44.0 → 4.45.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.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +110 -0
  3. data/README.rdoc +8 -9
  4. data/doc/active_record.rdoc +2 -3
  5. data/doc/model_plugins.rdoc +1 -1
  6. data/doc/opening_databases.rdoc +0 -46
  7. data/doc/release_notes/4.45.0.txt +370 -0
  8. data/lib/sequel/adapters/cubrid.rb +2 -0
  9. data/lib/sequel/adapters/do.rb +2 -0
  10. data/lib/sequel/adapters/jdbc/as400.rb +2 -0
  11. data/lib/sequel/adapters/jdbc/cubrid.rb +2 -0
  12. data/lib/sequel/adapters/jdbc/firebirdsql.rb +2 -0
  13. data/lib/sequel/adapters/jdbc/informix-sqli.rb +2 -0
  14. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +2 -0
  15. data/lib/sequel/adapters/jdbc/mysql.rb +1 -0
  16. data/lib/sequel/adapters/jdbc/postgresql.rb +5 -0
  17. data/lib/sequel/adapters/mysql.rb +1 -0
  18. data/lib/sequel/adapters/mysql2.rb +1 -0
  19. data/lib/sequel/adapters/odbc/oracle.rb +11 -0
  20. data/lib/sequel/adapters/odbc/progress.rb +2 -0
  21. data/lib/sequel/adapters/postgres.rb +0 -2
  22. data/lib/sequel/adapters/shared/cubrid.rb +2 -0
  23. data/lib/sequel/adapters/shared/firebird.rb +2 -0
  24. data/lib/sequel/adapters/shared/informix.rb +2 -0
  25. data/lib/sequel/adapters/shared/mssql.rb +47 -7
  26. data/lib/sequel/adapters/shared/mysql.rb +16 -1
  27. data/lib/sequel/adapters/shared/postgres.rb +9 -1
  28. data/lib/sequel/adapters/shared/progress.rb +2 -0
  29. data/lib/sequel/adapters/shared/sqlanywhere.rb +1 -1
  30. data/lib/sequel/adapters/swift.rb +2 -0
  31. data/lib/sequel/ast_transformer.rb +13 -6
  32. data/lib/sequel/core.rb +13 -16
  33. data/lib/sequel/database/connecting.rb +25 -10
  34. data/lib/sequel/database/dataset.rb +6 -1
  35. data/lib/sequel/database/dataset_defaults.rb +9 -2
  36. data/lib/sequel/database/misc.rb +10 -3
  37. data/lib/sequel/database/schema_methods.rb +4 -0
  38. data/lib/sequel/dataset/mutation.rb +8 -20
  39. data/lib/sequel/dataset/prepared_statements.rb +2 -0
  40. data/lib/sequel/dataset/query.rb +32 -7
  41. data/lib/sequel/dataset/sql.rb +13 -3
  42. data/lib/sequel/deprecated.rb +9 -1
  43. data/lib/sequel/exceptions.rb +37 -8
  44. data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +117 -0
  45. data/lib/sequel/extensions/date_arithmetic.rb +1 -0
  46. data/lib/sequel/extensions/identifier_mangling.rb +3 -2
  47. data/lib/sequel/extensions/pg_hstore.rb +1 -5
  48. data/lib/sequel/extensions/schema_dumper.rb +3 -1
  49. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +2 -2
  50. data/lib/sequel/extensions/string_agg.rb +1 -0
  51. data/lib/sequel/model.rb +23 -10
  52. data/lib/sequel/model/associations.rb +17 -5
  53. data/lib/sequel/model/base.rb +115 -62
  54. data/lib/sequel/model/dataset_module.rb +10 -3
  55. data/lib/sequel/model/exceptions.rb +7 -5
  56. data/lib/sequel/plugins/association_pks.rb +13 -1
  57. data/lib/sequel/plugins/association_proxies.rb +8 -1
  58. data/lib/sequel/plugins/before_after_save.rb +1 -0
  59. data/lib/sequel/plugins/class_table_inheritance.rb +7 -3
  60. data/lib/sequel/plugins/columns_updated.rb +42 -0
  61. data/lib/sequel/plugins/composition.rb +10 -5
  62. data/lib/sequel/plugins/error_splitter.rb +1 -1
  63. data/lib/sequel/plugins/hook_class_methods.rb +39 -5
  64. data/lib/sequel/plugins/instance_hooks.rb +58 -5
  65. data/lib/sequel/plugins/lazy_attributes.rb +10 -5
  66. data/lib/sequel/plugins/nested_attributes.rb +10 -5
  67. data/lib/sequel/plugins/prepared_statements.rb +7 -0
  68. data/lib/sequel/plugins/prepared_statements_associations.rb +2 -0
  69. data/lib/sequel/plugins/prepared_statements_with_pk.rb +2 -0
  70. data/lib/sequel/plugins/schema.rb +2 -0
  71. data/lib/sequel/plugins/scissors.rb +2 -0
  72. data/lib/sequel/plugins/serialization.rb +10 -5
  73. data/lib/sequel/plugins/split_values.rb +5 -1
  74. data/lib/sequel/plugins/static_cache.rb +2 -2
  75. data/lib/sequel/plugins/tactical_eager_loading.rb +1 -1
  76. data/lib/sequel/plugins/validation_contexts.rb +49 -0
  77. data/lib/sequel/plugins/validation_helpers.rb +1 -0
  78. data/lib/sequel/sql.rb +1 -1
  79. data/lib/sequel/version.rb +1 -1
  80. data/spec/adapters/mssql_spec.rb +31 -0
  81. data/spec/adapters/mysql_spec.rb +20 -2
  82. data/spec/adapters/postgres_spec.rb +43 -12
  83. data/spec/adapters/spec_helper.rb +5 -8
  84. data/spec/core/database_spec.rb +47 -12
  85. data/spec/core/dataset_mutation_spec.rb +22 -22
  86. data/spec/core/dataset_spec.rb +88 -20
  87. data/spec/core/deprecated_spec.rb +1 -1
  88. data/spec/core/expression_filters_spec.rb +1 -1
  89. data/spec/core/mock_adapter_spec.rb +0 -3
  90. data/spec/core/placeholder_literalizer_spec.rb +1 -1
  91. data/spec/core/schema_spec.rb +8 -1
  92. data/spec/core/spec_helper.rb +6 -1
  93. data/spec/core_extensions_spec.rb +4 -0
  94. data/spec/deprecation_helper.rb +17 -0
  95. data/spec/extensions/_deprecated_identifier_mangling_spec.rb +314 -0
  96. data/spec/extensions/association_pks_spec.rb +61 -13
  97. data/spec/extensions/association_proxies_spec.rb +3 -3
  98. data/spec/extensions/class_table_inheritance_spec.rb +39 -0
  99. data/spec/extensions/columns_updated_spec.rb +35 -0
  100. data/spec/extensions/composition_spec.rb +6 -1
  101. data/spec/extensions/hook_class_methods_spec.rb +114 -26
  102. data/spec/extensions/identifier_mangling_spec.rb +107 -73
  103. data/spec/extensions/instance_hooks_spec.rb +78 -14
  104. data/spec/extensions/lazy_attributes_spec.rb +8 -2
  105. data/spec/extensions/many_through_many_spec.rb +2 -2
  106. data/spec/extensions/mssql_optimistic_locking_spec.rb +1 -1
  107. data/spec/extensions/nested_attributes_spec.rb +8 -2
  108. data/spec/extensions/pg_array_spec.rb +18 -4
  109. data/spec/extensions/prepared_statements_associations_spec.rb +48 -39
  110. data/spec/extensions/prepared_statements_with_pk_spec.rb +13 -11
  111. data/spec/extensions/query_spec.rb +1 -1
  112. data/spec/extensions/schema_dumper_spec.rb +34 -6
  113. data/spec/extensions/schema_spec.rb +13 -7
  114. data/spec/extensions/scissors_spec.rb +3 -1
  115. data/spec/extensions/sequel_3_dataset_methods_spec.rb +4 -4
  116. data/spec/extensions/serialization_spec.rb +7 -1
  117. data/spec/extensions/set_overrides_spec.rb +2 -2
  118. data/spec/extensions/shared_caching_spec.rb +19 -15
  119. data/spec/extensions/spec_helper.rb +7 -3
  120. data/spec/extensions/split_values_spec.rb +45 -10
  121. data/spec/extensions/string_agg_spec.rb +2 -2
  122. data/spec/extensions/subset_conditions_spec.rb +3 -3
  123. data/spec/extensions/tactical_eager_loading_spec.rb +1 -1
  124. data/spec/extensions/validation_contexts_spec.rb +31 -0
  125. data/spec/guards_helper.rb +2 -0
  126. data/spec/integration/associations_test.rb +22 -20
  127. data/spec/integration/dataset_test.rb +25 -2
  128. data/spec/integration/model_test.rb +1 -1
  129. data/spec/integration/plugin_test.rb +11 -16
  130. data/spec/integration/prepared_statement_test.rb +40 -32
  131. data/spec/integration/spec_helper.rb +5 -8
  132. data/spec/model/association_reflection_spec.rb +4 -0
  133. data/spec/model/associations_spec.rb +37 -10
  134. data/spec/model/base_spec.rb +6 -0
  135. data/spec/model/hooks_spec.rb +56 -35
  136. data/spec/model/model_spec.rb +21 -5
  137. data/spec/model/record_spec.rb +14 -11
  138. data/spec/model/spec_helper.rb +7 -1
  139. data/spec/sequel_warning.rb +11 -0
  140. metadata +13 -3
@@ -9,12 +9,16 @@ module Sequel
9
9
 
10
10
  # Array of supported database adapters
11
11
  ADAPTERS = %w'ado amalgalite cubrid do ibmdb jdbc mock mysql mysql2 odbc oracle postgres sqlanywhere sqlite swift tinytds'.collect(&:to_sym)
12
+ # SEQUEL5: Remove cubrid do swift
12
13
 
13
- @single_threaded = false
14
+ def self.single_threaded
15
+ Sequel::Deprecation.deprecate("Sequel::Database.single_threaded", "Use Sequel.single_threaded instead")
16
+ Sequel.single_threaded
17
+ end
14
18
 
15
- class << self
16
- # Whether to use the single threaded connection pool by default
17
- attr_accessor :single_threaded
19
+ def self.single_threaded=(v)
20
+ Sequel::Deprecation.deprecate("Sequel::Database.single_threaded=", "Use Sequel.single_threaded= instead")
21
+ Sequel.single_threaded = v
18
22
  end
19
23
 
20
24
  # The Database subclass for the given adapter scheme.
@@ -37,6 +41,7 @@ module Sequel
37
41
  def self.connect(conn_string, opts = OPTS)
38
42
  case conn_string
39
43
  when String
44
+ # SEQUEL5: Remove do
40
45
  if match = /\A(jdbc|do):/o.match(conn_string)
41
46
  c = adapter_class(match[1].to_sym)
42
47
  opts = opts.merge(:orig_opts=>opts.dup)
@@ -65,6 +70,7 @@ module Sequel
65
70
  end
66
71
  begin
67
72
  db = c.new(opts)
73
+ # SEQUEL5: Default opts[:test] to true
68
74
  db.test_connection if opts[:test] && db.send(:typecast_value_boolean, opts[:test])
69
75
  if block_given?
70
76
  return yield(db)
@@ -183,10 +189,14 @@ module Sequel
183
189
  #
184
190
  # DB.add_servers(:f=>{:host=>"hash_host_f"})
185
191
  def add_servers(servers)
186
- if h = @opts[:servers]
187
- Sequel.synchronize{h.merge!(servers)}
188
- @pool.add_servers(servers.keys)
192
+ unless h = @opts[:servers]
193
+ Sequel::Deprecation.deprecate("Calling Database#add_servers on a database that does not use sharding", "This method should only be called if the database supports sharding.")
194
+ # raise Error, "cannot call Database#add_servers on a Database instance that does not use a sharded connection pool" # SEQUEL5
195
+ return
189
196
  end
197
+
198
+ Sequel.synchronize{h.merge!(servers)}
199
+ @pool.add_servers(servers.keys)
190
200
  end
191
201
 
192
202
  # The database type for this database object, the same as the adapter scheme
@@ -229,6 +239,7 @@ module Sequel
229
239
  #
230
240
  # DB.each_server{|db| db.create_table(:users){primary_key :id; String :name}}
231
241
  def each_server(&block)
242
+ Sequel::Deprecation.deprecate("Database#each_server", "Switching to using Dataset#servers and Database#with_server from the server_block extension: \"DB.servers.each{|s| DB.with_server(s){}}\"")
232
243
  raise(Error, "Database#each_server must be passed a block") unless block
233
244
  servers.each{|s| self.class.connect(server_opts(s), &block)}
234
245
  end
@@ -244,10 +255,14 @@ module Sequel
244
255
  #
245
256
  # DB.remove_servers(:f1, :f2)
246
257
  def remove_servers(*servers)
247
- if h = @opts[:servers]
248
- servers.flatten.each{|s| Sequel.synchronize{h.delete(s)}}
249
- @pool.remove_servers(servers)
258
+ unless h = @opts[:servers]
259
+ Sequel::Deprecation.deprecate("Calling Database#add_servers on a database that does not use sharding", "This method should only be called if the database supports sharding.")
260
+ # raise Error, "cannot call Database#remove_servers on a Database instance that does not use a sharded connection pool" # SEQUEL5
261
+ return
250
262
  end
263
+
264
+ servers.flatten.each{|s| Sequel.synchronize{h.delete(s)}}
265
+ @pool.remove_servers(servers)
251
266
  end
252
267
 
253
268
  # An array of servers/shards for this Database object.
@@ -59,7 +59,12 @@ module Sequel
59
59
  # DB.from(:items){id > 2} # SELECT * FROM items WHERE (id > 2)
60
60
  def from(*args, &block)
61
61
  ds = @default_dataset.from(*args)
62
- block ? ds.where(&block) : ds
62
+ if block
63
+ Sequel::Deprecation.deprecate("Sequel::Database#from with a block", "Use .from(*args).where(&block) instead")
64
+ ds.where(&block)
65
+ else
66
+ ds
67
+ end
63
68
  end
64
69
 
65
70
  # Returns a new dataset with the select method invoked.
@@ -10,10 +10,10 @@ module Sequel
10
10
  # The default class to use for datasets
11
11
  DatasetClass = Sequel::Dataset
12
12
 
13
+ # SEQUEL5: Remove
13
14
  @identifier_input_method = nil
14
15
  @identifier_output_method = nil
15
16
  @quote_identifiers = nil
16
-
17
17
  class << self
18
18
  # The identifier input method to use by default for all databases (default: adapter default)
19
19
  attr_reader :identifier_input_method
@@ -22,19 +22,26 @@ module Sequel
22
22
  attr_reader :identifier_output_method
23
23
 
24
24
  # Whether to quote identifiers (columns and tables) by default for all databases (default: adapter default)
25
- attr_accessor :quote_identifiers
25
+ attr_reader :quote_identifiers
26
26
  end
27
27
 
28
28
  # Change the default identifier input method to use for all databases,
29
29
  def self.identifier_input_method=(v)
30
+ Sequel::Deprecation.deprecate("Sequel.identifier_input_method= and Sequel::Database.identifier_input_method=", "Call Sequel::Database#identifier_input_method= instead")
30
31
  @identifier_input_method = v.nil? ? false : v
31
32
  end
32
33
 
33
34
  # Change the default identifier output method to use for all databases,
34
35
  def self.identifier_output_method=(v)
36
+ Sequel::Deprecation.deprecate("Sequel.identifier_output_method= and Sequel::Database.identifier_output_method=", "Call Sequel::Database#identifier_output_method= instead")
35
37
  @identifier_output_method = v.nil? ? false : v
36
38
  end
37
39
 
40
+ def self.quote_identifiers=(v)
41
+ Sequel::Deprecation.deprecate("Sequel.quote_identifiers= and Sequel::Database.quote_identifiers=", "Call Sequel::Database#quote_identifiers= instead")
42
+ @quote_identifiers = v
43
+ end
44
+
38
45
  # The class to use for creating datasets. Should respond to
39
46
  # new with the Database argument as the first argument, and
40
47
  # an optional options hash.
@@ -29,13 +29,14 @@ module Sequel
29
29
  # Module to be included in shared adapters so that when the DatabaseMethods are
30
30
  # included in the database, the identifier mangling defaults are reset correctly.
31
31
  module ResetIdentifierMangling
32
- def extended(obj)
32
+ def self.extended(obj)
33
33
  # :nocov:
34
34
  Sequel::Deprecation.deprecate("Sequel::Database::ResetIdentifierMangling is no longer needed and will be removed in Sequel 5. Please update your adapter.")
35
35
  obj.send(:reset_identifier_mangling) if obj.respond_to?(:reset_identifier_mangling)
36
36
  # :nocov:
37
37
  end
38
38
  end
39
+ Sequel::Deprecation.deprecate_constant(self, :ResetIdentifierMangling)
39
40
 
40
41
  # Nested hook Proc; each new hook Proc just wraps the previous one.
41
42
  @initialize_hook = Proc.new {|db| }
@@ -125,7 +126,7 @@ module Sequel
125
126
  @opts[:servers] = {} if @opts[:servers].is_a?(String)
126
127
  @sharded = !!@opts[:servers]
127
128
  @opts[:adapter_class] = self.class
128
- @opts[:single_threaded] = @single_threaded = typecast_value_boolean(@opts.fetch(:single_threaded, Database.single_threaded))
129
+ @opts[:single_threaded] = @single_threaded = typecast_value_boolean(@opts.fetch(:single_threaded, Sequel.single_threaded))
129
130
  @default_string_column_size = @opts[:default_string_column_size] || DEFAULT_STRING_COLUMN_SIZE
130
131
 
131
132
  @schemas = {}
@@ -150,7 +151,7 @@ module Sequel
150
151
  reset_default_dataset
151
152
  adapter_initialize
152
153
  if typecast_value_boolean(@opts.fetch(:identifier_mangling, true))
153
- extension(:identifier_mangling)
154
+ extension(:_deprecated_identifier_mangling)
154
155
  end
155
156
 
156
157
  unless typecast_value_boolean(@opts[:keep_reference]) == false
@@ -180,6 +181,12 @@ module Sequel
180
181
  super
181
182
  end
182
183
 
184
+ def initialize_copy(_)
185
+ Sequel::Deprecation.deprecate("Database#dup and #clone", "Use Sequel.connect to create a new Database instance")
186
+ # raise(Error, "cannot dup/clone a Sequel::Database instance") # SEQUEL5
187
+ super
188
+ end
189
+
183
190
  # Cast the given type to a literal type
184
191
  #
185
192
  # DB.cast_type_literal(Float) # double precision
@@ -808,6 +808,10 @@ module Sequel
808
808
 
809
809
  # Proxy the filter_expr call to the dataset, used for creating constraints.
810
810
  def filter_expr(*args, &block)
811
+ if args.length == 1 && args.first.is_a?(Proc) && !block
812
+ block = args.first
813
+ args = nil
814
+ end
811
815
  schema_utility_dataset.literal(schema_utility_dataset.send(:filter_expr, *args, &block))
812
816
  end
813
817
 
@@ -30,67 +30,55 @@ module Sequel
30
30
 
31
31
  # Like #extension, but modifies and returns the receiver instead of returning a modified clone.
32
32
  def extension!(*exts)
33
- raise_if_frozen!
33
+ raise_if_frozen!("extension!")
34
34
  _extension!(exts)
35
35
  end
36
36
 
37
37
  # Avoid self-referential dataset by cloning.
38
38
  def from_self!(*args, &block)
39
- raise_if_frozen!
39
+ raise_if_frozen!("from_self!")
40
40
  @opts = clone.from_self(*args, &block).opts
41
41
  self
42
42
  end
43
43
 
44
44
  # Remove the row_proc from the current dataset.
45
45
  def naked!
46
- raise_if_frozen!
46
+ raise_if_frozen!("naked=")
47
47
  @opts[:row_proc] = nil
48
48
  self
49
49
  end
50
50
 
51
51
  # Set whether to quote identifiers for this dataset
52
52
  def quote_identifiers=(v)
53
- raise_if_frozen!
53
+ raise_if_frozen!("quote_identifiers=")
54
54
  skip_symbol_cache!
55
55
  @opts[:quote_identifiers] = v
56
56
  end
57
57
 
58
58
  # Override the row_proc for this dataset
59
59
  def row_proc=(v)
60
- raise_if_frozen!
60
+ raise_if_frozen!("row_proc=")
61
61
  @opts[:row_proc] = v
62
62
  end
63
63
 
64
64
  private
65
65
 
66
- # Load the extensions into the receiver, without checking if the receiver is frozen.
67
- def _extension!(exts)
68
- Sequel.extension(*exts)
69
- exts.each do |ext|
70
- if pr = Sequel.synchronize{EXTENSIONS[ext]}
71
- pr.call(self)
72
- else
73
- raise(Error, "Extension #{ext} does not have specific support handling individual datasets (try: Sequel.extension #{ext.inspect})")
74
- end
75
- end
76
- self
77
- end
78
-
79
66
  # Modify the receiver with the results of sending the meth, args, and block
80
67
  # to the receiver and merging the options of the resulting dataset into
81
68
  # the receiver's options.
82
69
  def mutation_method(meth, *args, &block)
83
- raise_if_frozen!
70
+ raise_if_frozen!("#{meth}!")
84
71
  @opts = send(meth, *args, &block).opts
85
72
  @cache = {}
86
73
  self
87
74
  end
88
75
 
89
76
  # Raise a RuntimeError if the receiver is frozen
90
- def raise_if_frozen!
77
+ def raise_if_frozen!(meth = nil)
91
78
  if frozen?
92
79
  raise RuntimeError, "can't modify frozen #{visible_class_name}"
93
80
  end
81
+ Sequel::Deprecation.deprecate("Dataset mutation is deprecated and will be removed in Sequel 5#{" (method called: #{meth})" if meth}")
94
82
  end
95
83
 
96
84
  # Set the dataset to skip the symbol cache
@@ -217,6 +217,7 @@ module Sequel
217
217
  send(*prepared_type, &block)
218
218
  end
219
219
  else
220
+ Sequel::Deprecation.deprecate("Using an unsupported prepared statement type (#{prepared_type.inspect})", 'Switch to using :select as the prepared statement type')
220
221
  all(&block)
221
222
  end
222
223
  end
@@ -338,6 +339,7 @@ module Sequel
338
339
  db.set_prepared_statement(name, ps)
339
340
  else
340
341
  # :nocov:
342
+ # SEQUEL5: Add coverage
341
343
  Sequel::Deprecation.deprecate("Dataset#prepare will change to requiring a name argument in Sequel 5, please update your code.") unless name
342
344
  # :nocov:
343
345
  end
@@ -581,8 +581,8 @@ module Sequel
581
581
  when false
582
582
  nil # Do no qualification
583
583
  when :deep
584
- k = Sequel::Qualifier.new(self, table_name).transform(k)
585
- v = Sequel::Qualifier.new(self, last_alias).transform(v)
584
+ k = Sequel::Qualifier.new(table_name).transform(k)
585
+ v = Sequel::Qualifier.new(last_alias).transform(v)
586
586
  else
587
587
  k = qualified_column_name(k, table_name) if k.is_a?(Symbol)
588
588
  v = qualified_column_name(v, last_alias) if v.is_a?(Symbol)
@@ -897,6 +897,13 @@ module Sequel
897
897
  end
898
898
  end
899
899
 
900
+ # Specify that the check for limits/offsets when updating/deleting be skipped for the dataset.
901
+ def skip_limit_check
902
+ cached_dataset(:_skip_limit_check_ds) do
903
+ clone(:skip_limit_check=>true)
904
+ end
905
+ end
906
+
900
907
  # Skip locked rows when returning results from this dataset.
901
908
  def skip_locked
902
909
  cached_dataset(:_skip_locked_ds) do
@@ -916,6 +923,7 @@ module Sequel
916
923
  # bv # {:a => 1}
917
924
  # ds.call(:select, bv)
918
925
  def unbind
926
+ Sequel::Deprecation.deprecate("Dataset#unbind", "Switch to using placeholders manually instead of unbinding them")
919
927
  u = Unbinder.new
920
928
  ds = clone(:where=>u.transform(opts[:where]), :join=>u.transform(opts[:join]))
921
929
  [ds, u.binds]
@@ -1186,6 +1194,19 @@ module Sequel
1186
1194
 
1187
1195
  private
1188
1196
 
1197
+ # Load the extensions into the receiver, without checking if the receiver is frozen.
1198
+ def _extension!(exts)
1199
+ Sequel.extension(*exts)
1200
+ exts.each do |ext|
1201
+ if pr = Sequel.synchronize{EXTENSIONS[ext]}
1202
+ pr.call(self)
1203
+ else
1204
+ raise(Error, "Extension #{ext} does not have specific support handling individual datasets (try: Sequel.extension #{ext.inspect})")
1205
+ end
1206
+ end
1207
+ self
1208
+ end
1209
+
1189
1210
  # Internal filtering method so it works on either the WHERE or HAVING clauses, with or
1190
1211
  # without inversion.
1191
1212
  def _filter_or_exclude(invert, clause, *cond, &block)
@@ -1214,10 +1235,12 @@ module Sequel
1214
1235
  def filter_expr(expr = nil, &block)
1215
1236
  expr = nil if expr == []
1216
1237
 
1217
- if expr && block
1218
- return SQL::BooleanExpression.new(:AND, filter_expr(expr), filter_expr(block))
1219
- elsif block
1220
- expr = block
1238
+ if block
1239
+ if expr
1240
+ return SQL::BooleanExpression.new(:AND, filter_expr(expr), filter_expr(Sequel.virtual_row(&block)))
1241
+ else
1242
+ return filter_expr(Sequel.virtual_row(&block))
1243
+ end
1221
1244
  end
1222
1245
 
1223
1246
  case expr
@@ -1229,11 +1252,13 @@ module Sequel
1229
1252
  elsif Sequel.condition_specifier?(expr)
1230
1253
  SQL::BooleanExpression.from_value_pairs(expr)
1231
1254
  else
1255
+ Sequel::Deprecation.deprecate("Passing multiple arguments as filter arguments when not using a conditions specifier (#{expr.inspect})", "Pass the arguments to separate filter methods or use Sequel.& to combine them")
1232
1256
  SQL::BooleanExpression.new(:AND, *expr.map{|x| filter_expr(x)})
1233
1257
  end
1234
1258
  when Proc
1259
+ Sequel::Deprecation.deprecate("Passing Proc objects as filter arguments", "Pass them as blocks to the filtering methods or to Sequel.expr")
1235
1260
  filter_expr(Sequel.virtual_row(&expr))
1236
- when Numeric, SQL::NumericExpression, SQL::StringExpression
1261
+ when Numeric, SQL::NumericExpression, SQL::StringExpression #, Proc # SEQUEL5
1237
1262
  raise(Error, "Invalid filter expression: #{expr.inspect}")
1238
1263
  when TrueClass, FalseClass
1239
1264
  if supports_where_true?
@@ -155,6 +155,7 @@ module Sequel
155
155
  static_sql(opts[:sql])
156
156
  else
157
157
  check_truncation_allowed!
158
+ check_not_limited!(:truncate)
158
159
  raise(InvalidOperation, "Can't truncate filtered datasets") if opts[:where] || opts[:having]
159
160
  t = String.new
160
161
  source_list_append(t, opts[:from])
@@ -172,6 +173,7 @@ module Sequel
172
173
  def update_sql(values = OPTS)
173
174
  return static_sql(opts[:sql]) if opts[:sql]
174
175
  check_modification_allowed!
176
+ check_not_limited!(:update)
175
177
  clone(:values=>values).send(:_update_sql)
176
178
  end
177
179
 
@@ -205,7 +207,7 @@ module Sequel
205
207
  lines << "def #{'_' if priv}#{type}_sql"
206
208
  lines << 'if sql = opts[:sql]; return static_sql(sql) end' unless priv
207
209
  lines << "if sql = cache_get(:_#{type}_sql); return sql end" if cacheable
208
- lines << 'check_modification_allowed!' if type == :delete
210
+ lines << 'check_modification_allowed!' << 'check_not_limited!(:delete)' if type == :delete
209
211
  lines << 'sql = @opts[:append_sql] || sql_string_origin'
210
212
 
211
213
  if clauses.all?{|c| c.is_a?(Array)}
@@ -843,7 +845,7 @@ module Sequel
843
845
  # Return a from_self dataset if an order or limit is specified, so it works as expected
844
846
  # with UNION, EXCEPT, and INTERSECT clauses.
845
847
  def compound_from_self
846
- (@opts[:sql] || @opts[:limit] || @opts[:order]) ? from_self : self
848
+ (@opts[:sql] || @opts[:limit] || @opts[:order] || @opts[:offset]) ? from_self : self
847
849
  end
848
850
 
849
851
  private
@@ -922,6 +924,14 @@ module Sequel
922
924
  raise(InvalidOperation, "Joined datasets cannot be modified") if !supports_modifying_joins? && joined_dataset?
923
925
  end
924
926
 
927
+ # Emit deprecation warning if the dataset uses limits or offsets.
928
+ def check_not_limited!(type)
929
+ return if @opts[:skip_limit_check] && type != :truncate
930
+ # SEQUEL5
931
+ #raise InvalidOperation, "Dataset##{type} not supported on datasets with limits or offsets" if opts[:limit] || opts[:offset]
932
+ Sequel::Deprecation.deprecate("Dataset##{type} on datasets with limits or offsets", "Call unlimited to remove the limit #{'or skip_limit_check to ignore the limit ' unless type == :truncate}before calling #{type}") if @opts[:limit] || @opts[:offset]
933
+ end
934
+
925
935
  # Alias of check_modification_allowed!
926
936
  def check_truncation_allowed!
927
937
  check_modification_allowed!
@@ -1358,7 +1368,7 @@ module Sequel
1358
1368
 
1359
1369
  # Qualify the given expression e to the given table.
1360
1370
  def qualified_expression(e, table)
1361
- Qualifier.new(self, table).transform(e)
1371
+ Qualifier.new(table).transform(e)
1362
1372
  end
1363
1373
 
1364
1374
  def select_columns_sql(sql)
@@ -39,7 +39,7 @@ module Sequel
39
39
  # Print the message and possibly backtrace to the output.
40
40
  def self.deprecate(method, instead=nil)
41
41
  return unless output
42
- message = instead ? "#{method} is deprecated and will be removed in a future version of Sequel. #{instead}." : method
42
+ message = instead ? "#{method} is deprecated and will be removed in Sequel 5. #{instead}." : method
43
43
  message = "#{prefix}#{message}" if prefix
44
44
  output.puts(message)
45
45
  case b = backtrace_filter
@@ -56,5 +56,13 @@ module Sequel
56
56
  end
57
57
  nil
58
58
  end
59
+
60
+ # If using ruby 2.3+, use Module#deprecate_constant to deprecate the constant,
61
+ # otherwise do nothing as the ruby implementation does not support constant deprecation.
62
+ def self.deprecate_constant(mod, constant)
63
+ if RUBY_VERSION > '2.3'
64
+ mod.deprecate_constant(constant)
65
+ end
66
+ end
59
67
  end
60
68
  end