sequel 5.39.0 → 5.72.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (219) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +408 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +59 -27
  5. data/bin/sequel +11 -3
  6. data/doc/advanced_associations.rdoc +16 -14
  7. data/doc/association_basics.rdoc +119 -24
  8. data/doc/cheat_sheet.rdoc +11 -3
  9. data/doc/mass_assignment.rdoc +1 -1
  10. data/doc/migration.rdoc +13 -6
  11. data/doc/model_hooks.rdoc +1 -1
  12. data/doc/object_model.rdoc +8 -8
  13. data/doc/opening_databases.rdoc +26 -12
  14. data/doc/postgresql.rdoc +16 -8
  15. data/doc/querying.rdoc +5 -3
  16. data/doc/release_notes/5.40.0.txt +40 -0
  17. data/doc/release_notes/5.41.0.txt +25 -0
  18. data/doc/release_notes/5.42.0.txt +136 -0
  19. data/doc/release_notes/5.43.0.txt +98 -0
  20. data/doc/release_notes/5.44.0.txt +32 -0
  21. data/doc/release_notes/5.45.0.txt +34 -0
  22. data/doc/release_notes/5.46.0.txt +87 -0
  23. data/doc/release_notes/5.47.0.txt +59 -0
  24. data/doc/release_notes/5.48.0.txt +14 -0
  25. data/doc/release_notes/5.49.0.txt +59 -0
  26. data/doc/release_notes/5.50.0.txt +78 -0
  27. data/doc/release_notes/5.51.0.txt +47 -0
  28. data/doc/release_notes/5.52.0.txt +87 -0
  29. data/doc/release_notes/5.53.0.txt +23 -0
  30. data/doc/release_notes/5.54.0.txt +27 -0
  31. data/doc/release_notes/5.55.0.txt +21 -0
  32. data/doc/release_notes/5.56.0.txt +51 -0
  33. data/doc/release_notes/5.57.0.txt +23 -0
  34. data/doc/release_notes/5.58.0.txt +31 -0
  35. data/doc/release_notes/5.59.0.txt +73 -0
  36. data/doc/release_notes/5.60.0.txt +22 -0
  37. data/doc/release_notes/5.61.0.txt +43 -0
  38. data/doc/release_notes/5.62.0.txt +132 -0
  39. data/doc/release_notes/5.63.0.txt +33 -0
  40. data/doc/release_notes/5.64.0.txt +50 -0
  41. data/doc/release_notes/5.65.0.txt +21 -0
  42. data/doc/release_notes/5.66.0.txt +24 -0
  43. data/doc/release_notes/5.67.0.txt +32 -0
  44. data/doc/release_notes/5.68.0.txt +61 -0
  45. data/doc/release_notes/5.69.0.txt +26 -0
  46. data/doc/release_notes/5.70.0.txt +35 -0
  47. data/doc/release_notes/5.71.0.txt +21 -0
  48. data/doc/release_notes/5.72.0.txt +33 -0
  49. data/doc/schema_modification.rdoc +1 -1
  50. data/doc/security.rdoc +9 -9
  51. data/doc/sharding.rdoc +3 -1
  52. data/doc/sql.rdoc +28 -16
  53. data/doc/testing.rdoc +22 -11
  54. data/doc/transactions.rdoc +6 -6
  55. data/doc/virtual_rows.rdoc +2 -2
  56. data/lib/sequel/adapters/ado/access.rb +1 -1
  57. data/lib/sequel/adapters/ado.rb +17 -17
  58. data/lib/sequel/adapters/amalgalite.rb +3 -5
  59. data/lib/sequel/adapters/ibmdb.rb +2 -2
  60. data/lib/sequel/adapters/jdbc/derby.rb +8 -0
  61. data/lib/sequel/adapters/jdbc/h2.rb +60 -10
  62. data/lib/sequel/adapters/jdbc/hsqldb.rb +6 -0
  63. data/lib/sequel/adapters/jdbc/postgresql.rb +7 -4
  64. data/lib/sequel/adapters/jdbc.rb +16 -18
  65. data/lib/sequel/adapters/mysql.rb +92 -67
  66. data/lib/sequel/adapters/mysql2.rb +54 -49
  67. data/lib/sequel/adapters/odbc.rb +6 -2
  68. data/lib/sequel/adapters/oracle.rb +4 -3
  69. data/lib/sequel/adapters/postgres.rb +83 -40
  70. data/lib/sequel/adapters/shared/access.rb +11 -1
  71. data/lib/sequel/adapters/shared/db2.rb +30 -0
  72. data/lib/sequel/adapters/shared/mssql.rb +90 -9
  73. data/lib/sequel/adapters/shared/mysql.rb +47 -2
  74. data/lib/sequel/adapters/shared/oracle.rb +82 -1
  75. data/lib/sequel/adapters/shared/postgres.rb +496 -178
  76. data/lib/sequel/adapters/shared/sqlanywhere.rb +11 -1
  77. data/lib/sequel/adapters/shared/sqlite.rb +116 -11
  78. data/lib/sequel/adapters/sqlanywhere.rb +1 -1
  79. data/lib/sequel/adapters/sqlite.rb +60 -18
  80. data/lib/sequel/adapters/tinytds.rb +1 -1
  81. data/lib/sequel/adapters/trilogy.rb +117 -0
  82. data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
  83. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
  84. data/lib/sequel/ast_transformer.rb +6 -0
  85. data/lib/sequel/connection_pool/sharded_single.rb +5 -7
  86. data/lib/sequel/connection_pool/sharded_threaded.rb +16 -11
  87. data/lib/sequel/connection_pool/sharded_timed_queue.rb +374 -0
  88. data/lib/sequel/connection_pool/single.rb +6 -8
  89. data/lib/sequel/connection_pool/threaded.rb +14 -8
  90. data/lib/sequel/connection_pool/timed_queue.rb +270 -0
  91. data/lib/sequel/connection_pool.rb +55 -31
  92. data/lib/sequel/core.rb +28 -18
  93. data/lib/sequel/database/connecting.rb +27 -3
  94. data/lib/sequel/database/dataset.rb +16 -6
  95. data/lib/sequel/database/misc.rb +69 -14
  96. data/lib/sequel/database/query.rb +73 -2
  97. data/lib/sequel/database/schema_generator.rb +46 -53
  98. data/lib/sequel/database/schema_methods.rb +18 -2
  99. data/lib/sequel/dataset/actions.rb +108 -14
  100. data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +42 -0
  101. data/lib/sequel/dataset/features.rb +20 -0
  102. data/lib/sequel/dataset/misc.rb +12 -2
  103. data/lib/sequel/dataset/placeholder_literalizer.rb +20 -9
  104. data/lib/sequel/dataset/prepared_statements.rb +2 -0
  105. data/lib/sequel/dataset/query.rb +171 -44
  106. data/lib/sequel/dataset/sql.rb +182 -47
  107. data/lib/sequel/dataset.rb +4 -0
  108. data/lib/sequel/extensions/_model_pg_row.rb +0 -12
  109. data/lib/sequel/extensions/_pretty_table.rb +1 -1
  110. data/lib/sequel/extensions/any_not_empty.rb +1 -1
  111. data/lib/sequel/extensions/async_thread_pool.rb +439 -0
  112. data/lib/sequel/extensions/auto_literal_strings.rb +1 -1
  113. data/lib/sequel/extensions/blank.rb +8 -0
  114. data/lib/sequel/extensions/connection_expiration.rb +15 -9
  115. data/lib/sequel/extensions/connection_validator.rb +16 -11
  116. data/lib/sequel/extensions/constraint_validations.rb +1 -1
  117. data/lib/sequel/extensions/core_refinements.rb +36 -11
  118. data/lib/sequel/extensions/date_arithmetic.rb +71 -31
  119. data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
  120. data/lib/sequel/extensions/datetime_parse_to_time.rb +5 -1
  121. data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
  122. data/lib/sequel/extensions/eval_inspect.rb +2 -0
  123. data/lib/sequel/extensions/index_caching.rb +5 -1
  124. data/lib/sequel/extensions/inflector.rb +9 -1
  125. data/lib/sequel/extensions/is_distinct_from.rb +141 -0
  126. data/lib/sequel/extensions/looser_typecasting.rb +3 -0
  127. data/lib/sequel/extensions/migration.rb +11 -2
  128. data/lib/sequel/extensions/named_timezones.rb +26 -6
  129. data/lib/sequel/extensions/pagination.rb +1 -1
  130. data/lib/sequel/extensions/pg_array.rb +32 -4
  131. data/lib/sequel/extensions/pg_array_ops.rb +2 -2
  132. data/lib/sequel/extensions/pg_auto_parameterize.rb +509 -0
  133. data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +110 -0
  134. data/lib/sequel/extensions/pg_enum.rb +2 -3
  135. data/lib/sequel/extensions/pg_extended_date_support.rb +38 -27
  136. data/lib/sequel/extensions/pg_extended_integer_support.rb +116 -0
  137. data/lib/sequel/extensions/pg_hstore.rb +6 -1
  138. data/lib/sequel/extensions/pg_hstore_ops.rb +53 -3
  139. data/lib/sequel/extensions/pg_inet.rb +10 -11
  140. data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
  141. data/lib/sequel/extensions/pg_interval.rb +45 -19
  142. data/lib/sequel/extensions/pg_json.rb +13 -15
  143. data/lib/sequel/extensions/pg_json_ops.rb +73 -2
  144. data/lib/sequel/extensions/pg_loose_count.rb +3 -1
  145. data/lib/sequel/extensions/pg_multirange.rb +367 -0
  146. data/lib/sequel/extensions/pg_range.rb +11 -24
  147. data/lib/sequel/extensions/pg_range_ops.rb +37 -9
  148. data/lib/sequel/extensions/pg_row.rb +21 -19
  149. data/lib/sequel/extensions/pg_row_ops.rb +1 -1
  150. data/lib/sequel/extensions/query.rb +2 -0
  151. data/lib/sequel/extensions/s.rb +2 -1
  152. data/lib/sequel/extensions/schema_caching.rb +1 -1
  153. data/lib/sequel/extensions/schema_dumper.rb +45 -11
  154. data/lib/sequel/extensions/server_block.rb +10 -13
  155. data/lib/sequel/extensions/set_literalizer.rb +58 -0
  156. data/lib/sequel/extensions/sql_comments.rb +110 -3
  157. data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
  158. data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
  159. data/lib/sequel/extensions/string_agg.rb +1 -1
  160. data/lib/sequel/extensions/string_date_time.rb +19 -23
  161. data/lib/sequel/extensions/symbol_aref.rb +2 -0
  162. data/lib/sequel/model/associations.rb +345 -101
  163. data/lib/sequel/model/base.rb +51 -27
  164. data/lib/sequel/model/dataset_module.rb +3 -0
  165. data/lib/sequel/model/errors.rb +10 -1
  166. data/lib/sequel/model/inflections.rb +1 -1
  167. data/lib/sequel/model/plugins.rb +5 -0
  168. data/lib/sequel/plugins/association_proxies.rb +2 -0
  169. data/lib/sequel/plugins/async_thread_pool.rb +39 -0
  170. data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
  171. data/lib/sequel/plugins/auto_validations.rb +87 -15
  172. data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
  173. data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
  174. data/lib/sequel/plugins/column_encryption.rb +728 -0
  175. data/lib/sequel/plugins/composition.rb +10 -4
  176. data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
  177. data/lib/sequel/plugins/constraint_validations.rb +10 -6
  178. data/lib/sequel/plugins/dataset_associations.rb +4 -1
  179. data/lib/sequel/plugins/defaults_setter.rb +16 -0
  180. data/lib/sequel/plugins/dirty.rb +1 -1
  181. data/lib/sequel/plugins/enum.rb +124 -0
  182. data/lib/sequel/plugins/finder.rb +4 -2
  183. data/lib/sequel/plugins/insert_conflict.rb +4 -0
  184. data/lib/sequel/plugins/instance_specific_default.rb +1 -1
  185. data/lib/sequel/plugins/json_serializer.rb +39 -24
  186. data/lib/sequel/plugins/lazy_attributes.rb +3 -0
  187. data/lib/sequel/plugins/list.rb +3 -1
  188. data/lib/sequel/plugins/many_through_many.rb +109 -10
  189. data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -38
  190. data/lib/sequel/plugins/nested_attributes.rb +12 -7
  191. data/lib/sequel/plugins/optimistic_locking.rb +9 -42
  192. data/lib/sequel/plugins/optimistic_locking_base.rb +55 -0
  193. data/lib/sequel/plugins/pg_array_associations.rb +56 -38
  194. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +11 -3
  195. data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +109 -0
  196. data/lib/sequel/plugins/prepared_statements.rb +12 -2
  197. data/lib/sequel/plugins/prepared_statements_safe.rb +2 -1
  198. data/lib/sequel/plugins/primary_key_lookup_check_values.rb +154 -0
  199. data/lib/sequel/plugins/rcte_tree.rb +27 -19
  200. data/lib/sequel/plugins/require_valid_schema.rb +67 -0
  201. data/lib/sequel/plugins/serialization.rb +9 -3
  202. data/lib/sequel/plugins/serialization_modification_detection.rb +2 -1
  203. data/lib/sequel/plugins/single_table_inheritance.rb +8 -0
  204. data/lib/sequel/plugins/sql_comments.rb +189 -0
  205. data/lib/sequel/plugins/static_cache.rb +39 -1
  206. data/lib/sequel/plugins/static_cache_cache.rb +5 -1
  207. data/lib/sequel/plugins/subclasses.rb +28 -11
  208. data/lib/sequel/plugins/tactical_eager_loading.rb +23 -10
  209. data/lib/sequel/plugins/timestamps.rb +1 -1
  210. data/lib/sequel/plugins/unused_associations.rb +521 -0
  211. data/lib/sequel/plugins/update_or_create.rb +1 -1
  212. data/lib/sequel/plugins/validate_associated.rb +22 -12
  213. data/lib/sequel/plugins/validation_helpers.rb +46 -12
  214. data/lib/sequel/plugins/validation_helpers_generic_type_messages.rb +73 -0
  215. data/lib/sequel/plugins/xml_serializer.rb +1 -1
  216. data/lib/sequel/sql.rb +1 -1
  217. data/lib/sequel/timezones.rb +12 -14
  218. data/lib/sequel/version.rb +1 -1
  219. metadata +132 -38
@@ -22,31 +22,9 @@ module Sequel
22
22
  def insert_sql(*values)
23
23
  return static_sql(@opts[:sql]) if @opts[:sql]
24
24
 
25
- check_modification_allowed!
26
-
27
- columns = []
28
-
29
- case values.size
30
- when 0
31
- return insert_sql(OPTS)
32
- when 1
33
- case vals = values[0]
34
- when Hash
35
- values = []
36
- vals.each do |k,v|
37
- columns << k
38
- values << v
39
- end
40
- when Dataset, Array, LiteralString
41
- values = vals
42
- end
43
- when 2
44
- if (v0 = values[0]).is_a?(Array) && ((v1 = values[1]).is_a?(Array) || v1.is_a?(Dataset) || v1.is_a?(LiteralString))
45
- columns, values = v0, v1
46
- raise(Error, "Different number of values and columns given to insert_sql") if values.is_a?(Array) and columns.length != values.length
47
- end
48
- end
25
+ check_insert_allowed!
49
26
 
27
+ columns, values = _parse_insert_sql_args(values)
50
28
  if values.is_a?(Array) && values.empty? && !insert_supports_empty_values?
51
29
  columns, values = insert_empty_columns_values
52
30
  elsif values.is_a?(Dataset) && hoist_cte?(values) && supports_cte?(:insert)
@@ -112,6 +90,31 @@ module Sequel
112
90
  end
113
91
  end
114
92
 
93
+ # The SQL to use for the MERGE statement.
94
+ def merge_sql
95
+ raise Error, "This database doesn't support MERGE" unless supports_merge?
96
+ if sql = opts[:sql]
97
+ return static_sql(sql)
98
+ end
99
+ if sql = cache_get(:_merge_sql)
100
+ return sql
101
+ end
102
+ source, join_condition = @opts[:merge_using]
103
+ raise Error, "No USING clause for MERGE" unless source
104
+ sql = @opts[:append_sql] || sql_string_origin
105
+
106
+ select_with_sql(sql)
107
+ sql << "MERGE INTO "
108
+ source_list_append(sql, @opts[:from])
109
+ sql << " USING "
110
+ identifier_append(sql, source)
111
+ sql << " ON "
112
+ literal_append(sql, join_condition)
113
+ _merge_when_sql(sql)
114
+ cache_set(:_merge_sql, sql) if cache_sql?
115
+ sql
116
+ end
117
+
115
118
  # Returns an array of insert statements for inserting multiple records.
116
119
  # This method is used by +multi_insert+ to format insert statements and
117
120
  # expects a keys array and and an array of value arrays.
@@ -172,7 +175,7 @@ module Sequel
172
175
  # than one table.
173
176
  def update_sql(values = OPTS)
174
177
  return static_sql(opts[:sql]) if opts[:sql]
175
- check_modification_allowed!
178
+ check_update_allowed!
176
179
  check_not_limited!(:update)
177
180
 
178
181
  case values
@@ -215,7 +218,7 @@ module Sequel
215
218
  lines << "def #{'_' if priv}#{type}_sql"
216
219
  lines << 'if sql = opts[:sql]; return static_sql(sql) end' unless priv
217
220
  lines << "if sql = cache_get(:_#{type}_sql); return sql end" if cacheable
218
- lines << 'check_modification_allowed!' << 'check_not_limited!(:delete)' if type == :delete
221
+ lines << 'check_delete_allowed!' << 'check_not_limited!(:delete)' if type == :delete
219
222
  lines << 'sql = @opts[:append_sql] || sql_string_origin'
220
223
 
221
224
  if clauses.all?{|c| c.is_a?(Array)}
@@ -559,11 +562,9 @@ module Sequel
559
562
  # Append literalization of JOIN USING clause to SQL string.
560
563
  def join_using_clause_sql_append(sql, jc)
561
564
  join_clause_sql_append(sql, jc)
562
- sql << ' USING ('
563
- column_list_append(sql, jc.using)
564
- sql << ')'
565
+ join_using_clause_using_sql_append(sql, jc.using)
565
566
  end
566
-
567
+
567
568
  # Append literalization of negative boolean constant to SQL string.
568
569
  def negative_boolean_constant_sql_append(sql, constant)
569
570
  sql << 'NOT '
@@ -852,6 +853,83 @@ module Sequel
852
853
 
853
854
  private
854
855
 
856
+ # Append the INSERT sql used in a MERGE
857
+ def _merge_insert_sql(sql, data)
858
+ sql << " THEN INSERT"
859
+ columns, values = _parse_insert_sql_args(data[:values])
860
+ _insert_columns_sql(sql, columns)
861
+ _insert_values_sql(sql, values)
862
+ end
863
+
864
+ def _merge_update_sql(sql, data)
865
+ sql << " THEN UPDATE SET "
866
+ update_sql_values_hash(sql, data[:values])
867
+ end
868
+
869
+ def _merge_delete_sql(sql, data)
870
+ sql << " THEN DELETE"
871
+ end
872
+
873
+ # Mapping of merge types to related SQL
874
+ MERGE_TYPE_SQL = {
875
+ :insert => ' WHEN NOT MATCHED',
876
+ :delete => ' WHEN MATCHED',
877
+ :update => ' WHEN MATCHED',
878
+ :matched => ' WHEN MATCHED',
879
+ :not_matched => ' WHEN NOT MATCHED',
880
+ }.freeze
881
+ private_constant :MERGE_TYPE_SQL
882
+
883
+ # Add the WHEN clauses to the MERGE SQL
884
+ def _merge_when_sql(sql)
885
+ raise Error, "no WHEN [NOT] MATCHED clauses provided for MERGE" unless merge_when = @opts[:merge_when]
886
+ merge_when.each do |data|
887
+ type = data[:type]
888
+ sql << MERGE_TYPE_SQL[type]
889
+ _merge_when_conditions_sql(sql, data)
890
+ send(:"_merge_#{type}_sql", sql, data)
891
+ end
892
+ end
893
+
894
+ # Append MERGE WHEN conditions, if there are conditions provided.
895
+ def _merge_when_conditions_sql(sql, data)
896
+ if data.has_key?(:conditions)
897
+ sql << " AND "
898
+ literal_append(sql, data[:conditions])
899
+ end
900
+ end
901
+
902
+ # Parse the values passed to insert_sql, returning columns and values
903
+ # to use for the INSERT. Returned columns is always an array, but can be empty
904
+ # for an INSERT without explicit column references. Returned values can be an
905
+ # array, dataset, or literal string.
906
+ def _parse_insert_sql_args(values)
907
+ columns = []
908
+
909
+ case values.size
910
+ when 0
911
+ values = []
912
+ when 1
913
+ case vals = values[0]
914
+ when Hash
915
+ values = []
916
+ vals.each do |k,v|
917
+ columns << k
918
+ values << v
919
+ end
920
+ when Dataset, Array, LiteralString
921
+ values = vals
922
+ end
923
+ when 2
924
+ if (v0 = values[0]).is_a?(Array) && ((v1 = values[1]).is_a?(Array) || v1.is_a?(Dataset) || v1.is_a?(LiteralString))
925
+ columns, values = v0, v1
926
+ raise(Error, "Different number of values and columns given to insert_sql") if values.is_a?(Array) and columns.length != values.length
927
+ end
928
+ end
929
+
930
+ [columns, values]
931
+ end
932
+
855
933
  # Formats the truncate statement. Assumes the table given has already been
856
934
  # literalized.
857
935
  def _truncate_sql(table)
@@ -896,9 +974,15 @@ module Sequel
896
974
  # Clone of this dataset usable in aggregate operations. Does
897
975
  # a from_self if dataset contains any parameters that would
898
976
  # affect normal aggregation, or just removes an existing
899
- # order if not.
977
+ # order if not. Also removes the row_proc, which isn't needed
978
+ # for aggregate calculations.
900
979
  def aggregate_dataset
901
- options_overlap(COUNT_FROM_SELF_OPTS) ? from_self : unordered
980
+ (aggreate_dataset_use_from_self? ? from_self : unordered).naked
981
+ end
982
+
983
+ # Whether to use from_self for an aggregate dataset.
984
+ def aggreate_dataset_use_from_self?
985
+ options_overlap(COUNT_FROM_SELF_OPTS)
902
986
  end
903
987
 
904
988
  # Append aliasing expression to SQL string.
@@ -918,10 +1002,35 @@ module Sequel
918
1002
  !@opts[:no_cache_sql] && !cache_get(:_no_cache_sql)
919
1003
  end
920
1004
 
921
- # Raise an InvalidOperation exception if deletion is not allowed for this dataset.
1005
+ # Raise an InvalidOperation exception if modification is not allowed for this dataset.
1006
+ # Check whether it is allowed to insert into this dataset.
1007
+ # Only for backwards compatibility with older external adapters.
922
1008
  def check_modification_allowed!
1009
+ # SEQUEL6: Remove
1010
+ Sequel::Deprecation.deprecate("Dataset#check_modification_allowed!", "Use check_{insert,delete,update,truncation}_allowed! instead")
1011
+ _check_modification_allowed!(supports_modifying_joins?)
1012
+ end
1013
+
1014
+ # Check whether it is allowed to insert into this dataset.
1015
+ def check_insert_allowed!
1016
+ _check_modification_allowed!(false)
1017
+ end
1018
+ alias check_truncation_allowed! check_insert_allowed!
1019
+
1020
+ # Check whether it is allowed to delete from this dataset.
1021
+ def check_delete_allowed!
1022
+ _check_modification_allowed!(supports_deleting_joins?)
1023
+ end
1024
+
1025
+ # Check whether it is allowed to update this dataset.
1026
+ def check_update_allowed!
1027
+ _check_modification_allowed!(supports_updating_joins?)
1028
+ end
1029
+
1030
+ # Internals of the check_*_allowed! methods
1031
+ def _check_modification_allowed!(modifying_joins_supported)
923
1032
  raise(InvalidOperation, "Grouped datasets cannot be modified") if opts[:group]
924
- raise(InvalidOperation, "Joined datasets cannot be modified") if !supports_modifying_joins? && joined_dataset?
1033
+ raise(InvalidOperation, "Joined datasets cannot be modified") if !modifying_joins_supported && joined_dataset?
925
1034
  end
926
1035
 
927
1036
  # Raise error if the dataset uses limits or offsets.
@@ -930,11 +1039,6 @@ module Sequel
930
1039
  raise InvalidOperation, "Dataset##{type} not supported on datasets with limits or offsets" if opts[:limit] || opts[:offset]
931
1040
  end
932
1041
 
933
- # Alias of check_modification_allowed!
934
- def check_truncation_allowed!
935
- check_modification_allowed!
936
- end
937
-
938
1042
  # Append column list to SQL string.
939
1043
  # If the column list is empty, a wildcard (*) is appended.
940
1044
  def column_list_append(sql, columns)
@@ -971,7 +1075,9 @@ module Sequel
971
1075
  # operators unsupported by some databases. Used by adapters for databases
972
1076
  # that don't support the operators natively.
973
1077
  def complex_expression_emulate_append(sql, op, args)
1078
+ # :nocov:
974
1079
  case op
1080
+ # :nocov:
975
1081
  when :%
976
1082
  complex_expression_arg_pairs_append(sql, args){|a, b| Sequel.function(:MOD, a, b)}
977
1083
  when :>>
@@ -1144,7 +1250,10 @@ module Sequel
1144
1250
  end
1145
1251
 
1146
1252
  def insert_columns_sql(sql)
1147
- columns = opts[:columns]
1253
+ _insert_columns_sql(sql, opts[:columns])
1254
+ end
1255
+
1256
+ def _insert_columns_sql(sql, columns)
1148
1257
  if columns && !columns.empty?
1149
1258
  sql << ' ('
1150
1259
  identifier_list_append(sql, columns)
@@ -1163,7 +1272,11 @@ module Sequel
1163
1272
  end
1164
1273
 
1165
1274
  def insert_values_sql(sql)
1166
- case values = opts[:values]
1275
+ _insert_values_sql(sql, opts[:values])
1276
+ end
1277
+
1278
+ def _insert_values_sql(sql, values)
1279
+ case values
1167
1280
  when Array
1168
1281
  if values.empty?
1169
1282
  sql << " DEFAULT VALUES"
@@ -1196,6 +1309,13 @@ module Sequel
1196
1309
  "#{join_type.to_s.gsub('_', ' ').upcase} JOIN"
1197
1310
  end
1198
1311
 
1312
+ # Append USING clause for JOIN USING
1313
+ def join_using_clause_using_sql_append(sql, using_columns)
1314
+ sql << ' USING ('
1315
+ column_list_append(sql, using_columns)
1316
+ sql << ')'
1317
+ end
1318
+
1199
1319
  # Append a literalization of the array to SQL string.
1200
1320
  # Treats as an expression if an array of all two pairs, or as a SQL array otherwise.
1201
1321
  def literal_array_append(sql, v)
@@ -1516,15 +1636,14 @@ module Sequel
1516
1636
 
1517
1637
  def select_with_sql(sql)
1518
1638
  return unless supports_cte?
1519
- ws = opts[:with]
1520
- return if !ws || ws.empty?
1639
+ ctes = opts[:with]
1640
+ return if !ctes || ctes.empty?
1521
1641
  sql << select_with_sql_base
1522
1642
  c = false
1523
1643
  comma = ', '
1524
- ws.each do |w|
1644
+ ctes.each do |cte|
1525
1645
  sql << comma if c
1526
- select_with_sql_prefix(sql, w)
1527
- literal_dataset_append(sql, w[:dataset])
1646
+ select_with_sql_cte(sql, cte)
1528
1647
  c ||= true
1529
1648
  end
1530
1649
  sql << ' '
@@ -1537,6 +1656,11 @@ module Sequel
1537
1656
  "WITH "
1538
1657
  end
1539
1658
 
1659
+ def select_with_sql_cte(sql, cte)
1660
+ select_with_sql_prefix(sql, cte)
1661
+ literal_dataset_append(sql, cte[:dataset])
1662
+ end
1663
+
1540
1664
  def select_with_sql_prefix(sql, w)
1541
1665
  quote_identifier_append(sql, w[:name])
1542
1666
  if args = w[:args]
@@ -1545,6 +1669,13 @@ module Sequel
1545
1669
  sql << ')'
1546
1670
  end
1547
1671
  sql << ' AS '
1672
+
1673
+ case w[:materialized]
1674
+ when true
1675
+ sql << "MATERIALIZED "
1676
+ when false
1677
+ sql << "NOT MATERIALIZED "
1678
+ end
1548
1679
  end
1549
1680
 
1550
1681
  # Whether the symbol cache should be skipped when literalizing the dataset
@@ -1599,7 +1730,7 @@ module Sequel
1599
1730
  # Append literalization of the subselect to SQL string.
1600
1731
  def subselect_sql_append(sql, ds)
1601
1732
  sds = subselect_sql_dataset(sql, ds)
1602
- sds.sql
1733
+ subselect_sql_append_sql(sql, sds)
1603
1734
  unless sds.send(:cache_sql?)
1604
1735
  # If subquery dataset does not allow caching SQL,
1605
1736
  # then this dataset should not allow caching SQL.
@@ -1611,6 +1742,10 @@ module Sequel
1611
1742
  ds.clone(:append_sql=>sql)
1612
1743
  end
1613
1744
 
1745
+ def subselect_sql_append_sql(sql, ds)
1746
+ ds.sql
1747
+ end
1748
+
1614
1749
  # The number of decimal digits of precision to use in timestamps.
1615
1750
  def timestamp_precision
1616
1751
  supports_timestamp_usecs? ? 6 : 0
@@ -53,4 +53,8 @@ module Sequel
53
53
  require_relative "dataset/sql"
54
54
  require_relative "dataset/placeholder_literalizer"
55
55
  require_relative "dataset/dataset_module"
56
+
57
+ # :nocov:
58
+ require_relative "dataset/deprecated_singleton_class_methods" if Dataset::TRUE_FREEZE
59
+ # :nocov:
56
60
  end
@@ -23,18 +23,6 @@ module Sequel
23
23
  super
24
24
  end
25
25
  end
26
-
27
- private
28
-
29
- # Handle Sequel::Model instances in bound variable arrays.
30
- def bound_variable_array(arg)
31
- case arg
32
- when Sequel::Model
33
- "\"(#{arg.values.values_at(*arg.columns).map{|v| bound_variable_array(v)}.join(',').gsub(/("|\\)/, '\\\\\1')})\""
34
- else
35
- super
36
- end
37
- end
38
26
  end
39
27
  end
40
28
  end
@@ -39,7 +39,7 @@ module Sequel
39
39
 
40
40
  # Hash of the maximum size of the value for each column
41
41
  def self.column_sizes(records, columns) # :nodoc:
42
- sizes = Hash.new {0}
42
+ sizes = Hash.new(0)
43
43
  columns.each do |c|
44
44
  sizes[c] = c.to_s.size
45
45
  end
@@ -33,7 +33,7 @@ module Sequel
33
33
  module AnyNotEmpty
34
34
  # If a block is not given, return whether the dataset is not empty.
35
35
  def any?
36
- if block_given?
36
+ if defined?(yield)
37
37
  super
38
38
  else
39
39
  !empty?