sequel 4.46.0 → 4.49.0

Sign up to get free protection for your applications and to get access to all the features.
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