mongoid 6.0.3 → 6.1.0.rc0

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +3 -2
  4. data/lib/config/locales/en.yml +15 -0
  5. data/lib/mongoid.rb +5 -0
  6. data/lib/mongoid/clients.rb +10 -2
  7. data/lib/mongoid/clients/factory.rb +2 -0
  8. data/lib/mongoid/config.rb +1 -0
  9. data/lib/mongoid/contextual/map_reduce.rb +20 -115
  10. data/lib/mongoid/contextual/memory.rb +1 -0
  11. data/lib/mongoid/contextual/mongo.rb +16 -13
  12. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  13. data/lib/mongoid/criteria/queryable/optional.rb +14 -0
  14. data/lib/mongoid/errors.rb +1 -0
  15. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +20 -0
  16. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  17. data/lib/mongoid/extensions.rb +1 -0
  18. data/lib/mongoid/extensions/decimal128.rb +39 -0
  19. data/lib/mongoid/indexable/validators/options.rb +2 -1
  20. data/lib/mongoid/persistable/deletable.rb +3 -7
  21. data/lib/mongoid/query_cache.rb +2 -2
  22. data/lib/mongoid/relations/metadata.rb +3 -3
  23. data/lib/mongoid/relations/referenced/many.rb +2 -2
  24. data/lib/mongoid/version.rb +1 -1
  25. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -0
  26. data/spec/app/models/band.rb +1 -0
  27. data/spec/config/mongoid.yml +19 -0
  28. data/spec/mongoid/clients/factory_spec.rb +8 -0
  29. data/spec/mongoid/clients_spec.rb +69 -0
  30. data/spec/mongoid/config_spec.rb +34 -2
  31. data/spec/mongoid/contextual/atomic_spec.rb +342 -76
  32. data/spec/mongoid/contextual/map_reduce_spec.rb +102 -135
  33. data/spec/mongoid/contextual/memory_spec.rb +316 -56
  34. data/spec/mongoid/contextual/mongo_spec.rb +366 -4
  35. data/spec/mongoid/criteria/queryable/optional_spec.rb +13 -0
  36. data/spec/mongoid/criteria_spec.rb +19 -0
  37. data/spec/mongoid/extensions/boolean_spec.rb +14 -0
  38. data/spec/mongoid/extensions/decimal128_spec.rb +44 -0
  39. data/spec/mongoid/indexable_spec.rb +43 -0
  40. data/spec/mongoid/query_cache_spec.rb +34 -0
  41. data/spec/mongoid/relations/metadata_spec.rb +0 -1
  42. data/spec/mongoid/relations/referenced/many_spec.rb +11 -0
  43. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +11 -0
  44. data/spec/mongoid/scopable_spec.rb +12 -0
  45. data/spec/spec_helper.rb +9 -0
  46. metadata +17 -7
  47. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 33269ca75497a708d73b6f7964d3a21ba26e3f08
4
- data.tar.gz: a06dbbe583a3793aeafdc1fb3787de5d984ceb66
3
+ metadata.gz: cd1c5f3e10aa8f29d9a04da6580f7b2bd22b67e1
4
+ data.tar.gz: 0244eacd65adceb037276b870846e0a5fca9407a
5
5
  SHA512:
6
- metadata.gz: 6743d2621d3de8dab702c7cca8d7085616fb77988e397c75a8addfa17d0b968e0a7798cd0782e3cd32ddf7b49cec8190efa70aa5af7e292ad9387cf63dea39ae
7
- data.tar.gz: 162e448773b63c2687c4f00a8d673068e2805448b8c3f6542b32c68fbb6617c2f4fdd25b3fcc52ffebca3e31bccdbb9b6a38c67aafdf06e343355ffa636b3b11
6
+ metadata.gz: 28d80be687ea4b751298f72401eb18a45a3350c362cd78d83bd2a7fe6f51be41259dabec2ba856c752747b071dd4c18b41661325d7ba6f9e015a29557eb641f9
7
+ data.tar.gz: 22091327a5876754cba1a2cfaea2362e07abbf9e5613ac1a272637f06e379ca9d72878379ceb52e0bc2687baf5e007b27bb1569112c6545abc1e29682bc031ef
Binary file
data.tar.gz.sig CHANGED
@@ -1,2 +1,3 @@
1
- p����O-�\XZ����M�+����p����0vur�,9��NEZId����a��A������
2
- fTmʟ���.%�w;vYL`,���ښmp���^�L'V���R}�< �Y-5�ܓ-jb��I���gͩ�L�[l�!�09Ȏ{
1
+ V����J���R���Q���b#��YĐ�3Z=խ7��>�Zh3����� Wt���F63�@�$>�"(bh�5��n)SWj���� B()�_�
2
+ �����8XOGi7w���_[��݁�Ҟ��H��pļ\ D0��৔@�WU=������j.���
3
+ �3�������U%��h�:w2A���R����(٘0�PbK����:Q4( ���)Q����T�ݧ~�F��:�[�U��=@:�<̯�1�.�
@@ -76,6 +76,12 @@ en:
76
76
  resolution: "For access to the collection that the embedded document is
77
77
  in, use %{klass}#_root.collection, or do not attempt to persist an
78
78
  embedded document without a parent set."
79
+ in_memory_collation_not_supported:
80
+ message: "A collation option cannot be applied when querying documents in-memory."
81
+ summary: "The query being run against documents in memory has a collation option set.
82
+ A collation option is only supported if the query is executed on a MongoDB server
83
+ with version >= 3.4."
84
+ resolution: "Remove the collation option from the query."
79
85
  invalid_config_option:
80
86
  message: "Invalid configuration option: %{name}."
81
87
  summary: "A invalid configuration option was provided in your
@@ -134,9 +140,18 @@ en:
134
140
  \_\_min: 1\n
135
141
  \_\_max: 1\n
136
142
  \_\_bits: 26\n
143
+ \_\_key: 26\n
137
144
  \_\_bucket_size : 1\n
145
+ \_\_sphere_version : 1\n
146
+ \_\_text_version : 1\n
147
+ \_\_version : 1\n
138
148
  \_\_weights: { content: 1, title: 2 }\n
139
149
  \_\_expire_after_seconds: number_of_seconds\n
150
+ \_\_partial_filter_expression\n
151
+ \_\_storage_engine\n
152
+ \_\_language_override\n
153
+ \_\_default_language\n
154
+ \_\_collation\n
140
155
  Valid types are: 1, -1, '2d', '2dsphere', 'geoHaystack', 'text', 'hashed'\n\n
141
156
  Example:\n
142
157
  \_\_class Band\n
@@ -36,6 +36,11 @@ module Mongoid
36
36
  extend Loggable
37
37
  extend self
38
38
 
39
+ # A string added to the platform details of Ruby driver client handshake documents.
40
+ #
41
+ # @since 6.1.0
42
+ PLATFORM_DETAILS = "mongoid-#{VERSION}".freeze
43
+
39
44
  # The minimum MongoDB version supported.
40
45
  MONGODB_VERSION = "2.4.0"
41
46
 
@@ -33,7 +33,7 @@ module Mongoid
33
33
  #
34
34
  # @since 3.0.0
35
35
  def default
36
- clients[:default] ||= Clients::Factory.default
36
+ with_name(:default)
37
37
  end
38
38
 
39
39
  # Disconnect all active clients.
@@ -61,7 +61,11 @@ module Mongoid
61
61
  #
62
62
  # @since 3.0.0
63
63
  def with_name(name)
64
- clients[name.to_sym] ||= Clients::Factory.create(name)
64
+ name_as_symbol = name.to_sym
65
+ return clients[name_as_symbol] if clients[name_as_symbol]
66
+ CREATE_LOCK.synchronize do
67
+ clients[name_as_symbol] ||= Clients::Factory.create(name)
68
+ end
65
69
  end
66
70
 
67
71
  def set(name, client)
@@ -71,6 +75,10 @@ module Mongoid
71
75
  def clients
72
76
  @clients ||= {}
73
77
  end
78
+
79
+ private
80
+
81
+ CREATE_LOCK = Mutex.new
74
82
  end
75
83
  end
76
84
  end
@@ -71,6 +71,8 @@ module Mongoid
71
71
  def options(configuration)
72
72
  config = configuration.dup
73
73
  options = config.delete(:options) || {}
74
+ options[:platform] = PLATFORM_DETAILS
75
+ options[:app_name] = Mongoid::Config.app_name if Mongoid::Config.app_name
74
76
  options.reject{ |k, v| k == :hosts }.to_hash.symbolize_keys!
75
77
  end
76
78
  end
@@ -26,6 +26,7 @@ module Mongoid
26
26
  option :use_utc, default: false
27
27
  option :log_level, default: :info
28
28
  option :belongs_to_required_by_default, default: true
29
+ option :app_name, default: nil
29
30
 
30
31
  # Has Mongoid been configured? This is checking that at least a valid
31
32
  # client config exists.
@@ -32,12 +32,13 @@ module Mongoid
32
32
  #
33
33
  # @since 3.0.0
34
34
  def each
35
+ validate_out!
35
36
  if block_given?
36
- documents.each do |doc|
37
+ @map_reduce.each do |doc|
37
38
  yield doc
38
39
  end
39
40
  else
40
- to_enum
41
+ @map_reduce.to_enum
41
42
  end
42
43
  end
43
44
 
@@ -64,7 +65,7 @@ module Mongoid
64
65
  #
65
66
  # @since 3.0.0
66
67
  def finalize(function)
67
- command[:finalize] = function
68
+ @map_reduce = @map_reduce.finalize(function)
68
69
  self
69
70
  end
70
71
 
@@ -79,10 +80,9 @@ module Mongoid
79
80
  #
80
81
  # @since 3.0.0
81
82
  def initialize(collection, criteria, map, reduce)
82
- @collection, @criteria = collection, criteria
83
- command[:mapreduce] = collection.name.to_s
84
- command[:map], command[:reduce] = map, reduce
85
- apply_criteria_options
83
+ @collection = collection
84
+ @criteria = criteria
85
+ @map_reduce = @criteria.view.map_reduce(map, reduce)
86
86
  end
87
87
 
88
88
  # Get the number of documents that were input into the map/reduce.
@@ -106,7 +106,7 @@ module Mongoid
106
106
  #
107
107
  # @since 3.0.0
108
108
  def js_mode
109
- command[:jsMode] = true
109
+ @map_reduce = @map_reduce.js_mode(true)
110
110
  self
111
111
  end
112
112
 
@@ -134,7 +134,7 @@ module Mongoid
134
134
  normalized.update_values do |value|
135
135
  value.is_a?(::Symbol) ? value.to_s : value
136
136
  end
137
- command[:out] = normalized
137
+ @map_reduce = @map_reduce.out(normalized)
138
138
  self
139
139
  end
140
140
 
@@ -159,8 +159,12 @@ module Mongoid
159
159
  #
160
160
  # @since 3.0.0
161
161
  def raw
162
- results
162
+ validate_out!
163
+ cmd = command
164
+ opts = { read: cmd.delete(:read).options } if cmd[:read]
165
+ @map_reduce.database.command(cmd, opts || {}).first
163
166
  end
167
+ alias :results :raw
164
168
 
165
169
  # Execute the map/reduce, returning the raw output.
166
170
  # Useful when you don't care about map/reduce's ouptut.
@@ -196,7 +200,7 @@ module Mongoid
196
200
  #
197
201
  # @since 3.0.0
198
202
  def scope(object)
199
- command[:scope] = object
203
+ @map_reduce = @map_reduce.scope(object)
200
204
  self
201
205
  end
202
206
 
@@ -232,113 +236,14 @@ module Mongoid
232
236
  }
233
237
  end
234
238
 
235
- private
236
-
237
- # Apply criteria specific options - query, sort, limit.
238
- #
239
- # @api private
240
- #
241
- # @example Apply the criteria options
242
- # map_reduce.apply_criteria_options
243
- #
244
- # @return [ nil ] Nothing.
245
- #
246
- # @since 3.0.0
247
- def apply_criteria_options
248
- command[:query] = criteria.selector
249
- if sort = criteria.options[:sort]
250
- command[:sort] = sort
251
- end
252
- if limit = criteria.options[:limit]
253
- command[:limit] = limit
254
- end
239
+ def command
240
+ @map_reduce.send(:map_reduce_spec)[:selector]
255
241
  end
256
242
 
257
- # Get the result documents from the map/reduce. If the output was inline
258
- # then we grab them from the results key. If the output was a temp
259
- # collection then we need to execute a find on that collection.
260
- #
261
- # @api private
262
- #
263
- # @example Get the documents.
264
- # map_reduce.documents
265
- #
266
- # @return [ Array, Cursor ] The documents.
267
- #
268
- # @since 3.0.0
269
- def documents
270
- return results["results"] if results.has_key?("results")
271
- view = output_database[output_collection].find
272
- view.no_cursor_timeout if criteria.options[:timeout] == false
273
- view
274
- end
275
-
276
- # Get the database that the map/reduce results were stored in.
277
- #
278
- # @api private
279
- #
280
- # @example Get the output database.
281
- # map_reduce.output_database
282
- #
283
- # @return [ Mongo::Database ] The output database.
284
- #
285
- # @since 6.0.0
286
- def output_database
287
- if db = command[:out].fetch(:db, command[:out]['db'])
288
- client.with(database: db).database
289
- else
290
- client.database
291
- end
292
- end
293
-
294
- # Get the collection that the map/reduce results were stored in.
295
- #
296
- # @api private
297
- #
298
- # @example Get the output collection.
299
- # map_reduce.output_collection
300
- #
301
- # @return [ Symbol, String ] The output collection.
302
- #
303
- # @since 3.0.0
304
- def output_collection
305
- command[:out].values.first
306
- end
307
-
308
- # Execute the map/reduce command and get the results.
309
- #
310
- # @api private
311
- #
312
- # @example Get the results.
313
- # map_reduce.results
314
- #
315
- # @return [ Hash ] The results of the command.
316
- #
317
- # @since 3.0.0
318
- def results
319
- raise Errors::NoMapReduceOutput.new(command) unless command[:out]
320
- @results ||= __client__.command(command,__client__.options).first
321
- end
243
+ private
322
244
 
323
- # Get the client with the proper consistency.
324
- #
325
- # @api private
326
- #
327
- # @note We can use eventual if the output is set to inline.
328
- #
329
- # @example Get the client.
330
- # map_reduce.__client__
331
- #
332
- # @return [ Mongo::Client ] The client with consistency set.
333
- #
334
- # @since 3.0.15
335
- def __client__
336
- if command[:out][:inline] != 1
337
- # @todo: close
338
- client.with(read: { mode: :primary })
339
- else
340
- client
341
- end
245
+ def validate_out!
246
+ raise Errors::NoMapReduceOutput.new({}) unless @map_reduce.out
342
247
  end
343
248
  end
344
249
  end
@@ -373,6 +373,7 @@ module Mongoid
373
373
  #
374
374
  # @since 3.0.0
375
375
  def apply_options
376
+ raise Errors::InMemoryCollationNotSupported.new if criteria.options[:collation]
376
377
  skip(criteria.options[:skip]).limit(criteria.options[:limit])
377
378
  end
378
379
 
@@ -18,7 +18,19 @@ module Mongoid
18
18
  # Options constant.
19
19
  #
20
20
  # @since 5.0.0
21
- OPTIONS = [ :hint, :limit, :skip, :sort, :batch_size, :max_scan, :max_time_ms, :snapshot, :comment, :read ].freeze
21
+ OPTIONS = [ :hint,
22
+ :limit,
23
+ :skip,
24
+ :sort,
25
+ :batch_size,
26
+ :max_scan,
27
+ :max_time_ms,
28
+ :snapshot,
29
+ :comment,
30
+ :read,
31
+ :cursor_type,
32
+ :collation
33
+ ].freeze
22
34
 
23
35
  # @attribute [r] view The Mongo collection view.
24
36
  attr_reader :view
@@ -68,9 +80,7 @@ module Mongoid
68
80
  #
69
81
  # @since 3.0.0
70
82
  def delete
71
- self.count.tap do
72
- view.delete_many
73
- end
83
+ view.delete_many.deleted_count
74
84
  end
75
85
  alias :delete_all :delete
76
86
 
@@ -83,11 +93,10 @@ module Mongoid
83
93
  #
84
94
  # @since 3.0.0
85
95
  def destroy
86
- destroyed = self.count
87
- each do |doc|
96
+ each.inject(0) do |count, doc|
88
97
  doc.destroy
98
+ count += 1
89
99
  end
90
- destroyed
91
100
  end
92
101
  alias :destroy_all :destroy
93
102
 
@@ -568,12 +577,6 @@ module Mongoid
568
577
  if criteria.options[:timeout] == false
569
578
  @view = view.no_cursor_timeout
570
579
  end
571
- if criteria.options[:cursor_type]
572
- # @todo: update to use #cursor_type method on view when driver 2.3 is released.
573
- # See RUBY-1080
574
- @view = view.clone
575
- @view.options.merge!(cursor_type: criteria.options[:cursor_type])
576
- end
577
580
  end
578
581
 
579
582
  # Apply an option.
@@ -21,7 +21,7 @@ module Mongoid
21
21
  # @since 1.0.0
22
22
  def evolve(object)
23
23
  __evolve__(object) do |obj|
24
- obj.to_s =~ (/(true|t|yes|y|1|1.0)$/i) ? true : false
24
+ obj.to_s =~ (/\A(true|t|yes|y|on|1|1.0)\z/i) ? true : false
25
25
  end
26
26
  end
27
27
  end
@@ -324,6 +324,20 @@ module Mongoid
324
324
  clone.tap { |query| query.options.store(:cursor_type, type) }
325
325
  end
326
326
 
327
+ # Set the collation.
328
+ #
329
+ # @example Set the collation.
330
+ # optional.collation(locale: 'fr', strength: 2)
331
+ #
332
+ # @param [ Hash ] collation_doc The document describing the collation to use.
333
+ #
334
+ # @return [ Optional ] The cloned optional.
335
+ #
336
+ # @since 6.1.0
337
+ def collation(collation_doc)
338
+ clone.tap { |query| query.options.store(:collation, collation_doc) }
339
+ end
340
+
327
341
  private
328
342
 
329
343
  # Add a single sort option.
@@ -5,6 +5,7 @@ require "mongoid/errors/callback"
5
5
  require "mongoid/errors/document_not_destroyed"
6
6
  require "mongoid/errors/document_not_found"
7
7
  require "mongoid/errors/eager_load"
8
+ require "mongoid/errors/in_memory_collation_not_supported"
8
9
  require "mongoid/errors/invalid_collection"
9
10
  require "mongoid/errors/invalid_config_option"
10
11
  require "mongoid/errors/invalid_field"
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Errors
4
+
5
+ # This error is raised when attempting to do a query with a
6
+ # collation on documents in memory.
7
+ class InMemoryCollationNotSupported < MongoidError
8
+
9
+ # Create the new error.
10
+ #
11
+ # @example Create the new unsupported collation error.
12
+ # InMemoryCollationNotSupported.new
13
+ #
14
+ # @since 6.1.0
15
+ def initialize
16
+ super(compose_message("in_memory_collation_not_supported"))
17
+ end
18
+ end
19
+ end
20
+ end
@@ -19,7 +19,7 @@ module Mongoid
19
19
  # @return [ String ] The composed message.
20
20
  #
21
21
  # @since 3.0.0
22
- def compose_message(key, attributes)
22
+ def compose_message(key, attributes = {})
23
23
  @problem = translate_problem(key, attributes)
24
24
  @summary = translate_summary(key, attributes)
25
25
  @resolution = translate_resolution(key, attributes)