sequel 3.48.0 → 4.0.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 (267) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +114 -0
  3. data/Rakefile +10 -7
  4. data/doc/association_basics.rdoc +25 -23
  5. data/doc/code_order.rdoc +7 -0
  6. data/doc/core_extensions.rdoc +0 -10
  7. data/doc/object_model.rdoc +4 -1
  8. data/doc/querying.rdoc +3 -3
  9. data/doc/release_notes/4.0.0.txt +262 -0
  10. data/doc/security.rdoc +0 -28
  11. data/doc/testing.rdoc +8 -14
  12. data/lib/sequel/adapters/ado.rb +7 -11
  13. data/lib/sequel/adapters/ado/access.rb +8 -8
  14. data/lib/sequel/adapters/ado/mssql.rb +4 -4
  15. data/lib/sequel/adapters/amalgalite.rb +6 -6
  16. data/lib/sequel/adapters/cubrid.rb +7 -7
  17. data/lib/sequel/adapters/db2.rb +5 -9
  18. data/lib/sequel/adapters/dbi.rb +2 -6
  19. data/lib/sequel/adapters/do.rb +4 -4
  20. data/lib/sequel/adapters/firebird.rb +4 -4
  21. data/lib/sequel/adapters/ibmdb.rb +8 -8
  22. data/lib/sequel/adapters/informix.rb +2 -10
  23. data/lib/sequel/adapters/jdbc.rb +17 -17
  24. data/lib/sequel/adapters/jdbc/as400.rb +2 -2
  25. data/lib/sequel/adapters/jdbc/cubrid.rb +1 -1
  26. data/lib/sequel/adapters/jdbc/db2.rb +1 -1
  27. data/lib/sequel/adapters/jdbc/derby.rb +1 -1
  28. data/lib/sequel/adapters/jdbc/h2.rb +2 -2
  29. data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -1
  30. data/lib/sequel/adapters/jdbc/informix.rb +1 -1
  31. data/lib/sequel/adapters/jdbc/mssql.rb +2 -2
  32. data/lib/sequel/adapters/jdbc/mysql.rb +1 -1
  33. data/lib/sequel/adapters/jdbc/oracle.rb +5 -1
  34. data/lib/sequel/adapters/jdbc/postgresql.rb +3 -3
  35. data/lib/sequel/adapters/jdbc/sqlite.rb +3 -3
  36. data/lib/sequel/adapters/jdbc/transactions.rb +3 -3
  37. data/lib/sequel/adapters/mock.rb +7 -7
  38. data/lib/sequel/adapters/mysql.rb +3 -3
  39. data/lib/sequel/adapters/mysql2.rb +4 -4
  40. data/lib/sequel/adapters/odbc.rb +2 -6
  41. data/lib/sequel/adapters/odbc/mssql.rb +1 -1
  42. data/lib/sequel/adapters/openbase.rb +1 -5
  43. data/lib/sequel/adapters/oracle.rb +13 -17
  44. data/lib/sequel/adapters/postgres.rb +20 -25
  45. data/lib/sequel/adapters/shared/cubrid.rb +3 -3
  46. data/lib/sequel/adapters/shared/db2.rb +2 -2
  47. data/lib/sequel/adapters/shared/firebird.rb +7 -7
  48. data/lib/sequel/adapters/shared/mssql.rb +9 -9
  49. data/lib/sequel/adapters/shared/mysql.rb +29 -13
  50. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +7 -7
  51. data/lib/sequel/adapters/shared/oracle.rb +22 -13
  52. data/lib/sequel/adapters/shared/postgres.rb +61 -46
  53. data/lib/sequel/adapters/shared/sqlite.rb +9 -9
  54. data/lib/sequel/adapters/sqlite.rb +17 -11
  55. data/lib/sequel/adapters/swift.rb +3 -3
  56. data/lib/sequel/adapters/swift/mysql.rb +1 -1
  57. data/lib/sequel/adapters/swift/sqlite.rb +1 -1
  58. data/lib/sequel/adapters/tinytds.rb +8 -8
  59. data/lib/sequel/ast_transformer.rb +3 -1
  60. data/lib/sequel/connection_pool.rb +4 -2
  61. data/lib/sequel/connection_pool/sharded_single.rb +2 -2
  62. data/lib/sequel/connection_pool/sharded_threaded.rb +5 -5
  63. data/lib/sequel/connection_pool/threaded.rb +7 -7
  64. data/lib/sequel/core.rb +4 -67
  65. data/lib/sequel/database.rb +1 -0
  66. data/lib/sequel/database/connecting.rb +2 -8
  67. data/lib/sequel/database/dataset.rb +2 -7
  68. data/lib/sequel/database/dataset_defaults.rb +0 -18
  69. data/lib/sequel/database/features.rb +4 -4
  70. data/lib/sequel/database/misc.rb +6 -8
  71. data/lib/sequel/database/query.rb +5 -61
  72. data/lib/sequel/database/schema_generator.rb +22 -20
  73. data/lib/sequel/database/schema_methods.rb +48 -20
  74. data/lib/sequel/database/transactions.rb +7 -17
  75. data/lib/sequel/dataset.rb +2 -0
  76. data/lib/sequel/dataset/actions.rb +23 -91
  77. data/lib/sequel/dataset/features.rb +1 -4
  78. data/lib/sequel/dataset/graph.rb +3 -47
  79. data/lib/sequel/dataset/misc.rb +4 -33
  80. data/lib/sequel/dataset/prepared_statements.rb +3 -1
  81. data/lib/sequel/dataset/query.rb +116 -240
  82. data/lib/sequel/dataset/sql.rb +19 -97
  83. data/lib/sequel/deprecated.rb +0 -16
  84. data/lib/sequel/exceptions.rb +0 -3
  85. data/lib/sequel/extensions/_pretty_table.rb +1 -1
  86. data/lib/sequel/extensions/columns_introspection.rb +1 -12
  87. data/lib/sequel/extensions/constraint_validations.rb +3 -3
  88. data/lib/sequel/extensions/core_extensions.rb +0 -9
  89. data/lib/sequel/extensions/date_arithmetic.rb +1 -2
  90. data/lib/sequel/extensions/graph_each.rb +11 -0
  91. data/lib/sequel/extensions/migration.rb +5 -5
  92. data/lib/sequel/extensions/null_dataset.rb +11 -13
  93. data/lib/sequel/extensions/pagination.rb +3 -6
  94. data/lib/sequel/extensions/pg_array.rb +6 -4
  95. data/lib/sequel/extensions/pg_array_ops.rb +35 -1
  96. data/lib/sequel/extensions/pg_json.rb +12 -2
  97. data/lib/sequel/extensions/pg_json_ops.rb +266 -0
  98. data/lib/sequel/extensions/pg_range.rb +2 -2
  99. data/lib/sequel/extensions/pg_range_ops.rb +0 -8
  100. data/lib/sequel/extensions/pg_row.rb +2 -2
  101. data/lib/sequel/extensions/pretty_table.rb +0 -4
  102. data/lib/sequel/extensions/query.rb +3 -8
  103. data/lib/sequel/extensions/schema_caching.rb +0 -7
  104. data/lib/sequel/extensions/schema_dumper.rb +10 -17
  105. data/lib/sequel/extensions/select_remove.rb +0 -4
  106. data/lib/sequel/extensions/set_overrides.rb +28 -0
  107. data/lib/sequel/extensions/to_dot.rb +6 -10
  108. data/lib/sequel/model.rb +6 -7
  109. data/lib/sequel/model/associations.rb +127 -182
  110. data/lib/sequel/model/base.rb +88 -211
  111. data/lib/sequel/model/errors.rb +0 -13
  112. data/lib/sequel/model/plugins.rb +2 -2
  113. data/lib/sequel/no_core_ext.rb +0 -1
  114. data/lib/sequel/plugins/after_initialize.rb +11 -17
  115. data/lib/sequel/plugins/association_autoreloading.rb +1 -47
  116. data/lib/sequel/plugins/association_dependencies.rb +2 -2
  117. data/lib/sequel/plugins/auto_validations.rb +2 -8
  118. data/lib/sequel/plugins/blacklist_security.rb +32 -2
  119. data/lib/sequel/plugins/caching.rb +1 -1
  120. data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
  121. data/lib/sequel/plugins/composition.rb +10 -8
  122. data/lib/sequel/plugins/constraint_validations.rb +2 -2
  123. data/lib/sequel/plugins/dataset_associations.rb +4 -0
  124. data/lib/sequel/plugins/defaults_setter.rb +8 -6
  125. data/lib/sequel/plugins/dirty.rb +6 -6
  126. data/lib/sequel/plugins/force_encoding.rb +13 -8
  127. data/lib/sequel/plugins/hook_class_methods.rb +1 -7
  128. data/lib/sequel/plugins/json_serializer.rb +13 -74
  129. data/lib/sequel/plugins/lazy_attributes.rb +2 -4
  130. data/lib/sequel/plugins/list.rb +1 -1
  131. data/lib/sequel/plugins/many_through_many.rb +4 -11
  132. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +1 -49
  133. data/lib/sequel/plugins/nested_attributes.rb +1 -1
  134. data/lib/sequel/plugins/optimistic_locking.rb +3 -5
  135. data/lib/sequel/plugins/pg_array_associations.rb +453 -0
  136. data/lib/sequel/plugins/pg_typecast_on_load.rb +23 -7
  137. data/lib/sequel/plugins/prepared_statements.rb +1 -1
  138. data/lib/sequel/plugins/prepared_statements_associations.rb +20 -14
  139. data/lib/sequel/plugins/prepared_statements_safe.rb +2 -2
  140. data/lib/sequel/plugins/rcte_tree.rb +1 -1
  141. data/lib/sequel/plugins/serialization.rb +5 -4
  142. data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
  143. data/lib/sequel/plugins/sharding.rb +7 -1
  144. data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
  145. data/lib/sequel/plugins/timestamps.rb +1 -1
  146. data/lib/sequel/plugins/touch.rb +2 -2
  147. data/lib/sequel/plugins/tree.rb +1 -1
  148. data/lib/sequel/plugins/typecast_on_load.rb +19 -4
  149. data/lib/sequel/plugins/validation_class_methods.rb +0 -30
  150. data/lib/sequel/plugins/validation_helpers.rb +13 -31
  151. data/lib/sequel/plugins/xml_serializer.rb +18 -57
  152. data/lib/sequel/sql.rb +20 -22
  153. data/lib/sequel/version.rb +2 -2
  154. data/spec/adapters/db2_spec.rb +14 -23
  155. data/spec/adapters/firebird_spec.rb +25 -29
  156. data/spec/adapters/informix_spec.rb +11 -14
  157. data/spec/adapters/mssql_spec.rb +71 -77
  158. data/spec/adapters/mysql_spec.rb +165 -172
  159. data/spec/adapters/oracle_spec.rb +36 -39
  160. data/spec/adapters/postgres_spec.rb +175 -100
  161. data/spec/adapters/spec_helper.rb +13 -11
  162. data/spec/adapters/sqlite_spec.rb +36 -44
  163. data/spec/core/connection_pool_spec.rb +2 -1
  164. data/spec/core/database_spec.rb +55 -55
  165. data/spec/core/dataset_spec.rb +45 -249
  166. data/spec/core/deprecated_spec.rb +0 -8
  167. data/spec/core/expression_filters_spec.rb +23 -5
  168. data/spec/core/object_graph_spec.rb +4 -66
  169. data/spec/core/schema_spec.rb +35 -12
  170. data/spec/core/spec_helper.rb +3 -2
  171. data/spec/core_extensions_spec.rb +17 -19
  172. data/spec/extensions/arbitrary_servers_spec.rb +2 -3
  173. data/spec/extensions/association_dependencies_spec.rb +14 -14
  174. data/spec/extensions/auto_validations_spec.rb +7 -0
  175. data/spec/extensions/blacklist_security_spec.rb +5 -5
  176. data/spec/extensions/blank_spec.rb +2 -0
  177. data/spec/extensions/class_table_inheritance_spec.rb +2 -2
  178. data/spec/extensions/columns_introspection_spec.rb +2 -29
  179. data/spec/extensions/composition_spec.rb +10 -17
  180. data/spec/extensions/core_refinements_spec.rb +5 -1
  181. data/spec/extensions/dataset_associations_spec.rb +18 -0
  182. data/spec/extensions/date_arithmetic_spec.rb +2 -2
  183. data/spec/extensions/defaults_setter_spec.rb +9 -9
  184. data/spec/extensions/dirty_spec.rb +0 -5
  185. data/spec/extensions/eval_inspect_spec.rb +2 -0
  186. data/spec/extensions/force_encoding_spec.rb +2 -18
  187. data/spec/extensions/hash_aliases_spec.rb +8 -0
  188. data/spec/extensions/hook_class_methods_spec.rb +39 -58
  189. data/spec/extensions/inflector_spec.rb +2 -0
  190. data/spec/extensions/instance_filters_spec.rb +8 -8
  191. data/spec/extensions/json_serializer_spec.rb +1 -41
  192. data/spec/extensions/list_spec.rb +1 -1
  193. data/spec/extensions/many_through_many_spec.rb +106 -109
  194. data/spec/extensions/migration_spec.rb +2 -0
  195. data/spec/extensions/named_timezones_spec.rb +1 -0
  196. data/spec/extensions/pg_array_associations_spec.rb +603 -0
  197. data/spec/extensions/pg_array_ops_spec.rb +25 -0
  198. data/spec/extensions/pg_array_spec.rb +9 -1
  199. data/spec/extensions/pg_hstore_ops_spec.rb +13 -0
  200. data/spec/extensions/pg_hstore_spec.rb +1 -0
  201. data/spec/extensions/pg_json_ops_spec.rb +131 -0
  202. data/spec/extensions/pg_json_spec.rb +10 -4
  203. data/spec/extensions/pg_range_ops_spec.rb +2 -5
  204. data/spec/extensions/pg_range_spec.rb +6 -2
  205. data/spec/extensions/pg_row_ops_spec.rb +2 -0
  206. data/spec/extensions/prepared_statements_associations_spec.rb +26 -5
  207. data/spec/extensions/rcte_tree_spec.rb +15 -15
  208. data/spec/extensions/schema_dumper_spec.rb +0 -1
  209. data/spec/extensions/schema_spec.rb +9 -9
  210. data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
  211. data/spec/extensions/serialization_spec.rb +18 -29
  212. data/spec/extensions/set_overrides_spec.rb +4 -0
  213. data/spec/extensions/{many_to_one_pk_lookup_spec.rb → shared_caching_spec.rb} +1 -4
  214. data/spec/extensions/single_table_inheritance_spec.rb +4 -4
  215. data/spec/extensions/spec_helper.rb +8 -9
  216. data/spec/extensions/sql_expr_spec.rb +2 -0
  217. data/spec/extensions/string_date_time_spec.rb +2 -0
  218. data/spec/extensions/string_stripper_spec.rb +2 -0
  219. data/spec/extensions/tactical_eager_loading_spec.rb +12 -12
  220. data/spec/extensions/thread_local_timezones_spec.rb +2 -0
  221. data/spec/extensions/timestamps_spec.rb +1 -1
  222. data/spec/extensions/to_dot_spec.rb +1 -1
  223. data/spec/extensions/touch_spec.rb +24 -24
  224. data/spec/extensions/tree_spec.rb +7 -7
  225. data/spec/extensions/typecast_on_load_spec.rb +8 -1
  226. data/spec/extensions/update_primary_key_spec.rb +10 -10
  227. data/spec/extensions/validation_class_methods_spec.rb +10 -39
  228. data/spec/extensions/validation_helpers_spec.rb +29 -47
  229. data/spec/extensions/xml_serializer_spec.rb +1 -23
  230. data/spec/integration/associations_test.rb +231 -40
  231. data/spec/integration/database_test.rb +1 -1
  232. data/spec/integration/dataset_test.rb +64 -64
  233. data/spec/integration/eager_loader_test.rb +28 -28
  234. data/spec/integration/migrator_test.rb +1 -1
  235. data/spec/integration/model_test.rb +2 -2
  236. data/spec/integration/plugin_test.rb +21 -21
  237. data/spec/integration/prepared_statement_test.rb +7 -7
  238. data/spec/integration/schema_test.rb +115 -110
  239. data/spec/integration/spec_helper.rb +17 -27
  240. data/spec/integration/timezone_test.rb +1 -1
  241. data/spec/integration/transaction_test.rb +10 -10
  242. data/spec/integration/type_test.rb +2 -2
  243. data/spec/model/association_reflection_spec.rb +2 -28
  244. data/spec/model/associations_spec.rb +239 -188
  245. data/spec/model/base_spec.rb +27 -68
  246. data/spec/model/dataset_methods_spec.rb +4 -4
  247. data/spec/model/eager_loading_spec.rb +160 -172
  248. data/spec/model/hooks_spec.rb +62 -79
  249. data/spec/model/model_spec.rb +36 -51
  250. data/spec/model/plugins_spec.rb +5 -19
  251. data/spec/model/record_spec.rb +125 -151
  252. data/spec/model/spec_helper.rb +8 -6
  253. data/spec/model/validations_spec.rb +4 -17
  254. data/spec/spec_config.rb +2 -10
  255. metadata +50 -56
  256. data/lib/sequel/deprecated_core_extensions.rb +0 -135
  257. data/lib/sequel/extensions/pg_auto_parameterize.rb +0 -185
  258. data/lib/sequel/extensions/pg_statement_cache.rb +0 -318
  259. data/lib/sequel/plugins/identity_map.rb +0 -260
  260. data/lib/sequel_core.rb +0 -2
  261. data/lib/sequel_model.rb +0 -2
  262. data/spec/extensions/association_autoreloading_spec.rb +0 -102
  263. data/spec/extensions/identity_map_spec.rb +0 -337
  264. data/spec/extensions/pg_auto_parameterize_spec.rb +0 -70
  265. data/spec/extensions/pg_statement_cache_spec.rb +0 -208
  266. data/spec/rcov.opts +0 -8
  267. data/spec/spec_config.rb.example +0 -10
@@ -10,11 +10,8 @@ module Sequel
10
10
  def quote_identifiers?
11
11
  if defined?(@quote_identifiers)
12
12
  @quote_identifiers
13
- elsif db.respond_to?(:quote_identifiers?)
14
- @quote_identifiers = db.quote_identifiers?
15
13
  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.')
17
- @quote_identifiers = false
14
+ @quote_identifiers = db.quote_identifiers?
18
15
  end
19
16
  end
20
17
 
@@ -14,10 +14,8 @@ module Sequel
14
14
  # DB[:table].add_graph_aliases(:some_alias=>[:table, :column])
15
15
  # # SELECT ..., table.column AS some_alias
16
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
17
+ unless (ga = opts[:graph_aliases]) || (opts[:graph] && (ga = opts[:graph][:column_aliases]))
18
+ raise Error, "cannot call add_graph_aliases on a dataset that has not been called with graph or set_graph_aliases"
21
19
  end
22
20
  columns, graph_aliases = graph_alias_columns(graph_aliases)
23
21
  select_more(*columns).clone(:graph_aliases => ga.merge(graph_aliases))
@@ -48,7 +46,7 @@ module Sequel
48
46
  # :table_alias :: The alias to use for the table. If not specified, doesn't
49
47
  # alias the table. You will get an error if the the alias (or table) name is
50
48
  # used more than once.
51
- def graph(dataset, join_conditions = nil, options = {}, &block)
49
+ def graph(dataset, join_conditions = nil, options = OPTS, &block)
52
50
  # Allow the use of a dataset or symbol as the first argument
53
51
  # Find the table name/dataset based on the argument
54
52
  table_alias = options[:table_alias]
@@ -232,47 +230,5 @@ module Sequel
232
230
  end
233
231
  [identifiers, gas]
234
232
  end
235
-
236
- # Fetch the rows, split them into component table parts,
237
- # tranform and run the row_proc on each part (if applicable),
238
- # and yield a hash of the parts.
239
- def graph_each
240
- Sequel::Deprecation.deprecate('Dataset#graph_each', 'Load the graph_each extension if you want to continue using it')
241
- # Reject tables with nil datasets, as they are excluded from
242
- # the result set
243
- datasets = @opts[:graph][:table_aliases].to_a.reject{|ta,ds| ds.nil?}
244
- # Get just the list of table aliases into a local variable, for speed
245
- table_aliases = datasets.collect{|ta,ds| ta}
246
- # Get an array of arrays, one for each dataset, with
247
- # the necessary information about each dataset, for speed
248
- datasets = datasets.collect{|ta, ds| [ta, ds, ds.row_proc]}
249
- # Use the manually set graph aliases, if any, otherwise
250
- # use the ones automatically created by .graph
251
- column_aliases = @opts[:graph_aliases] || @opts[:graph][:column_aliases]
252
- fetch_rows(select_sql) do |r|
253
- graph = {}
254
- # Create the sub hashes, one per table
255
- table_aliases.each{|ta| graph[ta]={}}
256
- # Split the result set based on the column aliases
257
- # If there are columns in the result set that are
258
- # not in column_aliases, they are ignored
259
- column_aliases.each do |col_alias, tc|
260
- ta, column = tc
261
- graph[ta][column] = r[col_alias]
262
- end
263
- # For each dataset run the row_proc if applicable
264
- datasets.each do |ta,ds,rp|
265
- g = graph[ta]
266
- graph[ta] = if g.values.any?{|x| !x.nil?}
267
- rp ? rp.call(g) : g
268
- else
269
- nil
270
- end
271
- end
272
-
273
- yield graph
274
- end
275
- self
276
- end
277
233
  end
278
234
  end
@@ -17,27 +17,6 @@ module Sequel
17
17
  # The hash of options for this dataset, keys are symbols.
18
18
  attr_reader :opts
19
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
-
41
20
  # Constructs a new Dataset instance with an associated database and
42
21
  # options. Datasets are usually constructed by invoking the Database#[] method:
43
22
  #
@@ -46,11 +25,9 @@ module Sequel
46
25
  # Sequel::Dataset is an abstract class that is not useful by itself. Each
47
26
  # database adapter provides a subclass of Sequel::Dataset, and has
48
27
  # the Database#dataset method return an instance of that subclass.
49
- def initialize(db, opts = (no_arg_given=true; nil))
28
+ def initialize(db)
50
29
  @db = db
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)
30
+ @opts = OPTS
54
31
  end
55
32
 
56
33
  # Define a hash value such that datasets with the same DB, opts, and SQL
@@ -147,11 +124,8 @@ module Sequel
147
124
  def identifier_input_method
148
125
  if defined?(@identifier_input_method)
149
126
  @identifier_input_method
150
- elsif db.respond_to?(:identifier_input_method)
151
- @identifier_input_method = db.identifier_input_method
152
127
  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.')
154
- @identifier_input_method = nil
128
+ @identifier_input_method = db.identifier_input_method
155
129
  end
156
130
  end
157
131
 
@@ -160,11 +134,8 @@ module Sequel
160
134
  def identifier_output_method
161
135
  if defined?(@identifier_output_method)
162
136
  @identifier_output_method
163
- elsif db.respond_to?(:identifier_output_method)
164
- @identifier_output_method = db.identifier_output_method
165
137
  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.')
167
- @identifier_output_method = nil
138
+ @identifier_output_method = db.identifier_output_method
168
139
  end
169
140
  end
170
141
 
@@ -118,7 +118,9 @@ module Sequel
118
118
  # with the prepared SQL it represents (which in general won't have
119
119
  # substituted variables).
120
120
  def inspect
121
- "<#{self.class.name}/PreparedStatement #{prepared_sql.inspect}>"
121
+ c = self.class
122
+ c = c.superclass while c.name.nil? || c.name == ''
123
+ "<#{c.name}/PreparedStatement #{prepared_sql.inspect}>"
122
124
  end
123
125
 
124
126
  protected
@@ -64,22 +64,9 @@ module Sequel
64
64
  Sequel.synchronize{EXTENSIONS[ext] = block}
65
65
  end
66
66
 
67
- # Adds an further filter to an existing filter using AND. If no filter
68
- # exists an error is raised. This method is identical to #filter except
69
- # it expects an existing filter.
70
- #
71
- # DB[:table].filter(:a).and(:b) # SELECT * FROM table WHERE a AND b
67
+ # Alias for where.
72
68
  def and(*cond, &block)
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
69
+ where(*cond, &block)
83
70
  end
84
71
 
85
72
  # Returns a new clone of the dataset with with the given options merged.
@@ -128,17 +115,13 @@ module Sequel
128
115
  #
129
116
  # DB[:items].except(DB[:other_items], :alias=>:i)
130
117
  # # SELECT * FROM (SELECT * FROM items EXCEPT SELECT * FROM other_items) AS i
131
- def except(dataset, opts={})
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
118
+ def except(dataset, opts=OPTS)
136
119
  raise(InvalidOperation, "EXCEPT not supported") unless supports_intersect_except?
137
120
  raise(InvalidOperation, "EXCEPT ALL not supported") if opts[:all] && !supports_intersect_except_all?
138
121
  compound_clone(:except, dataset, opts)
139
122
  end
140
123
 
141
- # Performs the inverse of Dataset#filter. Note that if you have multiple filter
124
+ # Performs the inverse of Dataset#where. Note that if you have multiple filter
142
125
  # conditions, this is not the same as a negation of all conditions.
143
126
  #
144
127
  # DB[:items].exclude(:category => 'software')
@@ -147,8 +130,7 @@ module Sequel
147
130
  # DB[:items].exclude(:category => 'software', :id=>3)
148
131
  # # SELECT * FROM items WHERE ((category != 'software') OR (id != 3))
149
132
  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]
151
- _filter_or_exclude(true, @opts[:having] ? :having : :where, *cond, &block)
133
+ _filter_or_exclude(true, :where, *cond, &block)
152
134
  end
153
135
 
154
136
  # Inverts the given conditions and adds them to the HAVING clause.
@@ -159,18 +141,9 @@ module Sequel
159
141
  _filter_or_exclude(true, :having, *cond, &block)
160
142
  end
161
143
 
162
- # Inverts the given conditions and adds them to the WHERE clause.
163
- #
164
- # DB[:items].select_group(:name).exclude_where(:category => 'software')
165
- # # SELECT * FROM items WHERE (category != 'software')
166
- #
167
- # DB[:items].select_group(:name).
168
- # exclude_having{count(name) < 2}.
169
- # exclude_where(:category => 'software')
170
- # # SELECT name FROM items WHERE (category != 'software')
171
- # # GROUP BY name HAVING (count(name) >= 2)
144
+ # Alias for exclude.
172
145
  def exclude_where(*cond, &block)
173
- _filter_or_exclude(true, :where, *cond, &block)
146
+ exclude(*cond, &block)
174
147
  end
175
148
 
176
149
  # Return a clone of the dataset loaded with the extensions, see #extension!.
@@ -178,61 +151,9 @@ module Sequel
178
151
  clone.extension!(*exts)
179
152
  end
180
153
 
181
- # Returns a copy of the dataset with the given conditions imposed upon it.
182
- # If the query already has a HAVING clause, then the conditions are imposed in the
183
- # HAVING clause. If not, then they are imposed in the WHERE clause.
184
- #
185
- # filter accepts the following argument types:
186
- #
187
- # * Hash - list of equality/inclusion expressions
188
- # * Array - depends:
189
- # * If first member is a string, assumes the rest of the arguments
190
- # are parameters and interpolates them into the string.
191
- # * If all members are arrays of length two, treats the same way
192
- # as a hash, except it allows for duplicate keys to be
193
- # specified.
194
- # * Otherwise, treats each argument as a separate condition.
195
- # * String - taken literally
196
- # * Symbol - taken as a boolean column argument (e.g. WHERE active)
197
- # * Sequel::SQL::BooleanExpression - an existing condition expression,
198
- # probably created using the Sequel expression filter DSL.
199
- #
200
- # filter also takes a block, which should return one of the above argument
201
- # types, and is treated the same way. This block yields a virtual row object,
202
- # which is easy to use to create identifiers and functions. For more details
203
- # on the virtual row support, see the {"Virtual Rows" guide}[link:files/doc/virtual_rows_rdoc.html]
204
- #
205
- # If both a block and regular argument are provided, they get ANDed together.
206
- #
207
- # Examples:
208
- #
209
- # DB[:items].filter(:id => 3)
210
- # # SELECT * FROM items WHERE (id = 3)
211
- #
212
- # DB[:items].filter('price < ?', 100)
213
- # # SELECT * FROM items WHERE price < 100
214
- #
215
- # DB[:items].filter([[:id, [1,2,3]], [:id, 0..10]])
216
- # # SELECT * FROM items WHERE ((id IN (1, 2, 3)) AND ((id >= 0) AND (id <= 10)))
217
- #
218
- # DB[:items].filter('price < 100')
219
- # # SELECT * FROM items WHERE price < 100
220
- #
221
- # DB[:items].filter(:active)
222
- # # SELECT * FROM items WHERE :active
223
- #
224
- # DB[:items].filter{price < 100}
225
- # # SELECT * FROM items WHERE (price < 100)
226
- #
227
- # Multiple filter calls can be chained for scoping:
228
- #
229
- # software = dataset.filter(:category => 'software').filter{price < 100}
230
- # # SELECT * FROM items WHERE ((category = 'software') AND (price < 100))
231
- #
232
- # See the the {"Dataset Filtering" guide}[link:files/doc/dataset_filtering_rdoc.html] for more examples and details.
154
+ # Alias for where.
233
155
  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]
235
- _filter(@opts[:having] ? :having : :where, *cond, &block)
156
+ where(*cond, &block)
236
157
  end
237
158
 
238
159
  # Returns a cloned dataset with a :update lock style.
@@ -245,39 +166,38 @@ module Sequel
245
166
  # Returns a copy of the dataset with the source changed. If no
246
167
  # source is given, removes all tables. If multiple sources
247
168
  # are given, it is the same as using a CROSS JOIN (cartesian product) between all tables.
169
+ # If a block is given, it is treated as a virtual row block, similar to +where+.
248
170
  #
249
171
  # DB[:items].from # SQL: SELECT *
250
172
  # DB[:items].from(:blah) # SQL: SELECT * FROM blah
251
173
  # DB[:items].from(:blah, :foo) # SQL: SELECT * FROM blah, foo
252
- def from(*source)
174
+ # DB[:items].from{fun(arg)} # SQL: SELECT * FROM fun(arg)
175
+ def from(*source, &block)
176
+ virtual_row_columns(source, block)
253
177
  table_alias_num = 0
254
- sources = []
255
178
  ctes = nil
256
- source.each do |s|
179
+ source.map! do |s|
257
180
  case s
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.')
260
- s.each{|k,v| sources << SQL::AliasedExpression.new(k,v)}
261
181
  when Dataset
262
182
  if hoist_cte?(s)
263
183
  ctes ||= []
264
184
  ctes += s.opts[:with]
265
185
  s = s.clone(:with=>nil)
266
186
  end
267
- sources << SQL::AliasedExpression.new(s, dataset_alias(table_alias_num+=1))
187
+ SQL::AliasedExpression.new(s, dataset_alias(table_alias_num+=1))
268
188
  when Symbol
269
189
  sch, table, aliaz = split_symbol(s)
270
190
  if aliaz
271
191
  s = sch ? SQL::QualifiedIdentifier.new(sch, table) : SQL::Identifier.new(table)
272
- sources << SQL::AliasedExpression.new(s, aliaz.to_sym)
192
+ SQL::AliasedExpression.new(s, aliaz.to_sym)
273
193
  else
274
- sources << s
194
+ s
275
195
  end
276
196
  else
277
- sources << s
197
+ s
278
198
  end
279
199
  end
280
- o = {:from=>sources.empty? ? nil : sources}
200
+ o = {:from=>source.empty? ? nil : source}
281
201
  o[:with] = (opts[:with] || []) + ctes if ctes
282
202
  o[:num_dataset_sources] = table_alias_num if table_alias_num > 0
283
203
  clone(o)
@@ -294,7 +214,7 @@ module Sequel
294
214
  #
295
215
  # ds.from_self(:alias=>:foo)
296
216
  # # SELECT * FROM (SELECT id, name FROM items ORDER BY name) AS foo
297
- def from_self(opts={})
217
+ def from_self(opts=OPTS)
298
218
  fs = {}
299
219
  @opts.keys.each{|k| fs[k] = nil unless NON_SQL_OPTIONS.include?(k)}
300
220
  clone(fs).from(opts[:alias] ? as(opts[:alias]) : self)
@@ -331,23 +251,23 @@ module Sequel
331
251
  #
332
252
  # dataset.grep([:a, :b], %w'%foo% %bar%', :all_patterns=>true, :all_columns=>true)
333
253
  # # SELECT * FROM a WHERE ((a LIKE '%foo%') AND (b LIKE '%foo%') AND (a LIKE '%bar%') AND (b LIKE '%bar%'))
334
- def grep(columns, patterns, opts={})
254
+ def grep(columns, patterns, opts=OPTS)
335
255
  if opts[:all_patterns]
336
256
  conds = Array(patterns).map do |pat|
337
257
  SQL::BooleanExpression.new(opts[:all_columns] ? :AND : :OR, *Array(columns).map{|c| SQL::StringExpression.like(c, pat, opts)})
338
258
  end
339
- filter(SQL::BooleanExpression.new(opts[:all_patterns] ? :AND : :OR, *conds))
259
+ where(SQL::BooleanExpression.new(opts[:all_patterns] ? :AND : :OR, *conds))
340
260
  else
341
261
  conds = Array(columns).map do |c|
342
262
  SQL::BooleanExpression.new(:OR, *Array(patterns).map{|pat| SQL::StringExpression.like(c, pat, opts)})
343
263
  end
344
- filter(SQL::BooleanExpression.new(opts[:all_columns] ? :AND : :OR, *conds))
264
+ where(SQL::BooleanExpression.new(opts[:all_columns] ? :AND : :OR, *conds))
345
265
  end
346
266
  end
347
267
 
348
268
  # Returns a copy of the dataset with the results grouped by the value of
349
269
  # the given columns. If a block is given, it is treated
350
- # as a virtual row block, similar to +filter+.
270
+ # as a virtual row block, similar to +where+.
351
271
  #
352
272
  # DB[:items].group(:id) # SELECT * FROM items GROUP BY id
353
273
  # DB[:items].group(:id, :name) # SELECT * FROM items GROUP BY id, name
@@ -364,7 +284,7 @@ module Sequel
364
284
 
365
285
  # Returns a dataset grouped by the given column with count by group.
366
286
  # Column aliases may be supplied, and will be included in the select clause.
367
- # If a block is given, it is treated as a virtual row block, similar to +filter+.
287
+ # If a block is given, it is treated as a virtual row block, similar to +where+.
368
288
  #
369
289
  # Examples:
370
290
  #
@@ -399,7 +319,7 @@ module Sequel
399
319
  clone(:group_options=>:rollup)
400
320
  end
401
321
 
402
- # Returns a copy of the dataset with the HAVING conditions changed. See #filter for argument types.
322
+ # Returns a copy of the dataset with the HAVING conditions changed. See #where for argument types.
403
323
  #
404
324
  # DB[:items].group(:sum).having(:sum=>10)
405
325
  # # SELECT * FROM items GROUP BY sum HAVING (sum = 10)
@@ -424,33 +344,30 @@ module Sequel
424
344
  #
425
345
  # DB[:items].intersect(DB[:other_items], :alias=>:i)
426
346
  # # SELECT * FROM (SELECT * FROM items INTERSECT SELECT * FROM other_items) AS i
427
- def intersect(dataset, opts={})
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
347
+ def intersect(dataset, opts=OPTS)
432
348
  raise(InvalidOperation, "INTERSECT not supported") unless supports_intersect_except?
433
349
  raise(InvalidOperation, "INTERSECT ALL not supported") if opts[:all] && !supports_intersect_except_all?
434
350
  compound_clone(:intersect, dataset, opts)
435
351
  end
436
352
 
437
- # Inverts the current filter.
353
+ # Inverts the current WHERE and HAVING clauses. If there is neither a
354
+ # WHERE or HAVING clause, adds a WHERE clause that is always false.
438
355
  #
439
- # DB[:items].filter(:category => 'software').invert
356
+ # DB[:items].where(:category => 'software').invert
440
357
  # # SELECT * FROM items WHERE (category != 'software')
441
358
  #
442
- # DB[:items].filter(:category => 'software', :id=>3).invert
359
+ # DB[:items].where(:category => 'software', :id=>3).invert
443
360
  # # SELECT * FROM items WHERE ((category != 'software') OR (id != 3))
444
361
  def invert
445
- having, where = @opts[:having], @opts[:where]
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")
362
+ having, where = @opts.values_at(:having, :where)
363
+ if having.nil? && where.nil?
364
+ where(false)
365
+ else
366
+ o = {}
367
+ o[:having] = SQL::BooleanExpression.invert(having) if having
368
+ o[:where] = SQL::BooleanExpression.invert(where) if where
369
+ clone(o)
449
370
  end
450
- o = {}
451
- o[:having] = SQL::BooleanExpression.invert(having) if having
452
- o[:where] = SQL::BooleanExpression.invert(where) if where
453
- clone(o)
454
371
  end
455
372
 
456
373
  # Alias of +inner_join+
@@ -479,7 +396,7 @@ module Sequel
479
396
  # the result set if this is used.
480
397
  # * nil - If a block is not given, doesn't use ON or USING, so the JOIN should be a NATURAL
481
398
  # or CROSS join. If a block is given, uses an ON clause based on the block, see below.
482
- # * Everything else - pretty much the same as a using the argument in a call to filter,
399
+ # * Everything else - pretty much the same as a using the argument in a call to where,
483
400
  # so strings are considered literal, symbols specify boolean columns, and Sequel
484
401
  # expressions can be used. Uses a JOIN with an ON clause.
485
402
  # * options - a hash of options, with any of the following keys:
@@ -489,12 +406,12 @@ module Sequel
489
406
  # the last joined or primary table is used.
490
407
  # * :qualify - Can be set to false to not do any implicit qualification. Can be set
491
408
  # to :deep to use the Qualifier AST Transformer, which will attempt to qualify
492
- # subexpressions of the expression tree. Defaults to the value of
493
- # default_join_table_qualification.
409
+ # subexpressions of the expression tree. Can be set to :symbol to only qualify
410
+ # symbols. Defaults to the value of default_join_table_qualification.
494
411
  # * block - The block argument should only be given if a JOIN with an ON clause is used,
495
412
  # in which case it yields the table alias/name for the table currently being joined,
496
413
  # the table alias/name for the last joined (or first table), and an array of previous
497
- # SQL::JoinClause. Unlike +filter+, this block is not treated as a virtual row block.
414
+ # SQL::JoinClause. Unlike +where+, this block is not treated as a virtual row block.
498
415
  #
499
416
  # Examples:
500
417
  #
@@ -512,7 +429,7 @@ module Sequel
512
429
  # end
513
430
  # # SELECT * FROM a NATURAL JOIN b INNER JOIN c
514
431
  # # ON ((c.d > b.e) AND (c.f IN (SELECT g FROM b)))
515
- def join_table(type, table, expr=nil, options={}, &block)
432
+ def join_table(type, table, expr=nil, options=OPTS, &block)
516
433
  if hoist_cte?(table)
517
434
  s, ds = hoist_cte(table)
518
435
  return s.join_table(type, ds, expr, options, &block)
@@ -525,18 +442,9 @@ module Sequel
525
442
  return join_table(type, table, h, options)
526
443
  end
527
444
 
528
- case options
529
- when Hash
530
- table_alias = options[:table_alias]
531
- last_alias = options[:implicit_qualifier]
532
- qualify_type = options[:qualify]
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")
535
- table_alias = options
536
- last_alias = nil
537
- else
538
- raise Error, "invalid options format for join_table: #{options.inspect}"
539
- end
445
+ table_alias = options[:table_alias]
446
+ last_alias = options[:implicit_qualifier]
447
+ qualify_type = options[:qualify]
540
448
 
541
449
  if table.is_a?(Dataset)
542
450
  if table_alias.nil?
@@ -655,19 +563,14 @@ module Sequel
655
563
  # Adds an alternate filter to an existing filter using OR. If no filter
656
564
  # exists an +Error+ is raised.
657
565
  #
658
- # DB[:items].filter(:a).or(:b) # SELECT * FROM items WHERE a OR b
566
+ # DB[:items].where(:a).or(:b) # SELECT * FROM items WHERE a OR b
659
567
  def or(*cond, &block)
660
- clause = (@opts[:having] ? :having : :where)
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
666
568
  cond = cond.first if cond.size == 1
667
- if cond.respond_to?(:empty?) && cond.empty? && !block
569
+ v = @opts[:where]
570
+ if v.nil? || (cond.respond_to?(:empty?) && cond.empty? && !block)
668
571
  clone
669
572
  else
670
- clone(clause => SQL::BooleanExpression.new(:OR, @opts[clause], filter_expr(cond, &block)))
573
+ clone(:where => SQL::BooleanExpression.new(:OR, v, filter_expr(cond, &block)))
671
574
  end
672
575
  end
673
576
 
@@ -675,7 +578,7 @@ module Sequel
675
578
  # existing order, it is ignored and overwritten with this order. If a nil is given
676
579
  # the returned dataset has no order. This can accept multiple arguments
677
580
  # of varying kinds, such as SQL functions. If a block is given, it is treated
678
- # as a virtual row block, similar to +filter+.
581
+ # as a virtual row block, similar to +where+.
679
582
  #
680
583
  # DB[:items].order(:name) # SELECT * FROM items ORDER BY name
681
584
  # DB[:items].order(:a, :b) # SELECT * FROM items ORDER BY a, b
@@ -722,10 +625,10 @@ module Sequel
722
625
 
723
626
  # Qualify to the given table, or first source if no table is given.
724
627
  #
725
- # DB[:items].filter(:id=>1).qualify
628
+ # DB[:items].where(:id=>1).qualify
726
629
  # # SELECT items.* FROM items WHERE (items.id = 1)
727
630
  #
728
- # DB[:items].filter(:id=>1).qualify(:i)
631
+ # DB[:items].where(:id=>1).qualify(:i)
729
632
  # # SELECT i.* FROM items WHERE (i.id = 1)
730
633
  def qualify(table=first_source)
731
634
  o = @opts
@@ -738,31 +641,6 @@ module Sequel
738
641
  clone(h)
739
642
  end
740
643
 
741
- # Return a copy of the dataset with unqualified identifiers in the
742
- # SELECT, WHERE, GROUP, HAVING, and ORDER clauses qualified by the
743
- # given table. If no columns are currently selected, select all
744
- # columns of the given table.
745
- #
746
- # DB[:items].filter(:id=>1).qualify_to(:i)
747
- # # SELECT i.* FROM items WHERE (i.id = 1)
748
- def qualify_to(table)
749
- Sequel::Deprecation.deprecate('Dataset#qualify_to', 'Switch to Dataset#qualify or use the sequel_3_dataset_methods extension')
750
- qualify(table)
751
- end
752
-
753
- # Qualify the dataset to its current first source. This is useful
754
- # if you have unqualified identifiers in the query that all refer to
755
- # the first source, and you want to join to another table which
756
- # has columns with the same name as columns in the current dataset.
757
- # See +qualify_to+.
758
- #
759
- # DB[:items].filter(:id=>1).qualify_to_first_source
760
- # # SELECT items.* FROM items WHERE (items.id = 1)
761
- def qualify_to_first_source
762
- Sequel::Deprecation.deprecate('Dataset#qualify_to_first_source', 'Switch to Dataset#qualify or use the sequel_3_dataset_methods extension')
763
- qualify
764
- end
765
-
766
644
  # Modify the RETURNING clause, only supported on a few databases. If returning
767
645
  # is used, instead of insert returning the autogenerated primary key or
768
646
  # update/delete returning the number of modified rows, results are
@@ -794,23 +672,14 @@ module Sequel
794
672
 
795
673
  # Returns a copy of the dataset with the columns selected changed
796
674
  # to the given columns. This also takes a virtual row block,
797
- # similar to +filter+.
675
+ # similar to +where+.
798
676
  #
799
677
  # DB[:items].select(:a) # SELECT a FROM items
800
678
  # DB[:items].select(:a, :b) # SELECT a, b FROM items
801
679
  # DB[:items].select{[a, sum(b)]} # SELECT a, sum(b) FROM items
802
680
  def select(*columns, &block)
803
681
  virtual_row_columns(columns, block)
804
- m = []
805
- columns.each do |i|
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
812
- end
813
- clone(:select => m)
682
+ clone(:select => columns)
814
683
  end
815
684
 
816
685
  # Returns a copy of the dataset selecting the wildcard if no arguments
@@ -848,7 +717,7 @@ module Sequel
848
717
 
849
718
  # Set both the select and group clauses with the given +columns+.
850
719
  # Column aliases may be supplied, and will be included in the select clause.
851
- # This also takes a virtual row block similar to +filter+.
720
+ # This also takes a virtual row block similar to +where+.
852
721
  #
853
722
  # DB[:items].select_group(:a, :b)
854
723
  # # SELECT a, b FROM items GROUP BY a, b
@@ -860,20 +729,9 @@ module Sequel
860
729
  select(*columns).group(*columns.map{|c| unaliased_identifier(c)})
861
730
  end
862
731
 
863
- # Returns a copy of the dataset with the given columns added
864
- # to the existing selected columns. If no columns are currently selected
865
- # it will just select the columns given.
866
- #
867
- # DB[:items].select(:a).select(:b) # SELECT b FROM items
868
- # DB[:items].select(:a).select_more(:b) # SELECT a, b FROM items
869
- # DB[:items].select_more(:b) # SELECT b FROM items
732
+ # Alias for select_append.
870
733
  def select_more(*columns, &block)
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
876
- select(*columns, &block)
734
+ select_append(*columns, &block)
877
735
  end
878
736
 
879
737
  # Set the server for this dataset to use. Used to pick a specific database
@@ -889,35 +747,13 @@ module Sequel
889
747
  clone(:server=>servr)
890
748
  end
891
749
 
892
- # Set the default values for insert and update statements. The values hash passed
893
- # to insert or update are merged into this hash, so any values in the hash passed
894
- # to insert or update will override values passed to this method.
895
- #
896
- # DB[:items].set_defaults(:a=>'a', :c=>'c').insert(:a=>'d', :b=>'b')
897
- # # INSERT INTO items (a, c, b) VALUES ('d', 'c', 'b')
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')
900
- clone(:defaults=>(@opts[:defaults]||{}).merge(hash))
901
- end
902
-
903
- # Set values that override hash arguments given to insert and update statements.
904
- # This hash is merged into the hash provided to insert or update, so values
905
- # will override any values given in the insert/update hashes.
906
- #
907
- # DB[:items].set_overrides(:a=>'a', :c=>'c').insert(:a=>'d', :b=>'b')
908
- # # INSERT INTO items (a, c, b) VALUES ('a', 'c', 'b')
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')
911
- clone(:overrides=>hash.merge(@opts[:overrides]||{}))
912
- end
913
-
914
750
  # Unbind bound variables from this dataset's filter and return an array of two
915
751
  # objects. The first object is a modified dataset where the filter has been
916
752
  # replaced with one that uses bound variable placeholders. The second object
917
753
  # is the hash of unbound variables. You can then prepare and execute (or just
918
754
  # call) the dataset with the bound variables to get results.
919
755
  #
920
- # ds, bv = DB[:items].filter(:a=>1).unbind
756
+ # ds, bv = DB[:items].where(:a=>1).unbind
921
757
  # ds # SELECT * FROM items WHERE (a = $a)
922
758
  # bv # {:a => 1}
923
759
  # ds.call(:select, bv)
@@ -959,11 +795,7 @@ module Sequel
959
795
  #
960
796
  # DB[:items].union(DB[:other_items], :alias=>:i)
961
797
  # # SELECT * FROM (SELECT * FROM items UNION SELECT * FROM other_items) AS i
962
- def union(dataset, opts={})
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
798
+ def union(dataset, opts=OPTS)
967
799
  compound_clone(:union, dataset, opts)
968
800
  end
969
801
 
@@ -981,13 +813,56 @@ module Sequel
981
813
  order(nil)
982
814
  end
983
815
 
984
- # Add a condition to the WHERE clause. See +filter+ for argument types.
816
+ # Returns a copy of the dataset with the given WHERE conditions imposed upon it.
817
+ #
818
+ # Accepts the following argument types:
819
+ #
820
+ # * Hash - list of equality/inclusion expressions
821
+ # * Array - depends:
822
+ # * If first member is a string, assumes the rest of the arguments
823
+ # are parameters and interpolates them into the string.
824
+ # * If all members are arrays of length two, treats the same way
825
+ # as a hash, except it allows for duplicate keys to be
826
+ # specified.
827
+ # * Otherwise, treats each argument as a separate condition.
828
+ # * String - taken literally
829
+ # * Symbol - taken as a boolean column argument (e.g. WHERE active)
830
+ # * Sequel::SQL::BooleanExpression - an existing condition expression,
831
+ # probably created using the Sequel expression filter DSL.
985
832
  #
986
- # DB[:items].group(:a).having(:a).filter(:b)
987
- # # SELECT * FROM items GROUP BY a HAVING a AND b
833
+ # where also accepts a block, which should return one of the above argument
834
+ # types, and is treated the same way. This block yields a virtual row object,
835
+ # which is easy to use to create identifiers and functions. For more details
836
+ # on the virtual row support, see the {"Virtual Rows" guide}[link:files/doc/virtual_rows_rdoc.html]
837
+ #
838
+ # If both a block and regular argument are provided, they get ANDed together.
839
+ #
840
+ # Examples:
841
+ #
842
+ # DB[:items].where(:id => 3)
843
+ # # SELECT * FROM items WHERE (id = 3)
988
844
  #
989
- # DB[:items].group(:a).having(:a).where(:b)
990
- # # SELECT * FROM items WHERE b GROUP BY a HAVING a
845
+ # DB[:items].where('price < ?', 100)
846
+ # # SELECT * FROM items WHERE price < 100
847
+ #
848
+ # DB[:items].where([[:id, [1,2,3]], [:id, 0..10]])
849
+ # # SELECT * FROM items WHERE ((id IN (1, 2, 3)) AND ((id >= 0) AND (id <= 10)))
850
+ #
851
+ # DB[:items].where('price < 100')
852
+ # # SELECT * FROM items WHERE price < 100
853
+ #
854
+ # DB[:items].where(:active)
855
+ # # SELECT * FROM items WHERE :active
856
+ #
857
+ # DB[:items].where{price < 100}
858
+ # # SELECT * FROM items WHERE (price < 100)
859
+ #
860
+ # Multiple where calls can be chained for scoping:
861
+ #
862
+ # software = dataset.where(:category => 'software').where{price < 100}
863
+ # # SELECT * FROM items WHERE ((category = 'software') AND (price < 100))
864
+ #
865
+ # See the the {"Dataset Filtering" guide}[link:files/doc/dataset_filtering_rdoc.html] for more examples and details.
991
866
  def where(*cond, &block)
992
867
  _filter(:where, *cond, &block)
993
868
  end
@@ -998,9 +873,9 @@ module Sequel
998
873
  # :args :: Specify the arguments/columns for the CTE, should be an array of symbols.
999
874
  # :recursive :: Specify that this is a recursive CTE
1000
875
  #
1001
- # DB[:items].with(:items, DB[:syx].filter(:name.like('A%')))
876
+ # DB[:items].with(:items, DB[:syx].where(:name.like('A%')))
1002
877
  # # WITH items AS (SELECT * FROM syx WHERE (name LIKE 'A%')) SELECT * FROM items
1003
- def with(name, dataset, opts={})
878
+ def with(name, dataset, opts=OPTS)
1004
879
  raise(Error, 'This datatset does not support common table expressions') unless supports_cte?
1005
880
  if hoist_cte?(dataset)
1006
881
  s, ds = hoist_cte(dataset)
@@ -1017,7 +892,7 @@ module Sequel
1017
892
  # :union_all :: Set to false to use UNION instead of UNION ALL combining the nonrecursive and recursive parts.
1018
893
  #
1019
894
  # DB[:t].with_recursive(:t,
1020
- # DB[:i1].select(:id, :parent_id).filter(:parent_id=>nil),
895
+ # DB[:i1].select(:id, :parent_id).where(:parent_id=>nil),
1021
896
  # DB[:i1].join(:t, :id=>:parent_id).select(:i1__id, :i1__parent_id),
1022
897
  # :args=>[:id, :parent_id])
1023
898
  #
@@ -1026,7 +901,7 @@ module Sequel
1026
901
  # # UNION ALL
1027
902
  # # SELECT "i1"."id", "i1"."parent_id" FROM "i1" INNER JOIN "t" ON ("t"."id" = "i1"."parent_id")
1028
903
  # # ) SELECT * FROM "t"
1029
- def with_recursive(name, nonrecursive, recursive, opts={})
904
+ def with_recursive(name, nonrecursive, recursive, opts=OPTS)
1030
905
  raise(Error, 'This datatset does not support common table expressions') unless supports_cte?
1031
906
  if hoist_cte?(nonrecursive)
1032
907
  s, ds = hoist_cte(nonrecursive)
@@ -1085,7 +960,8 @@ module Sequel
1085
960
 
1086
961
  private
1087
962
 
1088
- # Internal filter/exclude method so it works on either the having or where clauses.
963
+ # Internal filtering method so it works on either the WHERE or HAVING clauses, with or
964
+ # without inversion.
1089
965
  def _filter_or_exclude(invert, clause, *cond, &block)
1090
966
  cond = cond.first if cond.size == 1
1091
967
  if cond.respond_to?(:empty?) && cond.empty? && !block
@@ -1108,7 +984,7 @@ module Sequel
1108
984
  :symbol
1109
985
  end
1110
986
 
1111
- # SQL expression object based on the expr type. See +filter+.
987
+ # SQL expression object based on the expr type. See +where+.
1112
988
  def filter_expr(expr = nil, &block)
1113
989
  expr = nil if expr == []
1114
990
  if expr && block