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
@@ -12,26 +12,6 @@ module Sequel
12
12
  # level (where level 1 is children, level 2 is children and grandchildren
13
13
  # etc.) in a single query.
14
14
  #
15
- # = Background
16
- #
17
- # There are two types of common models for storing tree structured data
18
- # in an SQL database, the adjacency list model and the nested set model.
19
- # Before recursive common table expressions (or similar capabilities such
20
- # as CONNECT BY for Oracle), the nested set model was the only easy way
21
- # to retrieve all ancestors and descendants in a single query. However,
22
- # it has significant performance corner cases.
23
- #
24
- # On PostgreSQL 8.4, with a significant number of rows, the nested set
25
- # model is almost 500 times slower than using a recursive common table
26
- # expression with the adjacency list model to get all descendants, and
27
- # almost 24,000 times slower to get all descendants to a given level.
28
- #
29
- # Considering that the nested set model requires more difficult management
30
- # than the adjacency list model, it's almost always better to use the
31
- # adjacency list model if your database supports common table expressions.
32
- # See http://explainextended.com/2009/09/24/adjacency-list-vs-nested-sets-postgresql/
33
- # for detailed analysis.
34
- #
35
15
  # = Usage
36
16
  #
37
17
  # The rcte_tree plugin adds four associations to the model: parent, children, ancestors, and
@@ -153,7 +133,7 @@ module Sequel
153
133
  base_ds = model.where(prkey_array.zip(key_array.map{|k| get_column_value(k)}))
154
134
  recursive_ds = model.join(t, key_array.zip(prkey_array))
155
135
  if c = a[:conditions]
156
- (base_ds, recursive_ds) = [base_ds, recursive_ds].collect do |ds|
136
+ (base_ds, recursive_ds) = [base_ds, recursive_ds].map do |ds|
157
137
  (c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.where(*c) : ds.where(c)
158
138
  end
159
139
  end
@@ -201,7 +181,7 @@ module Sequel
201
181
  recursive_case = model.join(t, key_array.zip(prkey_array)).
202
182
  select(*recursive_case_columns)
203
183
  if c = r[:conditions]
204
- (base_case, recursive_case) = [base_case, recursive_case].collect do |ds|
184
+ (base_case, recursive_case) = [base_case, recursive_case].map do |ds|
205
185
  (c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.where(*c) : ds.where(c)
206
186
  end
207
187
  end
@@ -248,7 +228,7 @@ module Sequel
248
228
  base_ds = model.where(key_array.zip(prkey_array.map{|k| get_column_value(k)}))
249
229
  recursive_ds = model.join(t, prkey_array.zip(key_array))
250
230
  if c = d[:conditions]
251
- (base_ds, recursive_ds) = [base_ds, recursive_ds].collect do |ds|
231
+ (base_ds, recursive_ds) = [base_ds, recursive_ds].map do |ds|
252
232
  (c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.where(*c) : ds.where(c)
253
233
  end
254
234
  end
@@ -299,7 +279,7 @@ module Sequel
299
279
  recursive_case = model.join(t, prkey_array.zip(key_array)).
300
280
  select(*recursive_case_columns)
301
281
  if c = r[:conditions]
302
- (base_case, recursive_case) = [base_case, recursive_case].collect do |ds|
282
+ (base_case, recursive_case) = [base_case, recursive_case].map do |ds|
303
283
  (c.is_a?(Array) && !Sequel.condition_specifier?(c)) ? ds.where(*c) : ds.where(c)
304
284
  end
305
285
  end
@@ -7,11 +7,11 @@ module Sequel
7
7
  # when you call an accessor.
8
8
  #
9
9
  # This plugin works by keeping the serialized value in the values, and
10
- # adding a @deserialized_values hash. The reader method for serialized columns
11
- # will check the @deserialized_values for the value, return it if present,
12
- # or deserialized the entry in @values and return it. The writer method will
13
- # set the @deserialized_values entry. This plugin adds a before_save hook
14
- # that serializes all @deserialized_values to @values.
10
+ # adding a deserialized_values hash. The reader method for serialized columns
11
+ # will check the deserialized_values for the value, return it if present,
12
+ # or deserialized the entry in values and return it. The writer method will
13
+ # set the deserialized_values entry. This plugin adds a before_save hook
14
+ # that serializes all deserialized_values to values.
15
15
  #
16
16
  # You can specify the serialization format as a pair of serializer/deserializer
17
17
  # callable objects. You can also specify the serialization format as a single
@@ -97,16 +97,9 @@ module Sequel
97
97
  end
98
98
  register_format(:marshal, lambda{|v| [Marshal.dump(v)].pack('m')},
99
99
  lambda do |v|
100
- begin
101
- Marshal.load(v.unpack('m')[0])
102
- rescue => e
103
- begin
104
- # Backwards compatibility for unpacked marshal output.
105
- Marshal.load(v)
106
- rescue
107
- raise e
108
- end
109
- end
100
+ # Handle unpacked marshalled data for backwards compat
101
+ v = v.unpack('m')[0] unless v[0..1] == "\x04\x08"
102
+ Marshal.load(v)
110
103
  end)
111
104
  register_format(:yaml, lambda(&:to_yaml), lambda{|v| YAML.load(v)})
112
105
  register_format(:json, lambda{|v| Sequel.object_to_json(v)}, lambda{|v| Sequel.parse_json(v)})
@@ -156,6 +149,7 @@ module Sequel
156
149
  # The columns that will be serialized. This is only for
157
150
  # backwards compatibility, use serialization_map in new code.
158
151
  def serialized_columns
152
+ Sequel::Deprecation.deprecate("#{self}.serialized_columns in the serialization plugin", "Use #{self}.serialization_map.keys instead")
159
153
  serialization_map.keys
160
154
  end
161
155
 
@@ -95,7 +95,7 @@ module Sequel
95
95
  end
96
96
  end
97
97
  km.each do |k,v|
98
- h[k.to_s] = [ ] unless h.key?(k.to_s)
98
+ h[k.to_s] = [] unless h.key?(k.to_s)
99
99
  h[k.to_s].push( *Array(v) )
100
100
  end
101
101
  h
@@ -111,7 +111,7 @@ module Sequel
111
111
  end
112
112
  end
113
113
  sti_model_map.each do |k,v|
114
- h[v.to_s] = [ ] unless h.key?(v.to_s)
114
+ h[v.to_s] = [] unless h.key?(v.to_s)
115
115
  h[v.to_s] << k
116
116
  end
117
117
  h
@@ -182,7 +182,12 @@ module Sequel
182
182
  # Return an instance of the class specified by sti_key,
183
183
  # used by the row_proc.
184
184
  def sti_load(r)
185
- sti_class(sti_model_map[r[sti_key]]).call(r)
185
+ sti_class_from_sti_key(r[sti_key]).call(r)
186
+ end
187
+
188
+ # Return the sti class based on one of the keys from sti_model_map.
189
+ def sti_class_from_sti_key(key)
190
+ sti_class(sti_model_map[key])
186
191
  end
187
192
 
188
193
  # Make sure that all subclasses of the parent class correctly include
@@ -57,11 +57,12 @@ module Sequel
57
57
  # Check all entries in the values hash. If any of the keys are not columns,
58
58
  # move the entry into the noncolumn_values hash.
59
59
  def split_noncolumn_values
60
- @values.keys.each do |k|
61
- unless columns.include?(k)
62
- (@noncolumn_values ||= {})[k] = @values.delete(k)
63
- end
64
- end
60
+ cols = (@values.keys - columns)
61
+ return self if cols.empty?
62
+
63
+ nc = @noncolumn_values ||= {}
64
+ vals = @values
65
+ cols.each{|k| nc[k] = vals.delete(k)}
65
66
  self
66
67
  end
67
68
  end
@@ -26,6 +26,7 @@ module Sequel
26
26
  # * Model.each
27
27
  # * Model.count (without an argument or block)
28
28
  # * Model.map
29
+ # * Model.as_hash
29
30
  # * Model.to_hash
30
31
  # * Model.to_hash_groups
31
32
  #
@@ -127,41 +128,46 @@ module Sequel
127
128
  Plugins.inherited_instance_variables(self, :@static_cache_frozen=>nil)
128
129
 
129
130
  # Use the cache instead of a query to get the results.
130
- def to_hash(key_column = nil, value_column = nil)
131
- if key_column.nil? && value_column.nil?
132
- if @static_cache_frozen
133
- return Hash[cache]
134
- else
135
- key_column = primary_key
131
+ def as_hash(key_column = nil, value_column = nil, opts = OPTS)
132
+ if key_column.nil? && value_column.nil?
133
+ if @static_cache_frozen && !opts[:hash]
134
+ return Hash[cache]
135
+ else
136
+ key_column = primary_key
137
+ end
136
138
  end
137
- end
138
139
 
139
- h = {}
140
- if value_column
141
- if value_column.is_a?(Array)
142
- if key_column.is_a?(Array)
143
- @all.each{|r| h[r.values.values_at(*key_column)] = r.values.values_at(*value_column)}
140
+ h = opts[:hash] || {}
141
+ if value_column
142
+ if value_column.is_a?(Array)
143
+ if key_column.is_a?(Array)
144
+ @all.each{|r| h[r.values.values_at(*key_column)] = r.values.values_at(*value_column)}
145
+ else
146
+ @all.each{|r| h[r[key_column]] = r.values.values_at(*value_column)}
147
+ end
144
148
  else
145
- @all.each{|r| h[r[key_column]] = r.values.values_at(*value_column)}
149
+ if key_column.is_a?(Array)
150
+ @all.each{|r| h[r.values.values_at(*key_column)] = r[value_column]}
151
+ else
152
+ @all.each{|r| h[r[key_column]] = r[value_column]}
153
+ end
146
154
  end
155
+ elsif key_column.is_a?(Array)
156
+ @all.each{|r| h[r.values.values_at(*key_column)] = static_cache_object(r)}
147
157
  else
148
- if key_column.is_a?(Array)
149
- @all.each{|r| h[r.values.values_at(*key_column)] = r[value_column]}
150
- else
151
- @all.each{|r| h[r[key_column]] = r[value_column]}
152
- end
158
+ @all.each{|r| h[r[key_column]] = static_cache_object(r)}
153
159
  end
154
- elsif key_column.is_a?(Array)
155
- @all.each{|r| h[r.values.values_at(*key_column)] = static_cache_object(r)}
156
- else
157
- @all.each{|r| h[r[key_column]] = static_cache_object(r)}
160
+ h
158
161
  end
159
- h
162
+
163
+ # Alias of as_hash for backwards compatibility.
164
+ def to_hash(*a)
165
+ as_hash(*a)
160
166
  end
161
167
 
162
168
  # Use the cache instead of a query to get the results
163
- def to_hash_groups(key_column, value_column = nil)
164
- h = {}
169
+ def to_hash_groups(key_column, value_column = nil, opts = OPTS)
170
+ h = opts[:hash] || {}
165
171
  if value_column
166
172
  if value_column.is_a?(Array)
167
173
  if key_column.is_a?(Array)
@@ -13,7 +13,9 @@ module Sequel
13
13
  # Album.plugin :subset_conditions
14
14
  #
15
15
  # # This will now create a published_conditions method
16
- # Album.subset :published, :published => true
16
+ # Album.dataset_module do
17
+ # subset :published, :published => true
18
+ # end
17
19
  #
18
20
  # Album.where(Album.published_conditions).sql
19
21
  # # SELECT * FROM albums WHERE (published IS TRUE)
@@ -32,7 +32,7 @@ module Sequel
32
32
  # has no explicit selection, select table.* from that table.
33
33
  def convert_input_dataset(ds)
34
34
  ds = super
35
- if !ds.opts[:select] && (from = ds.opts[:from]) && from.length == 1 && !ds.opts[:join]
35
+ if !ds.opts[:select] && (from = ds.opts[:from]) && from.length == 1 && !ds.opts[:join] # SEQUEL5: Only !ds.opts[:select]
36
36
  ds = ds.select_all(ds.first_source)
37
37
  end
38
38
  ds
@@ -31,6 +31,7 @@ module Sequel
31
31
  module Touch
32
32
  # The default column to update when touching
33
33
  TOUCH_COLUMN_DEFAULT = :updated_at
34
+ Sequel::Deprecation.deprecate_constant(self, :TOUCH_COLUMN_DEFAULT)
34
35
 
35
36
  def self.apply(model, opts=OPTS)
36
37
  model.instance_variable_set(:@touched_associations, {})
@@ -46,7 +47,7 @@ module Sequel
46
47
  # If a hash is used, the value is used as the column to update.
47
48
  # :column :: The column to modify when touching a model instance.
48
49
  def self.configure(model, opts=OPTS)
49
- model.touch_column = opts[:column] || TOUCH_COLUMN_DEFAULT if opts[:column] || !model.touch_column
50
+ model.touch_column = opts[:column] || :updated_at if opts[:column] || !model.touch_column
50
51
  model.touch_associations(opts[:associations]) if opts[:associations]
51
52
  end
52
53
 
@@ -136,10 +137,11 @@ module Sequel
136
137
  # Can't update all values at once, so update each instance individually.
137
138
  # Instead if doing a simple save, update via the instance's dataset,
138
139
  # to avoid going into an infinite loop in some cases.
139
- send(r[:name]).each{|x| x.this.update(column=>touch_association_value)}
140
+ send(assoc).each{|x| x.this.update(column=>touch_association_value)}
140
141
  else
141
142
  # Update all values at once for performance reasons.
142
143
  ds.update(column=>touch_association_value)
144
+ associations.delete(assoc)
143
145
  end
144
146
  end
145
147
  end
@@ -1,8 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Sequel
4
- extension :blank
5
-
6
4
  module Plugins
7
5
  # Sequel's built-in validation_class_methods plugin adds backwards compatibility
8
6
  # for the legacy class-level validation methods (e.g. validates_presence_of :column).
@@ -11,7 +9,7 @@ module Sequel
11
9
  # as it is less complex and more flexible. However, this plugin provides reflection
12
10
  # support, since it is class-level, while the instance-level validation_helpers
13
11
  # plugin does not.
14
- #
12
+ #
15
13
  # Usage:
16
14
  #
17
15
  # # Add the validation class methods to all model subclasses (called before loading subclasses)
@@ -118,7 +116,7 @@ module Sequel
118
116
  validations.each do |att, procs|
119
117
  v = case att
120
118
  when Array
121
- att.collect{|a| o.get_column_value(a)}
119
+ att.map{|a| o.get_column_value(a)}
122
120
  else
123
121
  o.get_column_value(att)
124
122
  end
@@ -194,11 +192,12 @@ module Sequel
194
192
  # :tag :: The tag to use for this validation.
195
193
  def validates_each(*atts, &block)
196
194
  opts = extract_options!(atts)
195
+ blank_meth = db.method(:blank_object?).to_proc
197
196
  blk = if (i = opts[:if]) || (am = opts[:allow_missing]) || (an = opts[:allow_nil]) || (ab = opts[:allow_blank])
198
197
  proc do |o,a,v|
199
198
  next if i && !validation_if_proc(o, i)
200
199
  next if an && Array(v).all?(&:nil?)
201
- next if ab && Array(v).all?(&:blank?)
200
+ next if ab && Array(v).all?(&blank_meth)
202
201
  next if am && Array(a).all?{|x| !o.values.has_key?(x)}
203
202
  block.call(o,a,v)
204
203
  end
@@ -317,7 +316,7 @@ module Sequel
317
316
  reflect_validation(:presence, opts, atts)
318
317
  atts << opts
319
318
  validates_each(*atts) do |o, a, v|
320
- o.errors.add(a, opts[:message]) if v.blank? && v != false
319
+ o.errors.add(a, opts[:message]) if db.send(:blank_object?, v) && v != false
321
320
  end
322
321
  end
323
322
 
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Sequel
4
4
  module Plugins
5
- # The validation_helpers plugin contains instance method equivalents for most of the legacy
6
- # class-level validations. The names and APIs are different, though. Example:
5
+ # The validation_helpers plugin contains validate_* methods designed to be called inside Model#validate
6
+ # to perform validations:
7
7
  #
8
8
  # Sequel::Model.plugin :validation_helpers
9
9
  # class Album < Sequel::Model
@@ -19,9 +19,7 @@ module Sequel
19
19
  # atts :: Single attribute symbol or an array of attribute symbols specifying the
20
20
  # attribute(s) to validate.
21
21
  # Options:
22
- # :allow_blank :: Whether to skip the validation if the value is blank. You should
23
- # make sure all objects respond to blank if you use this option, which you can do by:
24
- # Sequel.extension :blank
22
+ # :allow_blank :: Whether to skip the validation if the value is blank.
25
23
  # :allow_missing :: Whether to skip the validation if the attribute isn't a key in the
26
24
  # values hash. This is different from allow_nil, because Sequel only sends the attributes
27
25
  # in the values when doing an insert or update. If the attribute is not present, Sequel
@@ -92,6 +90,8 @@ module Sequel
92
90
  :presence=>{:message=>lambda{"is not present"}},
93
91
  :unique=>{:message=>lambda{'is already taken'}}
94
92
  }
93
+ DEFAULT__OPTIONS = DEFAULT_OPTIONS
94
+ Sequel::Deprecation.deprecate_constant(self, :DEFAULT_OPTIONS)
95
95
 
96
96
  module InstanceMethods
97
97
  # Check that the attribute values are the given exact length.
@@ -131,7 +131,13 @@ module Sequel
131
131
  # Accepts a :nil_message option that is the error message to use when the
132
132
  # value is nil instead of being too long.
133
133
  def validates_max_length(max, atts, opts=OPTS)
134
- validatable_attributes_for_type(:max_length, atts, opts){|a,v,m| v ? validation_error_message(m, max) : validation_error_message(opts[:nil_message] || DEFAULT_OPTIONS[:max_length][:nil_message]) if v.nil? || v.length > max}
134
+ validatable_attributes_for_type(:max_length, atts, opts) do |a,v,m|
135
+ if v.nil?
136
+ validation_error_message(opts[:nil_message] || default_validation_helpers_options(:max_length)[:nil_message])
137
+ elsif v.length > max
138
+ validation_error_message(m, max)
139
+ end
140
+ end
135
141
  end
136
142
 
137
143
  # Check that the attribute values are not shorter than the given min length.
@@ -270,7 +276,7 @@ module Sequel
270
276
  # The hash return must include a :message option that is either a
271
277
  # proc or string.
272
278
  def default_validation_helpers_options(type)
273
- DEFAULT_OPTIONS[type]
279
+ DEFAULT__OPTIONS[type]
274
280
  end
275
281
 
276
282
  # Skip validating any attribute that matches one of the allow_* options.
@@ -284,7 +290,7 @@ module Sequel
284
290
  next if am && !values.has_key?(a)
285
291
  v = from_values ? values[a] : get_column_value(a)
286
292
  next if an && v.nil?
287
- next if ab && v.respond_to?(:blank?) && v.blank?
293
+ next if ab && model.db.send(:blank_object?, v)
288
294
  if message = yield(a, v, m)
289
295
  errors.add(a, message)
290
296
  end
@@ -158,7 +158,7 @@ module Sequel
158
158
  opts[:builder]
159
159
  else
160
160
  builder_opts = if opts[:builder_opts]
161
- opts[:builder_opts]
161
+ Hash[opts[:builder_opts]]
162
162
  else
163
163
  {}
164
164
  end
@@ -234,10 +234,10 @@ module Sequel
234
234
  if assocs = opts[:associations]
235
235
  assocs = case assocs
236
236
  when Symbol
237
- {assocs=>{}}
237
+ {assocs=>OPTS}
238
238
  when Array
239
239
  assocs_tmp = {}
240
- assocs.each{|v| assocs_tmp[v] = {}}
240
+ assocs.each{|v| assocs_tmp[v] = OPTS}
241
241
  assocs_tmp
242
242
  when Hash
243
243
  assocs
@@ -347,7 +347,7 @@ module Sequel
347
347
  cols.each do |c|
348
348
  attrs = {}
349
349
  if types
350
- attrs[:type] = db_schema.fetch(c, {})[:type]
350
+ attrs[:type] = db_schema.fetch(c, OPTS)[:type]
351
351
  end
352
352
  v = vals[c]
353
353
  if v.nil?
data/lib/sequel/sql.rb CHANGED
@@ -1030,10 +1030,13 @@ module Sequel
1030
1030
  # The expression to alias
1031
1031
  attr_reader :expression
1032
1032
 
1033
- # The alias to use for the expression, not +alias+ since that is
1034
- # a keyword in ruby.
1035
- attr_reader :aliaz
1036
- alias_method :alias, :aliaz
1033
+ # The alias to use for the expression
1034
+ attr_reader :alias
1035
+
1036
+ def aliaz
1037
+ Sequel::Deprecation.deprecate("Sequel::SQL::AliasedExpression#aliaz", "Use #alias instead")
1038
+ self.alias
1039
+ end
1037
1040
 
1038
1041
  # The columns aliases to use, for when the aliased expression is
1039
1042
  # a record or set of records (such as a dataset).
@@ -1042,7 +1045,7 @@ module Sequel
1042
1045
  # Create an object with the given expression and alias.
1043
1046
  def initialize(expression, aliaz, columns=nil)
1044
1047
  @expression = expression
1045
- @aliaz = aliaz
1048
+ @alias = aliaz
1046
1049
  @columns = columns
1047
1050
  freeze
1048
1051
  end
@@ -1150,7 +1153,7 @@ module Sequel
1150
1153
  when BooleanExpression
1151
1154
  case op = ce.op
1152
1155
  when :AND, :OR
1153
- BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.collect{|a| BooleanExpression.invert(a)})
1156
+ BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.map{|a| BooleanExpression.invert(a)})
1154
1157
  else
1155
1158
  BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.dup)
1156
1159
  end
@@ -1359,7 +1362,11 @@ module Sequel
1359
1362
 
1360
1363
  # The SQL function to call
1361
1364
  attr_reader :name
1362
- alias f name
1365
+
1366
+ def f
1367
+ Sequel::Deprecation.deprecate("Sequel::SQL::Function#f", "Use #name instead")
1368
+ name
1369
+ end
1363
1370
 
1364
1371
  # The array of arguments to pass to the function (may be blank)
1365
1372
  attr_reader :args
@@ -1764,7 +1771,7 @@ module Sequel
1764
1771
  def self.like(l, *ces)
1765
1772
  l, lre, lci = like_element(l)
1766
1773
  lci = (ces.last.is_a?(Hash) ? ces.pop : {})[:case_insensitive] ? true : lci
1767
- ces.collect! do |ce|
1774
+ ces.map! do |ce|
1768
1775
  r, rre, rci = like_element(ce)
1769
1776
  BooleanExpression.new(LIKE_MAP[[lre||rre, lci||rci]], l, r)
1770
1777
  end
@@ -1917,7 +1924,9 @@ module Sequel
1917
1924
  # For a more detailed explanation, see the {Virtual Rows guide}[rdoc-ref:doc/virtual_rows.rdoc].
1918
1925
  class VirtualRow < BasicObject
1919
1926
  QUESTION_MARK = LiteralString.new('?').freeze
1927
+ Sequel::Deprecation.deprecate_constant(self, :QUESTION_MARK)
1920
1928
  DOUBLE_UNDERSCORE = '__'.freeze
1929
+ Sequel::Deprecation.deprecate_constant(self, :DOUBLE_UNDERSCORE)
1921
1930
 
1922
1931
  include OperatorBuilders
1923
1932
 
@@ -1972,7 +1981,7 @@ module Sequel
1972
1981
  end
1973
1982
  elsif args.empty?
1974
1983
  if split = Sequel.split_symbols?
1975
- table, column = m.to_s.split(DOUBLE_UNDERSCORE, 2)
1984
+ table, column = m.to_s.split('__', 2)
1976
1985
  if column && split == :deprecated
1977
1986
  Sequel::Deprecation.deprecate("Splitting virtual row method names", "Either set Sequel.split_symbols = true, or change #{m.inspect} to #{table}[:#{column}]")
1978
1987
  end
@@ -5,7 +5,7 @@ module Sequel
5
5
  MAJOR = 4
6
6
  # The minor version of Sequel. Bumped for every non-patch level
7
7
  # release, generally around once a month.
8
- MINOR = 46
8
+ MINOR = 49
9
9
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
10
10
  # releases that fix regressions from previous versions.
11
11
  TINY = 0