sequel 4.47.0 → 4.48.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 (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +134 -0
  3. data/Rakefile +1 -1
  4. data/doc/release_notes/4.48.0.txt +293 -0
  5. data/lib/sequel/adapters/ado/access.rb +2 -1
  6. data/lib/sequel/adapters/do/postgres.rb +5 -2
  7. data/lib/sequel/adapters/ibmdb.rb +24 -7
  8. data/lib/sequel/adapters/jdbc.rb +36 -22
  9. data/lib/sequel/adapters/jdbc/db2.rb +12 -3
  10. data/lib/sequel/adapters/jdbc/derby.rb +4 -5
  11. data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
  12. data/lib/sequel/adapters/jdbc/postgresql.rb +43 -18
  13. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
  14. data/lib/sequel/adapters/jdbc/sqlserver.rb +11 -4
  15. data/lib/sequel/adapters/mock.rb +24 -19
  16. data/lib/sequel/adapters/mysql.rb +17 -16
  17. data/lib/sequel/adapters/mysql2.rb +4 -5
  18. data/lib/sequel/adapters/oracle.rb +5 -9
  19. data/lib/sequel/adapters/postgres.rb +89 -102
  20. data/lib/sequel/adapters/shared/db2.rb +22 -6
  21. data/lib/sequel/adapters/shared/mssql.rb +5 -4
  22. data/lib/sequel/adapters/shared/mysql.rb +75 -24
  23. data/lib/sequel/adapters/shared/postgres.rb +196 -94
  24. data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
  25. data/lib/sequel/adapters/shared/sqlite.rb +72 -82
  26. data/lib/sequel/adapters/sqlanywhere.rb +4 -1
  27. data/lib/sequel/adapters/sqlite.rb +5 -3
  28. data/lib/sequel/adapters/swift/postgres.rb +5 -2
  29. data/lib/sequel/adapters/tinytds.rb +0 -5
  30. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
  31. data/lib/sequel/adapters/utils/pg_types.rb +2 -76
  32. data/lib/sequel/core.rb +2 -2
  33. data/lib/sequel/database/connecting.rb +5 -5
  34. data/lib/sequel/database/dataset.rb +6 -3
  35. data/lib/sequel/database/misc.rb +1 -1
  36. data/lib/sequel/database/query.rb +3 -0
  37. data/lib/sequel/database/schema_methods.rb +1 -1
  38. data/lib/sequel/dataset/actions.rb +18 -10
  39. data/lib/sequel/dataset/graph.rb +1 -1
  40. data/lib/sequel/dataset/misc.rb +1 -0
  41. data/lib/sequel/dataset/prepared_statements.rb +3 -3
  42. data/lib/sequel/dataset/query.rb +19 -8
  43. data/lib/sequel/extensions/core_extensions.rb +4 -1
  44. data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
  45. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
  46. data/lib/sequel/extensions/filter_having.rb +2 -0
  47. data/lib/sequel/extensions/freeze_datasets.rb +2 -0
  48. data/lib/sequel/extensions/from_block.rb +1 -1
  49. data/lib/sequel/extensions/graph_each.rb +2 -2
  50. data/lib/sequel/extensions/hash_aliases.rb +2 -0
  51. data/lib/sequel/extensions/identifier_mangling.rb +0 -7
  52. data/lib/sequel/extensions/meta_def.rb +2 -0
  53. data/lib/sequel/extensions/migration.rb +6 -6
  54. data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
  55. data/lib/sequel/extensions/pagination.rb +1 -1
  56. data/lib/sequel/extensions/pg_array.rb +207 -130
  57. data/lib/sequel/extensions/pg_hstore.rb +38 -20
  58. data/lib/sequel/extensions/pg_inet.rb +18 -6
  59. data/lib/sequel/extensions/pg_interval.rb +19 -12
  60. data/lib/sequel/extensions/pg_json.rb +25 -14
  61. data/lib/sequel/extensions/pg_json_ops.rb +2 -2
  62. data/lib/sequel/extensions/pg_range.rb +133 -100
  63. data/lib/sequel/extensions/pg_range_ops.rb +4 -3
  64. data/lib/sequel/extensions/pg_row.rb +68 -39
  65. data/lib/sequel/extensions/pg_row_ops.rb +11 -5
  66. data/lib/sequel/extensions/query_literals.rb +2 -0
  67. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
  68. data/lib/sequel/extensions/s.rb +1 -1
  69. data/lib/sequel/extensions/schema_dumper.rb +24 -24
  70. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
  71. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
  72. data/lib/sequel/extensions/set_overrides.rb +2 -2
  73. data/lib/sequel/extensions/string_agg.rb +0 -1
  74. data/lib/sequel/extensions/symbol_aref.rb +0 -4
  75. data/lib/sequel/model.rb +25 -57
  76. data/lib/sequel/model/associations.rb +14 -5
  77. data/lib/sequel/model/base.rb +96 -32
  78. data/lib/sequel/plugins/association_pks.rb +73 -46
  79. data/lib/sequel/plugins/association_proxies.rb +1 -1
  80. data/lib/sequel/plugins/auto_validations.rb +6 -2
  81. data/lib/sequel/plugins/boolean_readers.rb +1 -1
  82. data/lib/sequel/plugins/caching.rb +19 -13
  83. data/lib/sequel/plugins/class_table_inheritance.rb +19 -10
  84. data/lib/sequel/plugins/column_conflicts.rb +7 -2
  85. data/lib/sequel/plugins/column_select.rb +1 -1
  86. data/lib/sequel/plugins/csv_serializer.rb +8 -8
  87. data/lib/sequel/plugins/defaults_setter.rb +10 -0
  88. data/lib/sequel/plugins/eager_each.rb +1 -1
  89. data/lib/sequel/plugins/force_encoding.rb +2 -2
  90. data/lib/sequel/plugins/hook_class_methods.rb +9 -12
  91. data/lib/sequel/plugins/identifier_columns.rb +2 -0
  92. data/lib/sequel/plugins/instance_filters.rb +3 -1
  93. data/lib/sequel/plugins/instance_hooks.rb +17 -9
  94. data/lib/sequel/plugins/json_serializer.rb +17 -10
  95. data/lib/sequel/plugins/lazy_attributes.rb +8 -7
  96. data/lib/sequel/plugins/modification_detection.rb +3 -0
  97. data/lib/sequel/plugins/nested_attributes.rb +5 -1
  98. data/lib/sequel/plugins/pg_array_associations.rb +5 -0
  99. data/lib/sequel/plugins/prepared_statements.rb +1 -0
  100. data/lib/sequel/plugins/rcte_tree.rb +4 -4
  101. data/lib/sequel/plugins/serialization.rb +3 -10
  102. data/lib/sequel/plugins/single_table_inheritance.rb +2 -2
  103. data/lib/sequel/plugins/split_values.rb +6 -5
  104. data/lib/sequel/plugins/static_cache.rb +31 -25
  105. data/lib/sequel/plugins/subset_conditions.rb +3 -1
  106. data/lib/sequel/plugins/table_select.rb +1 -1
  107. data/lib/sequel/plugins/touch.rb +2 -1
  108. data/lib/sequel/plugins/validation_class_methods.rb +5 -6
  109. data/lib/sequel/plugins/validation_helpers.rb +2 -4
  110. data/lib/sequel/plugins/xml_serializer.rb +4 -4
  111. data/lib/sequel/sql.rb +2 -2
  112. data/lib/sequel/version.rb +1 -1
  113. data/spec/adapters/db2_spec.rb +115 -14
  114. data/spec/adapters/mysql_spec.rb +78 -28
  115. data/spec/adapters/oracle_spec.rb +24 -24
  116. data/spec/adapters/postgres_spec.rb +38 -24
  117. data/spec/adapters/sqlanywhere_spec.rb +88 -86
  118. data/spec/adapters/sqlite_spec.rb +29 -24
  119. data/spec/core/connection_pool_spec.rb +17 -0
  120. data/spec/core/database_spec.rb +6 -0
  121. data/spec/core/dataset_spec.rb +46 -36
  122. data/spec/core/schema_spec.rb +16 -0
  123. data/spec/core/spec_helper.rb +1 -0
  124. data/spec/core_extensions_spec.rb +6 -2
  125. data/spec/extensions/active_model_spec.rb +1 -1
  126. data/spec/extensions/arbitrary_servers_spec.rb +1 -1
  127. data/spec/extensions/association_pks_spec.rb +34 -2
  128. data/spec/extensions/auto_literal_strings_spec.rb +5 -1
  129. data/spec/extensions/auto_validations_spec.rb +2 -0
  130. data/spec/extensions/boolean_readers_spec.rb +1 -1
  131. data/spec/extensions/boolean_subsets_spec.rb +1 -1
  132. data/spec/extensions/class_table_inheritance_spec.rb +48 -2
  133. data/spec/extensions/column_conflicts_spec.rb +11 -0
  134. data/spec/extensions/connection_validator_spec.rb +1 -1
  135. data/spec/extensions/dataset_associations_spec.rb +8 -8
  136. data/spec/extensions/defaults_setter_spec.rb +1 -1
  137. data/spec/extensions/filter_having_spec.rb +5 -3
  138. data/spec/extensions/hash_aliases_spec.rb +3 -1
  139. data/spec/extensions/identifier_columns_spec.rb +3 -1
  140. data/spec/extensions/implicit_subquery_spec.rb +4 -2
  141. data/spec/extensions/json_serializer_spec.rb +18 -0
  142. data/spec/extensions/lazy_attributes_spec.rb +3 -3
  143. data/spec/extensions/meta_def_spec.rb +9 -0
  144. data/spec/extensions/migration_spec.rb +3 -3
  145. data/spec/extensions/nested_attributes_spec.rb +14 -3
  146. data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
  147. data/spec/extensions/pg_array_associations_spec.rb +29 -18
  148. data/spec/extensions/pg_array_spec.rb +44 -25
  149. data/spec/extensions/pg_hstore_spec.rb +10 -0
  150. data/spec/extensions/pg_inet_spec.rb +26 -0
  151. data/spec/extensions/pg_interval_spec.rb +20 -0
  152. data/spec/extensions/pg_json_spec.rb +24 -0
  153. data/spec/extensions/pg_range_spec.rb +98 -14
  154. data/spec/extensions/pg_row_spec.rb +14 -4
  155. data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
  156. data/spec/extensions/query_literals_spec.rb +3 -1
  157. data/spec/extensions/schema_dumper_spec.rb +96 -98
  158. data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
  159. data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
  160. data/spec/extensions/single_table_inheritance_spec.rb +1 -1
  161. data/spec/extensions/spec_helper.rb +7 -1
  162. data/spec/extensions/static_cache_spec.rb +75 -24
  163. data/spec/extensions/string_agg_spec.rb +1 -1
  164. data/spec/extensions/touch_spec.rb +9 -0
  165. data/spec/extensions/validation_helpers_spec.rb +9 -3
  166. data/spec/extensions/whitelist_security_spec.rb +26 -0
  167. data/spec/integration/dataset_test.rb +45 -44
  168. data/spec/integration/plugin_test.rb +20 -0
  169. data/spec/integration/prepared_statement_test.rb +3 -0
  170. data/spec/integration/schema_test.rb +21 -1
  171. data/spec/integration/transaction_test.rb +40 -40
  172. data/spec/model/class_dataset_methods_spec.rb +14 -4
  173. data/spec/model/dataset_methods_spec.rb +12 -3
  174. data/spec/model/model_spec.rb +8 -0
  175. metadata +6 -4
  176. data/spec/adapters/firebird_spec.rb +0 -405
  177. data/spec/adapters/informix_spec.rb +0 -100
@@ -41,6 +41,17 @@ module Sequel
41
41
  # If set to :remove, the setter will treat the nil as an empty array, removing
42
42
  # the association all currently associated values.
43
43
  #
44
+ # For many_to_many associations, association_pks assumes the related pks can be
45
+ # accessed directly from the join table. This works in most cases, but in cases
46
+ # where the :right_primary_key association option is used to specify a different
47
+ # primary key in the associated table, association_pks will return the value of
48
+ # the association primary keys (foreign key values to associated table in the join
49
+ # table), not the associated model primary keys. If you would like to use the
50
+ # associated model primary keys, you need to use the
51
+ # :association_pks_use_associated_table association option. If the
52
+ # :association_pks_use_associated_table association option is used, no setter
53
+ # method will be added.
54
+ #
44
55
  # Usage:
45
56
  #
46
57
  # # Make all model subclass *_to_many associations have association_pks
@@ -57,7 +68,7 @@ module Sequel
57
68
  # Define a association_pks method using the block for the association reflection
58
69
  def def_association_pks_methods(opts)
59
70
  association_module_def(:"#{singularize(opts[:name])}_pks", opts){_association_pks_getter(opts)}
60
- association_module_def(:"#{singularize(opts[:name])}_pks=", opts){|pks| _association_pks_setter(opts, pks)} unless opts[:read_only]
71
+ association_module_def(:"#{singularize(opts[:name])}_pks=", opts){|pks| _association_pks_setter(opts, pks)} if opts[:pks_setter]
61
72
  end
62
73
 
63
74
  # Add a getter that checks the join table for matching records and
@@ -73,11 +84,23 @@ module Sequel
73
84
  clpk = lpk.is_a?(Array)
74
85
  crk = rk.is_a?(Array)
75
86
 
76
- opts[:pks_getter] = if clpk
87
+ opts[:pks_getter] = if join_associated_table = opts[:association_pks_use_associated_table]
88
+ tname = opts[:join_table]
89
+ lambda do
90
+ cond = if clpk
91
+ lk.zip(lpk).map{|k, pk| [Sequel.qualify(tname, k), get_column_value(pk)]}
92
+ else
93
+ {Sequel.qualify(tname, lk) => get_column_value(lpk)}
94
+ end
95
+ rpk = opts.associated_class.primary_key
96
+ opts.associated_dataset.
97
+ naked.where(cond).
98
+ select_map(Sequel.send(rpk.is_a?(Array) ? :deep_qualify : :qualify, opts.associated_class.table_name, rpk))
99
+ end
100
+ elsif clpk
77
101
  lambda do
78
- h = {}
79
- lk.zip(lpk).each{|k, pk| h[k] = get_column_value(pk)}
80
- _join_table_dataset(opts).where(h).select_map(rk)
102
+ cond = lk.zip(lpk).map{|k, pk| [k, get_column_value(pk)]}
103
+ _join_table_dataset(opts).where(cond).select_map(rk)
81
104
  end
82
105
  else
83
106
  lambda do
@@ -85,25 +108,27 @@ module Sequel
85
108
  end
86
109
  end
87
110
 
88
- opts[:pks_setter] = lambda do |pks|
89
- if pks.empty?
90
- send(opts.remove_all_method)
91
- else
92
- checked_transaction do
93
- if clpk
94
- lpkv = lpk.map{|k| get_column_value(k)}
95
- cond = lk.zip(lpkv)
96
- else
97
- lpkv = get_column_value(lpk)
98
- cond = {lk=>lpkv}
111
+ if !opts[:read_only] && !join_associated_table
112
+ opts[:pks_setter] = lambda do |pks|
113
+ if pks.empty?
114
+ send(opts.remove_all_method)
115
+ else
116
+ checked_transaction do
117
+ if clpk
118
+ lpkv = lpk.map{|k| get_column_value(k)}
119
+ cond = lk.zip(lpkv)
120
+ else
121
+ lpkv = get_column_value(lpk)
122
+ cond = {lk=>lpkv}
123
+ end
124
+ ds = _join_table_dataset(opts).where(cond)
125
+ ds.exclude(rk=>pks).delete
126
+ pks -= ds.select_map(rk)
127
+ lpkv = Array(lpkv)
128
+ key_array = crk ? pks.map{|pk| lpkv + pk} : pks.map{|pk| lpkv + [pk]}
129
+ key_columns = Array(lk) + Array(rk)
130
+ ds.import(key_columns, key_array)
99
131
  end
100
- ds = _join_table_dataset(opts).where(cond)
101
- ds.exclude(rk=>pks).delete
102
- pks -= ds.select_map(rk)
103
- lpkv = Array(lpkv)
104
- key_array = crk ? pks.map{|pk| lpkv + pk} : pks.map{|pk| lpkv + [pk]}
105
- key_columns = Array(lk) + Array(rk)
106
- ds.import(key_columns, key_array)
107
132
  end
108
133
  end
109
134
  end
@@ -124,29 +149,31 @@ module Sequel
124
149
  send(opts.dataset_method).select_map(opts.associated_class.primary_key)
125
150
  end
126
151
 
127
- opts[:pks_setter] = lambda do |pks|
128
- if pks.empty?
129
- send(opts.remove_all_method)
130
- else
131
- primary_key = opts.associated_class.primary_key
132
- pkh = {primary_key=>pks}
133
-
134
- if key.is_a?(Array)
135
- h = {}
136
- nh = {}
137
- key.zip(pk).each do|k, v|
138
- h[k] = v
139
- nh[k] = nil
140
- end
152
+ unless opts[:read_only]
153
+ opts[:pks_setter] = lambda do |pks|
154
+ if pks.empty?
155
+ send(opts.remove_all_method)
141
156
  else
142
- h = {key=>pk}
143
- nh = {key=>nil}
144
- end
157
+ primary_key = opts.associated_class.primary_key
158
+ pkh = {primary_key=>pks}
145
159
 
146
- checked_transaction do
147
- ds = send(opts.dataset_method)
148
- ds.unfiltered.where(pkh).update(h)
149
- ds.exclude(pkh).update(nh)
160
+ if key.is_a?(Array)
161
+ h = {}
162
+ nh = {}
163
+ key.zip(pk).each do|k, v|
164
+ h[k] = v
165
+ nh[k] = nil
166
+ end
167
+ else
168
+ h = {key=>pk}
169
+ nh = {key=>nil}
170
+ end
171
+
172
+ checked_transaction do
173
+ ds = send(opts.dataset_method)
174
+ ds.unfiltered.where(pkh).update(h)
175
+ ds.exclude(pkh).update(nh)
176
+ end
150
177
  end
151
178
  end
152
179
  end
@@ -208,7 +235,7 @@ module Sequel
208
235
  pks = convert_pk_array(opts, pks)
209
236
 
210
237
  delay = opts.fetch(:delay_pks) do
211
- Sequel::Deprecation.deprecate("association_pks will default to assuming the :delay_pks=>:always association option starting in Sequel 5. Explicitly set :delay_pks=>false option for the association if you want changes to take effect immediately instead of being delayed until the object is saved (association: #{opts.inspect}).")
238
+ Sequel::Deprecation.deprecate("association_pks will default to assuming the :delay_pks=>:always association option starting in Sequel 5. Explicitly set :delay_pks=>false option for the association if you want changes to take effect immediately instead of being delayed until the object is saved (association: #{opts.inspect})")
212
239
  false
213
240
  end
214
241
  if (new? && delay) || (delay == :always)
@@ -216,7 +243,7 @@ module Sequel
216
243
  (@_association_pks ||= {})[opts[:name]] = pks
217
244
  else
218
245
  if !new? && delay && delay != :always
219
- Sequel::Deprecation.deprecate("association_pks with the :delay_pks=>true association option will also delay setting of associated values for existing objects in Sequel 5 (currently it just delays setting of associated values for new objects). Please change to using :delay_pks=>:always to avoid this message. Sequel 5 will not support the existing :delay_pks=>true behavior for only delaying for new objects and not for existing objects.")
246
+ Sequel::Deprecation.deprecate("association_pks with the :delay_pks=>true association option will also delay setting of associated values for existing objects in Sequel 5 (currently it just delays setting of associated values for new objects). Please change to using :delay_pks=>:always to avoid this message. Sequel 5 will not support the existing :delay_pks=>true behavior for only delaying for new objects and not for existing objects")
220
247
  end
221
248
  instance_exec(pks, &opts[:pks_setter])
222
249
  end
@@ -101,7 +101,7 @@ module Sequel
101
101
  def def_association_method(opts)
102
102
  if opts.returns_array?
103
103
  association_module_def(opts.association_method, opts) do |*dynamic_opts, &block|
104
- Sequel::Deprecation.deprecate("Passing multiple arguments to ##{opts.association_method}", "Additional arguments are currently ignored.") if dynamic_opts.length > 1
104
+ Sequel::Deprecation.deprecate("Passing multiple arguments to ##{opts.association_method}", "Additional arguments are currently ignored") if dynamic_opts.length > 1
105
105
  AssociationProxy.new(self, opts, dynamic_opts.length == 0 ? OPTS : dynamic_opts[0], &block)
106
106
  end
107
107
  else
@@ -140,9 +140,13 @@ module Sequel
140
140
  # Skip automatic validations for the given validation type (:not_null, :types, :unique).
141
141
  # If :all is given as the type, skip all auto validations.
142
142
  def skip_auto_validations(type)
143
- if type == :all
143
+ case type
144
+ when :all
144
145
  [:not_null, :types, :unique, :max_length].each{|v| skip_auto_validations(v)}
145
- elsif type == :types
146
+ when :not_null
147
+ auto_validate_not_null_columns.clear
148
+ auto_validate_explicit_not_null_columns.clear
149
+ when :types
146
150
  @auto_validate_types = false
147
151
  else
148
152
  send("auto_validate_#{type}_columns").clear
@@ -48,7 +48,7 @@ module Sequel
48
48
 
49
49
  # Add attribute? methods for all of the boolean attributes for this model.
50
50
  def create_boolean_readers
51
- im = instance_methods.collect(&:to_s)
51
+ im = instance_methods.map(&:to_s)
52
52
  if cs = check_non_connection_error(false){columns}
53
53
  cs.each{|c| create_boolean_reader(c) if boolean_attribute?(c) && !im.include?("#{c}?")}
54
54
  end
@@ -19,8 +19,13 @@ module Sequel
19
19
  # raise an exception for a missing record, so if you use memcached, you will
20
20
  # want to use this option.
21
21
  #
22
- # Note that only Model.[] method calls with a primary key argument are cached
23
- # using this plugin.
22
+ # Note that only lookups by primary key are cached using this plugin. The following
23
+ # methods use a lookup by primary key:
24
+ #
25
+ # * Model.with_pk
26
+ # * Model.with_pk!
27
+ # * Model.[] # when argument is not hash or nil
28
+ # * many_to_one association method # without dynamic callback, when primary key matches
24
29
  #
25
30
  # Usage:
26
31
  #
@@ -68,7 +73,7 @@ module Sequel
68
73
 
69
74
  # Returns the prefix used to namespace this class in the cache.
70
75
  def cache_key_prefix
71
- "#{self}"
76
+ to_s
72
77
  end
73
78
 
74
79
  # Return a key string for the given primary key.
@@ -86,26 +91,27 @@ module Sequel
86
91
 
87
92
  private
88
93
 
89
- # Delete the entry with the matching key from the cache
90
- def cache_delete(ck)
94
+ # Access the cache using the given method and key, rescuing exceptions if necessary.
95
+ def cache_op(meth, ck)
91
96
  if @cache_ignore_exceptions
92
- @cache_store.delete(ck) rescue nil
97
+ @cache_store.send(meth, ck) rescue nil
93
98
  else
94
- @cache_store.delete(ck)
99
+ @cache_store.send(meth, ck)
95
100
  end
101
+ end
102
+
103
+ # Delete the entry with the matching key from the cache
104
+ def cache_delete(ck)
105
+ cache_op(:delete, ck)
96
106
  nil
97
107
  end
98
108
 
99
109
  # Returned the cached object, or nil if the object was not
100
110
  # in the cached
101
111
  def cache_get(ck)
102
- if @cache_ignore_exceptions
103
- @cache_store.get(ck) rescue nil
104
- else
105
- @cache_store.get(ck)
106
- end
112
+ cache_op(:get, ck)
107
113
  end
108
-
114
+
109
115
  # Set the object in the cache_store with the given key for cache_ttl seconds.
110
116
  def cache_set(ck, obj)
111
117
  @cache_store.set(ck, obj, @cache_ttl)
@@ -203,7 +203,7 @@ module Sequel
203
203
  @cti_instance_dataset = @instance_dataset
204
204
  @cti_table_columns = columns
205
205
  @cti_table_map = opts[:table_map] || {}
206
- @cti_alias = opts[:alias]
206
+ @cti_alias = opts[:alias] # || table_name # SEQUEL5
207
207
  end
208
208
  end
209
209
 
@@ -216,6 +216,7 @@ module Sequel
216
216
  # This is the only model in the hierarchy that loads the
217
217
  # class_table_inheritance plugin. For backwards compatibility.
218
218
  def cti_base_model
219
+ Sequel::Deprecation.deprecate("#{self}.cti_base_model", "Use #{self}.cti_models.first instead")
219
220
  @cti_models.first
220
221
  end
221
222
 
@@ -228,12 +229,12 @@ module Sequel
228
229
  attr_reader :cti_instance_dataset
229
230
 
230
231
  # An array of table symbols that back this model. The first is
231
- # cti_base_model table symbol, and the last is the current model
232
+ # table symbol for the base model, and the last is the current model
232
233
  # table symbol.
233
234
  attr_reader :cti_tables
234
235
 
235
236
  # A hash with class name symbol keys and table name symbol values.
236
- # Specified with the :table_map option to the plugin, and used if
237
+ # Specified with the :table_map option to the plugin, and should be used if
237
238
  # the implicit naming is incorrect.
238
239
  attr_reader :cti_table_map
239
240
 
@@ -247,10 +248,16 @@ module Sequel
247
248
  end
248
249
 
249
250
  # Alias to sti_key, for backwards compatibility.
250
- def cti_key; sti_key; end
251
+ def cti_key
252
+ Sequel::Deprecation.deprecate("#{self}.cti_key", "Use #{self}.sti_key instead")
253
+ sti_key
254
+ end
251
255
 
252
256
  # Alias to sti_model_map, for backwards compatibility.
253
- def cti_model_map; sti_model_map; end
257
+ def cti_model_map
258
+ Sequel::Deprecation.deprecate("#{self}.cti_model_map", "Use #{self}.sti_model_map instead")
259
+ sti_model_map
260
+ end
254
261
 
255
262
  # Freeze CTI information when freezing model class.
256
263
  def freeze
@@ -297,19 +304,20 @@ module Sequel
297
304
  cols = columns - [pk]
298
305
  dup_cols = cols & ds.columns
299
306
  unless dup_cols.empty?
307
+ # raise Error, "class_table_inheritance with duplicate column names (other than the primary key column) is not supported, make sure tables have unique column names"
300
308
  Sequel::Deprecation.deprecate("Using class_table_inheritance with duplicate column names (#{n} => #{dup_cols}) in subclass tables (other than the primary key column)', 'Make sure all tables used have unique column names, or implement support for handling duplicate column names in the class_table_inheritance plugin")
301
309
  end
302
310
  sel_app = cols.map{|cc| Sequel.qualify(table, Sequel.identifier(cc))}
303
311
  @sti_dataset = ds = ds.join(table, pk=>pk).select_append(*sel_app)
304
312
 
305
- if @cti_alias
313
+ if @cti_alias # SEQUEL5: remove if
306
314
  ds = ds.from_self(:alias=>@cti_alias)
307
315
  end
308
316
 
309
317
  set_dataset(ds)
310
318
  set_columns(self.columns)
311
319
  @dataset = @dataset.with_row_proc(lambda{|r| subclass.sti_load(r)})
312
- cols.each{|a| define_lazy_attribute_getter(a, :dataset=>dataset, :table=>@cti_alias||table)}
320
+ cols.each{|a| define_lazy_attribute_getter(a, :dataset=>dataset, :table=>@cti_alias||table)} # SEQUEL5: remove ||table
313
321
 
314
322
  @cti_models += [self]
315
323
  @cti_tables += [table]
@@ -325,7 +333,7 @@ module Sequel
325
333
  # The table name for the current model class's main table.
326
334
  def table_name
327
335
  if cti_tables
328
- if @cti_alias
336
+ if @cti_alias # SEQUEL5: remove if
329
337
  @cti_alias
330
338
  else
331
339
  cti_tables.last
@@ -340,6 +348,7 @@ module Sequel
340
348
  cti_tables ? cti_tables.last : dataset.first_source_alias
341
349
  end
342
350
 
351
+ # The model class for the given key value.
343
352
  def sti_class_from_key(key)
344
353
  sti_class(sti_model_map[key])
345
354
  end
@@ -350,7 +359,7 @@ module Sequel
350
359
  # when setting subclass dataset.
351
360
  def sti_subclass_dataset(key)
352
361
  ds = super
353
- if @cti_alias
362
+ if @cti_alias && cti_models[0] != self # SEQUEL5: remove @cti_alias
354
363
  ds = ds.from_self(:alias=>@cti_alias)
355
364
  end
356
365
  ds
@@ -395,7 +404,7 @@ module Sequel
395
404
  # Insert rows into all backing tables, using the columns
396
405
  # in each table.
397
406
  def _insert
398
- return super if model.cti_tables.length == 1
407
+ return super if model.cti_models[0] == model
399
408
  model.cti_models.each do |m|
400
409
  v = {}
401
410
  m.cti_table_columns.each{|c| v[c] = @values[c] if @values.include?(c)}
@@ -29,11 +29,16 @@ module Sequel
29
29
  # # Make the Album class handle column conflicts automatically
30
30
  # Album.plugin :column_conflicts
31
31
  module ColumnConflicts
32
- # Check for column conflicts on the current model if the model has a dataset.
33
- def self.configure(model)
32
+ def self.apply(model)
34
33
  model.instance_eval do
35
34
  @get_column_conflicts = {}
36
35
  @set_column_conflicts = {}
36
+ end
37
+ end
38
+
39
+ # Check for column conflicts on the current model if the model has a dataset.
40
+ def self.configure(model)
41
+ model.instance_eval do
37
42
  check_column_conflicts if @dataset
38
43
  end
39
44
  end
@@ -41,7 +41,7 @@ module Sequel
41
41
  # qualifying them with table's name.
42
42
  def convert_input_dataset(ds)
43
43
  ds = super
44
- if !ds.opts[:select] && (from = ds.opts[:from]) && from.length == 1 && !ds.opts[:join]
44
+ if !ds.opts[:select] && (from = ds.opts[:from]) && from.length == 1 && !ds.opts[:join] # SEQUE5: just !ds.opts[:select]
45
45
  if db.supports_schema_parsing?
46
46
  cols = check_non_connection_error(false){db.schema(ds)}
47
47
  if cols
@@ -76,9 +76,9 @@ module Sequel
76
76
 
77
77
  # Set up the column readers to do deserialization and the column writers
78
78
  # to save the value in deserialized_values
79
- def self.configure(model, opts = {})
79
+ def self.configure(model, opts = OPTS)
80
80
  model.instance_eval do
81
- @csv_serializer_opts = (@csv_serializer_opts || {}).merge(opts)
81
+ @csv_serializer_opts = (@csv_serializer_opts || OPTS).merge(opts)
82
82
  end
83
83
  end
84
84
 
@@ -87,7 +87,7 @@ module Sequel
87
87
  attr_reader :csv_serializer_opts
88
88
 
89
89
  # Attempt to parse an array of instances from the given CSV string
90
- def array_from_csv(csv, opts = {})
90
+ def array_from_csv(csv, opts = OPTS)
91
91
  CSV.parse(csv, process_csv_serializer_opts(opts)).map do |row|
92
92
  row = row.to_hash
93
93
  row.delete(nil)
@@ -105,13 +105,13 @@ module Sequel
105
105
  end
106
106
 
107
107
  # Attempt to parse a single instance from the given CSV string
108
- def from_csv(csv, opts = {})
108
+ def from_csv(csv, opts = OPTS)
109
109
  new.from_csv(csv, opts)
110
110
  end
111
111
 
112
112
  # Convert the options hash to one that can be passed to CSV.
113
113
  def process_csv_serializer_opts(opts)
114
- opts = (csv_serializer_opts || {}).merge(opts)
114
+ opts = (csv_serializer_opts || OPTS).merge(opts)
115
115
  opts_cols = opts.delete(:columns)
116
116
  opts_include = opts.delete(:include)
117
117
  opts_except = opts.delete(:except)
@@ -136,7 +136,7 @@ module Sequel
136
136
  #
137
137
  # :headers :: The headers to use for the CSV line. Use nil for a header
138
138
  # to specify the column should be ignored.
139
- def from_csv(csv, opts = {})
139
+ def from_csv(csv, opts = OPTS)
140
140
  row = CSV.parse_line(csv, model.process_csv_serializer_opts(opts)).to_hash
141
141
  row.delete(nil)
142
142
  set(row)
@@ -151,7 +151,7 @@ module Sequel
151
151
  # output, ignoring all other columns
152
152
  # :include :: Symbol or Array of Symbols specifying non-column
153
153
  # attributes to include in the CSV output.
154
- def to_csv(opts = {})
154
+ def to_csv(opts = OPTS)
155
155
  opts = model.process_csv_serializer_opts(opts)
156
156
 
157
157
  CSV.generate(opts) do |csv|
@@ -168,7 +168,7 @@ module Sequel
168
168
  #
169
169
  # :array :: An array of instances. If this is not provided, calls #all
170
170
  # on the receiver to get the array.
171
- def to_csv(opts = {})
171
+ def to_csv(opts = OPTS)
172
172
  opts = model.process_csv_serializer_opts({:columns=>columns}.merge!(opts))
173
173
  items = opts.delete(:array) || self
174
174