mongoid 6.0.3 → 6.1.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
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)