sequel 4.46.0 → 4.49.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 (228) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +210 -0
  3. data/Rakefile +1 -1
  4. data/doc/advanced_associations.rdoc +1 -1
  5. data/doc/opening_databases.rdoc +3 -2
  6. data/doc/release_notes/4.47.0.txt +56 -0
  7. data/doc/release_notes/4.48.0.txt +293 -0
  8. data/doc/release_notes/4.49.0.txt +222 -0
  9. data/lib/sequel/adapters/ado/access.rb +2 -1
  10. data/lib/sequel/adapters/do/postgres.rb +5 -2
  11. data/lib/sequel/adapters/ibmdb.rb +30 -8
  12. data/lib/sequel/adapters/jdbc/as400.rb +1 -1
  13. data/lib/sequel/adapters/jdbc/db2.rb +12 -3
  14. data/lib/sequel/adapters/jdbc/derby.rb +4 -5
  15. data/lib/sequel/adapters/jdbc/h2.rb +10 -1
  16. data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
  17. data/lib/sequel/adapters/jdbc/postgresql.rb +46 -20
  18. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
  19. data/lib/sequel/adapters/jdbc/sqlserver.rb +20 -6
  20. data/lib/sequel/adapters/jdbc.rb +39 -23
  21. data/lib/sequel/adapters/mock.rb +27 -19
  22. data/lib/sequel/adapters/mysql.rb +17 -16
  23. data/lib/sequel/adapters/mysql2.rb +5 -6
  24. data/lib/sequel/adapters/oracle.rb +5 -9
  25. data/lib/sequel/adapters/postgres.rb +91 -103
  26. data/lib/sequel/adapters/shared/db2.rb +22 -6
  27. data/lib/sequel/adapters/shared/mssql.rb +5 -4
  28. data/lib/sequel/adapters/shared/mysql.rb +79 -25
  29. data/lib/sequel/adapters/shared/oracle.rb +26 -3
  30. data/lib/sequel/adapters/shared/postgres.rb +199 -95
  31. data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
  32. data/lib/sequel/adapters/shared/sqlite.rb +72 -82
  33. data/lib/sequel/adapters/sqlanywhere.rb +4 -1
  34. data/lib/sequel/adapters/sqlite.rb +5 -3
  35. data/lib/sequel/adapters/swift/postgres.rb +5 -2
  36. data/lib/sequel/adapters/tinytds.rb +0 -5
  37. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
  38. data/lib/sequel/adapters/utils/pg_types.rb +2 -76
  39. data/lib/sequel/ast_transformer.rb +1 -1
  40. data/lib/sequel/connection_pool/sharded_single.rb +1 -1
  41. data/lib/sequel/connection_pool/sharded_threaded.rb +1 -1
  42. data/lib/sequel/connection_pool/single.rb +2 -2
  43. data/lib/sequel/connection_pool/threaded.rb +2 -2
  44. data/lib/sequel/connection_pool.rb +9 -2
  45. data/lib/sequel/core.rb +2 -2
  46. data/lib/sequel/database/connecting.rb +8 -8
  47. data/lib/sequel/database/dataset.rb +6 -3
  48. data/lib/sequel/database/dataset_defaults.rb +14 -1
  49. data/lib/sequel/database/misc.rb +1 -1
  50. data/lib/sequel/database/query.rb +3 -0
  51. data/lib/sequel/database/schema_methods.rb +1 -1
  52. data/lib/sequel/dataset/actions.rb +72 -10
  53. data/lib/sequel/dataset/dataset_module.rb +58 -0
  54. data/lib/sequel/dataset/graph.rb +1 -1
  55. data/lib/sequel/dataset/misc.rb +1 -0
  56. data/lib/sequel/dataset/prepared_statements.rb +3 -3
  57. data/lib/sequel/dataset/query.rb +22 -11
  58. data/lib/sequel/dataset.rb +1 -1
  59. data/lib/sequel/exceptions.rb +8 -0
  60. data/lib/sequel/extensions/_model_pg_row.rb +5 -2
  61. data/lib/sequel/extensions/core_extensions.rb +4 -1
  62. data/lib/sequel/extensions/current_datetime_timestamp.rb +2 -1
  63. data/lib/sequel/extensions/date_arithmetic.rb +1 -0
  64. data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -3
  65. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
  66. data/lib/sequel/extensions/filter_having.rb +2 -0
  67. data/lib/sequel/extensions/freeze_datasets.rb +2 -0
  68. data/lib/sequel/extensions/from_block.rb +1 -1
  69. data/lib/sequel/extensions/graph_each.rb +2 -2
  70. data/lib/sequel/extensions/hash_aliases.rb +2 -0
  71. data/lib/sequel/extensions/identifier_mangling.rb +0 -7
  72. data/lib/sequel/extensions/meta_def.rb +2 -0
  73. data/lib/sequel/extensions/migration.rb +11 -8
  74. data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
  75. data/lib/sequel/extensions/null_dataset.rb +1 -0
  76. data/lib/sequel/extensions/pagination.rb +1 -1
  77. data/lib/sequel/extensions/pg_array.rb +207 -130
  78. data/lib/sequel/extensions/pg_hstore.rb +38 -20
  79. data/lib/sequel/extensions/pg_inet.rb +18 -6
  80. data/lib/sequel/extensions/pg_interval.rb +19 -12
  81. data/lib/sequel/extensions/pg_json.rb +25 -14
  82. data/lib/sequel/extensions/pg_json_ops.rb +2 -2
  83. data/lib/sequel/extensions/pg_range.rb +133 -100
  84. data/lib/sequel/extensions/pg_range_ops.rb +4 -3
  85. data/lib/sequel/extensions/pg_row.rb +68 -39
  86. data/lib/sequel/extensions/pg_row_ops.rb +11 -5
  87. data/lib/sequel/extensions/query_literals.rb +2 -0
  88. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
  89. data/lib/sequel/extensions/s.rb +1 -1
  90. data/lib/sequel/extensions/schema_dumper.rb +29 -25
  91. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
  92. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
  93. data/lib/sequel/extensions/server_block.rb +32 -15
  94. data/lib/sequel/extensions/set_overrides.rb +2 -2
  95. data/lib/sequel/extensions/string_agg.rb +0 -1
  96. data/lib/sequel/extensions/symbol_aref.rb +0 -4
  97. data/lib/sequel/model/associations.rb +35 -7
  98. data/lib/sequel/model/base.rb +113 -87
  99. data/lib/sequel/model/dataset_module.rb +5 -43
  100. data/lib/sequel/model/errors.rb +2 -1
  101. data/lib/sequel/model/inflections.rb +17 -5
  102. data/lib/sequel/model.rb +26 -58
  103. data/lib/sequel/plugins/active_model.rb +2 -2
  104. data/lib/sequel/plugins/association_autoreloading.rb +2 -0
  105. data/lib/sequel/plugins/association_dependencies.rb +3 -3
  106. data/lib/sequel/plugins/association_pks.rb +73 -46
  107. data/lib/sequel/plugins/association_proxies.rb +1 -1
  108. data/lib/sequel/plugins/auto_validations.rb +6 -2
  109. data/lib/sequel/plugins/boolean_readers.rb +2 -2
  110. data/lib/sequel/plugins/boolean_subsets.rb +1 -1
  111. data/lib/sequel/plugins/caching.rb +19 -13
  112. data/lib/sequel/plugins/class_table_inheritance.rb +24 -13
  113. data/lib/sequel/plugins/column_conflicts.rb +7 -2
  114. data/lib/sequel/plugins/column_select.rb +3 -3
  115. data/lib/sequel/plugins/composition.rb +2 -2
  116. data/lib/sequel/plugins/csv_serializer.rb +8 -8
  117. data/lib/sequel/plugins/dataset_associations.rb +25 -13
  118. data/lib/sequel/plugins/defaults_setter.rb +13 -1
  119. data/lib/sequel/plugins/eager_each.rb +1 -1
  120. data/lib/sequel/plugins/force_encoding.rb +2 -2
  121. data/lib/sequel/plugins/hook_class_methods.rb +9 -12
  122. data/lib/sequel/plugins/identifier_columns.rb +2 -0
  123. data/lib/sequel/plugins/instance_filters.rb +3 -1
  124. data/lib/sequel/plugins/instance_hooks.rb +17 -9
  125. data/lib/sequel/plugins/json_serializer.rb +19 -12
  126. data/lib/sequel/plugins/lazy_attributes.rb +8 -7
  127. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +2 -0
  128. data/lib/sequel/plugins/modification_detection.rb +3 -0
  129. data/lib/sequel/plugins/nested_attributes.rb +6 -2
  130. data/lib/sequel/plugins/pg_array_associations.rb +5 -0
  131. data/lib/sequel/plugins/pg_row.rb +4 -2
  132. data/lib/sequel/plugins/pg_typecast_on_load.rb +2 -0
  133. data/lib/sequel/plugins/prepared_statements.rb +1 -0
  134. data/lib/sequel/plugins/rcte_tree.rb +4 -24
  135. data/lib/sequel/plugins/serialization.rb +9 -15
  136. data/lib/sequel/plugins/single_table_inheritance.rb +8 -3
  137. data/lib/sequel/plugins/split_values.rb +6 -5
  138. data/lib/sequel/plugins/static_cache.rb +31 -25
  139. data/lib/sequel/plugins/subset_conditions.rb +3 -1
  140. data/lib/sequel/plugins/table_select.rb +1 -1
  141. data/lib/sequel/plugins/touch.rb +4 -2
  142. data/lib/sequel/plugins/validation_class_methods.rb +5 -6
  143. data/lib/sequel/plugins/validation_helpers.rb +14 -8
  144. data/lib/sequel/plugins/xml_serializer.rb +4 -4
  145. data/lib/sequel/sql.rb +18 -9
  146. data/lib/sequel/version.rb +1 -1
  147. data/spec/adapters/db2_spec.rb +115 -14
  148. data/spec/adapters/mssql_spec.rb +4 -4
  149. data/spec/adapters/mysql_spec.rb +83 -29
  150. data/spec/adapters/oracle_spec.rb +28 -24
  151. data/spec/adapters/postgres_spec.rb +40 -24
  152. data/spec/adapters/sqlanywhere_spec.rb +88 -86
  153. data/spec/adapters/sqlite_spec.rb +29 -24
  154. data/spec/bin_spec.rb +7 -1
  155. data/spec/core/connection_pool_spec.rb +45 -14
  156. data/spec/core/database_spec.rb +155 -0
  157. data/spec/core/dataset_spec.rb +219 -36
  158. data/spec/core/schema_spec.rb +16 -0
  159. data/spec/core/spec_helper.rb +1 -0
  160. data/spec/core_extensions_spec.rb +6 -2
  161. data/spec/extensions/active_model_spec.rb +1 -1
  162. data/spec/extensions/arbitrary_servers_spec.rb +1 -1
  163. data/spec/extensions/association_pks_spec.rb +34 -2
  164. data/spec/extensions/auto_literal_strings_spec.rb +5 -1
  165. data/spec/extensions/auto_validations_spec.rb +2 -0
  166. data/spec/extensions/boolean_readers_spec.rb +1 -1
  167. data/spec/extensions/boolean_subsets_spec.rb +1 -1
  168. data/spec/extensions/class_table_inheritance_spec.rb +106 -19
  169. data/spec/extensions/column_conflicts_spec.rb +11 -0
  170. data/spec/extensions/column_select_spec.rb +1 -0
  171. data/spec/extensions/composition_spec.rb +13 -0
  172. data/spec/extensions/connection_validator_spec.rb +1 -1
  173. data/spec/extensions/dataset_associations_spec.rb +20 -8
  174. data/spec/extensions/defaults_setter_spec.rb +15 -1
  175. data/spec/extensions/filter_having_spec.rb +5 -3
  176. data/spec/extensions/hash_aliases_spec.rb +3 -1
  177. data/spec/extensions/identifier_columns_spec.rb +3 -1
  178. data/spec/extensions/implicit_subquery_spec.rb +4 -2
  179. data/spec/extensions/json_serializer_spec.rb +18 -0
  180. data/spec/extensions/lazy_attributes_spec.rb +3 -3
  181. data/spec/extensions/many_through_many_spec.rb +4 -4
  182. data/spec/extensions/meta_def_spec.rb +9 -0
  183. data/spec/extensions/migration_spec.rb +3 -3
  184. data/spec/extensions/nested_attributes_spec.rb +14 -3
  185. data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
  186. data/spec/extensions/null_dataset_spec.rb +1 -1
  187. data/spec/extensions/pg_array_associations_spec.rb +29 -18
  188. data/spec/extensions/pg_array_spec.rb +44 -25
  189. data/spec/extensions/pg_hstore_spec.rb +10 -0
  190. data/spec/extensions/pg_inet_spec.rb +26 -0
  191. data/spec/extensions/pg_interval_spec.rb +20 -0
  192. data/spec/extensions/pg_json_spec.rb +24 -0
  193. data/spec/extensions/pg_range_spec.rb +98 -14
  194. data/spec/extensions/pg_row_spec.rb +14 -4
  195. data/spec/extensions/pg_typecast_on_load_spec.rb +11 -9
  196. data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
  197. data/spec/extensions/query_literals_spec.rb +3 -1
  198. data/spec/extensions/schema_dumper_spec.rb +108 -94
  199. data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
  200. data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
  201. data/spec/extensions/serialization_spec.rb +1 -1
  202. data/spec/extensions/server_block_spec.rb +7 -0
  203. data/spec/extensions/single_table_inheritance_spec.rb +17 -1
  204. data/spec/extensions/spec_helper.rb +7 -1
  205. data/spec/extensions/static_cache_spec.rb +75 -24
  206. data/spec/extensions/string_agg_spec.rb +1 -1
  207. data/spec/extensions/touch_spec.rb +9 -0
  208. data/spec/extensions/validation_helpers_spec.rb +10 -5
  209. data/spec/extensions/whitelist_security_spec.rb +26 -0
  210. data/spec/integration/associations_test.rb +8 -0
  211. data/spec/integration/dataset_test.rb +45 -44
  212. data/spec/integration/model_test.rb +53 -4
  213. data/spec/integration/plugin_test.rb +28 -4
  214. data/spec/integration/prepared_statement_test.rb +3 -0
  215. data/spec/integration/schema_test.rb +21 -1
  216. data/spec/integration/transaction_test.rb +40 -40
  217. data/spec/model/association_reflection_spec.rb +43 -1
  218. data/spec/model/associations_spec.rb +29 -9
  219. data/spec/model/class_dataset_methods_spec.rb +20 -4
  220. data/spec/model/dataset_methods_spec.rb +12 -3
  221. data/spec/model/eager_loading_spec.rb +8 -8
  222. data/spec/model/model_spec.rb +45 -1
  223. data/spec/model/plugins_spec.rb +34 -0
  224. data/spec/model/record_spec.rb +1 -1
  225. data/spec/spec_config.rb +2 -0
  226. metadata +11 -4
  227. data/spec/adapters/firebird_spec.rb +0 -405
  228. data/spec/adapters/informix_spec.rb +0 -100
@@ -31,7 +31,7 @@ module Sequel
31
31
  module ResetIdentifierMangling
32
32
  def self.extended(obj)
33
33
  # :nocov:
34
- Sequel::Deprecation.deprecate("Sequel::Database::ResetIdentifierMangling is no longer needed and will be removed in Sequel 5. Please update your adapter.")
34
+ Sequel::Deprecation.deprecate("Sequel::Database::ResetIdentifierMangling is no longer needed and will be removed in Sequel 5. Please update your adapter")
35
35
  obj.send(:reset_identifier_mangling) if obj.respond_to?(:reset_identifier_mangling)
36
36
  # :nocov:
37
37
  end
@@ -310,6 +310,9 @@ module Sequel
310
310
 
311
311
  # Remove the cached schema for the given schema name
312
312
  def remove_cached_schema(table)
313
+ #SEQUEL5
314
+ #cache = @default_dataset.send(:cache)
315
+ #Sequel.synchronize{cache.clear}
313
316
  k = quote_schema_table(table)
314
317
  Sequel.synchronize{@schemas.delete(k)}
315
318
  end
@@ -707,7 +707,7 @@ module Sequel
707
707
  e = options[:ignore_index_errors] || options[:if_not_exists]
708
708
  generator.indexes.each do |index|
709
709
  begin
710
- index_sql_list(name, [index]).each{|sql| execute_ddl(sql)}
710
+ transaction(:savepoint=>:only){index_sql_list(name, [index]).each{|sql| execute_ddl(sql)}}
711
711
  rescue Error
712
712
  raise unless e
713
713
  end
@@ -11,11 +11,13 @@ module Sequel
11
11
 
12
12
  # Action methods defined by Sequel that execute code on the database.
13
13
  ACTION_METHODS = (<<-METHS).split.map(&:to_sym).freeze
14
- << [] all avg count columns columns! delete each
14
+ << [] all as_hash avg count columns columns! delete each
15
15
  empty? fetch_rows first first! get import insert interval last
16
16
  map max min multi_insert paged_each range select_hash select_hash_groups select_map select_order_map
17
17
  single_record single_record! single_value single_value! sum to_hash to_hash_groups truncate update
18
+ where_all where_each where_single_value
18
19
  METHS
20
+ # SEQUEL5: Remove interval, range
19
21
 
20
22
  # The clone options to use when retriveing columns for a dataset.
21
23
  COLUMNS_CLONE_OPTIONS = {:distinct => nil, :limit => 1, :offset=>nil, :where=>nil, :having=>nil, :order=>nil, :row_proc=>nil, :graph=>nil, :eager_graph=>nil}.freeze
@@ -410,6 +412,7 @@ module Sequel
410
412
  # DB[:table].interval{function(column)} # SELECT (max(function(column)) - min(function(column))) FROM table LIMIT 1
411
413
  # # => 7
412
414
  def interval(column=Sequel.virtual_row(&Proc.new))
415
+ Sequel::Deprecation.deprecate("Sequel::Dataset#interval", "Use #max - #min, or use the sequel_4_dataset_methods extension")
413
416
  if loader = cached_placeholder_literalizer(:_interval_loader) do |pl|
414
417
  arg = pl.arg
415
418
  aggregate_dataset.limit(1).select((SQL::Function.new(:max, arg) - SQL::Function.new(:min, arg)).as(:interval))
@@ -623,6 +626,7 @@ module Sequel
623
626
  # DB[:table].interval{function(column)} # SELECT max(function(column)) AS v1, min(function(column)) AS v2 FROM table LIMIT 1
624
627
  # # => 0..7
625
628
  def range(column=Sequel.virtual_row(&Proc.new))
629
+ Sequel::Deprecation.deprecate("Sequel::Dataset#range", "Use #min..#max, or use the sequel_4_dataset_methods extension")
626
630
  r = if loader = cached_placeholder_literalizer(:_range_loader) do |pl|
627
631
  arg = pl.arg
628
632
  aggregate_dataset.limit(1).select(SQL::Function.new(:min, arg).as(:v1), SQL::Function.new(:max, arg).as(:v2))
@@ -639,8 +643,8 @@ module Sequel
639
643
  end
640
644
 
641
645
  # Returns a hash with key_column values as keys and value_column values as
642
- # values. Similar to to_hash, but only selects the columns given. Like
643
- # to_hash, it accepts an optional :hash parameter, into which entries will
646
+ # values. Similar to as_hash, but only selects the columns given. Like
647
+ # as_hash, it accepts an optional :hash parameter, into which entries will
644
648
  # be merged.
645
649
  #
646
650
  # DB[:table].select_hash(:id, :name) # SELECT id, name FROM table
@@ -656,7 +660,7 @@ module Sequel
656
660
  # that Sequel can determine. Usually you can do this by calling the #as method
657
661
  # on the expression and providing an alias.
658
662
  def select_hash(key_column, value_column, opts = OPTS)
659
- _select_hash(:to_hash, key_column, value_column, opts)
663
+ _select_hash(:as_hash, key_column, value_column, opts)
660
664
  end
661
665
 
662
666
  # Returns a hash with key_column values as keys and an array of value_column values.
@@ -786,19 +790,19 @@ module Sequel
786
790
  # will overwrite the value of the previous row(s). If the value_column
787
791
  # is not given or nil, uses the entire hash as the value.
788
792
  #
789
- # DB[:table].to_hash(:id, :name) # SELECT * FROM table
793
+ # DB[:table].as_hash(:id, :name) # SELECT * FROM table
790
794
  # # {1=>'Jim', 2=>'Bob', ...}
791
795
  #
792
- # DB[:table].to_hash(:id) # SELECT * FROM table
796
+ # DB[:table].as_hash(:id) # SELECT * FROM table
793
797
  # # {1=>{:id=>1, :name=>'Jim'}, 2=>{:id=>2, :name=>'Bob'}, ...}
794
798
  #
795
799
  # You can also provide an array of column names for either the key_column,
796
800
  # the value column, or both:
797
801
  #
798
- # DB[:table].to_hash([:id, :foo], [:name, :bar]) # SELECT * FROM table
802
+ # DB[:table].as_hash([:id, :foo], [:name, :bar]) # SELECT * FROM table
799
803
  # # {[1, 3]=>['Jim', 'bo'], [2, 4]=>['Bob', 'be'], ...}
800
804
  #
801
- # DB[:table].to_hash([:id, :name]) # SELECT * FROM table
805
+ # DB[:table].as_hash([:id, :name]) # SELECT * FROM table
802
806
  # # {[1, 'Jim']=>{:id=>1, :name=>'Jim'}, [2, 'Bob']=>{:id=>2, :name=>'Bob'}, ...}
803
807
  #
804
808
  # Options:
@@ -806,11 +810,11 @@ module Sequel
806
810
  # :hash :: The object into which the values will be placed. If this is not
807
811
  # given, an empty hash is used. This can be used to use a hash with
808
812
  # a default value or default proc.
809
- def to_hash(key_column, value_column = nil, opts = OPTS)
813
+ def as_hash(key_column, value_column = nil, opts = OPTS)
810
814
  h = opts[:hash] || {}
811
815
  meth = opts[:all] ? :all : :each
812
816
  if value_column
813
- return naked.to_hash(key_column, value_column, opts) if row_proc
817
+ return naked.as_hash(key_column, value_column, opts) if row_proc
814
818
  if value_column.is_a?(Array)
815
819
  if key_column.is_a?(Array)
816
820
  send(meth){|r| h[r.values_at(*key_column)] = r.values_at(*value_column)}
@@ -832,6 +836,11 @@ module Sequel
832
836
  h
833
837
  end
834
838
 
839
+ # Alias of as_hash for backwards compatibility.
840
+ def to_hash(*a)
841
+ as_hash(*a)
842
+ end
843
+
835
844
  # Returns a hash with one column used as key and the values being an
836
845
  # array of column values. If the value_column is not given or nil, uses
837
846
  # the entire hash as the value.
@@ -909,6 +918,52 @@ module Sequel
909
918
  end
910
919
  end
911
920
 
921
+ # Return an array of all rows matching the given filter condition, also
922
+ # yielding each row to the given block. Basically the same as where(cond).all(&block),
923
+ # except it can be optimized to not create an intermediate dataset.
924
+ #
925
+ # DB[:table].where_all(:id=>[1,2,3])
926
+ # # SELECT * FROM table WHERE (id IN (1, 2, 3))
927
+ def where_all(cond, &block)
928
+ if loader = _where_loader
929
+ loader.all(filter_expr(cond), &block)
930
+ else
931
+ where(cond).all(&block)
932
+ end
933
+ end
934
+
935
+ # Iterate over all rows matching the given filter condition,
936
+ # yielding each row to the given block. Basically the same as where(cond).each(&block),
937
+ # except it can be optimized to not create an intermediate dataset.
938
+ #
939
+ # DB[:table].where_each(:id=>[1,2,3]){|row| p row}
940
+ # # SELECT * FROM table WHERE (id IN (1, 2, 3))
941
+ def where_each(cond, &block)
942
+ if loader = _where_loader
943
+ loader.each(filter_expr(cond), &block)
944
+ else
945
+ where(cond).each(&block)
946
+ end
947
+ end
948
+
949
+ # Filter the datasets using the given filter condition, then return a single value.
950
+ # This assumes that the dataset has already been setup to limit the selection to
951
+ # a single column. Basically the same as where(cond).single_value,
952
+ # except it can be optimized to not create an intermediate dataset.
953
+ #
954
+ # DB[:table].select(:name).where_single_value(:id=>1)
955
+ # # SELECT name FROM table WHERE (id = 1) LIMIT 1
956
+ def where_single_value(cond)
957
+ if loader = cached_placeholder_literalizer(:_where_single_value_loader) do |pl|
958
+ single_value_ds.where(pl.arg)
959
+ end
960
+
961
+ loader.get(filter_expr(cond))
962
+ else
963
+ where(cond).single_value
964
+ end
965
+ end
966
+
912
967
  # Run the given SQL and return an array of all rows. If a block is given,
913
968
  # each row is yielded to the block after all rows are loaded. See with_sql_each.
914
969
  def with_sql_all(sql, &block)
@@ -1036,6 +1091,13 @@ module Sequel
1036
1091
  cached_dataset(:_single_record_ds){clone(:limit=>1)}
1037
1092
  end
1038
1093
 
1094
+ # Loader used for where_all and where_each.
1095
+ def _where_loader
1096
+ cached_placeholder_literalizer(:_where_loader) do |pl|
1097
+ where(pl.arg)
1098
+ end
1099
+ end
1100
+
1039
1101
  # Automatically alias the given expression if it does not have an identifiable alias.
1040
1102
  def auto_alias_expression(v)
1041
1103
  case v
@@ -0,0 +1,58 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Sequel
4
+ class Dataset
5
+ # This Module subclass is used by Database#extend_datasets
6
+ # and Dataset#with_extend to add dataset methods to classes.
7
+ # It adds some helper methods inside the module that can define
8
+ # named methods on the dataset instances which do specific actions.
9
+ # For example:
10
+ #
11
+ # DB.extend_datasets do
12
+ # order :by_id, :id
13
+ # select :with_id_and_name, :id, :name
14
+ # where :active, :active
15
+ # end
16
+ #
17
+ # DB[:table].active.with_id_and_name.by_id
18
+ # # SELECT id, name FROM table WHERE active ORDER BY id
19
+ class DatasetModule < ::Module
20
+ %w'where exclude exclude_having having'.map(&:to_sym).each do |meth|
21
+ define_method(meth) do |name, *args, &block|
22
+ if block || args.flatten.any?{|arg| arg.is_a?(Proc)}
23
+ define_method(name){send(meth, *args, &block)}
24
+ else
25
+ key = :"_#{meth}_#{name}_ds"
26
+ define_method(name) do
27
+ cached_dataset(key){send(meth, *args)}
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ meths = (<<-METHS).split.map(&:to_sym)
34
+ distinct grep group group_and_count group_append
35
+ limit offset order order_append order_prepend
36
+ select select_all select_append select_group server
37
+ METHS
38
+
39
+ # Define a method in the module
40
+ def self.def_dataset_caching_method(mod, meth)
41
+ mod.send(:define_method, meth) do |name, *args, &block|
42
+ if block
43
+ define_method(name){send(meth, *args, &block)}
44
+ else
45
+ key = :"_#{meth}_#{name}_ds"
46
+ define_method(name) do
47
+ cached_dataset(key){send(meth, *args)}
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ meths.each do |meth|
54
+ def_dataset_caching_method(self, meth)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -275,7 +275,7 @@ module Sequel
275
275
  # a select method, and the second is a new hash of preprocessed graph aliases.
276
276
  def graph_alias_columns(graph_aliases)
277
277
  gas = {}
278
- identifiers = graph_aliases.collect do |col_alias, tc|
278
+ identifiers = graph_aliases.map do |col_alias, tc|
279
279
  table, column, value = Array(tc)
280
280
  column ||= col_alias
281
281
  gas[col_alias] = [table, column].freeze
@@ -35,6 +35,7 @@ module Sequel
35
35
  @db = db
36
36
  @opts = {} # OPTS # SEQUEL5
37
37
  @cache = {}
38
+ # freeze # SEQUEL5
38
39
  end
39
40
 
40
41
  # Define a hash value such that datasets with the same class, DB, and opts
@@ -41,7 +41,7 @@ module Sequel
41
41
  meths.each do |meth|
42
42
  mod.send(:define_method, :"#{meth}=") do |v|
43
43
  # :nocov:
44
- Sequel::Deprecation.deprecate("Dataset##{meth}=", "The API has changed, and this value should now be passed in as an option via Dataset#clone.")
44
+ Sequel::Deprecation.deprecate("Dataset##{meth}=", "The API has changed, and this value should now be passed in as an option via Dataset#clone")
45
45
  @opts[meth] = v
46
46
  # :nocov:
47
47
  end
@@ -214,7 +214,7 @@ module Sequel
214
214
  fetch_rows(prepared_sql){|r| return r.values.first}
215
215
  when Array
216
216
  case prepared_type[0]
217
- when :map, :to_hash, :to_hash_groups
217
+ when :map, :as_hash, :to_hash, :to_hash_groups
218
218
  send(*prepared_type, &block)
219
219
  end
220
220
  else
@@ -341,7 +341,7 @@ module Sequel
341
341
  else
342
342
  # :nocov:
343
343
  # SEQUEL5: Add coverage
344
- Sequel::Deprecation.deprecate("Dataset#prepare will change to requiring a name argument in Sequel 5, please update your code.") unless name
344
+ Sequel::Deprecation.deprecate("Dataset#prepare will change to requiring a name argument in Sequel 5, please update your code") unless name
345
345
  # :nocov:
346
346
  end
347
347
 
@@ -20,7 +20,7 @@ module Sequel
20
20
 
21
21
  # Which options don't affect the SQL generation. Used by simple_select_all?
22
22
  # to determine if this is a simple SELECT * FROM table.
23
- NON_SQL_OPTIONS = [:server, :graph, :eager, :eager_graph, :graph_aliases, :row_proc, :quote_identifiers, :identifier_input_method, :identifier_output_method, :skip_symbol_cache, :model, :model_object, :association_reflection, :fetch, :numrows, :autoid].freeze # SEQUEL5: Remove graph_aliases
23
+ NON_SQL_OPTIONS = [:server, :graph, :graph_aliases, :row_proc, :quote_identifiers, :identifier_input_method, :identifier_output_method, :skip_symbol_cache].freeze # SEQUEL5: Remove graph_aliases
24
24
 
25
25
  # These symbols have _join methods created (e.g. inner_join) that
26
26
  # call join_table with the symbol, passing along the arguments and
@@ -44,6 +44,7 @@ module Sequel
44
44
  set_graph_aliases unfiltered ungraphed ungrouped union
45
45
  unlimited unordered where with with_recursive with_sql
46
46
  METHS
47
+ # SEQUEL5: Remove and, exclude_where
47
48
 
48
49
  # Register an extension callback for Dataset objects. ext should be the
49
50
  # extension name symbol, and mod should either be a Module that the
@@ -68,6 +69,7 @@ module Sequel
68
69
 
69
70
  # Alias for where.
70
71
  def and(*cond, &block)
72
+ Sequel::Deprecation.deprecate("Sequel::Dataset#and", "Use #where, or use the sequel_4_dataset_methods extension")
71
73
  where(*cond, &block)
72
74
  end
73
75
 
@@ -190,6 +192,7 @@ module Sequel
190
192
 
191
193
  # Alias for exclude.
192
194
  def exclude_where(*cond, &block)
195
+ Sequel::Deprecation.deprecate("Sequel::Dataset#exclude_where", "Use #exclude, or use the sequel_4_dataset_methods extension")
193
196
  exclude(*cond, &block)
194
197
  end
195
198
 
@@ -281,8 +284,7 @@ module Sequel
281
284
  # # SELECT * FROM (SELECT id, name FROM items ORDER BY name) AS foo(c1, c2)
282
285
  def from_self(opts=OPTS)
283
286
  fs = {}
284
- non_sql = non_sql_options
285
- @opts.keys.each{|k| fs[k] = nil unless non_sql.include?(k)}
287
+ @opts.keys.each{|k| fs[k] = nil unless non_sql_option?(k)}
286
288
  c = clone(fs).from(opts[:alias] ? as(opts[:alias], opts[:column_aliases]) : self)
287
289
  if cols = _columns
288
290
  c.send(:columns=, cols)
@@ -576,7 +578,7 @@ module Sequel
576
578
  last_alias = options[:implicit_qualifier] || @opts[:last_joined_table] || first_source_alias
577
579
  qualify_type = options[:qualify]
578
580
  if Sequel.condition_specifier?(expr)
579
- expr = expr.collect do |k, v|
581
+ expr = expr.map do |k, v|
580
582
  qualify_type = default_join_table_qualification if qualify_type.nil?
581
583
  case qualify_type
582
584
  when false
@@ -1085,12 +1087,12 @@ module Sequel
1085
1087
  # Return a clone of the dataset extended with the given modules.
1086
1088
  # Note that like Object#extend, when multiple modules are provided
1087
1089
  # as arguments the cloned dataset is extended with the modules in reverse
1088
- # order. If a block is provided, a module is created using the block and
1090
+ # order. If a block is provided, a DatasetModule is created using the block and
1089
1091
  # the clone is extended with that module after any modules given as arguments.
1090
1092
  def with_extend(*mods, &block)
1091
1093
  c = _clone(:freeze=>false)
1092
1094
  c.extend(*mods) unless mods.empty?
1093
- c.extend(Module.new(&block)) if block
1095
+ c.extend(DatasetModule.new(&block)) if block
1094
1096
  c.freeze if frozen? # SEQUEL5: Remove if frozen?
1095
1097
  c
1096
1098
  end
@@ -1099,7 +1101,7 @@ module Sequel
1099
1101
  def with_extend(*mods, &block) # :nodoc:
1100
1102
  c = clone
1101
1103
  c.extend(*mods) unless mods.empty?
1102
- c.extend(Module.new(&block)) if block
1104
+ c.extend(DatasetModule.new(&block)) if block
1103
1105
  c
1104
1106
  end
1105
1107
  # :nocov:
@@ -1137,7 +1139,9 @@ module Sequel
1137
1139
  # * single_record (if only one record could be returned)
1138
1140
  # * single_value (if only one record could be returned, and a single column is selected)
1139
1141
  # * map
1142
+ # * as_hash
1140
1143
  # * to_hash
1144
+ # * to_hash_groups
1141
1145
  # * delete (if a DELETE statement)
1142
1146
  # * update (if an UPDATE statement, with no arguments)
1143
1147
  # * insert (if an INSERT statement, with no arguments)
@@ -1169,7 +1173,7 @@ module Sequel
1169
1173
 
1170
1174
  # Return true if the dataset has a non-nil value for any key in opts.
1171
1175
  def options_overlap(opts)
1172
- !(@opts.collect{|k,v| k unless v.nil?}.compact & opts).empty?
1176
+ !(@opts.map{|k,v| k unless v.nil?}.compact & opts).empty?
1173
1177
  end
1174
1178
 
1175
1179
  # From types allowed to be considered a simple_select_all
@@ -1181,8 +1185,7 @@ module Sequel
1181
1185
  # SELECT table.* FROM table
1182
1186
  def simple_select_all?
1183
1187
  return false unless (f = @opts[:from]) && f.length == 1
1184
- non_sql = non_sql_options
1185
- o = @opts.reject{|k,v| v.nil? || non_sql.include?(k)}
1188
+ o = @opts.reject{|k,v| v.nil? || non_sql_option?(k)}
1186
1189
  from = f.first
1187
1190
  from = from.expression if from.is_a?(SQL::AliasedExpression)
1188
1191
 
@@ -1358,9 +1361,17 @@ module Sequel
1358
1361
  server?(:default)
1359
1362
  end
1360
1363
 
1361
- # Dataset options that do not affect the generated SQL.
1364
+ # SEQUEL5: Remove
1362
1365
  def non_sql_options
1366
+ # :nocov:
1367
+ Sequel::Deprecation.deprecate("Dataset#non_sql_options (private method)", "Convert the related code to use the non_sql_option? method")
1363
1368
  NON_SQL_OPTIONS
1369
+ # :nocov:
1370
+ end
1371
+
1372
+ # Whether the given option key does not affect the generated SQL.
1373
+ def non_sql_option?(key)
1374
+ NON_SQL_OPTIONS.include?(key)
1364
1375
  end
1365
1376
 
1366
1377
  # Treat the +block+ as a virtual_row block if not +nil+ and
@@ -42,5 +42,5 @@ module Sequel
42
42
  include SQL::StringMethods
43
43
  end
44
44
 
45
- require(%w"query actions features graph prepared_statements misc mutation sql placeholder_literalizer", 'dataset')
45
+ require(%w"query actions features graph prepared_statements misc mutation sql placeholder_literalizer dataset_module", 'dataset')
46
46
  end
@@ -7,6 +7,14 @@ module Sequel
7
7
  # If this exception wraps an underlying exception, the underlying
8
8
  # exception is held here.
9
9
  attr_accessor :wrapped_exception
10
+
11
+ if RUBY_VERSION >= '2.1'
12
+ # Returned the wrapped exception if one exists, otherwise use
13
+ # ruby's default behavior.
14
+ def cause
15
+ wrapped_exception || super
16
+ end
17
+ end
10
18
  end
11
19
 
12
20
  (
@@ -5,14 +5,17 @@ module Sequel
5
5
  module PgRow
6
6
  module DatabaseMethods
7
7
  ESCAPE_RE = /("|\\)/.freeze
8
+ Sequel::Deprecation.deprecate_constant(self, :ESCAPE_RE)
8
9
  ESCAPE_REPLACEMENT = '\\\\\1'.freeze
10
+ Sequel::Deprecation.deprecate_constant(self, :ESCAPE_REPLACEMENT)
9
11
  COMMA = ','
12
+ Sequel::Deprecation.deprecate_constant(self, :COMMA)
10
13
 
11
14
  # Handle Sequel::Model instances in bound variables.
12
15
  def bound_variable_arg(arg, conn)
13
16
  case arg
14
17
  when Sequel::Model
15
- "(#{arg.values.values_at(*arg.columns).map{|v| bound_variable_array(v)}.join(COMMA)})"
18
+ "(#{arg.values.values_at(*arg.columns).map{|v| bound_variable_array(v)}.join(',')})"
16
19
  else
17
20
  super
18
21
  end
@@ -34,7 +37,7 @@ module Sequel
34
37
  def bound_variable_array(arg)
35
38
  case arg
36
39
  when Sequel::Model
37
- "\"(#{arg.values.values_at(*arg.columns).map{|v| bound_variable_array(v)}.join(COMMA).gsub(ESCAPE_RE, ESCAPE_REPLACEMENT)})\""
40
+ "\"(#{arg.values.values_at(*arg.columns).map{|v| bound_variable_array(v)}.join(',').gsub(/("|\\)/, '\\\\\1')})\""
38
41
  else
39
42
  super
40
43
  end
@@ -48,7 +48,10 @@ class Array
48
48
  def sql_value_list
49
49
  ::Sequel::SQL::ValueList.new(self)
50
50
  end
51
- alias sql_array sql_value_list
51
+ def sql_array
52
+ Sequel::Deprecation.deprecate("Array#sql_array in the core_extensions extension", "Use Array#sql_value_list instead")
53
+ sql_value_list
54
+ end
52
55
 
53
56
  # Return a <tt>Sequel::SQL::BooleanExpression</tt> created from this array, matching all of the
54
57
  # conditions. Rarely do you need to call this explicitly, as Sequel generally
@@ -32,7 +32,7 @@ module Sequel
32
32
  # Return an instance of Sequel.datetime_class that will be literalized
33
33
  # as CURRENT_TIMESTAMP.
34
34
  def current_datetime
35
- MAP.fetch(Sequel.datetime_class).now
35
+ (Sequel.datetime_class == ::Time ? Time : DateTime).now
36
36
  end
37
37
 
38
38
  private
@@ -56,6 +56,7 @@ module Sequel
56
56
 
57
57
  # Mapping of Time/DateTime classes to subclasses literalized as CURRENT_TIMESTAMP
58
58
  MAP = {::Time=>Time, ::DateTime=>DateTime}
59
+ Sequel::Deprecation.deprecate_constant(self, :MAP)
59
60
  end
60
61
 
61
62
  Dataset.register_extension(:current_datetime_timestamp, CurrentDateTimeTimestamp::DatasetMethods)
@@ -67,6 +67,7 @@ module Sequel
67
67
  ACCESS_DURATION_UNITS = DURATION_UNITS.zip(%w'yyyy m d h n s'.map(&:freeze)).freeze
68
68
  DB2_DURATION_UNITS = DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit(s.to_s).freeze}).freeze
69
69
  FDBSQL_DURATION_UNITS = DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit(s.to_s.chop).freeze}).freeze
70
+ Sequel::Deprecation.deprecate_constant(self, :FDBSQL_DURATION_UNITS)
70
71
 
71
72
  # Append the SQL fragment for the DateAdd expression to the SQL query.
72
73
  def date_add_sql_append(sql, da)
@@ -35,7 +35,7 @@
35
35
 
36
36
  module Sequel
37
37
  module DuplicateColumnsHandler
38
- CALLER_ARGS = RUBY_VERSION >= '2.0' ? [0,1] : [0]
38
+ CALLER_ARGS = (RUBY_VERSION >= '2.0' ? [0,1] : [0]).freeze
39
39
 
40
40
  # Customize handling of duplicate columns for this dataset.
41
41
  def on_duplicate_columns(handler = (raise Error, "Must provide either an argument or a block to on_duplicate_columns" unless block_given?; nil), &block)
@@ -43,6 +43,8 @@ module Sequel
43
43
  clone(:on_duplicate_columns=>handler||block)
44
44
  end
45
45
 
46
+ private
47
+
46
48
  # Override the attr_writer to check for duplicate columns, and call
47
49
  # handle_duplicate_columns if necessary.
48
50
  def columns=(cols)
@@ -52,8 +54,6 @@ module Sequel
52
54
  super
53
55
  end
54
56
 
55
- private
56
-
57
57
  # Invoke the appropriate behavior when duplicate columns are present.
58
58
  def handle_duplicate_columns(cols)
59
59
  message = "#{caller(*CALLER_ARGS).first}: One or more duplicate columns present in #{cols.inspect}"
@@ -2,4 +2,7 @@
2
2
  #
3
3
  # This only exists for backwards compatibility, as the behavior
4
4
  # added by this extension is now the default Sequel behavior.
5
+
6
+ Sequel::Deprecation.deprecate("The empty_array_ignore_nulls", "It has been a no-op since 4.25.0")
7
+
5
8
  Sequel::Dataset.register_extension(:empty_array_ignore_nulls){}
@@ -18,6 +18,8 @@
18
18
  #
19
19
  # Related module: Sequel::FilterHaving
20
20
 
21
+ Sequel::Deprecation.deprecate("The filter_having extension", "Please consider maintaining it yourself as an external gem if you want to continue using it")
22
+
21
23
  #
22
24
  module Sequel
23
25
  module FilterHaving
@@ -67,3 +67,5 @@ module Sequel
67
67
  register_extension(:freeze_datasets, FreezeDatasets)
68
68
  end
69
69
  end
70
+
71
+ # Sequel::Database.register_extension(:freeze_datasets){} # SEQUEL5
@@ -29,9 +29,9 @@ module Sequel
29
29
  super
30
30
  end
31
31
  end
32
- # SEQUEL5: Make this an empty module, since it will be the default behavior
33
32
  end
34
33
 
35
34
  Database.register_extension(:from_block, Database::FromBlock)
36
35
  end
37
36
 
37
+ # Sequel::Database.register_extension(:from_block){} # SEQUEL5
@@ -50,10 +50,10 @@ module Sequel
50
50
  # the result set
51
51
  datasets = @opts[:graph][:table_aliases].to_a.reject{|ta,ds| ds.nil?}
52
52
  # Get just the list of table aliases into a local variable, for speed
53
- table_aliases = datasets.collect{|ta,ds| ta}
53
+ table_aliases = datasets.map{|ta,ds| ta}
54
54
  # Get an array of arrays, one for each dataset, with
55
55
  # the necessary information about each dataset, for speed
56
- datasets = datasets.collect{|ta, ds| [ta, ds, ds.row_proc]}
56
+ datasets = datasets.map{|ta, ds| [ta, ds, ds.row_proc]}
57
57
  # Use the manually set graph aliases, if any, otherwise
58
58
  # use the ones automatically created by .graph
59
59
  column_aliases = @opts[:graph_aliases] || @opts[:graph][:column_aliases] # SEQUEL5: Remove :graph_aliases support
@@ -18,6 +18,8 @@
18
18
  #
19
19
  # Related module: Sequel::HashAliases
20
20
 
21
+ Sequel::Deprecation.deprecate("The hash_aliases extension", "Please consider maintaining it yourself as an external gem if you want to continue using it")
22
+
21
23
  #
22
24
  module Sequel
23
25
  module HashAliases
@@ -34,13 +34,6 @@
34
34
  #
35
35
  # DB.extension :identifier_mangling
36
36
  #
37
- # Historically, Sequel supported these methods by default on
38
- # Databases and Datasets. Sequel 4 will continue to support
39
- # the methods for backwards compatibility, by loading this
40
- # extension automatically for databases unless the
41
- # <tt>:identifier_mangling=>false</tt> Database option is
42
- # used.
43
- #
44
37
  # Related modules: Sequel::IdentifierMangling::DatabaseMethods,
45
38
  # Sequel::IdentifierMangling::DatasetMethods
46
39
 
@@ -9,6 +9,8 @@
9
9
  #
10
10
  # Related module: Sequel::Metaprogramming
11
11
 
12
+ Sequel::Deprecation.deprecate("The meta_def extension", "Replace meta_def usage with define_singleton_method")
13
+
12
14
  #
13
15
  module Sequel
14
16
  # Contains meta_def method for adding methods to objects via blocks.