sequel 3.48.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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