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
@@ -46,7 +46,7 @@ module Sequel
46
46
  # :ignore_errors :: Ignore any DatabaseErrors that are raised
47
47
  #
48
48
  # See <tt>alter_table</tt>.
49
- def add_index(table, columns, options={})
49
+ def add_index(table, columns, options=OPTS)
50
50
  e = options[:ignore_errors]
51
51
  begin
52
52
  alter_table(table){add_index(columns, options)}
@@ -117,7 +117,7 @@ module Sequel
117
117
  # :name :: The name of the table to create
118
118
  # :no_index :: Set to true not to create the second index.
119
119
  # :no_primary_key :: Set to true to not create the primary key.
120
- def create_join_table(hash, options={})
120
+ def create_join_table(hash, options=OPTS)
121
121
  keys = hash.keys.sort_by{|k| k.to_s}
122
122
  create_table(join_table_name(hash, options), options) do
123
123
  keys.each do |key|
@@ -158,7 +158,7 @@ module Sequel
158
158
  # :unlogged :: Create the table as an unlogged table.
159
159
  #
160
160
  # See <tt>Schema::Generator</tt> and the {"Schema Modification" guide}[link:files/doc/schema_modification_rdoc.html].
161
- def create_table(name, options={}, &block)
161
+ def create_table(name, options=OPTS, &block)
162
162
  remove_cached_schema(name)
163
163
  options = {:generator=>options} if options.is_a?(Schema::CreateTableGenerator)
164
164
  if sql = options[:as]
@@ -178,7 +178,7 @@ module Sequel
178
178
  # # SELECT NULL FROM a LIMIT 1 -- check existence
179
179
  # # DROP TABLE a -- drop table if already exists
180
180
  # # CREATE TABLE a (a integer)
181
- def create_table!(name, options={}, &block)
181
+ def create_table!(name, options=OPTS, &block)
182
182
  drop_table?(name)
183
183
  create_table(name, options, &block)
184
184
  end
@@ -188,7 +188,7 @@ module Sequel
188
188
  # DB.create_table?(:a){Integer :a}
189
189
  # # SELECT NULL FROM a LIMIT 1 -- check existence
190
190
  # # CREATE TABLE a (a integer) -- if it doesn't already exist
191
- def create_table?(name, options={}, &block)
191
+ def create_table?(name, options=OPTS, &block)
192
192
  if supports_create_table_if_not_exists?
193
193
  create_table(name, options.merge(:if_not_exists=>true), &block)
194
194
  elsif !table_exists?(name)
@@ -209,7 +209,7 @@ module Sequel
209
209
  #
210
210
  # For databases where replacing a view is not natively supported, support
211
211
  # is emulated by dropping a view with the same name before creating the view.
212
- def create_or_replace_view(name, source, options = {})
212
+ def create_or_replace_view(name, source, options = OPTS)
213
213
  if supports_create_or_replace_view?
214
214
  options = options.merge(:replace=>true)
215
215
  else
@@ -224,9 +224,23 @@ module Sequel
224
224
  # DB.create_view(:cheap_items, "SELECT * FROM items WHERE price < 100")
225
225
  # DB.create_view(:ruby_items, DB[:items].filter(:category => 'ruby'))
226
226
  #
227
+ # Options:
228
+ # :columns :: The column names to use for the view. If not given,
229
+ # automatically determined based on the input dataset.
230
+ #
227
231
  # PostgreSQL/SQLite specific option:
228
232
  # :temp :: Create a temporary view, automatically dropped on disconnect.
229
- def create_view(name, source, options = {})
233
+ #
234
+ # PostgreSQL specific option:
235
+ # :materialized :: Creates a materialized view, similar to a regular view,
236
+ # but backed by a physical table.
237
+ # :recursive :: Creates a recursive view. As columns must be specified for
238
+ # recursive views, you can also set them as the value of this
239
+ # option. Since a recursive view requires a union that isn't
240
+ # in a subquery, if you are providing a Dataset as the source
241
+ # argument, if should probably call the union method with the
242
+ # :all=>true and :from_self=>false options.
243
+ def create_view(name, source, options = OPTS)
230
244
  execute_ddl(create_view_sql(name, source, options))
231
245
  remove_cached_schema(name)
232
246
  nil
@@ -247,7 +261,7 @@ module Sequel
247
261
  # DB.drop_index :posts, [:author, :title]
248
262
  #
249
263
  # See <tt>alter_table</tt>.
250
- def drop_index(table, columns, options={})
264
+ def drop_index(table, columns, options=OPTS)
251
265
  alter_table(table){drop_index(columns, options)}
252
266
  end
253
267
 
@@ -256,7 +270,7 @@ module Sequel
256
270
  #
257
271
  # drop_join_table(:cat_id=>:cats, :dog_id=>:dogs)
258
272
  # # DROP TABLE cats_dogs
259
- def drop_join_table(hash, options={})
273
+ def drop_join_table(hash, options=OPTS)
260
274
  drop_table(join_table_name(hash, options), options)
261
275
  end
262
276
 
@@ -299,6 +313,13 @@ module Sequel
299
313
  # DB.drop_view(:cheap_items)
300
314
  # DB.drop_view(:cheap_items, :pricey_items)
301
315
  # DB.drop_view(:cheap_items, :pricey_items, :cascade=>true)
316
+ #
317
+ # Options:
318
+ # :cascade :: Also drop objects depending on this view.
319
+ #
320
+ # PostgreSQL specific options:
321
+ # :if_exists :: Do not raise an error if the view does not exist.
322
+ # :materialized :: Drop a materialized view.
302
323
  def drop_view(*names)
303
324
  options = names.last.is_a?(Hash) ? names.pop : {}
304
325
  names.each do |n|
@@ -542,7 +563,10 @@ module Sequel
542
563
  case constraint[:type]
543
564
  when :check
544
565
  check = constraint[:check]
545
- sql << "CHECK #{filter_expr((check.is_a?(Array) && check.length == 1) ? check.first : check)}"
566
+ check = check.first if check.is_a?(Array) && check.length == 1
567
+ check = filter_expr(check)
568
+ check = "(#{check})" unless check[0..0] == '(' && check[-1..-1] == ')'
569
+ sql << "CHECK #{check}"
546
570
  when :primary_key
547
571
  sql << "PRIMARY KEY #{literal(constraint[:columns])}"
548
572
  when :foreign_key
@@ -631,22 +655,32 @@ module Sequel
631
655
  "CREATE #{temporary_table_sql if options[:temp]}TABLE#{' IF NOT EXISTS' if options[:if_not_exists]} #{options[:temp] ? quote_identifier(name) : quote_schema_table(name)}"
632
656
  end
633
657
 
658
+ # DDL fragment for initial part of CREATE VIEW statement
659
+ def create_view_prefix_sql(name, options)
660
+ create_view_sql_append_columns("CREATE #{'OR REPLACE 'if options[:replace]}VIEW #{quote_schema_table(name)}", options[:columns])
661
+ end
662
+
634
663
  # DDL statement for creating a view.
635
664
  def create_view_sql(name, source, options)
636
665
  source = source.sql if source.is_a?(Dataset)
637
666
  "#{create_view_prefix_sql(name, options)} AS #{source}"
638
667
  end
639
668
 
640
- # DDL fragment for initial part of CREATE VIEW statement
641
- def create_view_prefix_sql(name, options)
642
- "CREATE #{'OR REPLACE 'if options[:replace]}VIEW #{quote_schema_table(name)}"
669
+ # Append the column list to the SQL, if a column list is given.
670
+ def create_view_sql_append_columns(sql, columns)
671
+ if columns
672
+ sql << ' ('
673
+ schema_utility_dataset.send(:identifier_list_append, sql, columns)
674
+ sql << ')'
675
+ end
676
+ sql
643
677
  end
644
678
 
645
679
  # Default index name for the table and columns, may be too long
646
680
  # for certain databases.
647
681
  def default_index_name(table_name, columns)
648
682
  schema, table = schema_and_table(table_name)
649
- "#{"#{schema}_" if schema and schema != _default_schema}#{table}_#{columns.map{|c| [String, Symbol].any?{|cl| c.is_a?(cl)} ? c : literal(c).gsub(/\W/, '_')}.join(UNDERSCORE)}_index"
683
+ "#{"#{schema}_" if schema}#{table}_#{columns.map{|c| [String, Symbol].any?{|cl| c.is_a?(cl)} ? c : literal(c).gsub(/\W/, '_')}.join(UNDERSCORE)}_index"
650
684
  end
651
685
 
652
686
  # Get foreign key name for given table and columns.
@@ -752,12 +786,6 @@ module Sequel
752
786
  "ALTER TABLE #{quote_schema_table(name)} RENAME TO #{quote_schema_table(new_name)}"
753
787
  end
754
788
 
755
- # REMOVE40
756
- def reset_schema_utility_dataset
757
- Sequel::Deprecation.deprecate('Database#reset_schema_utility_dataset', 'Switch to Database#reset_default_dataset')
758
- reset_default_dataset
759
- end
760
-
761
789
  # Split the schema information from the table
762
790
  def schema_and_table(table_name)
763
791
  schema_utility_dataset.schema_and_table(table_name)
@@ -36,10 +36,6 @@ module Sequel
36
36
  #
37
37
  # The following general options are respected:
38
38
  #
39
- # :disconnect :: If set to :retry, automatically sets the :retry_on option
40
- # with a Sequel::DatabaseDisconnectError. This option is only
41
- # present for backwards compatibility, please use the :retry_on
42
- # option instead.
43
39
  # :isolation :: The transaction isolation level to use for this transaction,
44
40
  # should be :uncommitted, :committed, :repeatable, or :serializable,
45
41
  # used if given and the database/adapter supports customizable
@@ -72,13 +68,7 @@ module Sequel
72
68
  # :synchronous :: if non-nil, set synchronous_commit
73
69
  # appropriately. Valid values true, :on, false, :off, :local (9.1+),
74
70
  # and :remote_write (9.2+).
75
- def transaction(opts={}, &block)
76
- if opts[:disconnect] == :retry
77
- Sequel::Deprecation.deprecate('Database#transaction :disconnect=>:retry option', 'Please switch to :retry_on=>Sequel::DatabaseDisconnectError.')
78
- raise(Error, 'cannot specify both :disconnect=>:retry and :retry_on') if opts[:retry_on]
79
- return transaction(opts.merge(:retry_on=>Sequel::DatabaseDisconnectError, :disconnect=>nil), &block)
80
- end
81
-
71
+ def transaction(opts=OPTS, &block)
82
72
  if retry_on = opts[:retry_on]
83
73
  num_retries = opts.fetch(:num_retries, 5)
84
74
  begin
@@ -96,7 +86,7 @@ module Sequel
96
86
  synchronize(opts[:server]) do |conn|
97
87
  if already_in_transaction?(conn, opts)
98
88
  if opts[:retrying]
99
- raise Sequel::Error, "cannot set :disconnect=>:retry or :retry_on options if you are already inside a transaction"
89
+ raise Sequel::Error, "cannot set :retry_on options if you are already inside a transaction"
100
90
  end
101
91
  return yield(conn)
102
92
  end
@@ -111,7 +101,7 @@ module Sequel
111
101
  # block will cause the transaction to be rolled back. If the exception is
112
102
  # not a Sequel::Rollback, the error will be reraised. If no exception occurs
113
103
  # inside the block, the transaction is commited.
114
- def _transaction(conn, opts={})
104
+ def _transaction(conn, opts=OPTS)
115
105
  rollback = opts[:rollback]
116
106
  begin
117
107
  add_transaction(conn, opts)
@@ -207,7 +197,7 @@ module Sequel
207
197
  end
208
198
 
209
199
  # Start a new database transaction or a new savepoint on the given connection.
210
- def begin_transaction(conn, opts={})
200
+ def begin_transaction(conn, opts=OPTS)
211
201
  if supports_savepoints?
212
202
  th = _trans(conn)
213
203
  if (depth = th[:savepoint_level]) > 0
@@ -266,7 +256,7 @@ module Sequel
266
256
  end
267
257
 
268
258
  # Commit the active transaction on the connection
269
- def commit_transaction(conn, opts={})
259
+ def commit_transaction(conn, opts=OPTS)
270
260
  if supports_savepoints?
271
261
  depth = _trans(conn)[:savepoint_level]
272
262
  log_connection_execute(conn, depth > 1 ? commit_savepoint_sql(depth-1) : commit_transaction_sql)
@@ -307,7 +297,7 @@ module Sequel
307
297
  end
308
298
 
309
299
  # Rollback the active transaction on the connection
310
- def rollback_transaction(conn, opts={})
300
+ def rollback_transaction(conn, opts=OPTS)
311
301
  if supports_savepoints?
312
302
  depth = _trans(conn)[:savepoint_level]
313
303
  log_connection_execute(conn, depth > 1 ? rollback_savepoint_sql(depth-1) : rollback_transaction_sql)
@@ -334,7 +324,7 @@ module Sequel
334
324
  end
335
325
 
336
326
  # Raise a database error unless the exception is an Rollback.
337
- def transaction_error(e, opts={})
327
+ def transaction_error(e, opts=OPTS)
338
328
  if e.is_a?(Rollback)
339
329
  raise e if opts[:rollback] == :reraise
340
330
  else
@@ -23,6 +23,8 @@ module Sequel
23
23
  #
24
24
  # For more information, see the {"Dataset Basics" guide}[link:files/doc/dataset_basics_rdoc.html].
25
25
  class Dataset
26
+ OPTS = Sequel::OPTS
27
+
26
28
  include Enumerable
27
29
  include SQL::AliasMethods
28
30
  include SQL::BooleanMethods
@@ -34,16 +34,6 @@ module Sequel
34
34
  first(*conditions)
35
35
  end
36
36
 
37
- # Update all records matching the conditions with the values specified.
38
- # Returns the number of rows affected.
39
- #
40
- # DB[:table][:id=>1] = {:id=>2} # UPDATE table SET id = 2 WHERE id = 1
41
- # # => 1 # number of rows affected
42
- def []=(conditions, values)
43
- Sequel::Deprecation.deprecate('Dataset#[]=', 'Please load the sequel_3_dataset_methods extension to continue using it')
44
- filter(conditions).update(values)
45
- end
46
-
47
37
  # Returns an array with all records in the dataset. If a block is given,
48
38
  # the array is iterated over after all items have been loaded.
49
39
  #
@@ -148,9 +138,7 @@ module Sequel
148
138
  # running queries inside the block, you should use +all+ instead of +each+
149
139
  # for the outer queries, or use a separate thread or shard inside +each+.
150
140
  def each
151
- if @opts[:graph]
152
- graph_each{|r| yield r}
153
- elsif row_proc = @row_proc
141
+ if row_proc = @row_proc
154
142
  fetch_rows(select_sql){|r| yield row_proc.call(r)}
155
143
  else
156
144
  fetch_rows(select_sql){|r| yield r}
@@ -166,15 +154,6 @@ module Sequel
166
154
  get(Sequel::SQL::AliasedExpression.new(1, :one)).nil?
167
155
  end
168
156
 
169
- # Executes a select query and fetches records, yielding each record to the
170
- # supplied block. The yielded records should be hashes with symbol keys.
171
- # This method should probably should not be called by user code, use +each+
172
- # instead.
173
- def fetch_rows(sql)
174
- Sequel::Deprecation.deprecate('Dataset#fetch_rows default implementation and Sequel::NotImplemented', 'All dataset instances can be assumed to implement fetch_rows')
175
- raise NotImplemented, NOTIMPL_MSG
176
- end
177
-
178
157
  # If a integer argument is given, it is interpreted as a limit, and then returns all
179
158
  # matching records up to that limit. If no argument is passed,
180
159
  # it returns the first matching record. If any other type of
@@ -237,7 +216,7 @@ module Sequel
237
216
  # DB[:table].get(:id) # SELECT id FROM table LIMIT 1
238
217
  # # => 3
239
218
  #
240
- # ds.get{sum(id)} # SELECT sum(id) FROM table LIMIT 1
219
+ # ds.get{sum(id)} # SELECT sum(id) AS v FROM table LIMIT 1
241
220
  # # => 6
242
221
  #
243
222
  # You can pass an array of arguments to return multiple arguments,
@@ -260,7 +239,7 @@ module Sequel
260
239
  ds = if column.is_a?(Array)
261
240
  ds.select(*column)
262
241
  else
263
- ds.select(column)
242
+ ds.select(auto_alias_expression(column))
264
243
  end
265
244
  end
266
245
 
@@ -296,7 +275,7 @@ module Sequel
296
275
  # :server :: Set the server/shard to use for the transaction and insert
297
276
  # queries.
298
277
  # :slice :: Same as :commit_every, :commit_every takes precedence.
299
- def import(columns, values, opts={})
278
+ def import(columns, values, opts=OPTS)
300
279
  return @db.transaction{insert(columns, values)} if values.is_a?(Dataset)
301
280
 
302
281
  return if values.empty?
@@ -360,30 +339,6 @@ module Sequel
360
339
  end
361
340
  end
362
341
 
363
- # Inserts multiple values. If a block is given it is invoked for each
364
- # item in the given array before inserting it. See +multi_insert+ as
365
- # a possibly faster version that may be able to insert multiple
366
- # records in one SQL statement (if supported by the database).
367
- # Returns an array of primary keys of inserted rows.
368
- #
369
- # DB[:table].insert_multiple([{:x=>1}, {:x=>2}])
370
- # # => [4, 5]
371
- # # INSERT INTO table (x) VALUES (1)
372
- # # INSERT INTO table (x) VALUES (2)
373
- #
374
- # DB[:table].insert_multiple([{:x=>1}, {:x=>2}]){|row| row[:y] = row[:x] * 2; row }
375
- # # => [6, 7]
376
- # # INSERT INTO table (x, y) VALUES (1, 2)
377
- # # INSERT INTO table (x, y) VALUES (2, 4)
378
- def insert_multiple(array, &block)
379
- Sequel::Deprecation.deprecate('Dataset#insert_multiple', 'Please load the sequel_3_dataset_methods extension to continue using it')
380
- if block
381
- array.map{|i| insert(block.call(i))}
382
- else
383
- array.map{|i| insert(i)}
384
- end
385
- end
386
-
387
342
  # Returns the interval between minimum and maximum values for the given
388
343
  # column/expression. Uses a virtual row block if no argument is given.
389
344
  #
@@ -472,7 +427,7 @@ module Sequel
472
427
  # values.
473
428
  #
474
429
  # This respects the same options as #import.
475
- def multi_insert(hashes, opts={})
430
+ def multi_insert(hashes, opts=OPTS)
476
431
  return if hashes.empty?
477
432
  columns = hashes.first.keys
478
433
  import(columns, hashes.map{|h| columns.map{|c| h[c]}}, opts)
@@ -491,7 +446,7 @@ module Sequel
491
446
  #
492
447
  # Options:
493
448
  # :rows_per_fetch :: The number of rows to fetch per query. Defaults to 1000.
494
- def paged_each(opts={})
449
+ def paged_each(opts=OPTS)
495
450
  unless @opts[:order]
496
451
  raise Sequel::Error, "Dataset#paged_each requires the dataset be ordered"
497
452
  end
@@ -622,13 +577,6 @@ module Sequel
622
577
  _select_map(column, true, &block)
623
578
  end
624
579
 
625
- # Alias for update, but not aliased directly so subclasses
626
- # don't have to override both methods.
627
- def set(*args)
628
- Sequel::Deprecation.deprecate('Dataset#set', 'Please switch to Dataset#update or load the sequel_3_dataset_methods extension to continue using it')
629
- update(*args)
630
- end
631
-
632
580
  # Returns the first record in the dataset, or nil if the dataset
633
581
  # has no records. Users should probably use +first+ instead of
634
582
  # this method.
@@ -657,29 +605,6 @@ module Sequel
657
605
  aggregate_dataset.get{sum(column).as(:sum)}
658
606
  end
659
607
 
660
- # Returns a string in CSV format containing the dataset records. By
661
- # default the CSV representation includes the column titles in the
662
- # first line. You can turn that off by passing false as the
663
- # include_column_titles argument.
664
- #
665
- # This does not use a CSV library or handle quoting of values in
666
- # any way. If any values in any of the rows could include commas or line
667
- # endings, you shouldn't use this.
668
- #
669
- # puts DB[:table].to_csv # SELECT * FROM table
670
- # # id,name
671
- # # 1,Jim
672
- # # 2,Bob
673
- def to_csv(include_column_titles = true)
674
- Sequel::Deprecation.deprecate('Dataset#to_csv', 'Please load the sequel_3_dataset_methods extension to continue using it')
675
- n = naked
676
- cols = n.columns
677
- csv = ''
678
- csv << "#{cols.join(COMMA_SEPARATOR)}\r\n" if include_column_titles
679
- n.each{|r| csv << "#{cols.collect{|c| r[c]}.join(COMMA_SEPARATOR)}\r\n"}
680
- csv
681
- end
682
-
683
608
  # Returns a hash with one column used as key and another used as value.
684
609
  # If rows have duplicate values for the key column, the latter row(s)
685
610
  # will overwrite the value of the previous row(s). If the value_column
@@ -785,7 +710,7 @@ module Sequel
785
710
  #
786
711
  # DB[:table].update(:x=>:x+1, :y=>0) # UPDATE table SET x = (x + 1), y = 0
787
712
  # # => 10
788
- def update(values={}, &block)
713
+ def update(values=OPTS, &block)
789
714
  sql = update_sql(values)
790
715
  if uses_returning?(:update)
791
716
  returning_fetch_rows(sql, &block)
@@ -840,12 +765,21 @@ module Sequel
840
765
  columns = Array(column)
841
766
  virtual_row_columns(columns, block)
842
767
  select_cols = order ? columns.map{|c| c.is_a?(SQL::OrderedExpression) ? c.expression : c} : columns
843
- ds = ds.select(*select_cols)
844
768
  ds = ds.order(*columns.map{|c| unaliased_identifier(c)}) if order
845
769
  if column.is_a?(Array) || (columns.length > 1)
846
- ds._select_map_multiple(hash_key_symbols(select_cols))
770
+ ds.select(*select_cols)._select_map_multiple(hash_key_symbols(select_cols))
771
+ else
772
+ ds.select(auto_alias_expression(select_cols.first))._select_map_single
773
+ end
774
+ end
775
+
776
+ # Automatically alias the given expression if it does not have an identifiable alias.
777
+ def auto_alias_expression(v)
778
+ case v
779
+ when LiteralString, Symbol, SQL::Identifier, SQL::QualifiedIdentifier, SQL::AliasedExpression
780
+ v
847
781
  else
848
- ds._select_map_single
782
+ SQL::AliasedExpression.new(v, :v)
849
783
  end
850
784
  end
851
785
 
@@ -856,23 +790,23 @@ module Sequel
856
790
 
857
791
  # Execute the given select SQL on the database using execute. Use the
858
792
  # :read_only server unless a specific server is set.
859
- def execute(sql, opts={}, &block)
793
+ def execute(sql, opts=OPTS, &block)
860
794
  @db.execute(sql, {:server=>@opts[:server] || :read_only}.merge(opts), &block)
861
795
  end
862
796
 
863
797
  # Execute the given SQL on the database using execute_ddl.
864
- def execute_ddl(sql, opts={}, &block)
798
+ def execute_ddl(sql, opts=OPTS, &block)
865
799
  @db.execute_ddl(sql, default_server_opts(opts), &block)
866
800
  nil
867
801
  end
868
802
 
869
803
  # Execute the given SQL on the database using execute_dui.
870
- def execute_dui(sql, opts={}, &block)
804
+ def execute_dui(sql, opts=OPTS, &block)
871
805
  @db.execute_dui(sql, default_server_opts(opts), &block)
872
806
  end
873
807
 
874
808
  # Execute the given SQL on the database using execute_insert.
875
- def execute_insert(sql, opts={}, &block)
809
+ def execute_insert(sql, opts=OPTS, &block)
876
810
  @db.execute_insert(sql, default_server_opts(opts), &block)
877
811
  end
878
812
 
@@ -903,8 +837,6 @@ module Sequel
903
837
  def hash_key_symbol(s)
904
838
  if v = _hash_key_symbol(s)
905
839
  v
906
- elsif block_given?
907
- yield
908
840
  else
909
841
  raise(Error, "#{s.inspect} is not supported, should be a Symbol, SQL::Identifier, SQL::QualifiedIdentifier, or SQL::AliasedExpression")
910
842
  end