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
@@ -26,17 +26,29 @@ module Sequel
26
26
  # already have been loaded.
27
27
  module Inflections
28
28
  CAMELIZE_CONVERT_REGEXP = /(^|_)(.)/.freeze
29
+ Sequel::Deprecation.deprecate_constant(self, :CAMELIZE_CONVERT_REGEXP)
29
30
  CAMELIZE_MODULE_REGEXP = /\/(.?)/.freeze
31
+ Sequel::Deprecation.deprecate_constant(self, :CAMELIZE_MODULE_REGEXP)
30
32
  DASH = '-'.freeze
33
+ Sequel::Deprecation.deprecate_constant(self, :DASH)
31
34
  DEMODULIZE_CONVERT_REGEXP = /^.*::/.freeze
35
+ Sequel::Deprecation.deprecate_constant(self, :DEMODULIZE_CONVERT_REGEXP)
32
36
  EMPTY_STRING= ''.freeze
37
+ Sequel::Deprecation.deprecate_constant(self, :EMPTY_STRING)
33
38
  SLASH = '/'.freeze
39
+ Sequel::Deprecation.deprecate_constant(self, :SLASH)
34
40
  VALID_CONSTANT_NAME_REGEXP = /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/.freeze
41
+ Sequel::Deprecation.deprecate_constant(self, :VALID_CONSTANT_NAME_REGEXP)
35
42
  UNDERSCORE = '_'.freeze
43
+ Sequel::Deprecation.deprecate_constant(self, :UNDERSCORE)
36
44
  UNDERSCORE_CONVERT_REGEXP1 = /([A-Z]+)([A-Z][a-z])/.freeze
45
+ Sequel::Deprecation.deprecate_constant(self, :UNDERSCORE_CONVERT_REGEXP1)
37
46
  UNDERSCORE_CONVERT_REGEXP2 = /([a-z\d])([A-Z])/.freeze
47
+ Sequel::Deprecation.deprecate_constant(self, :UNDERSCORE_CONVERT_REGEXP2)
38
48
  UNDERSCORE_CONVERT_REPLACE = '\1_\2'.freeze
49
+ Sequel::Deprecation.deprecate_constant(self, :UNDERSCORE_CONVERT_REPLACE)
39
50
  UNDERSCORE_MODULE_REGEXP = /::/.freeze
51
+ Sequel::Deprecation.deprecate_constant(self, :UNDERSCORE_MODULE_REGEXP)
40
52
 
41
53
  @plurals, @singulars, @uncountables = [], [], []
42
54
 
@@ -113,7 +125,7 @@ module Sequel
113
125
  def camelize(s)
114
126
  s = s.to_s
115
127
  return s.camelize if s.respond_to?(:camelize)
116
- s = s.gsub(CAMELIZE_MODULE_REGEXP){|x| "::#{x[-1..-1].upcase unless x == SLASH}"}.gsub(CAMELIZE_CONVERT_REGEXP){|x| x[-1..-1].upcase}
128
+ s = s.gsub(/\/(.?)/){|x| "::#{x[-1..-1].upcase unless x == '/'}"}.gsub(/(^|_)(.)/){|x| x[-1..-1].upcase}
117
129
  s
118
130
  end
119
131
 
@@ -123,7 +135,7 @@ module Sequel
123
135
  def constantize(s)
124
136
  s = s.to_s
125
137
  return s.constantize if s.respond_to?(:constantize)
126
- raise(NameError, "#{s.inspect} is not a valid constant name!") unless m = VALID_CONSTANT_NAME_REGEXP.match(s)
138
+ raise(NameError, "#{s.inspect} is not a valid constant name!") unless m = /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/.match(s)
127
139
  Object.module_eval("::#{m[1]}", __FILE__, __LINE__)
128
140
  end
129
141
 
@@ -131,7 +143,7 @@ module Sequel
131
143
  def demodulize(s)
132
144
  s = s.to_s
133
145
  return s.demodulize if s.respond_to?(:demodulize)
134
- s.gsub(DEMODULIZE_CONVERT_REGEXP, EMPTY_STRING)
146
+ s.gsub(/^.*::/, '')
135
147
  end
136
148
 
137
149
  # Returns the plural form of the word in the string.
@@ -157,8 +169,8 @@ module Sequel
157
169
  def underscore(s)
158
170
  s = s.to_s
159
171
  return s.underscore if s.respond_to?(:underscore)
160
- s.gsub(UNDERSCORE_MODULE_REGEXP, SLASH).gsub(UNDERSCORE_CONVERT_REGEXP1, UNDERSCORE_CONVERT_REPLACE).
161
- gsub(UNDERSCORE_CONVERT_REGEXP2, UNDERSCORE_CONVERT_REPLACE).tr(DASH, UNDERSCORE).downcase
172
+ s.gsub('::', '/').gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
173
+ gsub(/([a-z\d])([A-Z])/, '\1_\2').tr('-', '_').downcase
162
174
  end
163
175
  end
164
176
  end
data/lib/sequel/model.rb CHANGED
@@ -31,62 +31,36 @@ module Sequel
31
31
  class Model
32
32
  OPTS = Sequel::OPTS
33
33
 
34
- # Class methods added to model that call the method of the same name on the dataset
35
- DATASET_METHODS = (Dataset::ACTION_METHODS + Dataset::QUERY_METHODS + [:each_server, :where_all, :where_each, :where_single_value]) -
36
- [:and, :or, :[], :columns, :columns!, :delete, :update, :add_graph_aliases] # SEQUEL5: Remove set_graph_aliases
37
-
38
- # Boolean settings that can be modified at the global, class, or instance level.
39
- BOOLEAN_SETTINGS = [:typecast_empty_string_to_nil, :typecast_on_assignment, :strict_param_setting, \
40
- :raise_on_save_failure, :raise_on_typecast_failure, :require_modification, :use_transactions,
41
- :use_after_commit_rollback # SEQUEL5: Remove
42
- ]
43
-
44
- # Hooks that are called before an action. Can return false to not do the action. When
45
- # overriding these, it is recommended to call +super+ as the last line of your method,
46
- # so later hooks are called before earlier hooks.
34
+ DATASET_METHODS = (Dataset::ACTION_METHODS + Dataset::QUERY_METHODS + [:each_server, :where_all, :where_each, :where_single_value]) - [:and, :or, :[], :columns, :columns!, :delete, :update, :add_graph_aliases]
35
+ Sequel::Deprecation.deprecate_constant(self, :DATASET_METHODS)
36
+ BOOLEAN_SETTINGS = [:typecast_empty_string_to_nil, :typecast_on_assignment, :strict_param_setting, :raise_on_save_failure, :raise_on_typecast_failure, :require_modification, :use_transactions, :use_after_commit_rollback]
37
+ Sequel::Deprecation.deprecate_constant(self, :BOOLEAN_SETTINGS)
47
38
  BEFORE_HOOKS = [:before_create, :before_update, :before_save, :before_destroy, :before_validation]
48
-
49
- # Hooks that are called after an action. When overriding these, it is recommended to call
50
- # +super+ on the first line of your method, so later hooks are called after earlier hooks.
51
- AFTER_HOOKS = [:after_create, :after_update, :after_save, :after_destroy, :after_validation,
52
- :after_commit, :after_rollback, :after_destroy_commit, :after_destroy_rollback] # SEQUEL5: Remove commit/rollback hooks
53
-
54
- # Hooks that are called around an action. If overridden, these methods must call super
55
- # exactly once if the behavior they wrap is desired. The can be used to rescue exceptions
56
- # raised by the code they wrap or ensure that some behavior is executed no matter what.
39
+ Sequel::Deprecation.deprecate_constant(self, :BEFORE_HOOKS)
40
+ AFTER_HOOKS = [:after_create, :after_update, :after_save, :after_destroy, :after_validation, :after_commit, :after_rollback, :after_destroy_commit, :after_destroy_rollback]
41
+ Sequel::Deprecation.deprecate_constant(self, :AFTER_HOOKS)
57
42
  AROUND_HOOKS = [:around_create, :around_update, :around_save, :around_destroy, :around_validation]
43
+ Sequel::Deprecation.deprecate_constant(self, :AROUND_HOOKS)
44
+ NORMAL_METHOD_NAME_REGEXP = /\A[A-Za-z_][A-Za-z0-9_]*\z/
45
+ Sequel::Deprecation.deprecate_constant(self, :NORMAL_METHOD_NAME_REGEXP)
46
+ SETTER_METHOD_REGEXP = /=\z/
47
+ Sequel::Deprecation.deprecate_constant(self, :SETTER_METHOD_REGEXP)
48
+ ANONYMOUS_MODEL_CLASSES = @Model_cache = {}
49
+ Sequel::Deprecation.deprecate_constant(self, :ANONYMOUS_MODEL_CLASSES)
50
+ ANONYMOUS_MODEL_CLASSES_MUTEX = Mutex.new
51
+ Sequel::Deprecation.deprecate_constant(self, :ANONYMOUS_MODEL_CLASSES_MUTEX)
52
+ INHERITED_INSTANCE_VARIABLES = { :@allowed_columns=>:dup, :@dataset_method_modules=>:dup, :@primary_key=>nil, :@use_transactions=>nil, :@raise_on_save_failure=>nil, :@require_modification=>nil, :@restrict_primary_key=>nil, :@simple_pk=>nil, :@simple_table=>nil, :@strict_param_setting=>nil, :@typecast_empty_string_to_nil=>nil, :@typecast_on_assignment=>nil, :@raise_on_typecast_failure=>nil, :@plugins=>:dup, :@setter_methods=>nil, :@use_after_commit_rollback=>nil, :@fast_pk_lookup_sql=>nil, :@fast_instance_delete_sql=>nil, :@finders=>:dup, :@finder_loaders=>:dup, :@db=>nil, :@default_set_fields_options=>:dup, :@require_valid_table=>nil, :@cache_anonymous_models=>nil, :@dataset_module_class=>nil}
53
+ Sequel::Deprecation.deprecate_constant(self, :INHERITED_INSTANCE_VARIABLES)
58
54
 
59
55
  # Empty instance methods to create that the user can override to get hook/callback behavior.
60
56
  # Just like any other method defined by Sequel, if you override one of these, you should
61
57
  # call +super+ to get the default behavior (while empty by default, they can also be defined
62
58
  # by plugins). See the {"Model Hooks" guide}[rdoc-ref:doc/model_hooks.rdoc] for
63
59
  # more detail on hooks.
64
- HOOKS = BEFORE_HOOKS + AFTER_HOOKS
65
-
66
- # Class instance variables that are inherited in subclasses. If the value is <tt>:dup</tt>, dup is called
67
- # on the superclass's instance variable when creating the instance variable in the subclass.
68
- # If the value is +nil+, the superclass's instance variable is used directly in the subclass.
69
- INHERITED_INSTANCE_VARIABLES = {
70
- :@allowed_columns=>:dup, # SEQUEL5: Remove
71
- :@dataset_method_modules=>:dup, :@primary_key=>nil, :@use_transactions=>nil,
72
- :@raise_on_save_failure=>nil, :@require_modification=>nil, :@restrict_primary_key=>nil,
73
- :@simple_pk=>nil, :@simple_table=>nil, :@strict_param_setting=>nil,
74
- :@typecast_empty_string_to_nil=>nil, :@typecast_on_assignment=>nil,
75
- :@raise_on_typecast_failure=>nil, :@plugins=>:dup, :@setter_methods=>nil,
76
- :@use_after_commit_rollback=>nil, :@fast_pk_lookup_sql=>nil,
77
- :@fast_instance_delete_sql=>nil,
78
- :@finders=>:dup, :@finder_loaders=>:dup, # SEQUEL5: Remove
79
- :@db=>nil, :@default_set_fields_options=>:dup, :@require_valid_table=>nil,
80
- :@cache_anonymous_models=>nil, :@dataset_module_class=>nil}
81
-
82
- # Regular expression that determines if a method name is normal in the sense that
83
- # it could be used literally in ruby code without using send. Used to
84
- # avoid problems when using eval with a string to define methods.
85
- NORMAL_METHOD_NAME_REGEXP = /\A[A-Za-z_][A-Za-z0-9_]*\z/
86
-
87
- # Regular expression that determines if the method is a valid setter name
88
- # (i.e. it ends with =).
89
- SETTER_METHOD_REGEXP = /=\z/
60
+ HOOKS = [:before_create, :before_update, :before_save, :before_destroy, :before_validation,
61
+ :after_create, :after_update, :after_save, :after_destroy, :after_validation,
62
+ :after_commit, :after_rollback, :after_destroy_commit, :after_destroy_rollback # SEQUEL5: Remove commit/rollback hooks
63
+ ]#.freeze # SEQUEL5
90
64
 
91
65
  @allowed_columns = nil # SEQUEL5: Remove
92
66
  @cache_anonymous_models = true
@@ -106,7 +80,7 @@ module Sequel
106
80
  @raise_on_save_failure = true
107
81
  @raise_on_typecast_failure = false
108
82
  @require_modification = nil
109
- @require_valid_table = false
83
+ @require_valid_table = nil
110
84
  @restrict_primary_key = true
111
85
  @setter_methods = nil
112
86
  @simple_pk = nil
@@ -123,11 +97,11 @@ module Sequel
123
97
  plugin Model::Associations
124
98
  end
125
99
 
100
+ def_Model(::Sequel)
101
+
126
102
  # The setter methods (methods ending with =) that are never allowed
127
103
  # to be called automatically via +set+/+update+/+new+/etc..
128
- RESTRICTED_SETTER_METHODS = instance_methods.map(&:to_s).grep(SETTER_METHOD_REGEXP)
129
-
130
- def_Model(::Sequel)
104
+ RESTRICTED_SETTER_METHODS = instance_methods.map(&:to_s).select{|l| l.end_with?('=')}#.freeze # SEQUEL5
131
105
 
132
106
  # SEQUEL5: Remove
133
107
  class DeprecatedColumnsUpdated # :nodoc:
@@ -140,11 +114,5 @@ module Sequel
140
114
  @columns_updated.send(*args, &block)
141
115
  end
142
116
  end
143
-
144
- ANONYMOUS_MODEL_CLASSES = @Model_cache # :nodoc:
145
- Sequel::Deprecation.deprecate_constant(self, :ANONYMOUS_MODEL_CLASSES)
146
-
147
- ANONYMOUS_MODEL_CLASSES_MUTEX = Mutex.new # :nodoc:
148
- Sequel::Deprecation.deprecate_constant(self, :ANONYMOUS_MODEL_CLASSES_MUTEX)
149
117
  end
150
118
  end
@@ -18,8 +18,8 @@ module Sequel
18
18
  # # Make the Album class active_model compliant
19
19
  # Album.plugin :active_model
20
20
  module ActiveModel
21
- # The default string to join composite primary keys with in to_param.
22
21
  DEFAULT_TO_PARAM_JOINER = '-'.freeze
22
+ Sequel::Deprecation.deprecate_constant(self, :DEFAULT_TO_PARAM_JOINER)
23
23
 
24
24
  # ActiveModel compliant error class
25
25
  class Errors < Sequel::Model::Errors
@@ -119,7 +119,7 @@ module Sequel
119
119
 
120
120
  # The string to use to join composite primary key param strings.
121
121
  def to_param_joiner
122
- DEFAULT_TO_PARAM_JOINER
122
+ '-'
123
123
  end
124
124
  end
125
125
  end
@@ -1,5 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
+ Sequel::Deprecation.deprecate("The association_autoreloading plugin", "This plugin was integrated into the default model behavior in Sequel 4.0, and no longer has an effect")
4
+
3
5
  module Sequel
4
6
  module Plugins
5
7
  # Empty plugin module for backwards compatibility
@@ -6,9 +6,9 @@ module Sequel
6
6
  # for destroying, deleting, or nullifying associated model objects. The following
7
7
  # association types support the following dependency actions:
8
8
  #
9
- # * :many_to_many - :nullify (removes all related entries in join table)
10
- # * :many_to_one - :delete, :destroy
11
- # * :one_to_many, one_to_one - :delete, :destroy, :nullify (sets foreign key to NULL for all associated objects)
9
+ # :many_to_many :: :nullify (removes all related entries in join table)
10
+ # :many_to_one :: :delete, :destroy
11
+ # :one_to_many, one_to_one :: :delete, :destroy, :nullify (sets foreign key to NULL for all associated objects)
12
12
  #
13
13
  # This plugin works directly with the association datasets and does not use any cached association values.
14
14
  # The :delete action will delete all associated objects from the database in a single SQL call.
@@ -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,8 +48,8 @@ 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)
52
- if cs = check_non_connection_error{columns}
51
+ im = instance_methods.map(&:to_s)
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
55
55
  end
@@ -48,7 +48,7 @@ module Sequel
48
48
 
49
49
  # Add subset methods for all of the boolean columns in this model.
50
50
  def create_boolean_subsets
51
- if cs = check_non_connection_error{columns}
51
+ if cs = check_non_connection_error(false){columns}
52
52
  cs = cs.select{|c| db_schema[c][:type] == :boolean}.map{|c| boolean_subset_args(c)}
53
53
  dataset_module do
54
54
  cs.each{|c| where(*c)}
@@ -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
 
@@ -241,16 +242,23 @@ module Sequel
241
242
  # giving the columns to update in each backing database table.
242
243
  # For backwards compatibility.
243
244
  def cti_columns
245
+ Sequel::Deprecation.deprecate("#{self}.cti_columns", "Use #{self}.cti_models to get the models, cti_table_name to get the name for the model, and cti_table_columns to get the columns for the model")
244
246
  h = {}
245
247
  cti_models.each { |m| h[m.cti_table_name] = m.cti_table_columns }
246
248
  h
247
249
  end
248
250
 
249
251
  # Alias to sti_key, for backwards compatibility.
250
- def cti_key; sti_key; end
252
+ def cti_key
253
+ Sequel::Deprecation.deprecate("#{self}.cti_key", "Use #{self}.sti_key instead")
254
+ sti_key
255
+ end
251
256
 
252
257
  # Alias to sti_model_map, for backwards compatibility.
253
- def cti_model_map; sti_model_map; end
258
+ def cti_model_map
259
+ Sequel::Deprecation.deprecate("#{self}.cti_model_map", "Use #{self}.sti_model_map instead")
260
+ sti_model_map
261
+ end
254
262
 
255
263
  # Freeze CTI information when freezing model class.
256
264
  def freeze
@@ -281,7 +289,7 @@ module Sequel
281
289
  columns = db.from(table).columns
282
290
  else
283
291
  table = subclass.implicit_table_name
284
- columns = check_non_connection_error{db.from(table).columns}
292
+ columns = check_non_connection_error(false){db.from(table).columns}
285
293
  table = nil if !columns || columns.empty?
286
294
  end
287
295
  end
@@ -295,20 +303,22 @@ module Sequel
295
303
  ds = ds.select(*self.columns.map{|cc| Sequel.qualify(cti_table_name, Sequel.identifier(cc))})
296
304
  end
297
305
  cols = columns - [pk]
298
- unless (cols & ds.columns).empty?
299
- Sequel::Deprecation.deprecate('Using class_table_inheritance with duplicate column names 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')
306
+ dup_cols = cols & ds.columns
307
+ unless dup_cols.empty?
308
+ # 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"
309
+ 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")
300
310
  end
301
311
  sel_app = cols.map{|cc| Sequel.qualify(table, Sequel.identifier(cc))}
302
312
  @sti_dataset = ds = ds.join(table, pk=>pk).select_append(*sel_app)
303
313
 
304
- if @cti_alias
314
+ if @cti_alias # SEQUEL5: remove if
305
315
  ds = ds.from_self(:alias=>@cti_alias)
306
316
  end
307
317
 
308
318
  set_dataset(ds)
309
319
  set_columns(self.columns)
310
320
  @dataset = @dataset.with_row_proc(lambda{|r| subclass.sti_load(r)})
311
- cols.each{|a| define_lazy_attribute_getter(a, :dataset=>dataset, :table=>@cti_alias||table)}
321
+ cols.each{|a| define_lazy_attribute_getter(a, :dataset=>dataset, :table=>@cti_alias||table)} # SEQUEL5: remove ||table
312
322
 
313
323
  @cti_models += [self]
314
324
  @cti_tables += [table]
@@ -324,7 +334,7 @@ module Sequel
324
334
  # The table name for the current model class's main table.
325
335
  def table_name
326
336
  if cti_tables
327
- if @cti_alias
337
+ if @cti_alias # SEQUEL5: remove if
328
338
  @cti_alias
329
339
  else
330
340
  cti_tables.last
@@ -339,6 +349,7 @@ module Sequel
339
349
  cti_tables ? cti_tables.last : dataset.first_source_alias
340
350
  end
341
351
 
352
+ # The model class for the given key value.
342
353
  def sti_class_from_key(key)
343
354
  sti_class(sti_model_map[key])
344
355
  end
@@ -349,7 +360,7 @@ module Sequel
349
360
  # when setting subclass dataset.
350
361
  def sti_subclass_dataset(key)
351
362
  ds = super
352
- if @cti_alias
363
+ if @cti_alias && cti_models[0] != self # SEQUEL5: remove @cti_alias
353
364
  ds = ds.from_self(:alias=>@cti_alias)
354
365
  end
355
366
  ds
@@ -394,7 +405,7 @@ module Sequel
394
405
  # Insert rows into all backing tables, using the columns
395
406
  # in each table.
396
407
  def _insert
397
- return super if model.cti_tables.length == 1
408
+ return super if model.cti_models[0] == model
398
409
  model.cti_models.each do |m|
399
410
  v = {}
400
411
  m.cti_table_columns.each{|c| v[c] = @values[c] if @values.include?(c)}