sequel 4.48.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 +56 -0
- data/doc/advanced_associations.rdoc +1 -1
- data/doc/opening_databases.rdoc +3 -2
- data/doc/release_notes/4.49.0.txt +222 -0
- data/lib/sequel/adapters/ibmdb.rb +6 -1
- data/lib/sequel/adapters/jdbc.rb +3 -1
- data/lib/sequel/adapters/jdbc/h2.rb +10 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +3 -2
- data/lib/sequel/adapters/jdbc/sqlserver.rb +9 -2
- data/lib/sequel/adapters/mock.rb +3 -0
- data/lib/sequel/adapters/mysql2.rb +1 -1
- data/lib/sequel/adapters/postgres.rb +2 -1
- data/lib/sequel/adapters/shared/mysql.rb +4 -1
- data/lib/sequel/adapters/shared/oracle.rb +26 -3
- data/lib/sequel/connection_pool.rb +9 -2
- 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/database/connecting.rb +3 -3
- data/lib/sequel/database/dataset_defaults.rb +14 -1
- data/lib/sequel/dataset.rb +1 -1
- data/lib/sequel/dataset/actions.rb +54 -0
- data/lib/sequel/dataset/dataset_module.rb +58 -0
- data/lib/sequel/dataset/query.rb +3 -3
- data/lib/sequel/exceptions.rb +8 -0
- data/lib/sequel/extensions/_model_pg_row.rb +5 -2
- 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 +2 -2
- data/lib/sequel/extensions/migration.rb +5 -2
- data/lib/sequel/extensions/null_dataset.rb +1 -0
- data/lib/sequel/model/associations.rb +3 -0
- data/lib/sequel/model/base.rb +10 -55
- 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/plugins/active_model.rb +2 -2
- data/lib/sequel/plugins/class_table_inheritance.rb +1 -0
- data/lib/sequel/plugins/composition.rb +2 -2
- data/lib/sequel/plugins/dataset_associations.rb +25 -13
- data/lib/sequel/plugins/json_serializer.rb +2 -2
- data/lib/sequel/plugins/pg_row.rb +4 -2
- data/lib/sequel/plugins/serialization.rb +1 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +6 -1
- data/lib/sequel/plugins/touch.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +10 -2
- data/lib/sequel/sql.rb +16 -7
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +4 -4
- data/spec/adapters/mysql_spec.rb +5 -1
- data/spec/adapters/oracle_spec.rb +4 -0
- data/spec/bin_spec.rb +7 -1
- data/spec/core/connection_pool_spec.rb +28 -14
- data/spec/core/database_spec.rb +149 -0
- data/spec/core/dataset_spec.rb +173 -0
- data/spec/extensions/class_table_inheritance_spec.rb +58 -17
- data/spec/extensions/composition_spec.rb +13 -0
- data/spec/extensions/dataset_associations_spec.rb +12 -0
- data/spec/extensions/many_through_many_spec.rb +4 -4
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/serialization_spec.rb +1 -1
- data/spec/extensions/single_table_inheritance_spec.rb +16 -0
- data/spec/extensions/validation_helpers_spec.rb +1 -2
- data/spec/integration/associations_test.rb +8 -0
- data/spec/integration/plugin_test.rb +8 -3
- data/spec/model/association_reflection_spec.rb +1 -1
- data/spec/model/associations_spec.rb +29 -9
- data/spec/model/class_dataset_methods_spec.rb +6 -0
- data/spec/model/eager_loading_spec.rb +8 -8
- data/spec/model/plugins_spec.rb +34 -0
- data/spec/model/record_spec.rb +1 -1
- data/spec/spec_config.rb +2 -0
- metadata +5 -2
@@ -67,6 +67,7 @@ module Sequel
|
|
67
67
|
ACCESS_DURATION_UNITS = DURATION_UNITS.zip(%w'yyyy m d h n s'.map(&:freeze)).freeze
|
68
68
|
DB2_DURATION_UNITS = DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit(s.to_s).freeze}).freeze
|
69
69
|
FDBSQL_DURATION_UNITS = DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit(s.to_s.chop).freeze}).freeze
|
70
|
+
Sequel::Deprecation.deprecate_constant(self, :FDBSQL_DURATION_UNITS)
|
70
71
|
|
71
72
|
# Append the SQL fragment for the DateAdd expression to the SQL query.
|
72
73
|
def date_add_sql_append(sql, da)
|
@@ -43,6 +43,8 @@ module Sequel
|
|
43
43
|
clone(:on_duplicate_columns=>handler||block)
|
44
44
|
end
|
45
45
|
|
46
|
+
private
|
47
|
+
|
46
48
|
# Override the attr_writer to check for duplicate columns, and call
|
47
49
|
# handle_duplicate_columns if necessary.
|
48
50
|
def columns=(cols)
|
@@ -52,8 +54,6 @@ module Sequel
|
|
52
54
|
super
|
53
55
|
end
|
54
56
|
|
55
|
-
private
|
56
|
-
|
57
57
|
# Invoke the appropriate behavior when duplicate columns are present.
|
58
58
|
def handle_duplicate_columns(cols)
|
59
59
|
message = "#{caller(*CALLER_ARGS).first}: One or more duplicate columns present in #{cols.inspect}"
|
@@ -352,8 +352,11 @@ module Sequel
|
|
352
352
|
# Part of the +migration+ extension.
|
353
353
|
class Migrator
|
354
354
|
MIGRATION_FILE_PATTERN = /\A(\d+)_.+\.rb\z/i.freeze
|
355
|
+
|
355
356
|
MIGRATION_SPLITTER = '_'.freeze
|
357
|
+
Sequel::Deprecation.deprecate_constant(self, :MIGRATION_SPLITTER)
|
356
358
|
MINIMUM_TIMESTAMP = 20000101
|
359
|
+
Sequel::Deprecation.deprecate_constant(self, :MINIMUM_TIMESTAMP)
|
357
360
|
|
358
361
|
# Exception class raised when there is an error with the migrator's
|
359
362
|
# file structure, database, or arguments.
|
@@ -408,7 +411,7 @@ module Sequel
|
|
408
411
|
if self.equal?(Migrator)
|
409
412
|
Dir.new(directory).each do |file|
|
410
413
|
next unless MIGRATION_FILE_PATTERN.match(file)
|
411
|
-
return TimestampMigrator if file.split(
|
414
|
+
return TimestampMigrator if file.split('_', 2).first.to_i > 20000101
|
412
415
|
end
|
413
416
|
IntegerMigrator
|
414
417
|
else
|
@@ -497,7 +500,7 @@ module Sequel
|
|
497
500
|
|
498
501
|
# Return the integer migration version based on the filename.
|
499
502
|
def migration_version_from_file(filename)
|
500
|
-
filename.split(
|
503
|
+
filename.split('_', 2).first.to_i
|
501
504
|
end
|
502
505
|
end
|
503
506
|
|
@@ -327,6 +327,7 @@ module Sequel
|
|
327
327
|
|
328
328
|
# Alias of predicate_key, only for backwards compatibility.
|
329
329
|
def eager_loading_predicate_key
|
330
|
+
Sequel::Deprecation.deprecate("AssociationReflection#eager_loading_predicate_key", "Use #predicate_key instead")
|
330
331
|
predicate_key
|
331
332
|
end
|
332
333
|
|
@@ -1803,6 +1804,7 @@ module Sequel
|
|
1803
1804
|
|
1804
1805
|
opts[:eager_block] = opts[:block] unless opts.include?(:eager_block)
|
1805
1806
|
if !opts.has_key?(:predicate_key) && opts.has_key?(:eager_loading_predicate_key)
|
1807
|
+
Sequel::Deprecation.deprecate("The :eager_loading_predicate_key association option", "Use the :predicate_key option instead")
|
1806
1808
|
opts[:predicate_key] = opts[:eager_loading_predicate_key]
|
1807
1809
|
end
|
1808
1810
|
opts[:graph_join_type] ||= :left_outer
|
@@ -2555,6 +2557,7 @@ module Sequel
|
|
2555
2557
|
end
|
2556
2558
|
|
2557
2559
|
if res == false and stop_on_false
|
2560
|
+
Sequel::Deprecation.deprecate("Having #{callback_type} association callback return false to cancel modification", "Instead, call Model#cancel_action inside the association callback")
|
2558
2561
|
raise(HookFailed, "Unable to modify association for #{inspect}: one of the #{callback_type} hooks returned false")
|
2559
2562
|
end
|
2560
2563
|
end
|
data/lib/sequel/model/base.rb
CHANGED
@@ -26,9 +26,8 @@ module Sequel
|
|
26
26
|
# (default: not set, so all columns not otherwise restricted are allowed).
|
27
27
|
attr_reader :allowed_columns # SEQUEL5: Deprecate after release
|
28
28
|
|
29
|
-
# Whether to cache the anonymous models created by Sequel::Model(). This is
|
30
|
-
# required for reloading them correctly (avoiding the superclass mismatch).
|
31
|
-
# by default for backwards compatibility.
|
29
|
+
# Whether to cache the anonymous models created by Sequel::Model(), true by default. This is
|
30
|
+
# required for reloading them correctly (avoiding the superclass mismatch).
|
32
31
|
attr_accessor :cache_anonymous_models
|
33
32
|
|
34
33
|
# Array of modules that extend this model's dataset. Stored
|
@@ -716,7 +715,7 @@ module Sequel
|
|
716
715
|
pluralize(underscore(demodulize(name))).to_sym
|
717
716
|
end
|
718
717
|
|
719
|
-
# Calls #call with the values hash.
|
718
|
+
# Calls #call with the values hash.
|
720
719
|
def load(values)
|
721
720
|
call(values)
|
722
721
|
end
|
@@ -992,7 +991,7 @@ module Sequel
|
|
992
991
|
end
|
993
992
|
|
994
993
|
# Add model methods that call dataset methods
|
995
|
-
Plugins.def_dataset_methods(self, (Dataset::ACTION_METHODS + Dataset::QUERY_METHODS + [:each_server
|
994
|
+
Plugins.def_dataset_methods(self, (Dataset::ACTION_METHODS + Dataset::QUERY_METHODS + [:each_server]) - [:<<, :and, :or, :[], :columns, :columns!, :delete, :update, :add_graph_aliases])
|
996
995
|
# SEQUEL5: add :set_graph_aliases to remove list and remove :and
|
997
996
|
|
998
997
|
private
|
@@ -1249,6 +1248,7 @@ module Sequel
|
|
1249
1248
|
rescue LoadError => e
|
1250
1249
|
begin
|
1251
1250
|
require "sequel_#{plugin}"
|
1251
|
+
Sequel::Deprecation.deprecate("requiring 'sequel_#{plugin}' to load a plugin", "Update the #{plugin} plugin to be required via 'sequel/plugins/#{plugin}'")
|
1252
1252
|
rescue LoadError => e2
|
1253
1253
|
e.message << "; #{e2.message}"
|
1254
1254
|
raise e
|
@@ -2684,52 +2684,6 @@ module Sequel
|
|
2684
2684
|
as_hash(*a)
|
2685
2685
|
end
|
2686
2686
|
|
2687
|
-
# Return an array of all rows matching the given filter condition, also
|
2688
|
-
# yielding each row to the given block. Basically the same as where(cond).all(&block),
|
2689
|
-
# except it can be optimized to not create an intermediate dataset.
|
2690
|
-
#
|
2691
|
-
# Artist.where_all(:id=>[1,2,3])
|
2692
|
-
# # SELECT * FROM artists WHERE (id IN (1, 2, 3))
|
2693
|
-
def where_all(cond, &block)
|
2694
|
-
if loader = _model_where_loader
|
2695
|
-
loader.all(filter_expr(cond), &block)
|
2696
|
-
else
|
2697
|
-
where(cond).all(&block)
|
2698
|
-
end
|
2699
|
-
end
|
2700
|
-
|
2701
|
-
# Iterate over all rows matching the given filter condition,
|
2702
|
-
# yielding each row to the given block. Basically the same as where(cond).each(&block),
|
2703
|
-
# except it can be optimized to not create an intermediate dataset.
|
2704
|
-
#
|
2705
|
-
# Artist.where_each(:id=>[1,2,3]){|row| p row}
|
2706
|
-
# # SELECT * FROM artists WHERE (id IN (1, 2, 3))
|
2707
|
-
def where_each(cond, &block)
|
2708
|
-
if loader = _model_where_loader
|
2709
|
-
loader.each(filter_expr(cond), &block)
|
2710
|
-
else
|
2711
|
-
where(cond).each(&block)
|
2712
|
-
end
|
2713
|
-
end
|
2714
|
-
|
2715
|
-
# Filter the datasets using the given filter condition, then return a single value.
|
2716
|
-
# This assumes that the dataset has already been setup to limit the selection to
|
2717
|
-
# a single column. Basically the same as where(cond).single_value,
|
2718
|
-
# except it can be optimized to not create an intermediate dataset.
|
2719
|
-
#
|
2720
|
-
# Artist.select(:name).where_single_value(:id=>1)
|
2721
|
-
# # SELECT name FROM artists WHERE (id = 1) LIMIT 1
|
2722
|
-
def where_single_value(cond)
|
2723
|
-
if loader = cached_placeholder_literalizer(:_model_where_single_value_loader) do |pl|
|
2724
|
-
single_value_ds.where(pl.arg)
|
2725
|
-
end
|
2726
|
-
|
2727
|
-
loader.get(filter_expr(cond))
|
2728
|
-
else
|
2729
|
-
where(cond).single_value
|
2730
|
-
end
|
2731
|
-
end
|
2732
|
-
|
2733
2687
|
# Given a primary key value, return the first record in the dataset with that primary key
|
2734
2688
|
# value. If no records matches, returns nil.
|
2735
2689
|
#
|
@@ -2756,11 +2710,12 @@ module Sequel
|
|
2756
2710
|
|
2757
2711
|
private
|
2758
2712
|
|
2759
|
-
#
|
2713
|
+
# SEQUEL5: Remove
|
2760
2714
|
def _model_where_loader
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2715
|
+
# :nocov:
|
2716
|
+
Sequel::Deprecation.deprecate("Dataset#_model_where_loader", "Use _where_loader instead")
|
2717
|
+
_where_loader
|
2718
|
+
# :nocov:
|
2764
2719
|
end
|
2765
2720
|
|
2766
2721
|
# If the dataset is not already ordered, and the model has a primary key,
|
@@ -3,12 +3,11 @@
|
|
3
3
|
module Sequel
|
4
4
|
class Model
|
5
5
|
# This Module subclass is used by Model.dataset_module
|
6
|
-
# to add dataset methods to classes.
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
|
11
|
-
class DatasetModule < ::Module
|
6
|
+
# to add dataset methods to classes. In addition to the
|
7
|
+
# methods offered by Dataset::DatasetModule, it also
|
8
|
+
# automatically creates class methods for public dataset
|
9
|
+
# methods.
|
10
|
+
class DatasetModule < Dataset::DatasetModule
|
12
11
|
# Store the model related to this dataset module.
|
13
12
|
def initialize(model)
|
14
13
|
@model = model
|
@@ -19,43 +18,6 @@ module Sequel
|
|
19
18
|
where(name, *args, &block)
|
20
19
|
end
|
21
20
|
|
22
|
-
%w'where exclude exclude_having having'.map(&:to_sym).each do |meth|
|
23
|
-
define_method(meth) do |name, *args, &block|
|
24
|
-
if block || args.flatten.any?{|arg| arg.is_a?(Proc)}
|
25
|
-
define_method(name){send(meth, *args, &block)}
|
26
|
-
else
|
27
|
-
key = :"_#{meth}_#{name}_ds"
|
28
|
-
define_method(name) do
|
29
|
-
cached_dataset(key){send(meth, *args)}
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
meths = (<<-METHS).split.map(&:to_sym)
|
36
|
-
distinct grep group group_and_count group_append
|
37
|
-
limit offset order order_append order_prepend
|
38
|
-
select select_all select_append select_group server
|
39
|
-
METHS
|
40
|
-
|
41
|
-
# Define a method in the module
|
42
|
-
def self.def_dataset_caching_method(mod, meth)
|
43
|
-
mod.send(:define_method, meth) do |name, *args, &block|
|
44
|
-
if block
|
45
|
-
define_method(name){send(meth, *args, &block)}
|
46
|
-
else
|
47
|
-
key = :"_#{meth}_#{name}_ds"
|
48
|
-
define_method(name) do
|
49
|
-
cached_dataset(key){send(meth, *args)}
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
meths.each do |meth|
|
56
|
-
def_dataset_caching_method(self, meth)
|
57
|
-
end
|
58
|
-
|
59
21
|
private
|
60
22
|
|
61
23
|
# Add a class method to the related model that
|
data/lib/sequel/model/errors.rb
CHANGED
@@ -6,6 +6,7 @@ module Sequel
|
|
6
6
|
# with a few convenience methods.
|
7
7
|
class Errors < ::Hash
|
8
8
|
ATTRIBUTE_JOINER = ' and '.freeze
|
9
|
+
Sequel::Deprecation.deprecate_constant(self, :ATTRIBUTE_JOINER)
|
9
10
|
|
10
11
|
# Adds an error for the given attribute.
|
11
12
|
#
|
@@ -40,7 +41,7 @@ module Sequel
|
|
40
41
|
def full_messages
|
41
42
|
inject([]) do |m, kv|
|
42
43
|
att, errors = *kv
|
43
|
-
errors.each {|e| m << (e.is_a?(LiteralString) ? e : "#{Array(att).join(
|
44
|
+
errors.each {|e| m << (e.is_a?(LiteralString) ? e : "#{Array(att).join(' and ')} #{e}")}
|
44
45
|
m
|
45
46
|
end
|
46
47
|
end
|
@@ -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
|
@@ -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
|
@@ -242,6 +242,7 @@ module Sequel
|
|
242
242
|
# giving the columns to update in each backing database table.
|
243
243
|
# For backwards compatibility.
|
244
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")
|
245
246
|
h = {}
|
246
247
|
cti_models.each { |m| h[m.cti_table_name] = m.cti_table_columns }
|
247
248
|
h
|
@@ -123,9 +123,9 @@ module Sequel
|
|
123
123
|
setters = setter_meths.zip(cov_methods)
|
124
124
|
opts[:decomposer] = proc do
|
125
125
|
if (o = compositions[name]).nil?
|
126
|
-
setter_meths.each{|sm|
|
126
|
+
setter_meths.each{|sm| set_column_value(sm, nil)}
|
127
127
|
else
|
128
|
-
setters.each{|sm, cm|
|
128
|
+
setters.each{|sm, cm| set_column_value(sm, o.send(cm))}
|
129
129
|
end
|
130
130
|
end
|
131
131
|
end
|
@@ -93,22 +93,34 @@ module Sequel
|
|
93
93
|
where(r.qualify(r.join_table_alias, r[:left_keys])=>sds.select(*r.qualify(model.table_name, r[:left_primary_key_columns])))
|
94
94
|
ds.where(r.qualified_right_primary_key=>r.send(:apply_filter_by_associations_limit_strategy, mds))
|
95
95
|
when :many_through_many, :one_through_many
|
96
|
-
|
97
|
-
edges << r.final_edge
|
98
|
-
if fre = r.reverse_edges.first
|
99
|
-
table = fre[:table]
|
100
|
-
left = fre[:left]
|
101
|
-
mds = model.join(fe[:table], Array(fe[:right]).zip(Array(fe[:left])), :implicit_qualifier=>model.table_name)
|
102
|
-
else
|
103
|
-
table = fe[:table]
|
104
|
-
left = edges.first[:left]
|
105
|
-
edges = []
|
96
|
+
if r.reverse_edges.empty?
|
106
97
|
mds = r.associated_dataset
|
98
|
+
fe = r.edges.first
|
99
|
+
selection = Array(r.qualify(fe[:table], r.final_edge[:left]))
|
100
|
+
predicate_key = r.qualify(fe[:table], fe[:right])
|
101
|
+
else
|
102
|
+
mds = model.dataset
|
103
|
+
iq = model.table_name
|
104
|
+
edges = r.edges.map(&:dup)
|
105
|
+
edges << r.final_edge.dup
|
106
|
+
edges.each do |e|
|
107
|
+
alias_expr = e[:table]
|
108
|
+
aliaz = mds.unused_table_alias(e[:table])
|
109
|
+
unless aliaz == alias_expr
|
110
|
+
alias_expr = Sequel.as(e[:table], aliaz)
|
111
|
+
end
|
112
|
+
e[:alias] = aliaz
|
113
|
+
mds = mds.join(alias_expr, Array(e[:right]).zip(Array(e[:left])), :implicit_qualifier=>iq)
|
114
|
+
iq = nil
|
115
|
+
end
|
116
|
+
fe, f1e, f2e = edges.values_at(0, -1, -2)
|
117
|
+
selection = Array(r.qualify(f2e[:alias], f1e[:left]))
|
118
|
+
predicate_key = r.qualify(fe[:alias], fe[:right])
|
107
119
|
end
|
120
|
+
|
108
121
|
mds = mds.
|
109
|
-
select(*
|
110
|
-
where(
|
111
|
-
edges.each{|e| mds = mds.join(e[:table], Array(e[:right]).zip(Array(e[:left])))}
|
122
|
+
select(*selection).
|
123
|
+
where(predicate_key=>sds.select(*r.qualify(model.table_name, r[:left_primary_key_columns])))
|
112
124
|
ds.where(r.qualified_right_primary_key=>r.send(:apply_filter_by_associations_limit_strategy, mds))
|
113
125
|
when :pg_array_to_many
|
114
126
|
ds.where(Sequel[r.primary_key=>sds.select{Sequel.pg_array_op(r.qualify(r[:model].table_name, r[:key])).unnest}])
|
@@ -321,7 +321,7 @@ module Sequel
|
|
321
321
|
if inc.is_a?(Hash)
|
322
322
|
inc.each do |k, v|
|
323
323
|
if k.is_a?(Sequel::SQL::AliasedExpression)
|
324
|
-
key_name = k.
|
324
|
+
key_name = k.alias.to_s
|
325
325
|
k = k.expression
|
326
326
|
else
|
327
327
|
key_name = k.to_s
|
@@ -346,7 +346,7 @@ module Sequel
|
|
346
346
|
else
|
347
347
|
Array(inc).each do |c|
|
348
348
|
if c.is_a?(Sequel::SQL::AliasedExpression)
|
349
|
-
key_name = c.
|
349
|
+
key_name = c.alias.to_s
|
350
350
|
c = c.expression
|
351
351
|
else
|
352
352
|
key_name = c.to_s
|