sequel 5.104.0 → 5.105.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: a28329284b305f2ea739dc8ca05aa690db11c9c68c0dcd5fb47035ee621edbf9
4
- data.tar.gz: 8cdf6a6239baddff4fc926718409413713801d4d49481b7f151a439fa8a8bbe1
3
+ metadata.gz: aa9e8681d693c24d9f5dc7f6369be50dfcbf73c648402ec486e9ba69d5792f76
4
+ data.tar.gz: 7de020c93e5388ea9d58bd6e4d601bd06b240684e4c9001985549fd3b1c2d665
5
5
  SHA512:
6
- metadata.gz: 9f1f61fc96b631a8c081b831fa8a9dfa962908bcb11bde6975cc75c234e416941492ac140b6b9d995aa8fcd84ffec0c519eb11e4aba43b16fe779cf66e23973e
7
- data.tar.gz: ae638f7d62552732ebe9fd7af00fb3bdb931c078cabb3cc134e3d370a3104b5ce711a454d57f14e427fb7e522b95755366d7128cb3d1de3f325da19dd3e8ce5f
6
+ metadata.gz: 34030c2c1a045fa5fc36a6a36e1414960315469d415be97c3734fea182e63224c86c0882fa1958d5549f77c420879f6402af61a1756a4b7575a315ceb9c67f11
7
+ data.tar.gz: ea08def92c00668ca1898eac5a3dd37b50aeb1f81379e7c3ab19544e01cc5ef0c0c54786fc2a76f885e14b71534a3895451f33891cb374b3a3f10c08b0244d8a
@@ -46,8 +46,10 @@ module Sequel
46
46
  # Initialize the data structures used by this extension.
47
47
  def self.extended(pool)
48
48
  case pool.pool_type
49
- when :single, :sharded_single
50
- raise Error, "cannot load connection_expiration extension if using single or sharded_single connection pool"
49
+ when :threaded, :sharded_threaded, :timed_queue, :sharded_timed_queue
50
+ nil
51
+ else
52
+ raise Error, "cannot load connection_expiration extension if using single or sharded_single connection pool (or other unsupported connection pool)"
51
53
  end
52
54
 
53
55
  pool.instance_exec do
@@ -55,6 +57,39 @@ module Sequel
55
57
  @connection_expiration_timestamps ||= {}
56
58
  @connection_expiration_timeout ||= 14400
57
59
  @connection_expiration_random_delay ||= 0
60
+
61
+ # Record an expiration timestamp for any connections that already
62
+ # exist in the pool, so that a connection opened before the extension
63
+ # was loaded (e.g. via Sequel.connect) will eventually be expired.
64
+ register = method(:register_connection_expiration_time)
65
+
66
+ case pool_type
67
+ when :timed_queue, :sharded_timed_queue
68
+ register_queued_connections = lambda do |queue|
69
+ conns = []
70
+ while conn = queue.pop(timeout: 0)
71
+ conns << conn
72
+ end
73
+ conns.each do |conn|
74
+ queue.push(register_connection_expiration_time(conn))
75
+ end
76
+ end
77
+ end
78
+
79
+ case pool_type
80
+ when :threaded
81
+ @available_connections.each(&register)
82
+ @allocated.each_value(&register)
83
+ when :sharded_threaded
84
+ @available_connections.each_value{|conns| conns.each(&register)}
85
+ @allocated.each_value{|threads| threads.each_value(&register)}
86
+ when :timed_queue
87
+ register_queued_connections.call(@queue)
88
+ @allocated.each_value(&register)
89
+ else # when :sharded_timed_queue
90
+ @queues.each_value(&register_queued_connections)
91
+ @allocated.each_value{|threads| threads.each_value(&register)}
92
+ end
58
93
  end
59
94
  end
60
95
  end
@@ -69,8 +104,12 @@ module Sequel
69
104
 
70
105
  # Record the time the connection was created.
71
106
  def make_new(*)
72
- conn = super
73
- @connection_expiration_timestamps[conn] = [Sequel.start_timer, @connection_expiration_timeout + (rand * @connection_expiration_random_delay)].freeze
107
+ register_connection_expiration_time(super)
108
+ end
109
+
110
+ # Record an expiration entry for a connection, returns the connection.
111
+ def register_connection_expiration_time(conn)
112
+ @connection_expiration_timestamps[conn] ||= [Sequel.start_timer, @connection_expiration_timeout + (rand * @connection_expiration_random_delay)].freeze
74
113
  conn
75
114
  end
76
115
 
@@ -2174,6 +2174,7 @@ module Sequel
2174
2174
  associate(:one_to_one, name, opts, &block)
2175
2175
  end
2176
2176
 
2177
+ Plugins.model_instance_variables(self, :@associations, :@set_associated_object_if_same)
2177
2178
  Plugins.inherited_instance_variables(self, :@association_reflections=>:dup, :@autoreloading_associations=>:hash_dup, :@default_association_options=>:dup, :@default_association_type_options=>:hash_dup, :@cache_associations=>nil, :@default_eager_limit_strategy=>nil)
2178
2179
  Plugins.def_dataset_methods(self, [:eager, :eager_graph, :eager_graph_with_options, :association_join, :association_full_join, :association_inner_join, :association_left_join, :association_right_join])
2179
2180
 
@@ -84,6 +84,10 @@ module Sequel
84
84
  # underlying table doesn't exist.
85
85
  attr_accessor :require_valid_table
86
86
 
87
+ # Whether the model uses a shape friendly design (initializing all potentially
88
+ # used instance variables to nil).
89
+ attr_reader :shape_friendly
90
+
87
91
  # Should be the literal primary key column name if this Model's table has a simple primary key, or
88
92
  # nil if the model has a compound primary key or no primary key.
89
93
  attr_reader :simple_pk
@@ -221,9 +225,7 @@ module Sequel
221
225
  # Requires that values be a hash where all keys are symbols. It
222
226
  # probably should not be used by external code.
223
227
  def call(values)
224
- o = allocate
225
- o.instance_variable_set(:@values, values)
226
- o
228
+ allocate.initialize_from_db(values)
227
229
  end
228
230
 
229
231
  # Clear the setter_methods cache
@@ -501,7 +503,13 @@ module Sequel
501
503
  unless @plugins.include?(m)
502
504
  @plugins << m
503
505
  m.apply(self, *args, &block) if m.respond_to?(:apply)
504
- extend(m::ClassMethods) if m.const_defined?(:ClassMethods, false)
506
+ if m.const_defined?(:ClassMethods, false)
507
+ class_methods = m::ClassMethods
508
+ extend(class_methods)
509
+ if class_methods.private_method_defined?(:each_model_instance_variable)
510
+ def_initialize_nil_instance_variables
511
+ end
512
+ end
505
513
  include(m::InstanceMethods) if m.const_defined?(:InstanceMethods, false)
506
514
  if m.const_defined?(:DatasetMethods, false)
507
515
  dataset_extend(m::DatasetMethods, :create_class_methods=>false)
@@ -631,6 +639,13 @@ module Sequel
631
639
  self
632
640
  end
633
641
 
642
+ # Set instance variables used by instances of this model class.
643
+ # Only has an effect if shape_friendly is true.
644
+ def set_model_instance_variables(*ivs)
645
+ Plugins.model_instance_variables(singleton_class, *ivs)
646
+ def_initialize_nil_instance_variables
647
+ end
648
+
634
649
  # Sets the primary key for this model. You can use either a regular
635
650
  # or a composite primary key. To not use a primary key, set to nil
636
651
  # or use +no_primary_key+. On most adapters, Sequel can automatically
@@ -665,6 +680,12 @@ module Sequel
665
680
  @setter_methods || (@setter_methods = get_setter_methods)
666
681
  end
667
682
 
683
+ # Set whether the model should be shape friendly.
684
+ def shape_friendly=(v)
685
+ @shape_friendly = v
686
+ def_initialize_nil_instance_variables
687
+ end
688
+
668
689
  # Returns name of primary table for the dataset. If the table for the dataset
669
690
  # is aliased, returns the aliased name.
670
691
  #
@@ -814,6 +835,60 @@ END
814
835
  mod.send(:alias_method, meth, meth)
815
836
  end
816
837
 
838
+ # Defines the private _initialize_nil_instance_variables method.
839
+ # If shape_friendly is true, defines a method that initials the
840
+ # model's instance variables to nil. If shape_friendly is not
841
+ # true, does nothing.
842
+ def def_initialize_nil_instance_variables
843
+ if @shape_friendly
844
+ ivs = []
845
+ each_model_instance_variable do |iv|
846
+ unless iv.match(/\A@[a-z_][a-z0-9_]*\z/)
847
+ raise Error, "invalid model instance variable used"
848
+ end
849
+
850
+ ivs << iv
851
+ end
852
+ ivs.uniq!
853
+ ivs = ivs.reverse.join(" = ")
854
+ new_method_content = "#{ivs} = nil"
855
+ new_from_db_method_content = "#{ivs} = @new = @modified = nil"
856
+ end
857
+
858
+ class_eval(<<-RUBY, __FILE__, __LINE__+1)
859
+ def _initialize_nil_instance_variables
860
+ #{new_method_content}
861
+ end
862
+ def _initialize_from_db_nil_instance_variables
863
+ #{new_from_db_method_content}
864
+ end
865
+ RUBY
866
+ private :_initialize_nil_instance_variables, :_initialize_from_db_nil_instance_variables
867
+ alias_method :_initialize_nil_instance_variables, :_initialize_nil_instance_variables
868
+ alias_method :_initialize_from_db_nil_instance_variables, :_initialize_from_db_nil_instance_variables
869
+ nil
870
+ end
871
+
872
+ # Yield the default model instance variables. Designed only for
873
+ # use by def_initialize_nil_instance_variables.
874
+ def each_model_instance_variable
875
+ [
876
+ :@changed_columns,
877
+ :@errors,
878
+ :@raise_on_save_failure,
879
+ :@raise_on_typecast_failure,
880
+ :@require_modification,
881
+ :@server,
882
+ :@singleton_setter_added,
883
+ :@skip_validation_on_next_save,
884
+ :@strict_param_setting,
885
+ :@this,
886
+ :@typecast_empty_string_to_nil,
887
+ :@typecast_on_assignment,
888
+ :@use_transactions,
889
+ ].each{|iv| yield iv}
890
+ end
891
+
817
892
  # Get the schema from the database, fall back on checking the columns
818
893
  # via the database if that will return inaccurate results or if
819
894
  # it raises an error.
@@ -937,6 +1012,7 @@ END
937
1012
  :@require_valid_table=>nil,
938
1013
  :@restrict_primary_key=>nil,
939
1014
  :@setter_methods=>nil,
1015
+ :@shape_friendly=>nil,
940
1016
  :@simple_pk=>nil,
941
1017
  :@simple_table=>nil,
942
1018
  :@strict_param_setting=>nil,
@@ -1094,7 +1170,7 @@ END
1094
1170
  # standard attr_writer method for modifying that instance variable.
1095
1171
  [:typecast_empty_string_to_nil, :typecast_on_assignment, :strict_param_setting,
1096
1172
  :raise_on_save_failure, :raise_on_typecast_failure, :require_modification, :use_transactions].each do |meth|
1097
- class_eval("def #{meth}; !defined?(@#{meth}) ? (frozen? ? self.class.#{meth} : (@#{meth} = self.class.#{meth})) : @#{meth} end", __FILE__, __LINE__)
1173
+ class_eval("def #{meth}; @#{meth}.nil? ? (frozen? ? self.class.#{meth} : (@#{meth} = self.class.#{meth})) : @#{meth} end", __FILE__, __LINE__)
1098
1174
  attr_writer(meth)
1099
1175
  end
1100
1176
 
@@ -1135,13 +1211,23 @@ END
1135
1211
  # end
1136
1212
  def initialize(values = OPTS)
1137
1213
  @values = {}
1138
- @new = true
1139
- @modified = true
1214
+ @new = @modified = true
1215
+ _initialize_nil_instance_variables
1216
+
1140
1217
  initialize_set(values)
1141
1218
  _clear_changed_columns(:initialize)
1142
1219
  yield self if defined?(yield)
1143
1220
  end
1144
1221
 
1222
+ # Initialize a new record using values retrieved from a database.
1223
+ # This should not be called directly, only via Model.call.
1224
+ def initialize_from_db(values) # :nodoc:
1225
+ @values = values
1226
+ _initialize_from_db_nil_instance_variables
1227
+
1228
+ self
1229
+ end
1230
+
1145
1231
  # Returns value of the column's attribute.
1146
1232
  #
1147
1233
  # Artist[1][:id] #=> 1
@@ -1445,7 +1531,7 @@ END
1445
1531
  # Artist.new.new? # => true
1446
1532
  # Artist[1].new? # => false
1447
1533
  def new?
1448
- defined?(@new) ? @new : (@new = false)
1534
+ @new || false
1449
1535
  end
1450
1536
 
1451
1537
  # Returns the primary key value identifying the model instance.
@@ -2337,6 +2423,7 @@ END
2337
2423
 
2338
2424
  extend ClassMethods
2339
2425
  plugin self
2426
+ def_initialize_nil_instance_variables
2340
2427
 
2341
2428
  singleton_class.send(:undef_method, :dup, :clone, :initialize_copy)
2342
2429
  # :nocov:
@@ -38,7 +38,8 @@ module Sequel
38
38
  end
39
39
 
40
40
  # Add method to +mod+ that overrides inherited_instance_variables to include the
41
- # values in this hash.
41
+ # values in this hash. These affects how class instance variables will be treated
42
+ # during subclassing.
42
43
  def self.inherited_instance_variables(mod, hash)
43
44
  mod.send(:define_method, :inherited_instance_variables) do ||
44
45
  super().merge!(hash)
@@ -46,6 +47,16 @@ module Sequel
46
47
  mod.send(:private, :inherited_instance_variables)
47
48
  end
48
49
 
50
+ # Sets the model instance variables used by the plugin. These instance variables
51
+ # will be initialized to nil for created model objects.
52
+ def self.model_instance_variables(mod, *ivs)
53
+ mod.send(:define_method, :each_model_instance_variable) do |&block|
54
+ super(&block)
55
+ ivs.each(&block)
56
+ end
57
+ mod.send(:private, :each_model_instance_variable)
58
+ end
59
+
49
60
  # Add method to +mod+ that overrides set_dataset to call the method afterward.
50
61
  def self.after_set_dataset(mod, meth)
51
62
  mod.send(:define_method, :set_dataset) do |*a|
data/lib/sequel/model.rb CHANGED
@@ -55,6 +55,7 @@ module Sequel
55
55
  @require_valid_table = true
56
56
  @restrict_primary_key = true
57
57
  @setter_methods = nil
58
+ @shape_friendly = false
58
59
  @simple_pk = nil
59
60
  @simple_table = nil
60
61
  @strict_param_setting = true
@@ -26,6 +26,10 @@ module Sequel
26
26
  # # Make the Album instances record accessed columns
27
27
  # Album.plugin :accessed_columns
28
28
  module AccessedColumns
29
+ module ClassMethods
30
+ Plugins.model_instance_variables(self, :@accessed_columns)
31
+ end
32
+
29
33
  module InstanceMethods
30
34
  # Record the column access before retrieving the value.
31
35
  def [](c)
@@ -29,6 +29,8 @@ module Sequel
29
29
  module ClassMethods
30
30
  include ::ActiveModel::Naming
31
31
 
32
+ Plugins.model_instance_variables(self, :@destroyed, :@rollback_checker)
33
+
32
34
  # Cache model_name and to_partial path value before freezing.
33
35
  def freeze
34
36
  model_name
@@ -58,13 +60,10 @@ module Sequel
58
60
 
59
61
  # False if the object is new? or has been destroyed, true otherwise.
60
62
  def persisted?
61
- return false if new?
62
- return false if defined?(@destroyed)
63
+ return false if new? || @destroyed
63
64
 
64
- if defined?(@rollback_checker)
65
- if @rollback_checker.call
66
- return false
67
- end
65
+ if @rollback_checker && @rollback_checker.call
66
+ return false
68
67
  end
69
68
 
70
69
  true
@@ -67,6 +67,8 @@ module Sequel
67
67
  # Album.plugin :association_pks
68
68
  module AssociationPks
69
69
  module ClassMethods
70
+ Plugins.model_instance_variables(self, :@_association_pks)
71
+
70
72
  private
71
73
 
72
74
  # Define a association_pks method using the block for the association reflection
@@ -131,6 +131,8 @@ module Sequel
131
131
  end
132
132
 
133
133
  module ClassMethods
134
+ Plugins.model_instance_variables(self, :@_skip_auto_validations)
135
+
134
136
  # The columns with automatic no_null_byte validations
135
137
  attr_reader :auto_validate_no_null_byte_columns
136
138
 
@@ -15,6 +15,10 @@ module Sequel
15
15
  # # Make the Album class store the columns hash used for updating
16
16
  # Album.plugin :columns_updated
17
17
  module ColumnsUpdated
18
+ module ClassMethods
19
+ Plugins.model_instance_variables(self, :@columns_updated)
20
+ end
21
+
18
22
  module InstanceMethods
19
23
  private
20
24
 
@@ -66,6 +66,8 @@ module Sequel
66
66
  end
67
67
 
68
68
  module ClassMethods
69
+ Plugins.model_instance_variables(self, :@compositions)
70
+
69
71
  # A hash with composition name keys and composition reflection
70
72
  # hash values.
71
73
  attr_reader :compositions
@@ -63,6 +63,10 @@ module Sequel
63
63
  # # Make the Album class record previous values
64
64
  # Album.plugin :dirty
65
65
  module Dirty
66
+ module ClassMethods
67
+ Plugins.model_instance_variables(self, :@previous_changes, :@initial_values, :@missing_initial_values)
68
+ end
69
+
66
70
  module InstanceMethods
67
71
  # A hash of previous changes before the object was
68
72
  # saved, in the same format as #column_changes.
@@ -118,6 +118,7 @@ module Sequel
118
118
  end
119
119
 
120
120
  module ClassMethods
121
+ Plugins.model_instance_variables(self, :@forbid_lazy_load)
121
122
  Plugins.def_dataset_methods(self, :forbid_lazy_load)
122
123
 
123
124
  # If the static_cache plugin is used by the associated class for
@@ -42,6 +42,10 @@ module Sequel
42
42
  end
43
43
  end
44
44
 
45
+ module ClassMethods
46
+ Plugins.model_instance_variables(self, :@insert_conflict_opts)
47
+ end
48
+
45
49
  module InstanceMethods
46
50
  # Set the insert_conflict options to pass to the dataset when inserting.
47
51
  def insert_conflict(opts=OPTS)
@@ -50,6 +50,10 @@ module Sequel
50
50
  model.require_modification = true
51
51
  end
52
52
 
53
+ module ClassMethods
54
+ Plugins.model_instance_variables(self, :@instance_filters)
55
+ end
56
+
53
57
  module InstanceMethods
54
58
  # Clear the instance filters after successfully destroying the object.
55
59
  def after_destroy
@@ -28,6 +28,10 @@ module Sequel
28
28
  # # Add the instance hook methods just to Album instances
29
29
  # Album.plugin :instance_hooks
30
30
  module InstanceHooks
31
+ module ClassMethods
32
+ Plugins.model_instance_variables(self, :@instance_hooks)
33
+ end
34
+
31
35
  module InstanceMethods
32
36
  Sequel::Model::HOOKS.each{|h| class_eval(<<-END , __FILE__, __LINE__+1)}
33
37
  def #{h}_hook(&block)
@@ -162,6 +162,8 @@ module Sequel
162
162
  end
163
163
 
164
164
  module ClassMethods
165
+ Plugins.model_instance_variables(self, :@json_serializer_opts)
166
+
165
167
  # The default opts to use when serializing model objects to JSON.
166
168
  attr_reader :json_serializer_opts
167
169
 
@@ -34,6 +34,8 @@ module Sequel
34
34
  # Album.plugin :modification_detection
35
35
  module ModificationDetection
36
36
  module ClassMethods
37
+ Plugins.model_instance_variables(self, :@values_hashes)
38
+
37
39
  # Calculate the hashes for all of the column values, so that they
38
40
  # can be compared later to determine if the column value has changed.
39
41
  def call(_)
@@ -113,6 +113,8 @@ module Sequel
113
113
  register_format(:json, Sequel.method(:object_to_json), Sequel.method(:parse_json))
114
114
 
115
115
  module ClassMethods
116
+ Plugins.model_instance_variables(self, :@deserialized_values)
117
+
116
118
  # A hash with column name symbols and callable values, with the value
117
119
  # called to deserialize the column.
118
120
  attr_reader :deserialization_map
@@ -30,6 +30,10 @@ module Sequel
30
30
  def self.apply(model)
31
31
  model.plugin :serialization
32
32
  end
33
+
34
+ module ClassMethods
35
+ Plugins.model_instance_variables(self, :@original_deserialized_values)
36
+ end
33
37
 
34
38
  module InstanceMethods
35
39
  # Clear the cache of original deserialized values after saving so that it doesn't
@@ -36,6 +36,8 @@ module Sequel
36
36
  # Album.plugin :split_values
37
37
  module SplitValues
38
38
  module ClassMethods
39
+ Plugins.model_instance_variables(self, :@noncolumn_values)
40
+
39
41
  # Split the noncolumn values when creating a new object retrieved from
40
42
  # the database.
41
43
  def call(_)
@@ -124,6 +124,10 @@ module Sequel
124
124
  # # Make the Album class use tactical eager loading
125
125
  # Album.plugin :tactical_eager_loading
126
126
  module TacticalEagerLoading
127
+ module ClassMethods
128
+ Plugins.model_instance_variables(self, :@retrieved_by, :@retrieved_with)
129
+ end
130
+
127
131
  module InstanceMethods
128
132
  # The dataset that retrieved this object, set if the object was
129
133
  # reteived via Dataset#all.
@@ -22,6 +22,10 @@ module Sequel
22
22
  # # Make the Album class support primary key updates
23
23
  # Album.plugin :update_primary_key
24
24
  module UpdatePrimaryKey
25
+ module ClassMethods
26
+ Plugins.model_instance_variables(self, :@pk_hash)
27
+ end
28
+
25
29
  module InstanceMethods
26
30
  # Clear the cached primary key.
27
31
  def after_update
@@ -29,6 +29,10 @@ module Sequel
29
29
  # of that model, you can no longer specify a validation context when
30
30
  # validating the instance.
31
31
  module ValidationContexts
32
+ module ClassMethods
33
+ Plugins.model_instance_variables(self, :@validation_context)
34
+ end
35
+
32
36
  module InstanceMethods
33
37
  # The validation context to use for the current validation.
34
38
  # Set via the :validation_context option passed to save/valid?.
@@ -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 = 104
9
+ MINOR = 105
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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.104.0
4
+ version: 5.105.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
@@ -455,7 +455,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
455
455
  - !ruby/object:Gem::Version
456
456
  version: '0'
457
457
  requirements: []
458
- rubygems_version: 4.0.3
458
+ rubygems_version: 4.0.10
459
459
  specification_version: 4
460
460
  summary: The Database Toolkit for Ruby
461
461
  test_files: []