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
@@ -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