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.
- checksums.yaml +4 -4
- data/CHANGELOG +210 -0
- data/Rakefile +1 -1
- data/doc/advanced_associations.rdoc +1 -1
- data/doc/opening_databases.rdoc +3 -2
- data/doc/release_notes/4.47.0.txt +56 -0
- data/doc/release_notes/4.48.0.txt +293 -0
- data/doc/release_notes/4.49.0.txt +222 -0
- data/lib/sequel/adapters/ado/access.rb +2 -1
- data/lib/sequel/adapters/do/postgres.rb +5 -2
- data/lib/sequel/adapters/ibmdb.rb +30 -8
- data/lib/sequel/adapters/jdbc/as400.rb +1 -1
- data/lib/sequel/adapters/jdbc/db2.rb +12 -3
- data/lib/sequel/adapters/jdbc/derby.rb +4 -5
- data/lib/sequel/adapters/jdbc/h2.rb +10 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +46 -20
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +20 -6
- data/lib/sequel/adapters/jdbc.rb +39 -23
- data/lib/sequel/adapters/mock.rb +27 -19
- data/lib/sequel/adapters/mysql.rb +17 -16
- data/lib/sequel/adapters/mysql2.rb +5 -6
- data/lib/sequel/adapters/oracle.rb +5 -9
- data/lib/sequel/adapters/postgres.rb +91 -103
- data/lib/sequel/adapters/shared/db2.rb +22 -6
- data/lib/sequel/adapters/shared/mssql.rb +5 -4
- data/lib/sequel/adapters/shared/mysql.rb +79 -25
- data/lib/sequel/adapters/shared/oracle.rb +26 -3
- data/lib/sequel/adapters/shared/postgres.rb +199 -95
- data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
- data/lib/sequel/adapters/shared/sqlite.rb +72 -82
- data/lib/sequel/adapters/sqlanywhere.rb +4 -1
- data/lib/sequel/adapters/sqlite.rb +5 -3
- data/lib/sequel/adapters/swift/postgres.rb +5 -2
- data/lib/sequel/adapters/tinytds.rb +0 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/adapters/utils/pg_types.rb +2 -76
- data/lib/sequel/ast_transformer.rb +1 -1
- data/lib/sequel/connection_pool/sharded_single.rb +1 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +1 -1
- data/lib/sequel/connection_pool/single.rb +2 -2
- data/lib/sequel/connection_pool/threaded.rb +2 -2
- data/lib/sequel/connection_pool.rb +9 -2
- data/lib/sequel/core.rb +2 -2
- data/lib/sequel/database/connecting.rb +8 -8
- data/lib/sequel/database/dataset.rb +6 -3
- data/lib/sequel/database/dataset_defaults.rb +14 -1
- data/lib/sequel/database/misc.rb +1 -1
- data/lib/sequel/database/query.rb +3 -0
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset/actions.rb +72 -10
- data/lib/sequel/dataset/dataset_module.rb +58 -0
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/misc.rb +1 -0
- data/lib/sequel/dataset/prepared_statements.rb +3 -3
- data/lib/sequel/dataset/query.rb +22 -11
- data/lib/sequel/dataset.rb +1 -1
- data/lib/sequel/exceptions.rb +8 -0
- data/lib/sequel/extensions/_model_pg_row.rb +5 -2
- data/lib/sequel/extensions/core_extensions.rb +4 -1
- data/lib/sequel/extensions/current_datetime_timestamp.rb +2 -1
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -3
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
- data/lib/sequel/extensions/filter_having.rb +2 -0
- data/lib/sequel/extensions/freeze_datasets.rb +2 -0
- data/lib/sequel/extensions/from_block.rb +1 -1
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/hash_aliases.rb +2 -0
- data/lib/sequel/extensions/identifier_mangling.rb +0 -7
- data/lib/sequel/extensions/meta_def.rb +2 -0
- data/lib/sequel/extensions/migration.rb +11 -8
- data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/null_dataset.rb +1 -0
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +207 -130
- data/lib/sequel/extensions/pg_hstore.rb +38 -20
- data/lib/sequel/extensions/pg_inet.rb +18 -6
- data/lib/sequel/extensions/pg_interval.rb +19 -12
- data/lib/sequel/extensions/pg_json.rb +25 -14
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/extensions/pg_range.rb +133 -100
- data/lib/sequel/extensions/pg_range_ops.rb +4 -3
- data/lib/sequel/extensions/pg_row.rb +68 -39
- data/lib/sequel/extensions/pg_row_ops.rb +11 -5
- data/lib/sequel/extensions/query_literals.rb +2 -0
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
- data/lib/sequel/extensions/s.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +29 -25
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
- data/lib/sequel/extensions/server_block.rb +32 -15
- data/lib/sequel/extensions/set_overrides.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +0 -1
- data/lib/sequel/extensions/symbol_aref.rb +0 -4
- data/lib/sequel/model/associations.rb +35 -7
- data/lib/sequel/model/base.rb +113 -87
- data/lib/sequel/model/dataset_module.rb +5 -43
- data/lib/sequel/model/errors.rb +2 -1
- data/lib/sequel/model/inflections.rb +17 -5
- data/lib/sequel/model.rb +26 -58
- data/lib/sequel/plugins/active_model.rb +2 -2
- data/lib/sequel/plugins/association_autoreloading.rb +2 -0
- data/lib/sequel/plugins/association_dependencies.rb +3 -3
- data/lib/sequel/plugins/association_pks.rb +73 -46
- data/lib/sequel/plugins/association_proxies.rb +1 -1
- data/lib/sequel/plugins/auto_validations.rb +6 -2
- data/lib/sequel/plugins/boolean_readers.rb +2 -2
- data/lib/sequel/plugins/boolean_subsets.rb +1 -1
- data/lib/sequel/plugins/caching.rb +19 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +24 -13
- data/lib/sequel/plugins/column_conflicts.rb +7 -2
- data/lib/sequel/plugins/column_select.rb +3 -3
- data/lib/sequel/plugins/composition.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +8 -8
- data/lib/sequel/plugins/dataset_associations.rb +25 -13
- data/lib/sequel/plugins/defaults_setter.rb +13 -1
- data/lib/sequel/plugins/eager_each.rb +1 -1
- data/lib/sequel/plugins/force_encoding.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +9 -12
- data/lib/sequel/plugins/identifier_columns.rb +2 -0
- data/lib/sequel/plugins/instance_filters.rb +3 -1
- data/lib/sequel/plugins/instance_hooks.rb +17 -9
- data/lib/sequel/plugins/json_serializer.rb +19 -12
- data/lib/sequel/plugins/lazy_attributes.rb +8 -7
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +2 -0
- data/lib/sequel/plugins/modification_detection.rb +3 -0
- data/lib/sequel/plugins/nested_attributes.rb +6 -2
- data/lib/sequel/plugins/pg_array_associations.rb +5 -0
- data/lib/sequel/plugins/pg_row.rb +4 -2
- data/lib/sequel/plugins/pg_typecast_on_load.rb +2 -0
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/plugins/rcte_tree.rb +4 -24
- data/lib/sequel/plugins/serialization.rb +9 -15
- data/lib/sequel/plugins/single_table_inheritance.rb +8 -3
- data/lib/sequel/plugins/split_values.rb +6 -5
- data/lib/sequel/plugins/static_cache.rb +31 -25
- data/lib/sequel/plugins/subset_conditions.rb +3 -1
- data/lib/sequel/plugins/table_select.rb +1 -1
- data/lib/sequel/plugins/touch.rb +4 -2
- data/lib/sequel/plugins/validation_class_methods.rb +5 -6
- data/lib/sequel/plugins/validation_helpers.rb +14 -8
- data/lib/sequel/plugins/xml_serializer.rb +4 -4
- data/lib/sequel/sql.rb +18 -9
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +115 -14
- data/spec/adapters/mssql_spec.rb +4 -4
- data/spec/adapters/mysql_spec.rb +83 -29
- data/spec/adapters/oracle_spec.rb +28 -24
- data/spec/adapters/postgres_spec.rb +40 -24
- data/spec/adapters/sqlanywhere_spec.rb +88 -86
- data/spec/adapters/sqlite_spec.rb +29 -24
- data/spec/bin_spec.rb +7 -1
- data/spec/core/connection_pool_spec.rb +45 -14
- data/spec/core/database_spec.rb +155 -0
- data/spec/core/dataset_spec.rb +219 -36
- data/spec/core/schema_spec.rb +16 -0
- data/spec/core/spec_helper.rb +1 -0
- data/spec/core_extensions_spec.rb +6 -2
- data/spec/extensions/active_model_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +34 -2
- data/spec/extensions/auto_literal_strings_spec.rb +5 -1
- data/spec/extensions/auto_validations_spec.rb +2 -0
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +106 -19
- data/spec/extensions/column_conflicts_spec.rb +11 -0
- data/spec/extensions/column_select_spec.rb +1 -0
- data/spec/extensions/composition_spec.rb +13 -0
- data/spec/extensions/connection_validator_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +20 -8
- data/spec/extensions/defaults_setter_spec.rb +15 -1
- data/spec/extensions/filter_having_spec.rb +5 -3
- data/spec/extensions/hash_aliases_spec.rb +3 -1
- data/spec/extensions/identifier_columns_spec.rb +3 -1
- data/spec/extensions/implicit_subquery_spec.rb +4 -2
- data/spec/extensions/json_serializer_spec.rb +18 -0
- data/spec/extensions/lazy_attributes_spec.rb +3 -3
- data/spec/extensions/many_through_many_spec.rb +4 -4
- data/spec/extensions/meta_def_spec.rb +9 -0
- data/spec/extensions/migration_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +14 -3
- data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/pg_array_associations_spec.rb +29 -18
- data/spec/extensions/pg_array_spec.rb +44 -25
- data/spec/extensions/pg_hstore_spec.rb +10 -0
- data/spec/extensions/pg_inet_spec.rb +26 -0
- data/spec/extensions/pg_interval_spec.rb +20 -0
- data/spec/extensions/pg_json_spec.rb +24 -0
- data/spec/extensions/pg_range_spec.rb +98 -14
- data/spec/extensions/pg_row_spec.rb +14 -4
- data/spec/extensions/pg_typecast_on_load_spec.rb +11 -9
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +3 -1
- data/spec/extensions/schema_dumper_spec.rb +108 -94
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
- data/spec/extensions/serialization_spec.rb +1 -1
- data/spec/extensions/server_block_spec.rb +7 -0
- data/spec/extensions/single_table_inheritance_spec.rb +17 -1
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/static_cache_spec.rb +75 -24
- data/spec/extensions/string_agg_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +9 -0
- data/spec/extensions/validation_helpers_spec.rb +10 -5
- data/spec/extensions/whitelist_security_spec.rb +26 -0
- data/spec/integration/associations_test.rb +8 -0
- data/spec/integration/dataset_test.rb +45 -44
- data/spec/integration/model_test.rb +53 -4
- data/spec/integration/plugin_test.rb +28 -4
- data/spec/integration/prepared_statement_test.rb +3 -0
- data/spec/integration/schema_test.rb +21 -1
- data/spec/integration/transaction_test.rb +40 -40
- data/spec/model/association_reflection_spec.rb +43 -1
- data/spec/model/associations_spec.rb +29 -9
- data/spec/model/class_dataset_methods_spec.rb +20 -4
- data/spec/model/dataset_methods_spec.rb +12 -3
- data/spec/model/eager_loading_spec.rb +8 -8
- data/spec/model/model_spec.rb +45 -1
- data/spec/model/plugins_spec.rb +34 -0
- data/spec/model/record_spec.rb +1 -1
- data/spec/spec_config.rb +2 -0
- metadata +11 -4
- data/spec/adapters/firebird_spec.rb +0 -405
- 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(
|
|
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 =
|
|
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(
|
|
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(
|
|
161
|
-
gsub(
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
50
|
-
|
|
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 =
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
#
|
|
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 =
|
|
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).
|
|
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
|
-
|
|
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
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
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)}
|
|
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
|
|
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
|
-
|
|
79
|
-
|
|
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[:
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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[:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
end
|
|
157
|
+
primary_key = opts.associated_class.primary_key
|
|
158
|
+
pkh = {primary_key=>pks}
|
|
145
159
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
|
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
|
-
|
|
143
|
+
case type
|
|
144
|
+
when :all
|
|
144
145
|
[:not_null, :types, :unique, :max_length].each{|v| skip_auto_validations(v)}
|
|
145
|
-
|
|
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.
|
|
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
|
|
23
|
-
#
|
|
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
|
-
|
|
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
|
-
#
|
|
90
|
-
def
|
|
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.
|
|
97
|
+
@cache_store.send(meth, ck) rescue nil
|
|
93
98
|
else
|
|
94
|
-
@cache_store.
|
|
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
|
-
|
|
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
|
-
#
|
|
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
|
|
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
|
|
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
|
-
|
|
299
|
-
|
|
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.
|
|
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)}
|