mongoid 5.1.5 → 5.2.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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/config/locales/en.yml +15 -0
- data/lib/mongoid.rb +5 -0
- data/lib/mongoid/attributes/dynamic.rb +3 -3
- data/lib/mongoid/clients/factory.rb +2 -0
- data/lib/mongoid/config.rb +1 -0
- data/lib/mongoid/config/options.rb +1 -1
- data/lib/mongoid/contextual/aggregable/mongo.rb +0 -1
- data/lib/mongoid/contextual/map_reduce.rb +20 -97
- data/lib/mongoid/contextual/memory.rb +1 -0
- data/lib/mongoid/contextual/mongo.rb +20 -15
- data/lib/mongoid/criteria.rb +2 -0
- data/lib/mongoid/document.rb +1 -0
- data/lib/mongoid/errors.rb +1 -0
- data/lib/mongoid/errors/in_memory_collation_not_supported.rb +20 -0
- data/lib/mongoid/errors/mongoid_error.rb +1 -1
- data/lib/mongoid/extensions.rb +1 -0
- data/lib/mongoid/extensions/decimal128.rb +39 -0
- data/lib/mongoid/fields/localized.rb +8 -3
- data/lib/mongoid/indexable/validators/options.rb +2 -1
- data/lib/mongoid/persistable/deletable.rb +3 -7
- data/lib/mongoid/persistable/settable.rb +3 -1
- data/lib/mongoid/query_cache.rb +24 -2
- data/lib/mongoid/relations/accessors.rb +1 -1
- data/lib/mongoid/relations/builders.rb +2 -2
- data/lib/mongoid/relations/eager.rb +2 -2
- data/lib/mongoid/relations/reflections.rb +5 -3
- data/lib/mongoid/relations/touchable.rb +1 -1
- data/lib/mongoid/scopable.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +6 -2
- data/spec/app/models/band.rb +1 -0
- data/spec/config/mongoid.yml +5 -0
- data/spec/mongoid/clients/factory_spec.rb +8 -0
- data/spec/mongoid/clients_spec.rb +78 -1
- data/spec/mongoid/config_spec.rb +31 -0
- data/spec/mongoid/contextual/atomic_spec.rb +342 -76
- data/spec/mongoid/contextual/map_reduce_spec.rb +111 -119
- data/spec/mongoid/contextual/memory_spec.rb +316 -56
- data/spec/mongoid/contextual/mongo_spec.rb +391 -11
- data/spec/mongoid/criteria_spec.rb +21 -2
- data/spec/mongoid/extensions/decimal128_spec.rb +44 -0
- data/spec/mongoid/extensions/time_spec.rb +2 -2
- data/spec/mongoid/fields/localized_spec.rb +91 -0
- data/spec/mongoid/indexable_spec.rb +44 -0
- data/spec/mongoid/persistable/settable_spec.rb +44 -0
- data/spec/mongoid/query_cache_spec.rb +86 -0
- data/spec/mongoid/relations/cyclic_spec.rb +22 -0
- data/spec/mongoid/relations/referenced/many_spec.rb +11 -0
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +11 -0
- data/spec/mongoid/relations/reflections_spec.rb +9 -9
- data/spec/mongoid/scopable_spec.rb +12 -0
- data/spec/spec_helper.rb +9 -0
- metadata +26 -16
- metadata.gz.sig +0 -0
data/lib/mongoid/extensions.rb
CHANGED
@@ -30,6 +30,7 @@ require "mongoid/extensions/big_decimal"
|
|
30
30
|
require "mongoid/extensions/boolean"
|
31
31
|
require "mongoid/extensions/date"
|
32
32
|
require "mongoid/extensions/date_time"
|
33
|
+
require "mongoid/extensions/decimal128"
|
33
34
|
require "mongoid/extensions/false_class"
|
34
35
|
require "mongoid/extensions/float"
|
35
36
|
require "mongoid/extensions/hash"
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid
|
3
|
+
module Extensions
|
4
|
+
module Decimal128
|
5
|
+
|
6
|
+
# Evolve the decimal128.
|
7
|
+
#
|
8
|
+
# @example Evolve the decimal128.
|
9
|
+
# decimal128.__evolve_decimal128__
|
10
|
+
#
|
11
|
+
# @return [ BSON::Decimal128 ] self.
|
12
|
+
#
|
13
|
+
# @since 5.2.0
|
14
|
+
def __evolve_decimal128__
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
|
20
|
+
# Evolve the object into a mongo-friendly value to query with.
|
21
|
+
#
|
22
|
+
# @example Evolve the object.
|
23
|
+
# Decimal128.evolve(dec)
|
24
|
+
#
|
25
|
+
# @param [ Object ] object The object to evolve.
|
26
|
+
#
|
27
|
+
# @return [ BSON::Decimal128 ] The decimal128.
|
28
|
+
#
|
29
|
+
# @since 5.2.0
|
30
|
+
def evolve(object)
|
31
|
+
object.__evolve_decimal128__
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
BSON::Decimal128.__send__(:include, Mongoid::Extensions::Decimal128)
|
39
|
+
BSON::Decimal128.extend(Mongoid::Extensions::Decimal128::ClassMethods)
|
@@ -77,9 +77,14 @@ module Mongoid
|
|
77
77
|
# @since 3.0.0
|
78
78
|
def lookup(object)
|
79
79
|
locale = ::I18n.locale
|
80
|
-
|
81
|
-
|
82
|
-
|
80
|
+
|
81
|
+
value = if object.key?(locale.to_s)
|
82
|
+
object[locale.to_s]
|
83
|
+
elsif object.key?(locale)
|
84
|
+
object[locale]
|
85
|
+
end
|
86
|
+
return value unless value.nil?
|
87
|
+
if fallbacks? && ::I18n.respond_to?(:fallbacks)
|
83
88
|
object[::I18n.fallbacks[locale].map(&:to_s).find{ |loc| object.has_key?(loc) }]
|
84
89
|
end
|
85
90
|
end
|
@@ -135,13 +135,9 @@ module Mongoid
|
|
135
135
|
# @return [ Integer ] The number of documents deleted.
|
136
136
|
#
|
137
137
|
# @since 1.0.0
|
138
|
-
def delete_all(conditions =
|
139
|
-
selector = conditions
|
140
|
-
|
141
|
-
coll = collection
|
142
|
-
deleted = coll.find(selector).count
|
143
|
-
coll.find(selector).delete_many
|
144
|
-
deleted
|
138
|
+
def delete_all(conditions = {})
|
139
|
+
selector = hereditary? ? conditions.merge(_type: name) : conditions
|
140
|
+
collection.find(selector).delete_many.deleted_count
|
145
141
|
end
|
146
142
|
end
|
147
143
|
end
|
@@ -27,7 +27,9 @@ module Mongoid
|
|
27
27
|
field = field_and_value_hash.keys.first.to_s
|
28
28
|
|
29
29
|
if fields[field] && fields[field].type == Hash && attributes.key?(field)
|
30
|
-
|
30
|
+
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
|
31
|
+
value = attributes[field].merge(field_and_value_hash[field], &merger)
|
32
|
+
process_attribute(field.to_s, value)
|
31
33
|
else
|
32
34
|
process_attribute(field.to_s, field_and_value_hash[field])
|
33
35
|
end
|
data/lib/mongoid/query_cache.rb
CHANGED
@@ -70,6 +70,20 @@ module Mongoid
|
|
70
70
|
ensure
|
71
71
|
QueryCache.enabled = enabled
|
72
72
|
end
|
73
|
+
|
74
|
+
# Execute the block with the query cache disabled.
|
75
|
+
#
|
76
|
+
# @example Execute without the cache.
|
77
|
+
# QueryCache.uncached { collection.find }
|
78
|
+
#
|
79
|
+
# @return [ Object ] The result of the block.
|
80
|
+
def uncached
|
81
|
+
enabled = QueryCache.enabled?
|
82
|
+
QueryCache.enabled = false
|
83
|
+
yield
|
84
|
+
ensure
|
85
|
+
QueryCache.enabled = enabled
|
86
|
+
end
|
73
87
|
end
|
74
88
|
|
75
89
|
# The middleware to be added to a rack application in order to activate the
|
@@ -222,7 +236,7 @@ module Mongoid
|
|
222
236
|
|
223
237
|
def cached_cursor
|
224
238
|
if limit
|
225
|
-
key = [ collection.namespace, selector, nil, skip, projection ]
|
239
|
+
key = [ collection.namespace, selector, nil, skip, sort, projection, collation ]
|
226
240
|
cursor = QueryCache.cache_table[key]
|
227
241
|
if cursor
|
228
242
|
limited_docs = cursor.to_a[0...limit.abs]
|
@@ -233,7 +247,7 @@ module Mongoid
|
|
233
247
|
end
|
234
248
|
|
235
249
|
def cache_key
|
236
|
-
[ collection.namespace, selector, limit, skip, projection ]
|
250
|
+
[ collection.namespace, selector, limit, skip, sort, projection, collation ]
|
237
251
|
end
|
238
252
|
|
239
253
|
def system_collection?
|
@@ -252,8 +266,16 @@ module Mongoid
|
|
252
266
|
alias_query_cache_clear :insert_one, :insert_many
|
253
267
|
end
|
254
268
|
end
|
269
|
+
|
270
|
+
# Bypass the query cache when reloading a document.
|
271
|
+
module Document
|
272
|
+
def reload
|
273
|
+
QueryCache.uncached { super }
|
274
|
+
end
|
275
|
+
end
|
255
276
|
end
|
256
277
|
end
|
257
278
|
|
258
279
|
Mongo::Collection.__send__(:include, Mongoid::QueryCache::Collection)
|
259
280
|
Mongo::Collection::View.__send__(:include, Mongoid::QueryCache::View)
|
281
|
+
Mongoid::Document.__send__(:include, Mongoid::QueryCache::Document)
|
@@ -64,7 +64,7 @@ module Mongoid
|
|
64
64
|
# @since 2.0.0.rc.1
|
65
65
|
def builder(name, metadata)
|
66
66
|
re_define_method("build_#{name}") do |*args|
|
67
|
-
attributes,
|
67
|
+
attributes, _options = parse_args(*args)
|
68
68
|
document = Factory.build(metadata.klass, attributes)
|
69
69
|
_building do
|
70
70
|
child = send("#{name}=", document)
|
@@ -89,7 +89,7 @@ module Mongoid
|
|
89
89
|
# @since 2.0.0.rc.1
|
90
90
|
def creator(name, metadata)
|
91
91
|
re_define_method("create_#{name}") do |*args|
|
92
|
-
attributes,
|
92
|
+
attributes, _options = parse_args(*args)
|
93
93
|
document = Factory.build(metadata.klass, attributes)
|
94
94
|
doc = _assigning do
|
95
95
|
send("#{name}=", document)
|
@@ -24,7 +24,7 @@ module Mongoid
|
|
24
24
|
# @example Find multiple relation metadata by macro.
|
25
25
|
# person.reflect_on_all_associations(:embeds_many)
|
26
26
|
#
|
27
|
-
# @param [ Array<
|
27
|
+
# @param [ Array<Symbol> ] *macros The relation macros.
|
28
28
|
#
|
29
29
|
# @return [ Array<Metadata> ] The matching relation metadata.
|
30
30
|
def reflect_on_all_associations(*macros)
|
@@ -50,11 +50,13 @@ module Mongoid
|
|
50
50
|
# @example Find multiple relation metadata by macro.
|
51
51
|
# Person.reflect_on_all_associations(:embeds_many)
|
52
52
|
#
|
53
|
-
# @param [ Array<
|
53
|
+
# @param [ Array<Symbol> ] *macros The relation macros.
|
54
54
|
#
|
55
55
|
# @return [ Array<Metadata> ] The matching relation metadata.
|
56
56
|
def reflect_on_all_associations(*macros)
|
57
|
-
relations.values
|
57
|
+
association_reflections = relations.values
|
58
|
+
association_reflections.select! { |reflection| macros.include?(reflection.macro) } unless macros.empty?
|
59
|
+
association_reflections
|
58
60
|
end
|
59
61
|
end
|
60
62
|
end
|
@@ -78,7 +78,7 @@ module Mongoid
|
|
78
78
|
# @return [ Symbol ] The method name.
|
79
79
|
def define_relation_touch_method(name)
|
80
80
|
method_name = "touch_#{name}_after_create_or_destroy"
|
81
|
-
class_eval <<-TOUCH
|
81
|
+
class_eval <<-TOUCH, __FILE__, __LINE__ + 1
|
82
82
|
def #{method_name}
|
83
83
|
without_autobuild do
|
84
84
|
relation = __send__(:#{name})
|
data/lib/mongoid/scopable.rb
CHANGED
@@ -117,7 +117,7 @@ module Mongoid
|
|
117
117
|
# @since 3.0.0
|
118
118
|
def queryable
|
119
119
|
crit = Threaded.current_scope(self) || Criteria.new(self)
|
120
|
-
crit.embedded = true if crit.klass.embedded?
|
120
|
+
crit.embedded = true if (crit.klass.embedded? && !crit.klass.cyclic?)
|
121
121
|
crit
|
122
122
|
end
|
123
123
|
|
data/lib/mongoid/version.rb
CHANGED
@@ -50,8 +50,8 @@ development:
|
|
50
50
|
# via ismaster commands. (default: 10)
|
51
51
|
# heartbeat_frequency: 10
|
52
52
|
|
53
|
-
# The time in seconds for selecting servers for a near read preference. (default:
|
54
|
-
# local_threshold:
|
53
|
+
# The time in seconds for selecting servers for a near read preference. (default: 0.015)
|
54
|
+
# local_threshold: 0.015
|
55
55
|
|
56
56
|
# The timeout in seconds for selecting a server for an operation. (default: 30)
|
57
57
|
# server_selection_timeout: 30
|
@@ -130,6 +130,10 @@ development:
|
|
130
130
|
# environment. The Mongoid logger will be set to the Rails logger
|
131
131
|
# otherwise.(default: :info)
|
132
132
|
# log_level: :info
|
133
|
+
|
134
|
+
# Application name that is printed to the mongodb logs upon establishing a
|
135
|
+
# connection in server versions >= 3.4. Note that the name cannot exceed 128 bytes.
|
136
|
+
# app_name: MyApplicationName
|
133
137
|
test:
|
134
138
|
clients:
|
135
139
|
default:
|
data/spec/app/models/band.rb
CHANGED
@@ -13,6 +13,7 @@ class Band
|
|
13
13
|
field :upserted, type: Mongoid::Boolean, default: false
|
14
14
|
field :created, type: DateTime
|
15
15
|
field :sales, type: BigDecimal
|
16
|
+
field :decimal, type: BSON::Decimal128
|
16
17
|
field :y, as: :years, type: Integer
|
17
18
|
field :founded, type: Date
|
18
19
|
field :deleted, type: Boolean
|
data/spec/config/mongoid.yml
CHANGED
@@ -13,6 +13,10 @@ test:
|
|
13
13
|
tag_sets:
|
14
14
|
- use: web
|
15
15
|
max_pool_size: 1
|
16
|
+
reports:
|
17
|
+
database: reports
|
18
|
+
hosts:
|
19
|
+
- <%=ENV["MONGOID_SPEC_HOST"]%>:<%=ENV["MONGOID_SPEC_PORT"]%>
|
16
20
|
options:
|
17
21
|
include_root_in_json: false
|
18
22
|
include_type_for_serialization: false
|
@@ -22,3 +26,4 @@ test:
|
|
22
26
|
use_activesupport_time_zone: true
|
23
27
|
use_utc: false
|
24
28
|
log_level: :warn
|
29
|
+
app_name: 'testing'
|
@@ -36,6 +36,10 @@ describe Mongoid::Clients::Factory do
|
|
36
36
|
it "sets the cluster's seeds" do
|
37
37
|
expect(cluster.addresses.first.to_s).to eq("127.0.0.1:27017")
|
38
38
|
end
|
39
|
+
|
40
|
+
it "sets the platform to Mongoid's platform constant" do
|
41
|
+
expect(client.options[:platform]).to eq(Mongoid::PLATFORM_DETAILS)
|
42
|
+
end
|
39
43
|
end
|
40
44
|
|
41
45
|
context "when the configuration has no ports" do
|
@@ -280,5 +284,9 @@ describe Mongoid::Clients::Factory do
|
|
280
284
|
it "sets the write concern" do
|
281
285
|
expect(client.write_concern).to be_a(Mongo::WriteConcern::Acknowledged)
|
282
286
|
end
|
287
|
+
|
288
|
+
it "sets the platform to Mongoid's platform constant" do
|
289
|
+
expect(client.options[:platform]).to eq(Mongoid::PLATFORM_DETAILS)
|
290
|
+
end
|
283
291
|
end
|
284
292
|
end
|
@@ -408,6 +408,14 @@ describe Mongoid::Clients do
|
|
408
408
|
it "returns the default client" do
|
409
409
|
expect(mongo_client.options[:database].to_s).to eq(database_id)
|
410
410
|
end
|
411
|
+
|
412
|
+
it "sets the platform to Mongoid's platform constant" do
|
413
|
+
expect(mongo_client.options[:platform]).to eq(Mongoid::PLATFORM_DETAILS)
|
414
|
+
end
|
415
|
+
|
416
|
+
it "sets the app_name to the config value" do
|
417
|
+
expect(mongo_client.options[:app_name]).to eq('testing')
|
418
|
+
end
|
411
419
|
end
|
412
420
|
|
413
421
|
context "when no client exists with the key" do
|
@@ -416,6 +424,10 @@ describe Mongoid::Clients do
|
|
416
424
|
Band.store_in(client: :nonexistent)
|
417
425
|
end
|
418
426
|
|
427
|
+
after do
|
428
|
+
Band.reset_storage_options!
|
429
|
+
end
|
430
|
+
|
419
431
|
let(:band) do
|
420
432
|
Band.new
|
421
433
|
end
|
@@ -426,6 +438,63 @@ describe Mongoid::Clients do
|
|
426
438
|
}.to raise_error(Mongoid::Errors::NoClientConfig)
|
427
439
|
end
|
428
440
|
end
|
441
|
+
|
442
|
+
context "when getting a client by name", if: testing_locally? do
|
443
|
+
|
444
|
+
let(:file) do
|
445
|
+
File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
|
446
|
+
end
|
447
|
+
|
448
|
+
before do
|
449
|
+
described_class.clear
|
450
|
+
Mongoid.load!(file, :test)
|
451
|
+
Band.store_in(client: :reports)
|
452
|
+
end
|
453
|
+
|
454
|
+
after do
|
455
|
+
mongo_client.close
|
456
|
+
Mongoid::Config.reset
|
457
|
+
Band.reset_storage_options!
|
458
|
+
end
|
459
|
+
|
460
|
+
let!(:band) do
|
461
|
+
Band.store_in(client: :reports)
|
462
|
+
end
|
463
|
+
|
464
|
+
let!(:mongo_client) do
|
465
|
+
Band.new.mongo_client
|
466
|
+
end
|
467
|
+
|
468
|
+
it "uses the reports client" do
|
469
|
+
expect(mongo_client.options[:database].to_s).to eq('reports')
|
470
|
+
end
|
471
|
+
|
472
|
+
it "sets the platform to Mongoid's platform constant" do
|
473
|
+
expect(mongo_client.options[:platform]).to eq(Mongoid::PLATFORM_DETAILS)
|
474
|
+
end
|
475
|
+
|
476
|
+
it "sets the app_name to the config value" do
|
477
|
+
expect(mongo_client.options[:app_name]).to eq('testing')
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
context 'when the app_name is not set in the config' do
|
482
|
+
|
483
|
+
before do
|
484
|
+
Mongoid::Config.reset
|
485
|
+
Mongoid.configure do |config|
|
486
|
+
config.load_configuration(CONFIG)
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
490
|
+
let(:mongo_client) do
|
491
|
+
Band.new.mongo_client
|
492
|
+
end
|
493
|
+
|
494
|
+
it 'does not set the Mongoid.app_name option' do
|
495
|
+
expect(mongo_client.options.has_key?(:app_name)).to be(false)
|
496
|
+
end
|
497
|
+
end
|
429
498
|
end
|
430
499
|
|
431
500
|
describe ".mongo_client", if: non_legacy_server? do
|
@@ -457,13 +526,21 @@ describe Mongoid::Clients do
|
|
457
526
|
Mongoid.clients[:default][:database] = database_id
|
458
527
|
end
|
459
528
|
|
460
|
-
let
|
529
|
+
let(:mongo_client) do
|
461
530
|
Band.mongo_client
|
462
531
|
end
|
463
532
|
|
464
533
|
it "returns the default client" do
|
465
534
|
expect(mongo_client.options[:database].to_s).to eq(database_id)
|
466
535
|
end
|
536
|
+
|
537
|
+
it "sets the platform to Mongoid's platform constant" do
|
538
|
+
expect(mongo_client.options[:platform]).to eq(Mongoid::PLATFORM_DETAILS)
|
539
|
+
end
|
540
|
+
|
541
|
+
it "sets the app_name to the config value" do
|
542
|
+
expect(mongo_client.options[:app_name]).to eq('testing')
|
543
|
+
end
|
467
544
|
end
|
468
545
|
|
469
546
|
context "when no client exists with the key" do
|
data/spec/mongoid/config_spec.rb
CHANGED
@@ -82,6 +82,37 @@ describe Mongoid::Config do
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
+
context 'when the app_name is set in the config' do
|
86
|
+
|
87
|
+
let(:conf) do
|
88
|
+
CONFIG.merge(options: {app_name: 'admin-reporting'})
|
89
|
+
end
|
90
|
+
|
91
|
+
before do
|
92
|
+
Mongoid.configure do |config|
|
93
|
+
config.load_configuration(conf)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'sets the Mongoid.app_name to the provided value' do
|
98
|
+
expect(Mongoid.app_name).to eq('admin-reporting')
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when the app_name is not set in the config' do
|
103
|
+
|
104
|
+
before do
|
105
|
+
Mongoid::Config.reset
|
106
|
+
Mongoid.configure do |config|
|
107
|
+
config.load_configuration(CONFIG)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'does not set the Mongoid.app_name option' do
|
112
|
+
expect(Mongoid.app_name).to be_nil
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
85
116
|
describe "#load!" do
|
86
117
|
|
87
118
|
before(:all) do
|