sequel 5.89.0 → 5.90.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8248e272e580f0e89e508e2aa97ebea83ac083b3f1bd347fc9d34700fd98ae42
4
- data.tar.gz: a74658ae42f7e087a541056d5f0cac2db4cc67b11ca56367b2bea309e502df49
3
+ metadata.gz: ba9973675e3b9e358ff96c334052ab6ba73e1db4c87c455163b60e367d0eb568
4
+ data.tar.gz: 86c4197ba9ced0d6bd3a789e5c20e4d0656bf5baca103f0b6db33e45b7981258
5
5
  SHA512:
6
- metadata.gz: c2875a0f53a46efa87b3380b3fe2c1bbae46542076e3e5615ddcd53b55ac6dfefa53fc828ec4f1277df85a7852eb0e2934377d074e58a6410837138ed2e2a7db
7
- data.tar.gz: 8c1a3591085be13aef51f3bc63f0407249858c57e91c3f314b92d929d362c4aafd0b801ee52ca0f96acb18f6fa133d33c4532b5a0fc13fc61e599ba3e05f4e6c
6
+ metadata.gz: 0247f84faceeb8a8c97d85bdefc3d0b781986e630981c163ca58bf7965f852a472d9e9501c5913ee1f4e7b02c005817c76ae8e71fcb0479fae252b27662e05f7
7
+ data.tar.gz: f90672de6e1ae901dca735988fa1466647bdc8f0cfeba75c1f27892e14e4eaf316b0141906039c9a33a70150b1860cda1f7a1972858ece6e3752614a91a60f2c
@@ -119,7 +119,7 @@ module Sequel
119
119
  end
120
120
 
121
121
  disconnect_connection(conn)
122
- redo
122
+ redo if valid == false
123
123
  end
124
124
  end
125
125
  end
@@ -27,9 +27,14 @@
27
27
  # treating strings as text can break programs, since the type for
28
28
  # literal strings in PostgreSQL is +unknown+, not +text+.
29
29
  #
30
- # The conversion is only done for single dimensional arrays that have more
31
- # than two elements, where all elements are of the same class (other than
32
- # nil values).
30
+ # The conversion is only done for single dimensional arrays that have two or
31
+ # more elements, where all elements are of the same class (other than
32
+ # +nil+ values). You can also do the conversion for arrays of 1 element by setting
33
+ # <tt>pg_auto_parameterize_min_array_size: 1</tt> Database option. This makes
34
+ # finding cases that need special handling easier, but it doesn't match
35
+ # how PostgreSQL internally converts the expression (PostgreSQL converts
36
+ # <tt>IN (single_value)</tt> to <tt>= single_value</tt>, not
37
+ # <tt>= ANY(ARRAY[single_value])</tt>).
33
38
  #
34
39
  # Related module: Sequel::Postgres::AutoParameterizeInArray
35
40
 
@@ -68,7 +73,7 @@ module Sequel
68
73
  # The bound variable type string to use for the bound variable array.
69
74
  # Returns nil if a bound variable should not be used for the array.
70
75
  def _bound_variable_type_for_array(r)
71
- return unless Array === r && r.size > 1
76
+ return unless Array === r && r.size >= (db.typecast_value(:integer, db.opts[:pg_auto_parameterize_min_array_size]) || 2)
72
77
  classes = r.map(&:class)
73
78
  classes.uniq!
74
79
  classes.delete(NilClass)
@@ -149,12 +149,12 @@ module Sequel
149
149
  from(:pg_type).
150
150
  where(:oid=>enum_labels.keys).
151
151
  exclude(:typarray=>0).
152
- select_map([:typname, Sequel.cast(:typarray, Integer).as(:v)])
152
+ select_map([:typname, Sequel.cast(:typarray, Integer).as(:v), Sequel.cast(:oid, Integer).as(:sv)])
153
153
 
154
154
  existing_oids = conversion_procs.keys
155
- array_types.each do |name, oid|
155
+ array_types.each do |name, oid, scalar_oid|
156
156
  next if existing_oids.include?(oid)
157
- register_array_type(name, :oid=>oid)
157
+ register_array_type(name, :oid=>oid, :scalar_oid=>scalar_oid)
158
158
  end
159
159
  end
160
160
 
@@ -693,6 +693,9 @@ module Sequel
693
693
 
694
694
  # The predicate condition to use for the eager_loader.
695
695
  def eager_loading_predicate_condition(keys)
696
+ if transform = self[:eager_loading_predicate_transform]
697
+ keys = transform.call(keys, self)
698
+ end
696
699
  {predicate_key=>keys}
697
700
  end
698
701
 
@@ -759,7 +762,15 @@ module Sequel
759
762
  def placeholder_eager_loader
760
763
  cached_fetch(:placeholder_eager_loader) do
761
764
  eager_loading_dataset.placeholder_literalizer_loader do |pl, ds|
762
- apply_eager_limit_strategy(ds.where(predicate_key=>pl.arg), eager_limit_strategy)
765
+ arg = pl.arg
766
+
767
+ if transform = self[:eager_loading_predicate_transform]
768
+ arg = arg.transform do |v|
769
+ transform.call(v, self)
770
+ end
771
+ end
772
+
773
+ apply_eager_limit_strategy(ds.where(predicate_key=>arg), eager_limit_strategy)
763
774
  end
764
775
  end
765
776
  end
@@ -1707,6 +1718,9 @@ module Sequel
1707
1718
  # record should be populated.
1708
1719
  # :eager_loader_key :: A symbol for the key column to use to populate the key_hash
1709
1720
  # for the eager loader. Can be set to nil to not populate the key_hash.
1721
+ # :eager_loading_predicate_transform :: A callable object with which to transform the predicate key values used
1722
+ # when eager loading. Called with two arguments, the array of predicate key
1723
+ # values, and a the reflection for the association being eager loaded.
1710
1724
  # :extend :: A module or array of modules to extend the dataset with.
1711
1725
  # :filter_limit_strategy :: Determines the strategy used for enforcing limits and offsets when filtering by
1712
1726
  # limited associations. Possible options are :window_function, :distinct_on, or
@@ -1769,6 +1783,9 @@ module Sequel
1769
1783
  # Set to nil to not define a setter method for the association.
1770
1784
  # :subqueries_per_union :: The number of subqueries to use in each UNION query, for eager
1771
1785
  # loading limited associations using the default :union strategy.
1786
+ # :use_placeholder_loader :: Whether to use a placeholder loader when eager loading the
1787
+ # association. Can be set to false to disable the use of a placeholder
1788
+ # loader if one would be used by default.
1772
1789
  # :validate :: Set to false to not validate when implicitly saving any associated object.
1773
1790
  # === :many_to_one
1774
1791
  # :key :: foreign key in current model's table that references
@@ -1891,7 +1908,7 @@ module Sequel
1891
1908
  raise(Error, "cannot clone an association to an association of different type (association #{name} with type #{type} cloning #{opts[:clone]} with type #{cloned_assoc[:type]})")
1892
1909
  end
1893
1910
 
1894
- opts[:use_placeholder_loader] = !opts[:instance_specific] && !opts[:eager_graph]
1911
+ opts[:use_placeholder_loader] = !opts[:instance_specific] && !opts[:eager_graph] unless opts.include?(:use_placeholder_loader)
1895
1912
  opts[:eager_block] = opts[:block] unless opts.include?(:eager_block)
1896
1913
  opts[:graph_join_type] ||= :left_outer
1897
1914
  opts[:order_eager_graph] = true unless opts.include?(:order_eager_graph)
@@ -768,7 +768,8 @@ module Sequel
768
768
  # default behavior.
769
769
  def dataset_methods_module
770
770
  return @dataset_methods_module if defined?(@dataset_methods_module)
771
- Sequel.synchronize{@dataset_methods_module ||= Sequel.set_temp_name(Module.new){"#{name}::@dataset_methods_module"}}
771
+ mod_name = "#{name}::@dataset_methods_module"
772
+ Sequel.synchronize{@dataset_methods_module ||= Sequel.set_temp_name(Module.new){mod_name}}
772
773
  extend(@dataset_methods_module)
773
774
  @dataset_methods_module
774
775
  end
@@ -956,7 +957,10 @@ END
956
957
  # Module that the class includes that holds methods the class adds for column accessors and
957
958
  # associations so that the methods can be overridden with +super+.
958
959
  def overridable_methods_module
959
- include(@overridable_methods_module = Sequel.set_temp_name(Module.new){"#{name}::@overridable_methods_module"}) unless @overridable_methods_module
960
+ return @overridable_methods_module if defined?(@overridable_methods_module)
961
+ mod_name = "#{name}::@overridable_methods_module"
962
+ Sequel.synchronize{@overridable_methods_module ||= Sequel.set_temp_name(Module.new){mod_name}}
963
+ include(@overridable_methods_module)
960
964
  @overridable_methods_module
961
965
  end
962
966
 
@@ -1610,7 +1614,7 @@ END
1610
1614
  @skip_validation_on_next_save = true
1611
1615
  end
1612
1616
 
1613
- # Returns (naked) dataset that should return only this instance.
1617
+ # Returns naked dataset that should return only the row related to this instance.
1614
1618
  #
1615
1619
  # Artist[1].this
1616
1620
  # # SELECT * FROM artists WHERE (id = 1) LIMIT 1
@@ -0,0 +1,95 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Sequel
4
+ module Plugins
5
+ # The pg_eager_any_typed_array plugin automatically converts
6
+ # the predicate expressions used for eager loading from:
7
+ #
8
+ # table.column IN (value_list)
9
+ #
10
+ # to:
11
+ #
12
+ # table.column = ANY(array_expr::type[])
13
+ #
14
+ # This makes it easier to use the pg_auto_parameterize_in_array
15
+ # extension with the :treat_string_list_as_text_array option,
16
+ # when using foreign keys with non-text database types that are represented
17
+ # by Ruby strings, such as enum and uuid types.
18
+ #
19
+ # Most association types that ship with Sequel have their predicate
20
+ # expressions converted by this plugin. Here are the exceptions:
21
+ #
22
+ # * associations using composite predicate keys
23
+ # * many_to_pg_array associations
24
+ # * many_to_many/one_through_one associations using :join_table_db option
25
+ # * many_through_many/one_through_many associations using
26
+ # :separate_table_per_query option
27
+ #
28
+ # To avoid predicate conversion for particular associations, set the
29
+ # :eager_loading_predicate_transform association option to nil/false.
30
+ #
31
+ # This plugin loads the pg_array extension into the model's Database.
32
+ module PgEagerAnyTypedArray
33
+ # Add the pg_array extension to the database
34
+ def self.apply(model)
35
+ model.db.extension(:pg_array)
36
+ end
37
+
38
+ module ClassMethods
39
+ TRANSFORM = proc do |values, ref|
40
+ type = ref.send(:cached_fetch, :_pg_eager_any_typed_array_type) do
41
+ key = ref.predicate_key
42
+ next if key.is_a?(Array)
43
+
44
+ while key.is_a?(SQL::QualifiedIdentifier)
45
+ key = key.column
46
+ end
47
+
48
+ # :nocov:
49
+ # many_to_pg_array association type does not need changes, as it
50
+ # already converts the values to a typed postgres array, it does
51
+ # not call the code that uses :eager_loading_predicate_transform.
52
+ #
53
+ # No association type that ships with Sequel can reach this code
54
+ # unless it is one of these types, but external association types
55
+ # could potentially reach it.
56
+ sch = case ref[:type]
57
+ # :nocov:
58
+ when :many_to_one, :one_to_one, :one_to_many, :pg_array_to_many
59
+ ref.associated_class.db_schema
60
+ when :many_to_many, :one_through_one
61
+ # Not compatible with the :join_table_db option, but that option
62
+ # does not call into this code.
63
+ Hash[ref.associated_class.db.schema(ref.join_table_source)]
64
+ when :many_through_many, :one_through_many
65
+ # Not compatible with the :separate_query_per_table option, but
66
+ # that option does not call into this code.
67
+ Hash[ref.associated_class.db.schema(ref[:through][0][:table])]
68
+ end
69
+
70
+ if sch && (sch = sch[key])
71
+ sch[:db_type]
72
+ end
73
+ end
74
+
75
+ if type
76
+ Sequel.function(:ANY, Sequel.pg_array(values, type))
77
+ else
78
+ values
79
+ end
80
+ end
81
+
82
+ # Set the :eager_loading_predicate_transform option if not already set
83
+ def associate(type, name, opts = OPTS, &block)
84
+ res = super
85
+
86
+ unless res.has_key?(:eager_loading_predicate_transform)
87
+ res[:eager_loading_predicate_transform] = TRANSFORM
88
+ end
89
+
90
+ res
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -40,7 +40,8 @@ module Sequel
40
40
  # Album.sql_comments_dataset_methods :to_csv # csv_serializer plugin
41
41
  #
42
42
  # In order for the sql_comments plugin to work, the sql_comments
43
- # Database extension must be loaded into the model's database.
43
+ # Database extension must be loaded into the model's database, so
44
+ # loading the plugin does this automatically.
44
45
  #
45
46
  # Note that in order to make sure SQL comments are included, some
46
47
  # optimizations are disabled if this plugin is loaded.
@@ -67,6 +68,10 @@ module Sequel
67
68
  # :nocov:
68
69
  end
69
70
 
71
+ def self.apply(model)
72
+ model.db.extension(:sql_comments)
73
+ end
74
+
70
75
  def self.configure(model)
71
76
  model.send(:reset_fast_pk_lookup_sql)
72
77
  end
@@ -99,7 +99,8 @@ module Sequel
99
99
  # it before calling creating this module.
100
100
  dataset_methods_module
101
101
 
102
- Sequel.synchronize{@subset_static_cache_module ||= Sequel.set_temp_name(Module.new){"#{name}::@subset_static_cache_module"}}
102
+ mod_name = "#{name}::@subset_static_cache_module"
103
+ Sequel.synchronize{@subset_static_cache_module ||= Sequel.set_temp_name(Module.new){mod_name}}
103
104
  extend(@subset_static_cache_module)
104
105
  @subset_static_cache_module
105
106
  end
data/lib/sequel/sql.rb CHANGED
@@ -1127,7 +1127,13 @@ module Sequel
1127
1127
  when DelayedEvaluation
1128
1128
  Sequel.delay{|ds| from_value_pair(l, r.call(ds))}
1129
1129
  when Dataset::PlaceholderLiteralizer::Argument
1130
- r.transform{|v| from_value_pair(l, v)}
1130
+ prev_transform = r.instance_variable_get(:@transformer)
1131
+ r.transform do |v|
1132
+ if prev_transform
1133
+ v = prev_transform.call(v)
1134
+ end
1135
+ from_value_pair(l, v)
1136
+ end
1131
1137
  else
1132
1138
  new(:'=', l, r)
1133
1139
  end
@@ -6,7 +6,7 @@ module Sequel
6
6
 
7
7
  # The minor version of Sequel. Bumped for every non-patch level
8
8
  # release, generally around once a month.
9
- MINOR = 89
9
+ MINOR = 90
10
10
 
11
11
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
12
12
  # releases that fix regressions from previous versions.
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.89.0
4
+ version: 5.90.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-02-01 00:00:00.000000000 Z
10
+ date: 2025-03-01 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bigdecimal
@@ -371,6 +371,7 @@ files:
371
371
  - lib/sequel/plugins/paged_operations.rb
372
372
  - lib/sequel/plugins/pg_array_associations.rb
373
373
  - lib/sequel/plugins/pg_auto_constraint_validations.rb
374
+ - lib/sequel/plugins/pg_eager_any_typed_array.rb
374
375
  - lib/sequel/plugins/pg_row.rb
375
376
  - lib/sequel/plugins/pg_xmin_optimistic_locking.rb
376
377
  - lib/sequel/plugins/prepared_statements.rb