mongoid 7.5.1 → 7.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35ea6871ead43684bcaba29452a4d21a63d40a2703e5a954c60318bc4242759f
4
- data.tar.gz: bb819713b38b1639d9e0ccc4ac95bd171a054fc1025b330cbac492f980d93015
3
+ metadata.gz: e67e9eccd518e5c987bbca2d4943a461d7ceaf382abd091842806fb300dffb1e
4
+ data.tar.gz: 441f04f551b51c8b5f3300e4158fd7d0b6b0c3406b39dfa073bf1ce11cead324
5
5
  SHA512:
6
- metadata.gz: 80981e2b9473bac38edf29ee73aa49f4f5932b577ee8095e1af9407f113e9a156f5860049300c8b486ec66ff267ec8fd9b91007697d3d6e953cc65580e29e4b9
7
- data.tar.gz: 45077ad45b7d833dddaee515736c3faf54b5472e684a1e0e4220c1bff1b6ba6b9284bea082b235eb7371540af95481e728ad09c082ae40f5cf3d6d77f45e2f11
6
+ metadata.gz: 31d1d76cbe4923b0cb2a54a62d3758183a80ef8c8833448760115d2299153724e8cb2e6160745989357f6a4bbd3e6873380e73f500e13ffb14b307dfa503a3a9
7
+ data.tar.gz: 9c3acad387939c0bfe4746102e73e24124597bf311adbd3ce301bfe9a6882a066dadbb67ccb05a470a983c6b0d55ca43cce01f247111cd9d64efb2653614fbd8
checksums.yaml.gz.sig CHANGED
Binary file
@@ -15,7 +15,7 @@ module Mongoid
15
15
  # plural model name.
16
16
  #
17
17
  # If new_record? - will append /new
18
- # If not - will append /id-updated_at.to_s(cache_timestamp_format)
18
+ # If not - will append /id-updated_at.to_formatted_s(cache_timestamp_format)
19
19
  # Without updated_at - will append /id
20
20
  #
21
21
  # This is usually called inside a cache() block
@@ -26,7 +26,7 @@ module Mongoid
26
26
  # @return [ String ] the string with or without updated_at
27
27
  def cache_key
28
28
  return "#{model_key}/new" if new_record?
29
- return "#{model_key}/#{_id}-#{updated_at.utc.to_s(cache_timestamp_format)}" if do_or_do_not(:updated_at)
29
+ return "#{model_key}/#{_id}-#{updated_at.utc.to_formatted_s(cache_timestamp_format)}" if do_or_do_not(:updated_at)
30
30
  "#{model_key}/#{_id}"
31
31
  end
32
32
  end
@@ -116,6 +116,12 @@ module Mongoid
116
116
  # using and's instead of overwriting them.
117
117
  option :overwrite_chained_operators, default: true
118
118
 
119
+ # When this flag is true, the attributes method on a document will return
120
+ # a BSON::Document when that document is retrieved from the database, and
121
+ # a Hash otherwise. When this flag is false, the attributes method will
122
+ # always return a Hash.
123
+ option :legacy_attributes, default: true
124
+
119
125
  # Has Mongoid been configured? This is checking that at least a valid
120
126
  # client config exists.
121
127
  #
@@ -277,8 +277,15 @@ module Mongoid
277
277
  # criteria.
278
278
  #
279
279
  # @return [ Document ] A new document.
280
+ #
281
+ # @api private
280
282
  def instantiate(attrs = nil, selected_fields = nil)
281
- attributes = attrs || {}
283
+ attributes = if Mongoid.legacy_attributes
284
+ attrs
285
+ else
286
+ attrs&.to_h
287
+ end || {}
288
+
282
289
  doc = allocate
283
290
  doc.__selected_fields = selected_fields
284
291
  doc.instance_variable_set(:@attributes, attributes)
@@ -122,6 +122,21 @@ module Mongoid
122
122
  options == other.options
123
123
  end
124
124
 
125
+ # Whether the client of the context can be reused later, and therefore should
126
+ # not be closed.
127
+ #
128
+ # If the persistence context is requested with :client option only, it means
129
+ # that the context should use a client configured in mongoid.yml.
130
+ # Such clients should not be closed when the context is cleared since they
131
+ # will be reused later.
132
+ #
133
+ # @return [ true | false ] True if client can be reused, otherwise false.
134
+ #
135
+ # @api private
136
+ def reusable_client?
137
+ @options.keys == [:client]
138
+ end
139
+
125
140
  private
126
141
 
127
142
  def set_options!(opts)
@@ -172,8 +187,7 @@ module Mongoid
172
187
  #
173
188
  # @return [ Mongoid::PersistenceContext ] The persistence context for the object.
174
189
  def set(object, options_or_context)
175
- key = "[mongoid][#{object.object_id}]:context"
176
- existing_context = Thread.current[key]
190
+ existing_context = get_context(object)
177
191
  existing_options = if existing_context
178
192
  existing_context.options
179
193
  else
@@ -184,7 +198,7 @@ module Mongoid
184
198
  end
185
199
  new_options = existing_options.merge(options_or_context)
186
200
  context = PersistenceContext.new(object, new_options)
187
- Thread.current[key] = context
201
+ store_context(object, context)
188
202
  end
189
203
 
190
204
  # Get the persistence context for a particular class or model instance.
@@ -196,7 +210,7 @@ module Mongoid
196
210
  #
197
211
  # @return [ Mongoid::PersistenceContext ] The persistence context for the object.
198
212
  def get(object)
199
- Thread.current["[mongoid][#{object.object_id}]:context"]
213
+ get_context(object)
200
214
  end
201
215
 
202
216
  # Clear the persistence context for a particular class or model instance.
@@ -211,11 +225,48 @@ module Mongoid
211
225
  def clear(object, cluster = nil, original_context = nil)
212
226
  if context = get(object)
213
227
  unless cluster.nil? || context.cluster.equal?(cluster)
214
- context.client.close
228
+ context.client.close unless context.reusable_client?
215
229
  end
216
230
  end
217
231
  ensure
218
- Thread.current["[mongoid][#{object.object_id}]:context"] = original_context
232
+ store_context(object, original_context)
233
+ end
234
+
235
+ private
236
+
237
+ # Key to store persistence contexts in the thread local storage.
238
+ #
239
+ # @api private
240
+ PERSISTENCE_CONTEXT_KEY = :"[mongoid]:persistence_context"
241
+
242
+ # Get the persistence context for a given object from the thread local
243
+ # storage.
244
+ #
245
+ # @param [ Object ] object Object to get the persistance context for.
246
+ #
247
+ # @return [ Mongoid::PersistenceContext | nil ] The persistence context
248
+ # for the object if previously stored, otherwise nil.
249
+ #
250
+ # @api private
251
+ def get_context(object)
252
+ Thread.current[PERSISTENCE_CONTEXT_KEY] ||= {}
253
+ Thread.current[PERSISTENCE_CONTEXT_KEY][object.object_id]
254
+ end
255
+
256
+ # Store persistence context for a given object in the thread local
257
+ # storage.
258
+ #
259
+ # @param [ Object ] object Object to store the persistance context for.
260
+ # @param [ Mongoid::PersistenceContext ] context Context to store
261
+ #
262
+ # @api private
263
+ def store_context(object, context)
264
+ if context.nil?
265
+ Thread.current[PERSISTENCE_CONTEXT_KEY]&.delete(object.object_id)
266
+ else
267
+ Thread.current[PERSISTENCE_CONTEXT_KEY] ||= {}
268
+ Thread.current[PERSISTENCE_CONTEXT_KEY][object.object_id] = context
269
+ end
219
270
  end
220
271
  end
221
272
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mongoid
4
- VERSION = "7.5.1"
4
+ VERSION = "7.5.2"
5
5
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
+ require_relative "../has_and_belongs_to_many_models.rb"
4
5
 
5
6
  describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
6
7
 
@@ -3770,4 +3771,33 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
3770
3771
  expect(p2.d_ids).to match_array([d2.id])
3771
3772
  end
3772
3773
  end
3774
+
3775
+ # This test is for MONGOID-5344 which tests that the initial call to
3776
+ # signature_ids refers to the same array as subsequent calls to signature_ids.
3777
+ # Prior to the change in that ticket, this test broke because the array
3778
+ # returned from write_attribute (which is triggered the first time the
3779
+ # foreign key array is referenced, to set the default), refers to a different
3780
+ # array to the one stored in the attributes hash. This happened because,
3781
+ # when retrieving a document from the database, the attributes hash is actually
3782
+ # a BSON::Document, which applies a transformation to the array before
3783
+ # storing it.
3784
+ context "when executing concat on foreign key array from the db" do
3785
+ config_override :legacy_attributes, false
3786
+
3787
+ before do
3788
+ HabtmmContract.create!
3789
+ HabtmmSignature.create!
3790
+ end
3791
+
3792
+ let!(:contract) { HabtmmContract.first }
3793
+ let!(:signature) { HabtmmSignature.first }
3794
+
3795
+ before do
3796
+ contract.signature_ids.concat([signature.id])
3797
+ end
3798
+
3799
+ it "works on the first attempt" do
3800
+ expect(contract.signature_ids).to eq([signature.id])
3801
+ end
3802
+ end
3773
3803
  end
@@ -4089,4 +4089,24 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
4089
4089
  expect(band.same_name).to eq([agent])
4090
4090
  end
4091
4091
  end
4092
+
4093
+ context "when executing concat on foreign key array from the db" do
4094
+ config_override :legacy_attributes, false
4095
+
4096
+ before do
4097
+ Agent.create!
4098
+ Basic.create!
4099
+ end
4100
+
4101
+ let!(:agent) { Agent.first }
4102
+ let!(:basic) { Basic.first }
4103
+
4104
+ before do
4105
+ agent.basic_ids.concat([basic.id])
4106
+ end
4107
+
4108
+ it "works on the first attempt" do
4109
+ expect(agent.basic_ids).to eq([basic.id])
4110
+ end
4111
+ end
4092
4112
  end
@@ -1675,6 +1675,50 @@ describe Mongoid::Attributes do
1675
1675
  end
1676
1676
  end
1677
1677
  end
1678
+
1679
+ context "when comparing the object_ids of the written value" do
1680
+ config_override :legacy_attributes, false
1681
+
1682
+ before do
1683
+ Person.create!
1684
+ end
1685
+
1686
+ let(:person) do
1687
+ Person.first
1688
+ end
1689
+
1690
+ context "when the field is not resizable" do
1691
+ let(:test) do
1692
+ person.write_attribute(:test, "aliased field to test")
1693
+ end
1694
+
1695
+ it "has the same object_id as the attributes hash value" do
1696
+ expect(test.object_id).to eq(person.test.object_id)
1697
+ end
1698
+ end
1699
+
1700
+ context "when the field is resizable" do
1701
+
1702
+ let(:arrays) do
1703
+ person.write_attribute(:arrays, [])
1704
+ end
1705
+
1706
+ it "has the same object_id as the attributes hash value" do
1707
+ expect(arrays.object_id).to eq(person.arrays.object_id)
1708
+ end
1709
+ end
1710
+
1711
+ context "when the field is a HABTM foreign key array" do
1712
+
1713
+ let(:preference_ids) do
1714
+ person.write_attribute(:preference_ids, [])
1715
+ end
1716
+
1717
+ it "has the same object_id as the attributes hash value" do
1718
+ expect(preference_ids.object_id).to eq(person.preference_ids.object_id)
1719
+ end
1720
+ end
1721
+ end
1678
1722
  end
1679
1723
 
1680
1724
  describe "#typed_value_for" do
@@ -45,7 +45,7 @@ describe Mongoid::Cacheable do
45
45
  context "with the default cache_timestamp_format" do
46
46
 
47
47
  let!(:updated_at) do
48
- document.updated_at.utc.to_s(:nsec)
48
+ document.updated_at.utc.to_formatted_s(:nsec)
49
49
  end
50
50
 
51
51
  it "has the id and updated_at key name" do
@@ -64,7 +64,7 @@ describe Mongoid::Cacheable do
64
64
  end
65
65
 
66
66
  let!(:updated_at) do
67
- document.updated_at.utc.to_s(:number)
67
+ document.updated_at.utc.to_formatted_s(:number)
68
68
  end
69
69
 
70
70
  it "has the id and updated_at key name" do
@@ -103,7 +103,7 @@ describe Mongoid::Cacheable do
103
103
  end
104
104
 
105
105
  let!(:updated_at) do
106
- agent.updated_at.utc.to_s(:nsec)
106
+ agent.updated_at.utc.to_formatted_s(:nsec)
107
107
  end
108
108
 
109
109
  it "has the id and updated_at key name" do
@@ -1012,6 +1012,36 @@ describe Mongoid::Clients do
1012
1012
  end
1013
1013
  end
1014
1014
  end
1015
+
1016
+ context 'when requesting named client' do
1017
+ let(:secondary_client) do
1018
+ double(Mongo::Client).tap do |client|
1019
+ allow(client).to receive(:cluster).and_return(double("cluster"))
1020
+ end
1021
+ end
1022
+
1023
+ before do
1024
+ expect(Mongoid::Clients::Factory).to receive(:create)
1025
+ .with(:secondary)
1026
+ .and_return(secondary_client)
1027
+ end
1028
+
1029
+ after do
1030
+ Mongoid::Clients.clients.delete(:secondary)
1031
+ end
1032
+
1033
+ it 'does not close the client' do
1034
+ expect(secondary_client).not_to receive(:close)
1035
+
1036
+ Band.with(client: :default) do |klass|
1037
+ klass.mongo_client
1038
+ end
1039
+
1040
+ Band.with(client: :secondary) do |klass|
1041
+ klass.mongo_client
1042
+ end
1043
+ end
1044
+ end
1015
1045
  end
1016
1046
 
1017
1047
  context "when overriding the default database" do
@@ -335,6 +335,13 @@ describe Mongoid::Config do
335
335
  it_behaves_like "a config option"
336
336
  end
337
337
 
338
+ context 'when setting the legacy_attributes option in the config' do
339
+ let(:option) { :legacy_attributes }
340
+ let(:default) { true }
341
+
342
+ it_behaves_like "a config option"
343
+ end
344
+
338
345
  describe "#load!" do
339
346
 
340
347
  before(:all) do
@@ -39,7 +39,6 @@ describe Mongoid::PersistenceContext do
39
39
  end
40
40
  end
41
41
 
42
-
43
42
  describe '.get' do
44
43
 
45
44
  let(:options) do
@@ -134,6 +133,32 @@ describe Mongoid::PersistenceContext do
134
133
  end
135
134
  end
136
135
  end
136
+
137
+ context 'with reusable client' do
138
+ let(:options) do
139
+ {client: :some_client}
140
+ end
141
+
142
+ let(:cluster) do
143
+ double(Mongo::Cluster)
144
+ end
145
+
146
+ let(:client) do
147
+ double(Mongo::Client).tap do |client|
148
+ allow(client).to receive(:cluster).and_return(cluster)
149
+ end
150
+ end
151
+
152
+ before do
153
+ expect(Mongoid::Clients).to receive(:with_name).with(:some_client).and_return(client)
154
+ expect(client).not_to receive(:close)
155
+ end
156
+
157
+ it 'does not close the client' do
158
+ described_class.set(object, options)
159
+ described_class.clear(object, cluster.dup)
160
+ end
161
+ end
137
162
  end
138
163
 
139
164
  describe '#initialize' do
@@ -123,6 +123,10 @@ module Mrss
123
123
  end
124
124
 
125
125
  def run_deployment
126
+ puts(BASE_TEST_COMMAND + tty_arg + extra_env + [
127
+ '-e', %q`TEST_CMD=watch -x bash -c "ps awwxu |egrep 'mongo|ocsp'"`,
128
+ '-e', 'BIND_ALL=true',
129
+ ] + port_forwards + [image_tag] + script.split(/\s+/))
126
130
  run_command(BASE_TEST_COMMAND + tty_arg + extra_env + [
127
131
  '-e', %q`TEST_CMD=watch -x bash -c "ps awwxu |egrep 'mongo|ocsp'"`,
128
132
  '-e', 'BIND_ALL=true',
data.tar.gz.sig CHANGED
@@ -1,3 +1 @@
1
- �;-'}^���!�HI�i���2��dB'�Z}���\!��
2
- ����p����fX���5��r��
3
- ��R���Ѧ&�$��}C� 6Y�Ƨ!�Ӭ����|Z��h�ٮ ��''׾8^�C�C���z=}4̪�D¶k��}�N�V'3��W�'�Q�"|B���!zD���b��i�!$�l6�e��C�ܯ��!!B���b�p�n��N
1
+ "V�i}L�X٫/!-