mongoid 6.3.0 → 6.4.5
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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Rakefile +12 -0
- data/lib/config/locales/en.yml +21 -0
- data/lib/mongoid.rb +2 -2
- data/lib/mongoid/clients.rb +2 -0
- data/lib/mongoid/clients/sessions.rb +113 -0
- data/lib/mongoid/clients/storage_options.rb +1 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
- data/lib/mongoid/contextual/map_reduce.rb +7 -3
- data/lib/mongoid/contextual/memory.rb +7 -2
- data/lib/mongoid/contextual/mongo.rb +11 -2
- data/lib/mongoid/criteria.rb +1 -0
- data/lib/mongoid/criteria/modifiable.rb +12 -2
- data/lib/mongoid/criteria/queryable/mergeable.rb +3 -1
- data/lib/mongoid/criteria/queryable/selectable.rb +34 -7
- data/lib/mongoid/document.rb +4 -4
- data/lib/mongoid/errors.rb +1 -0
- data/lib/mongoid/errors/invalid_session_use.rb +24 -0
- data/lib/mongoid/extensions/big_decimal.rb +1 -1
- data/lib/mongoid/extensions/regexp.rb +1 -0
- data/lib/mongoid/extensions/string.rb +3 -1
- data/lib/mongoid/indexable.rb +4 -4
- data/lib/mongoid/matchable.rb +3 -0
- data/lib/mongoid/matchable/nor.rb +37 -0
- data/lib/mongoid/persistable.rb +1 -1
- data/lib/mongoid/persistable/creatable.rb +4 -2
- data/lib/mongoid/persistable/deletable.rb +4 -2
- data/lib/mongoid/persistable/destroyable.rb +1 -5
- data/lib/mongoid/persistable/settable.rb +5 -5
- data/lib/mongoid/persistable/updatable.rb +2 -2
- data/lib/mongoid/persistable/upsertable.rb +2 -1
- data/lib/mongoid/persistence_context.rb +4 -0
- data/lib/mongoid/railtie.rb +17 -0
- data/lib/mongoid/railties/controller_runtime.rb +86 -0
- data/lib/mongoid/relations/embedded/batchable.rb +10 -4
- data/lib/mongoid/relations/embedded/many.rb +23 -0
- data/lib/mongoid/relations/many.rb +4 -0
- data/lib/mongoid/relations/referenced/many.rb +1 -1
- data/lib/mongoid/relations/touchable.rb +1 -1
- data/lib/mongoid/reloadable.rb +1 -1
- data/lib/mongoid/scopable.rb +3 -3
- data/lib/mongoid/tasks/database.rb +3 -2
- data/lib/mongoid/threaded.rb +74 -0
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -0
- data/spec/app/models/array_field.rb +7 -0
- data/spec/app/models/delegating_patient.rb +16 -0
- data/spec/integration/document_spec.rb +22 -0
- data/spec/mongoid/attributes/nested_spec.rb +4 -0
- data/spec/mongoid/clients/factory_spec.rb +52 -28
- data/spec/mongoid/clients/options_spec.rb +30 -15
- data/spec/mongoid/clients/sessions_spec.rb +334 -0
- data/spec/mongoid/contextual/geo_near_spec.rb +1 -0
- data/spec/mongoid/contextual/mongo_spec.rb +40 -2
- data/spec/mongoid/criteria/modifiable_spec.rb +59 -10
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +3 -3
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +74 -6
- data/spec/mongoid/criteria/queryable/selector_spec.rb +2 -2
- data/spec/mongoid/criteria/scopable_spec.rb +81 -0
- data/spec/mongoid/criteria_spec.rb +4 -1
- data/spec/mongoid/document_spec.rb +54 -0
- data/spec/mongoid/extensions/big_decimal_spec.rb +9 -9
- data/spec/mongoid/extensions/regexp_spec.rb +23 -0
- data/spec/mongoid/extensions/string_spec.rb +35 -7
- data/spec/mongoid/fields_spec.rb +1 -1
- data/spec/mongoid/findable_spec.rb +1 -1
- data/spec/mongoid/interceptable_spec.rb +1 -1
- data/spec/mongoid/matchable/nor_spec.rb +209 -0
- data/spec/mongoid/matchable_spec.rb +26 -1
- data/spec/mongoid/persistable/deletable_spec.rb +19 -0
- data/spec/mongoid/persistable/destroyable_spec.rb +19 -0
- data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
- data/spec/mongoid/persistable/settable_spec.rb +35 -1
- data/spec/mongoid/persistable_spec.rb +16 -16
- data/spec/mongoid/relations/embedded/many_spec.rb +246 -16
- data/spec/mongoid/scopable_spec.rb +13 -0
- data/spec/mongoid/threaded_spec.rb +68 -0
- data/spec/rails/controller_extension/controller_runtime_spec.rb +110 -0
- data/spec/spec_helper.rb +79 -0
- data/spec/support/cluster_config.rb +158 -0
- data/spec/support/constraints.rb +101 -0
- data/spec/support/macros.rb +20 -0
- data/spec/support/spec_config.rb +42 -0
- metadata +471 -443
- metadata.gz.sig +0 -0
@@ -477,7 +477,7 @@ module Mongoid
|
|
477
477
|
# @since 3.0.0
|
478
478
|
def persist_delayed(docs, inserts)
|
479
479
|
unless docs.empty?
|
480
|
-
collection.insert_many(inserts)
|
480
|
+
collection.insert_many(inserts, session: _session)
|
481
481
|
docs.each do |doc|
|
482
482
|
doc.new_record = false
|
483
483
|
doc.run_after_callbacks(:create, :save)
|
@@ -31,7 +31,7 @@ module Mongoid
|
|
31
31
|
touches = touch_atomic_updates(field)
|
32
32
|
unless touches["$set"].blank?
|
33
33
|
selector = atomic_selector
|
34
|
-
_root.collection.find(selector).update_one(positionally(selector, touches))
|
34
|
+
_root.collection.find(selector).update_one(positionally(selector, touches), session: _session)
|
35
35
|
end
|
36
36
|
run_callbacks(:touch)
|
37
37
|
true
|
data/lib/mongoid/reloadable.rb
CHANGED
@@ -58,7 +58,7 @@ module Mongoid
|
|
58
58
|
#
|
59
59
|
# @since 2.3.2
|
60
60
|
def reload_root_document
|
61
|
-
{}.merge(collection.find(_id: _id).read(mode: :primary).first || {})
|
61
|
+
{}.merge(collection.find({ _id: _id }, session: _session).read(mode: :primary).first || {})
|
62
62
|
end
|
63
63
|
|
64
64
|
# Reload the embedded document.
|
data/lib/mongoid/scopable.rb
CHANGED
@@ -102,7 +102,7 @@ module Mongoid
|
|
102
102
|
#
|
103
103
|
# @since 3.0.0
|
104
104
|
def default_scopable?
|
105
|
-
default_scoping? && !Threaded.
|
105
|
+
default_scoping? && !Threaded.without_default_scope?(self)
|
106
106
|
end
|
107
107
|
|
108
108
|
# Get a queryable, either the last one on the scope stack or a fresh one.
|
@@ -244,10 +244,10 @@ module Mongoid
|
|
244
244
|
#
|
245
245
|
# @since 3.0.0
|
246
246
|
def without_default_scope
|
247
|
-
Threaded.
|
247
|
+
Threaded.begin_without_default_scope(self)
|
248
248
|
yield
|
249
249
|
ensure
|
250
|
-
Threaded.
|
250
|
+
Threaded.exit_without_default_scope(self)
|
251
251
|
end
|
252
252
|
|
253
253
|
private
|
@@ -44,7 +44,7 @@ module Mongoid
|
|
44
44
|
models.each do |model|
|
45
45
|
unless model.embedded?
|
46
46
|
begin
|
47
|
-
model.collection.indexes.each do |index|
|
47
|
+
model.collection.indexes(session: model.send(:_session)).each do |index|
|
48
48
|
# ignore default index
|
49
49
|
unless index['name'] == '_id_'
|
50
50
|
key = index['key'].symbolize_keys
|
@@ -77,7 +77,7 @@ module Mongoid
|
|
77
77
|
indexes.each do |index|
|
78
78
|
key = index['key'].symbolize_keys
|
79
79
|
collection = model.collection
|
80
|
-
collection.indexes.drop_one(key)
|
80
|
+
collection.indexes(session: model.send(:_session)).drop_one(key)
|
81
81
|
logger.info(
|
82
82
|
"MONGOID: Removed index '#{index['name']}' on collection " +
|
83
83
|
"'#{collection.name}' in database '#{collection.database.name}'."
|
@@ -107,6 +107,7 @@ module Mongoid
|
|
107
107
|
end
|
108
108
|
|
109
109
|
private
|
110
|
+
|
110
111
|
def logger
|
111
112
|
Mongoid.logger
|
112
113
|
end
|
data/lib/mongoid/threaded.rb
CHANGED
@@ -163,6 +163,30 @@ module Mongoid
|
|
163
163
|
validations_for(document.class).delete_one(document._id)
|
164
164
|
end
|
165
165
|
|
166
|
+
# Begin suppressing default scopes for given model on the current thread.
|
167
|
+
#
|
168
|
+
# @example Begin without default scope stack.
|
169
|
+
# Threaded.begin_without_default_scope(klass)
|
170
|
+
#
|
171
|
+
# @param [ Class ] klass The model to suppress default scoping on.
|
172
|
+
#
|
173
|
+
# @api private
|
174
|
+
def begin_without_default_scope(klass)
|
175
|
+
stack(:without_default_scope).push(klass)
|
176
|
+
end
|
177
|
+
|
178
|
+
# Exit suppressing default scopes for given model on the current thread.
|
179
|
+
#
|
180
|
+
# @example Exit without default scope stack.
|
181
|
+
# Threaded.exit_without_default_scope(klass)
|
182
|
+
#
|
183
|
+
# @param [ Class ] klass The model to unsuppress default scoping on.
|
184
|
+
#
|
185
|
+
# @api private
|
186
|
+
def exit_without_default_scope(klass)
|
187
|
+
stack(:without_default_scope).delete(klass)
|
188
|
+
end
|
189
|
+
|
166
190
|
# Get the global client override.
|
167
191
|
#
|
168
192
|
# @example Get the global client override.
|
@@ -247,6 +271,18 @@ module Mongoid
|
|
247
271
|
end
|
248
272
|
end
|
249
273
|
|
274
|
+
# Is the given klass' default scope suppressed on the current thread?
|
275
|
+
#
|
276
|
+
# @example Is the given klass' default scope suppressed?
|
277
|
+
# Threaded.without_default_scope?(klass)
|
278
|
+
#
|
279
|
+
# @param [ Class ] klass The model to check for default scope suppression.
|
280
|
+
#
|
281
|
+
# @api private
|
282
|
+
def without_default_scope?(klass)
|
283
|
+
stack(:without_default_scope).include?(klass)
|
284
|
+
end
|
285
|
+
|
250
286
|
# Is the document autosaved on the current thread?
|
251
287
|
#
|
252
288
|
# @example Is the document autosaved?
|
@@ -325,5 +361,43 @@ module Mongoid
|
|
325
361
|
def validations_for(klass)
|
326
362
|
validations[klass] ||= []
|
327
363
|
end
|
364
|
+
|
365
|
+
# Cache a session for this thread.
|
366
|
+
#
|
367
|
+
# @example Save a session for this thread.
|
368
|
+
# Threaded.set_session(session)
|
369
|
+
#
|
370
|
+
# @param [ Mongo::Session ] session The session to save.
|
371
|
+
#
|
372
|
+
# @since 6.4.0
|
373
|
+
def set_session(session)
|
374
|
+
Thread.current[:session] = session
|
375
|
+
end
|
376
|
+
|
377
|
+
# Get the cached session for this thread.
|
378
|
+
#
|
379
|
+
# @example Get the session for this thread.
|
380
|
+
# Threaded.get_session
|
381
|
+
#
|
382
|
+
# @return [ Mongo::Session, nil ] The session cached on this thread or nil.
|
383
|
+
#
|
384
|
+
# @since 6.4.0
|
385
|
+
def get_session
|
386
|
+
Thread.current[:session]
|
387
|
+
end
|
388
|
+
|
389
|
+
# Clear the cached session for this thread.
|
390
|
+
#
|
391
|
+
# @example Clear this thread's session.
|
392
|
+
# Threaded.clear_session
|
393
|
+
#
|
394
|
+
# @return [ nil ]
|
395
|
+
#
|
396
|
+
# @since 6.4.0
|
397
|
+
def clear_session
|
398
|
+
session = get_session
|
399
|
+
session.end_session if session
|
400
|
+
Thread.current[:session] = nil
|
401
|
+
end
|
328
402
|
end
|
329
403
|
end
|
data/lib/mongoid/version.rb
CHANGED
@@ -11,6 +11,10 @@ development:
|
|
11
11
|
hosts:
|
12
12
|
- localhost:27017
|
13
13
|
options:
|
14
|
+
# Note that all options listed below are Ruby driver client options (the mongo gem).
|
15
|
+
# Please refer to the driver documentation of the version of the mongo gem you are using
|
16
|
+
# for the most up-to-date list of options.
|
17
|
+
#
|
14
18
|
# Change the default write concern. (default = { w: 1 })
|
15
19
|
# write:
|
16
20
|
# w: 1
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
class DelegatingPatient
|
5
|
+
include Mongoid::Document
|
6
|
+
|
7
|
+
embeds_one :email
|
8
|
+
|
9
|
+
# Instance level delegation
|
10
|
+
delegate :address, to: :email
|
11
|
+
|
12
|
+
class << self
|
13
|
+
# Class level delegation
|
14
|
+
delegate :default_client, to: ::Mongoid
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
describe Mongoid::Document do
|
7
|
+
context 'when including class uses delegate' do
|
8
|
+
let(:patient) do
|
9
|
+
DelegatingPatient.new(
|
10
|
+
email: Email.new(address: 'test@example.com'),
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'works for instance level delegation' do
|
15
|
+
patient.address.should == 'test@example.com'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'works for class level delegation' do
|
19
|
+
DelegatingPatient.default_client.should be Mongoid.default_client
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,7 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
1
4
|
require "spec_helper"
|
2
5
|
|
3
6
|
describe Mongoid::Clients::Factory do
|
4
7
|
|
8
|
+
shared_examples_for 'includes seed address' do
|
9
|
+
let(:configured_address) do
|
10
|
+
address = SpecConfig.instance.addresses.first
|
11
|
+
unless address.include?(':')
|
12
|
+
address = "#{address}:27017"
|
13
|
+
end
|
14
|
+
address
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:expected_addresses) do
|
18
|
+
[
|
19
|
+
configured_address,
|
20
|
+
configured_address.sub(/\Alocalhost:/, '127.0.0.1:'),
|
21
|
+
configured_address.sub(/\A127\.0\.0\.1:/, 'localhost:'),
|
22
|
+
].uniq
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'includes seed address' do
|
26
|
+
ok = cluster_addresses.any? do |address|
|
27
|
+
expected_addresses.include?(address)
|
28
|
+
end
|
29
|
+
expect(ok).to be true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
5
33
|
describe ".create" do
|
6
34
|
|
7
35
|
context "when provided a name" do
|
@@ -12,8 +40,8 @@ describe Mongoid::Clients::Factory do
|
|
12
40
|
|
13
41
|
let(:config) do
|
14
42
|
{
|
15
|
-
default: { hosts:
|
16
|
-
secondary: { hosts:
|
43
|
+
default: { hosts: SpecConfig.instance.addresses, database: database_id },
|
44
|
+
secondary: { hosts: SpecConfig.instance.addresses, database: database_id }
|
17
45
|
}
|
18
46
|
end
|
19
47
|
|
@@ -37,10 +65,12 @@ describe Mongoid::Clients::Factory do
|
|
37
65
|
expect(client).to be_a(Mongo::Client)
|
38
66
|
end
|
39
67
|
|
40
|
-
|
41
|
-
|
68
|
+
let(:cluster_addresses) do
|
69
|
+
cluster.addresses.map(&:to_s)
|
42
70
|
end
|
43
71
|
|
72
|
+
it_behaves_like 'includes seed address'
|
73
|
+
|
44
74
|
it "sets the platform to Mongoid's platform constant" do
|
45
75
|
expect(client.options[:platform]).to eq(Mongoid::PLATFORM_DETAILS)
|
46
76
|
end
|
@@ -80,11 +110,11 @@ describe Mongoid::Clients::Factory do
|
|
80
110
|
end
|
81
111
|
|
82
112
|
it "sets the cluster's seed ports to 27017" do
|
83
|
-
expect(
|
113
|
+
expect(%w(127.0.0.1:27017 localhost:27017)).to include(cluster.addresses.first.to_s)
|
84
114
|
end
|
85
115
|
|
86
116
|
it "sets ips with no ports to 27017" do
|
87
|
-
expect(
|
117
|
+
expect(%w(127.0.0.1:27017 localhost:27017)).to include(cluster.addresses.first.to_s)
|
88
118
|
end
|
89
119
|
end
|
90
120
|
|
@@ -120,7 +150,7 @@ describe Mongoid::Clients::Factory do
|
|
120
150
|
end
|
121
151
|
|
122
152
|
it "sets the cluster's seeds" do
|
123
|
-
expect(
|
153
|
+
expect(%w(127.0.0.1:27017 localhost:27017)).to include(cluster.addresses.first.to_s)
|
124
154
|
end
|
125
155
|
|
126
156
|
it "sets the database" do
|
@@ -132,8 +162,8 @@ describe Mongoid::Clients::Factory do
|
|
132
162
|
|
133
163
|
let(:config) do
|
134
164
|
{
|
135
|
-
default: { hosts: [ "127.0.0.1:
|
136
|
-
secondary: { uri: "mongodb://127.0.0.1:
|
165
|
+
default: { hosts: [ "127.0.0.1:1234" ], database: database_id, server_selection_timeout: 1 },
|
166
|
+
secondary: { uri: "mongodb://127.0.0.1:1234,127.0.0.1:5678/mongoid_test?serverSelectionTimeoutMS=1000" }
|
137
167
|
}
|
138
168
|
end
|
139
169
|
|
@@ -162,7 +192,7 @@ describe Mongoid::Clients::Factory do
|
|
162
192
|
end
|
163
193
|
|
164
194
|
it "sets the cluster's seeds" do
|
165
|
-
expect(seeds).to eq([ "127.0.0.1:
|
195
|
+
expect(seeds).to eq([ "127.0.0.1:1234", "127.0.0.1:5678" ])
|
166
196
|
end
|
167
197
|
end
|
168
198
|
end
|
@@ -181,7 +211,7 @@ describe Mongoid::Clients::Factory do
|
|
181
211
|
context "when no name is provided" do
|
182
212
|
|
183
213
|
let(:config) do
|
184
|
-
{ default: { hosts:
|
214
|
+
{ default: { hosts: SpecConfig.instance.addresses, database: database_id }}
|
185
215
|
end
|
186
216
|
|
187
217
|
before do
|
@@ -200,17 +230,15 @@ describe Mongoid::Clients::Factory do
|
|
200
230
|
client.cluster
|
201
231
|
end
|
202
232
|
|
203
|
-
let(:
|
204
|
-
cluster.addresses.map
|
233
|
+
let(:cluster_addresses) do
|
234
|
+
cluster.addresses.map(&:to_s)
|
205
235
|
end
|
206
236
|
|
207
237
|
it "returns the default client" do
|
208
238
|
expect(client).to be_a(Mongo::Client)
|
209
239
|
end
|
210
240
|
|
211
|
-
|
212
|
-
expect(seeds).to eq([ "127.0.0.1:27017" ])
|
213
|
-
end
|
241
|
+
it_behaves_like 'includes seed address'
|
214
242
|
end
|
215
243
|
|
216
244
|
context "when nil is provided and no default config" do
|
@@ -230,7 +258,7 @@ describe Mongoid::Clients::Factory do
|
|
230
258
|
describe ".default" do
|
231
259
|
|
232
260
|
let(:config) do
|
233
|
-
{ default: { hosts:
|
261
|
+
{ default: { hosts: SpecConfig.instance.addresses, database: database_id }}
|
234
262
|
end
|
235
263
|
|
236
264
|
before do
|
@@ -249,17 +277,15 @@ describe Mongoid::Clients::Factory do
|
|
249
277
|
client.cluster
|
250
278
|
end
|
251
279
|
|
252
|
-
let(:
|
253
|
-
cluster.addresses.map
|
280
|
+
let(:cluster_addresses) do
|
281
|
+
cluster.addresses.map(&:to_s)
|
254
282
|
end
|
255
283
|
|
256
284
|
it "returns the default client" do
|
257
285
|
expect(client).to be_a(Mongo::Client)
|
258
286
|
end
|
259
287
|
|
260
|
-
|
261
|
-
expect(seeds).to eq([ "127.0.0.1:27017" ])
|
262
|
-
end
|
288
|
+
it_behaves_like 'includes seed address'
|
263
289
|
end
|
264
290
|
|
265
291
|
context "when options are provided with string keys" do
|
@@ -267,7 +293,7 @@ describe Mongoid::Clients::Factory do
|
|
267
293
|
let(:config) do
|
268
294
|
{
|
269
295
|
default: {
|
270
|
-
hosts:
|
296
|
+
hosts: SpecConfig.instance.addresses,
|
271
297
|
database: database_id,
|
272
298
|
options: {
|
273
299
|
"server_selection_timeout" => 10,
|
@@ -293,17 +319,15 @@ describe Mongoid::Clients::Factory do
|
|
293
319
|
client.cluster
|
294
320
|
end
|
295
321
|
|
296
|
-
let(:
|
297
|
-
cluster.addresses.map
|
322
|
+
let(:cluster_addresses) do
|
323
|
+
cluster.addresses.map(&:to_s)
|
298
324
|
end
|
299
325
|
|
300
326
|
it "returns the default client" do
|
301
327
|
expect(client).to be_a(Mongo::Client)
|
302
328
|
end
|
303
329
|
|
304
|
-
|
305
|
-
expect(seeds).to eq([ "127.0.0.1:27017" ])
|
306
|
-
end
|
330
|
+
it_behaves_like 'includes seed address'
|
307
331
|
|
308
332
|
it "sets the server selection timeout" do
|
309
333
|
expect(cluster.options[:server_selection_timeout]).to eq(10)
|