mongoid 7.1.0.rc0 → 7.1.0

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