mongoid 7.1.0.rc0 → 7.1.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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE +1 -1
  5. data/README.md +4 -4
  6. data/lib/mongoid.rb +3 -2
  7. data/lib/mongoid/association/many.rb +3 -2
  8. data/lib/mongoid/association/proxy.rb +5 -3
  9. data/lib/mongoid/association/referenced/has_many/enumerable.rb +2 -22
  10. data/lib/mongoid/association/referenced/has_many/proxy.rb +3 -2
  11. data/lib/mongoid/attributes.rb +28 -20
  12. data/lib/mongoid/config.rb +3 -3
  13. data/lib/mongoid/config/options.rb +5 -2
  14. data/lib/mongoid/contextual.rb +5 -4
  15. data/lib/mongoid/contextual/geo_near.rb +3 -2
  16. data/lib/mongoid/contextual/map_reduce.rb +3 -2
  17. data/lib/mongoid/contextual/mongo.rb +2 -1
  18. data/lib/mongoid/fields/standard.rb +2 -1
  19. data/lib/mongoid/findable.rb +5 -4
  20. data/lib/mongoid/interceptable.rb +5 -1
  21. data/lib/mongoid/railties/database.rake +7 -0
  22. data/lib/mongoid/serializable.rb +3 -1
  23. data/lib/mongoid/shardable.rb +56 -4
  24. data/lib/mongoid/tasks/database.rake +10 -5
  25. data/lib/mongoid/tasks/database.rb +48 -0
  26. data/lib/mongoid/timestamps/timeless.rb +3 -1
  27. data/lib/mongoid/version.rb +1 -1
  28. data/spec/integration/shardable_spec.rb +133 -0
  29. data/spec/lite_spec_helper.rb +3 -0
  30. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +41 -68
  31. data/spec/mongoid/attributes_spec.rb +19 -7
  32. data/spec/mongoid/changeable_spec.rb +23 -0
  33. data/spec/mongoid/document_fields_spec.rb +29 -0
  34. data/spec/mongoid/interceptable_spec.rb +62 -0
  35. data/spec/mongoid/interceptable_spec_models.rb +76 -0
  36. data/spec/mongoid/shardable_models.rb +61 -0
  37. data/spec/mongoid/shardable_spec.rb +69 -16
  38. data/spec/support/lite_constraints.rb +22 -0
  39. metadata +20 -12
  40. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5be07e768fab481565fe3b29a550dffa07427780a9cc6ed55cdab15621464223
4
- data.tar.gz: f89e567cfae14b99e6b4864e0ac36f7a88b7c9aa110024fd4970189be82dec5d
3
+ metadata.gz: 8352346c7b47e2323d4afee8968a5581b091735a11d3aacaf9a1c73197d511db
4
+ data.tar.gz: 4780a1d8ec316330301e933a145957e48f4927c9fbcbe582404f062179280947
5
5
  SHA512:
6
- metadata.gz: acaef29b0e2a8f2297a9fe64e2422dbb741d068819596da631813cae5ea9ea838db090cc6fcd46fdf7f09c5d9983bdc9446f846903662fe6939fc0e200993581
7
- data.tar.gz: 9fdb5ce28104e6b2cf06ea6f290486c14448181e453522530cb956b43d3dc4699564dd7a618b99ac4d057a6615115012322cba69d47d37559fb0dbfa01c1305f
6
+ metadata.gz: 870e9d5aff9bd06217cea69dd7b86b15ea9ec89464a8e6f579e24e58789a1e5612256026927e6cdd0e17cb39340cf4ef7758bc75fc1b5176939f8b11968bd76c
7
+ data.tar.gz: fc095139739ed83771b35d9f2c91b2a0e33bb99125df7622fe0f8f24bf971c6d0cabcd5ac507d4bb72e8a178bc988661197258f20f0193b7e72c8d7a219d2459
Binary file
data.tar.gz.sig CHANGED
Binary file
data/LICENSE CHANGED
@@ -1,5 +1,5 @@
1
1
  Copyright (c) 2009-2016 Durran Jordan
2
- Copyright (c) 2015-2019 MongoDB, Inc.
2
+ Copyright (c) 2015-2020 MongoDB, Inc.
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining
5
5
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -17,9 +17,9 @@ Compatibility
17
17
 
18
18
  Mongoid supports and is tested against:
19
19
 
20
- - MRI 2.2-2.6
21
- - JRuby 9.1-9.2
22
- - MongoDB server 2.6-4.0
20
+ - MRI 2.3-2.7
21
+ - JRuby 9.2
22
+ - MongoDB server 2.6-4.4
23
23
 
24
24
  Issues
25
25
  ------
@@ -38,7 +38,7 @@ License
38
38
  -------
39
39
 
40
40
  Copyright (c) 2009-2016 Durran Jordan
41
- Copyright (c) 2015-2019 MongoDB, Inc.
41
+ Copyright (c) 2015-2020 MongoDB, Inc.
42
42
 
43
43
  Permission is hereby granted, free of charge, to any person obtaining
44
44
  a copy of this software and associated documentation files (the
@@ -3,7 +3,7 @@
3
3
 
4
4
  require "support/ruby_version"
5
5
 
6
- require "delegate"
6
+ require "forwardable"
7
7
  require "time"
8
8
  require "set"
9
9
 
@@ -36,6 +36,7 @@ end
36
36
  I18n.load_path << File.join(File.dirname(__FILE__), "config", "locales", "en.yml")
37
37
 
38
38
  module Mongoid
39
+ extend Forwardable
39
40
  extend Loggable
40
41
  extend self
41
42
 
@@ -109,5 +110,5 @@ module Mongoid
109
110
  # Mongoid.database = Mongo::Connection.new.db("test")
110
111
  #
111
112
  # @since 1.0.0
112
- delegate(*(Config.public_instance_methods(false) - [ :logger=, :logger ] << { to: Config }))
113
+ def_delegators Config, *(Config.public_instance_methods(false) - [ :logger=, :logger ])
113
114
  end
@@ -7,10 +7,11 @@ module Mongoid
7
7
  # This is the superclass for all many to one and many to many association
8
8
  # proxies.
9
9
  class Many < Association::Proxy
10
+ extend Forwardable
10
11
  include ::Enumerable
11
12
 
12
- delegate :avg, :max, :min, :sum, to: :criteria
13
- delegate :length, :size, to: :_target
13
+ def_delegators :criteria, :avg, :max, :min, :sum
14
+ def_delegators :_target, :length, :size
14
15
 
15
16
  # Is the association empty?
16
17
  #
@@ -9,6 +9,8 @@ module Mongoid
9
9
  # This class is the superclass for all association proxy objects, and contains
10
10
  # common behavior for all of them.
11
11
  class Proxy
12
+ extend Forwardable
13
+
12
14
  alias :extend_proxy :extend
13
15
 
14
16
  # We undefine most methods to get them sent through to the target.
@@ -36,9 +38,9 @@ module Mongoid
36
38
  attr_accessor :_target
37
39
 
38
40
  # Backwards compatibility with Mongoid beta releases.
39
- delegate :foreign_key, :inverse_foreign_key, to: :_association
40
- delegate :bind_one, :unbind_one, to: :binding
41
- delegate :collection_name, to: :_base
41
+ def_delegators :_association, :foreign_key, :inverse_foreign_key
42
+ def_delegators :binding, :bind_one, :unbind_one
43
+ def_delegator :_base, :collection_name
42
44
 
43
45
  # Convenience for setting the target and the association metadata properties since
44
46
  # all proxies will need to do this.
@@ -11,6 +11,7 @@ module Mongoid
11
11
  # target that can be a criteria or array of _loaded documents. This
12
12
  # handles both cases or a combination of the two.
13
13
  class Enumerable
14
+ extend Forwardable
14
15
  include ::Enumerable
15
16
 
16
17
  # The three main instance variables are collections of documents.
@@ -20,7 +21,7 @@ module Mongoid
20
21
  # @attribute [rw] _unloaded A criteria representing persisted docs.
21
22
  attr_accessor :_added, :_loaded, :_unloaded
22
23
 
23
- delegate :is_a?, :kind_of?, to: []
24
+ def_delegators [], :is_a?, :kind_of?
24
25
 
25
26
  # Check if the enumerable is equal to the other object.
26
27
  #
@@ -215,27 +216,6 @@ module Mongoid
215
216
  end
216
217
  end
217
218
 
218
- # Get an arbitrary document in the enumerable. Will check the persisted
219
- # documents first. Does not load the entire enumerable.
220
- #
221
- # @example Get an arbitrary document.
222
- # enumerable.one
223
- #
224
- # @note Unlike #first, this does not automatically sort the result set.
225
- #
226
- # @param [ Hash ] opts The options for the query returning the first document.
227
- #
228
- # @option opts [ :none ] :id_sort Don't apply a sort on _id.
229
- #
230
- # @return [ Document ] The first document found.
231
- #
232
- # @since 7.1.0
233
- def one(opts = {})
234
- opts = opts.dup
235
- opts[:id_sort] ||= :none
236
- first(opts)
237
- end
238
-
239
219
  # Get the first document in the enumerable. Will check the persisted
240
220
  # documents first. Does not load the entire enumerable.
241
221
  #
@@ -9,9 +9,10 @@ module Mongoid
9
9
  # This class defines the behavior for all associations that are a
10
10
  # one-to-many between documents in different collections.
11
11
  class Proxy < Association::Many
12
+ extend Forwardable
12
13
 
13
- delegate :count, to: :criteria
14
- delegate :first, :in_memory, :last, :reset, :uniq, to: :_target
14
+ def_delegator :criteria, :count
15
+ def_delegators :_target, :first, :in_memory, :last, :reset, :uniq
15
16
 
16
17
  # Appends a document or array of documents to the association. Will set
17
18
  # the parent and update the index in the process.
@@ -159,21 +159,21 @@ module Mongoid
159
159
  #
160
160
  # @since 1.0.0
161
161
  def write_attribute(name, value)
162
- access = database_field_name(name)
163
- if attribute_writable?(access)
162
+ field_name = database_field_name(name)
163
+ if attribute_writable?(field_name)
164
164
  _assigning do
165
- validate_attribute_value(access, value)
166
- localized = fields[access].try(:localized?)
165
+ validate_attribute_value(field_name, value)
166
+ localized = fields[field_name].try(:localized?)
167
167
  attributes_before_type_cast[name.to_s] = value
168
- typed_value = typed_value_for(access, value)
169
- unless attributes[access] == typed_value || attribute_changed?(access)
170
- attribute_will_change!(access)
168
+ typed_value = typed_value_for(field_name, value)
169
+ unless attributes[field_name] == typed_value || attribute_changed?(field_name)
170
+ attribute_will_change!(field_name)
171
171
  end
172
172
  if localized
173
- attributes[access] ||= {}
174
- attributes[access].merge!(typed_value)
173
+ attributes[field_name] ||= {}
174
+ attributes[field_name].merge!(typed_value)
175
175
  else
176
- attributes[access] = typed_value
176
+ attributes[field_name] = typed_value
177
177
  end
178
178
  typed_value
179
179
  end
@@ -338,20 +338,28 @@ module Mongoid
338
338
 
339
339
  private
340
340
 
341
- # Validates an attribute value. This provides validation checking if
342
- # the value is valid for given a field.
343
- # For now, only Hash and Array fields are validated.
341
+ # Validates an attribute value as being assignable to the specified field.
344
342
  #
345
- # @param [ String, Symbol ] access The name of the attribute to validate.
346
- # @param [ Object ] value The to be validated.
343
+ # For now, only Hash and Array fields are validated, and the value is
344
+ # being checked to be of an appropriate type (i.e. either Hash or Array,
345
+ # respectively, or nil).
346
+ #
347
+ # This method takes the name of the field as stored in the document
348
+ # in the database, not (necessarily) the Ruby method name used to read/write
349
+ # the said field.
350
+ #
351
+ # @param [ String, Symbol ] field_name The name of the field.
352
+ # @param [ Object ] value The value to be validated.
347
353
  #
348
354
  # @since 3.0.10
349
- def validate_attribute_value(access, value)
350
- return unless fields[access] && value
355
+ def validate_attribute_value(field_name, value)
356
+ return if value.nil?
357
+ field = fields[field_name]
358
+ return unless field
351
359
  validatable_types = [ Hash, Array ]
352
- if validatable_types.include? fields[access].type
353
- unless value.is_a? fields[access].type
354
- raise Mongoid::Errors::InvalidValue.new(fields[access].type, value.class)
360
+ if validatable_types.include?(field.type)
361
+ unless value.is_a?(field.type)
362
+ raise Mongoid::Errors::InvalidValue.new(field.type, value.class)
355
363
  end
356
364
  end
357
365
  end
@@ -10,11 +10,11 @@ module Mongoid
10
10
  # This module defines all the configuration options for Mongoid, including
11
11
  # the database connections.
12
12
  module Config
13
- extend self
13
+ extend Forwardable
14
14
  extend Options
15
+ extend self
15
16
 
16
- delegate :logger=, to: ::Mongoid
17
- delegate :logger, to: ::Mongoid
17
+ def_delegators ::Mongoid, :logger, :logger=
18
18
 
19
19
  LOCK = Mutex.new
20
20
 
@@ -34,8 +34,11 @@ module Mongoid
34
34
  defaults[name] = settings[name] = options[:default]
35
35
 
36
36
  class_eval do
37
- define_method(name) do
38
- settings[name]
37
+ # log_level accessor is defined specially below
38
+ unless name.to_sym == :log_level
39
+ define_method(name) do
40
+ settings[name]
41
+ end
39
42
  end
40
43
 
41
44
  define_method("#{name}=") do |value|
@@ -8,21 +8,22 @@ require "mongoid/contextual/none"
8
8
 
9
9
  module Mongoid
10
10
  module Contextual
11
+ extend Forwardable
11
12
 
12
13
  # The aggregate operations provided in the aggregate module get delegated
13
14
  # through to the context from the criteria.
14
- delegate(*Aggregable::Mongo.public_instance_methods(false), to: :context)
15
+ def_delegators :context, *Aggregable::Mongo.public_instance_methods(false)
15
16
 
16
17
  # The atomic operations provided in the atomic context get delegated
17
18
  # through to the context from the criteria.
18
- delegate(*Atomic.public_instance_methods(false), to: :context)
19
+ def_delegators :context, *Atomic.public_instance_methods(false)
19
20
 
20
21
  # The methods in the contexts themselves should all get delegated to,
21
22
  # including destructive, modification, and optional methods.
22
- delegate(*(Mongo.public_instance_methods(false) - [ :skip, :limit ]), to: :context)
23
+ def_delegators :context, *(Mongo.public_instance_methods(false) - [ :skip, :limit ])
23
24
 
24
25
  # This gets blank and empty included.
25
- delegate(*Queryable.public_instance_methods(false), to: :context)
26
+ def_delegators :context, *Queryable.public_instance_methods(false)
26
27
 
27
28
  # Get the context in which criteria queries should execute. This is either
28
29
  # in memory (for embedded documents) or mongo (for root level documents.)
@@ -4,11 +4,12 @@
4
4
  module Mongoid
5
5
  module Contextual
6
6
  class GeoNear
7
+ extend Forwardable
7
8
  include Enumerable
8
9
  include Command
9
10
 
10
- delegate :[], to: :results
11
- delegate :==, :empty?, to: :entries
11
+ def_delegator :results, :[]
12
+ def_delegators :entries, :==, :empty?
12
13
 
13
14
  # Get the average distance for all documents from the point in the
14
15
  # command.
@@ -4,11 +4,12 @@
4
4
  module Mongoid
5
5
  module Contextual
6
6
  class MapReduce
7
+ extend Forwardable
7
8
  include Enumerable
8
9
  include Command
9
10
 
10
- delegate :[], to: :results
11
- delegate :==, :empty?, to: :entries
11
+ def_delegators :results, :[]
12
+ def_delegators :entries, :==, :empty?
12
13
 
13
14
  # Get all the counts returned by the map/reduce.
14
15
  #
@@ -11,6 +11,7 @@ require "mongoid/association/eager_loadable"
11
11
  module Mongoid
12
12
  module Contextual
13
13
  class Mongo
14
+ extend Forwardable
14
15
  include Enumerable
15
16
  include Aggregable::Mongo
16
17
  include Atomic
@@ -349,7 +350,7 @@ module Mongoid
349
350
  apply_options
350
351
  end
351
352
 
352
- delegate(:database_field_name, to: :@klass)
353
+ def_delegator :@klass, :database_field_name
353
354
 
354
355
  # Get the last document in the database for the criteria's selector.
355
356
  #
@@ -4,12 +4,13 @@
4
4
  module Mongoid
5
5
  module Fields
6
6
  class Standard
7
+ extend Forwardable
7
8
 
8
9
  # Defines the behavior for defined fields in the document.
9
10
  # Set readers for the instance variables.
10
11
  attr_accessor :default_val, :label, :name, :options
11
12
 
12
- delegate :demongoize, :evolve, :mongoize, to: :type
13
+ def_delegators :type, :demongoize, :evolve, :mongoize
13
14
 
14
15
  # Adds the atomic changes for this type of resizable field.
15
16
  #
@@ -8,15 +8,16 @@ module Mongoid
8
8
  #
9
9
  # @since 4.0.0
10
10
  module Findable
11
+ extend Forwardable
11
12
 
12
- delegate *(
13
+ def_delegators :with_default_scope, *(
13
14
  Criteria::Queryable::Selectable.forwardables +
14
15
  Criteria::Queryable::Optional.forwardables
15
- ), to: :with_default_scope
16
+ )
16
17
 
17
18
  # These are methods defined on the criteria that should also be accessible
18
19
  # directly from the class level.
19
- delegate \
20
+ def_delegators :with_default_scope,
20
21
  :aggregates,
21
22
  :avg,
22
23
  :create_with,
@@ -45,7 +46,7 @@ module Mongoid
45
46
  :sum,
46
47
  :text_search,
47
48
  :update,
48
- :update_all, to: :with_default_scope
49
+ :update_all
49
50
 
50
51
  # Returns a count of records in the database.
51
52
  # If you want to specify conditions use where.
@@ -131,7 +131,11 @@ module Mongoid
131
131
  return false
132
132
  end
133
133
  end
134
- callback_executable?(kind) ? super(kind, *args, &block) : true
134
+ if callback_executable?(kind)
135
+ super(kind, *args, &block)
136
+ else
137
+ true
138
+ end
135
139
  end
136
140
 
137
141
  private
@@ -60,13 +60,20 @@ namespace :db do
60
60
  end
61
61
 
62
62
  unless Rake::Task.task_defined?("db:create_indexes")
63
+ desc "Create indexes specified in Mongoid models"
63
64
  task :create_indexes => "mongoid:create_indexes"
64
65
  end
65
66
 
66
67
  unless Rake::Task.task_defined?("db:remove_indexes")
68
+ desc "Remove indexes specified in Mongoid models"
67
69
  task :remove_indexes => "mongoid:remove_indexes"
68
70
  end
69
71
 
72
+ unless Rake::Task.task_defined?("db:shard_collections")
73
+ desc "Shard collections with shard keys specified in Mongoid models"
74
+ task :shard_collections => "mongoid:shard_collections"
75
+ end
76
+
70
77
  namespace :mongoid do
71
78
  task :load_models do
72
79
  ::Rails.application.eager_load! if defined?(::Rails)
@@ -13,8 +13,10 @@ module Mongoid
13
13
  # We need to redefine where the JSON configuration is getting defined,
14
14
  # similar to +ActiveRecord+.
15
15
  included do
16
+ extend Forwardable
17
+
16
18
  undef_method :include_root_in_json
17
- delegate :include_root_in_json, to: ::Mongoid
19
+ def_delegator ::Mongoid, :include_root_in_json
18
20
  end
19
21
 
20
22
  # Gets the document as a serializable hash, used by ActiveModel's JSON
@@ -10,8 +10,32 @@ module Mongoid
10
10
  extend ActiveSupport::Concern
11
11
 
12
12
  included do
13
+ # Returns the list of shard key fields, if shard key was declared on
14
+ # this model. If no shard key was declared, returns an empty array.
15
+ #
16
+ # @return [ Array<Symbol> ] List of shard key fields.
17
+ # @api public
13
18
  cattr_accessor :shard_key_fields
14
19
  self.shard_key_fields = []
20
+
21
+ # Returns the shard configuration, which is a hash with the following
22
+ # (symbol) keys:
23
+ #
24
+ # - keys: A hash mapping (symbol) field names to values, defining the
25
+ # shard key. Values can be either the integer 1 for ranged sharding
26
+ # or the string "hashed" for hashed sharding.
27
+ # - options: A hash containing options for shardCollections command.
28
+ #
29
+ # If shard key was not declared via the +shard_key+ macro, +shard_config+
30
+ # attribute is nil.
31
+ #
32
+ # @example Get the shard configuration.
33
+ # Model.shard_config
34
+ # # => {key: {foo: 1, bar: 1}, options: {unique: true}}
35
+ #
36
+ # @return [ Hash | nil ] Shard configuration.
37
+ # @api public
38
+ cattr_accessor :shard_config
15
39
  end
16
40
 
17
41
  # Get the shard key fields.
@@ -55,14 +79,42 @@ module Mongoid
55
79
  # field :first_name, :type => String
56
80
  # field :last_name, :type => String
57
81
  #
58
- # shard_key :first_name, :last_name
82
+ # shard_key first_name: 1, last_name: 1
59
83
  # end
60
84
  #
61
85
  # @since 2.0.0
62
- def shard_key(*names)
63
- names.each do |name|
64
- self.shard_key_fields << self.database_field_name(name).to_sym
86
+ def shard_key(*args)
87
+ unless args.first.is_a?(Hash)
88
+ # Shorthand syntax
89
+ if args.last.is_a?(Hash)
90
+ raise ArgumentError, 'Shorthand shard_key syntax does not permit options'
91
+ end
92
+
93
+ spec = Hash[args.map do |name|
94
+ [name, 1]
95
+ end]
96
+
97
+ return shard_key(spec)
98
+ end
99
+
100
+ if args.length > 2
101
+ raise ArgumentError, 'Full shard_key syntax requires 1 or 2 arguments'
65
102
  end
103
+
104
+ spec, options = args
105
+
106
+ spec = Hash[spec.map do |name, value|
107
+ if value.is_a?(Symbol)
108
+ value = value.to_s
109
+ end
110
+ [database_field_name(name).to_sym, value]
111
+ end]
112
+
113
+ self.shard_key_fields = spec.keys
114
+ self.shard_config = {
115
+ key: spec.freeze,
116
+ options: (options || {}).dup.freeze,
117
+ }.freeze
66
118
  end
67
119
  end
68
120
  end