mongoid 4.0.2 → 5.0.0.beta

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 (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -1
  3. data/README.md +14 -13
  4. data/lib/config/locales/en.yml +28 -28
  5. data/lib/mongoid.rb +28 -21
  6. data/lib/mongoid/atomic.rb +2 -4
  7. data/lib/mongoid/attributes.rb +7 -7
  8. data/lib/mongoid/attributes/processing.rb +4 -1
  9. data/lib/mongoid/attributes/readonly.rb +2 -2
  10. data/lib/mongoid/changeable.rb +4 -6
  11. data/lib/mongoid/clients.rb +142 -0
  12. data/lib/mongoid/clients/factory.rb +78 -0
  13. data/lib/mongoid/{sessions → clients}/options.rb +30 -19
  14. data/lib/mongoid/{sessions → clients}/storage_options.rb +27 -13
  15. data/lib/mongoid/{sessions → clients}/thread_options.rb +6 -3
  16. data/lib/mongoid/clients/validators.rb +2 -0
  17. data/lib/mongoid/{sessions → clients}/validators/storage.rb +5 -2
  18. data/lib/mongoid/composable.rb +3 -3
  19. data/lib/mongoid/config.rb +39 -41
  20. data/lib/mongoid/config/environment.rb +1 -1
  21. data/lib/mongoid/config/validators.rb +1 -1
  22. data/lib/mongoid/config/validators/{session.rb → client.rb} +31 -28
  23. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  24. data/lib/mongoid/contextual/atomic.rb +11 -11
  25. data/lib/mongoid/contextual/command.rb +9 -6
  26. data/lib/mongoid/contextual/geo_near.rb +17 -1
  27. data/lib/mongoid/contextual/map_reduce.rb +12 -11
  28. data/lib/mongoid/contextual/memory.rb +2 -5
  29. data/lib/mongoid/contextual/mongo.rb +92 -82
  30. data/lib/mongoid/contextual/none.rb +13 -0
  31. data/lib/mongoid/copyable.rb +6 -1
  32. data/lib/mongoid/criteria.rb +36 -3
  33. data/lib/mongoid/document.rb +3 -4
  34. data/lib/mongoid/errors.rb +6 -6
  35. data/lib/mongoid/errors/{mixed_session_configuration.rb → mixed_client_configuration.rb} +5 -5
  36. data/lib/mongoid/errors/no_client_config.rb +22 -0
  37. data/lib/mongoid/errors/{no_session_database.rb → no_client_database.rb} +4 -4
  38. data/lib/mongoid/errors/{no_session_hosts.rb → no_client_hosts.rb} +4 -4
  39. data/lib/mongoid/errors/{no_sessions_config.rb → no_clients_config.rb} +4 -4
  40. data/lib/mongoid/errors/no_default_client.rb +23 -0
  41. data/lib/mongoid/extensions/hash.rb +5 -1
  42. data/lib/mongoid/extensions/object.rb +3 -2
  43. data/lib/mongoid/extensions/set.rb +5 -5
  44. data/lib/mongoid/factory.rb +4 -2
  45. data/lib/mongoid/fields.rb +7 -2
  46. data/lib/mongoid/findable.rb +4 -1
  47. data/lib/mongoid/indexable.rb +15 -9
  48. data/lib/mongoid/persistable.rb +1 -2
  49. data/lib/mongoid/persistable/creatable.rb +2 -2
  50. data/lib/mongoid/persistable/deletable.rb +3 -3
  51. data/lib/mongoid/persistable/incrementable.rb +1 -1
  52. data/lib/mongoid/persistable/logical.rb +1 -1
  53. data/lib/mongoid/persistable/poppable.rb +1 -1
  54. data/lib/mongoid/persistable/pullable.rb +2 -2
  55. data/lib/mongoid/persistable/pushable.rb +2 -2
  56. data/lib/mongoid/persistable/renamable.rb +1 -1
  57. data/lib/mongoid/persistable/settable.rb +1 -1
  58. data/lib/mongoid/persistable/unsettable.rb +1 -1
  59. data/lib/mongoid/persistable/updatable.rb +2 -2
  60. data/lib/mongoid/persistable/upsertable.rb +1 -1
  61. data/lib/mongoid/query_cache.rb +98 -104
  62. data/lib/mongoid/railtie.rb +1 -21
  63. data/lib/mongoid/railties/database.rake +1 -1
  64. data/lib/mongoid/relations/builders.rb +3 -1
  65. data/lib/mongoid/relations/counter_cache.rb +1 -1
  66. data/lib/mongoid/relations/embedded/batchable.rb +3 -10
  67. data/lib/mongoid/relations/embedded/many.rb +4 -2
  68. data/lib/mongoid/relations/many.rb +1 -0
  69. data/lib/mongoid/relations/proxy.rb +6 -6
  70. data/lib/mongoid/relations/referenced/many.rb +2 -1
  71. data/lib/mongoid/relations/targets/enumerable.rb +11 -11
  72. data/lib/mongoid/relations/touchable.rb +1 -1
  73. data/lib/mongoid/reloadable.rb +2 -2
  74. data/lib/mongoid/scopable.rb +6 -17
  75. data/lib/mongoid/selectable.rb +1 -36
  76. data/lib/mongoid/serializable.rb +2 -2
  77. data/lib/mongoid/stateful.rb +0 -1
  78. data/lib/mongoid/tasks/database.rake +2 -2
  79. data/lib/mongoid/tasks/database.rb +23 -16
  80. data/lib/mongoid/threaded.rb +54 -33
  81. data/lib/mongoid/threaded/lifecycle.rb +21 -16
  82. data/lib/mongoid/traversable.rb +16 -1
  83. data/lib/mongoid/validatable.rb +1 -1
  84. data/lib/mongoid/validatable/queryable.rb +1 -1
  85. data/lib/mongoid/validatable/uniqueness.rb +3 -20
  86. data/lib/mongoid/version.rb +1 -1
  87. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +91 -57
  88. data/lib/rails/mongoid.rb +2 -2
  89. data/spec/app/models/audio.rb +1 -1
  90. data/spec/app/models/band.rb +1 -0
  91. data/spec/app/models/company.rb +5 -0
  92. data/spec/app/models/label.rb +7 -0
  93. data/spec/app/models/pub.rb +6 -0
  94. data/spec/app/models/staff.rb +7 -0
  95. data/spec/app/models/store_as_dup_test1.rb +5 -0
  96. data/spec/app/models/store_as_dup_test2.rb +5 -0
  97. data/spec/config/mongoid.yml +7 -25
  98. data/spec/mongoid/atomic/paths_spec.rb +3 -11
  99. data/spec/mongoid/attributes/nested_spec.rb +16 -16
  100. data/spec/mongoid/attributes/readonly_spec.rb +80 -18
  101. data/spec/mongoid/attributes_spec.rb +3 -3
  102. data/spec/mongoid/changeable_spec.rb +70 -0
  103. data/spec/mongoid/clients/factory_spec.rb +284 -0
  104. data/spec/mongoid/{sessions → clients}/options_spec.rb +4 -6
  105. data/spec/mongoid/clients_spec.rb +739 -0
  106. data/spec/mongoid/config/environment_spec.rb +14 -11
  107. data/spec/mongoid/config_spec.rb +33 -48
  108. data/spec/mongoid/contextual/atomic_spec.rb +1 -17
  109. data/spec/mongoid/contextual/geo_near_spec.rb +35 -0
  110. data/spec/mongoid/contextual/mongo_spec.rb +26 -83
  111. data/spec/mongoid/contextual/none_spec.rb +15 -0
  112. data/spec/mongoid/copyable_spec.rb +35 -1
  113. data/spec/mongoid/criteria/findable_spec.rb +197 -0
  114. data/spec/mongoid/criteria/modifiable_spec.rb +7 -29
  115. data/spec/mongoid/criteria_spec.rb +74 -91
  116. data/spec/mongoid/document_spec.rb +1 -1
  117. data/spec/mongoid/errors/{mixed_session_configuration_spec.rb → mixed_client_configuration_spec.rb} +1 -1
  118. data/spec/mongoid/errors/{no_session_config_spec.rb → no_client_config_spec.rb} +4 -4
  119. data/spec/mongoid/errors/{no_session_database_spec.rb → no_client_database_spec.rb} +4 -4
  120. data/spec/mongoid/errors/{no_session_hosts_spec.rb → no_client_hosts_spec.rb} +3 -3
  121. data/spec/mongoid/errors/{no_sessions_config_spec.rb → no_clients_config_spec.rb} +2 -2
  122. data/spec/mongoid/fields/localized_spec.rb +1 -0
  123. data/spec/mongoid/fields_spec.rb +1 -0
  124. data/spec/mongoid/findable_spec.rb +2 -23
  125. data/spec/mongoid/indexable_spec.rb +12 -8
  126. data/spec/mongoid/interceptable_spec.rb +15 -0
  127. data/spec/mongoid/persistable/settable_spec.rb +16 -0
  128. data/spec/mongoid/persistable/updatable_spec.rb +3 -2
  129. data/spec/mongoid/persistable_spec.rb +4 -4
  130. data/spec/mongoid/query_cache_spec.rb +13 -8
  131. data/spec/mongoid/relations/auto_save_spec.rb +1 -1
  132. data/spec/mongoid/relations/counter_cache_spec.rb +34 -0
  133. data/spec/mongoid/relations/eager/belongs_to_spec.rb +9 -0
  134. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +3 -3
  135. data/spec/mongoid/relations/embedded/many_spec.rb +123 -1
  136. data/spec/mongoid/relations/embedded/one_spec.rb +3 -3
  137. data/spec/mongoid/relations/proxy_spec.rb +28 -0
  138. data/spec/mongoid/relations/referenced/in_spec.rb +1 -1
  139. data/spec/mongoid/relations/referenced/many_spec.rb +47 -23
  140. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +1 -1
  141. data/spec/mongoid/relations/referenced/one_spec.rb +1 -1
  142. data/spec/mongoid/relations/targets/enumerable_spec.rb +9 -2
  143. data/spec/mongoid/reloadable_spec.rb +6 -6
  144. data/spec/mongoid/scopable_spec.rb +41 -28
  145. data/spec/mongoid/selectable_spec.rb +6 -16
  146. data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
  147. data/spec/mongoid/tasks/database_spec.rb +2 -2
  148. data/spec/mongoid/threaded_spec.rb +0 -7
  149. data/spec/mongoid/traversable_spec.rb +2 -2
  150. data/spec/mongoid/validatable/uniqueness_spec.rb +30 -1
  151. data/spec/mongoid_spec.rb +13 -15
  152. data/spec/rails/mongoid_spec.rb +13 -4
  153. data/spec/spec_helper.rb +44 -27
  154. data/spec/support/authorization.rb +12 -0
  155. data/spec/support/expectations.rb +14 -0
  156. metadata +52 -59
  157. data/lib/mongoid/contextual/find_and_modify.rb +0 -69
  158. data/lib/mongoid/contextual/text_search.rb +0 -178
  159. data/lib/mongoid/criteria/#findable.rb# +0 -141
  160. data/lib/mongoid/errors/no_default_session.rb +0 -23
  161. data/lib/mongoid/errors/no_session_config.rb +0 -22
  162. data/lib/mongoid/log_subscriber.rb +0 -55
  163. data/lib/mongoid/positional.rb +0 -71
  164. data/lib/mongoid/sessions.rb +0 -125
  165. data/lib/mongoid/sessions/factory.rb +0 -131
  166. data/lib/mongoid/sessions/mongo_uri.rb +0 -93
  167. data/lib/mongoid/sessions/validators.rb +0 -2
  168. data/lib/mongoid/support/query_counter.rb +0 -23
  169. data/spec/helpers.rb +0 -18
  170. data/spec/mongoid/#atomic_spec.rb# +0 -365
  171. data/spec/mongoid/contextual/find_and_modify_spec.rb +0 -220
  172. data/spec/mongoid/contextual/text_search_spec.rb +0 -209
  173. data/spec/mongoid/log_subscriber_spec.rb +0 -75
  174. data/spec/mongoid/positional_spec.rb +0 -222
  175. data/spec/mongoid/sessions/factory_spec.rb +0 -333
  176. data/spec/mongoid/sessions/mongo_uri_spec.rb +0 -103
  177. data/spec/mongoid/sessions_spec.rb +0 -1252
@@ -31,10 +31,10 @@ module Mongoid
31
31
  index_specifications.each do |spec|
32
32
  key, options = spec.key, spec.options
33
33
  if database = options[:database]
34
- with(read: :primary, database: database).
35
- collection.indexes.create(key, options.except(:database))
34
+ with(read: { mode: :primary }, database: database).
35
+ collection.indexes.create_one(key, options.except(:database))
36
36
  else
37
- with(read: :primary).collection.indexes.create(key, options)
37
+ with(read: { mode: :primary }).collection.indexes.create_one(key, options)
38
38
  end
39
39
  end and true
40
40
  end
@@ -50,12 +50,18 @@ module Mongoid
50
50
  # @since 3.0.0
51
51
  def remove_indexes
52
52
  indexed_database_names.each do |database|
53
- collection = with(read: :primary, database: database).collection
54
- collection.indexes.each do |spec|
55
- unless spec["name"] == "_id_"
56
- collection.indexes.drop(spec["key"])
53
+ collection = with(read: { mode: :primary }, database: database).collection
54
+ begin
55
+ collection.indexes.each do |spec|
56
+ unless spec["name"] == "_id_"
57
+ collection.indexes.drop_one(spec["key"])
58
+ logger.info(
59
+ "MONGOID: Removed index '#{spec["name"]}' on collection " +
60
+ "'#{collection.name}' in database '#{database}'."
61
+ )
62
+ end
57
63
  end
58
- end
64
+ rescue Mongo::Error::OperationFailure; end
59
65
  end and true
60
66
  end
61
67
 
@@ -142,7 +148,7 @@ module Mongoid
142
148
  #
143
149
  # @since 4.0.0
144
150
  def index_keys
145
- index_specifications.map{ |spec| spec.key }
151
+ index_specifications.map(&:key)
146
152
  end
147
153
  end
148
154
  end
@@ -27,7 +27,6 @@ module Mongoid
27
27
  include Incrementable
28
28
  include Logical
29
29
  include Poppable
30
- include Positional
31
30
  include Pullable
32
31
  include Pushable
33
32
  include Renamable
@@ -209,7 +208,7 @@ module Mongoid
209
208
  def persist_atomic_operations(operations)
210
209
  if persisted?
211
210
  selector = atomic_selector
212
- _root.collection.find(selector).update(positionally(selector, operations))
211
+ _root.collection.find(selector).update_one(operations)
213
212
  end
214
213
  end
215
214
  end
@@ -61,7 +61,7 @@ module Mongoid
61
61
  _parent.insert
62
62
  else
63
63
  selector = _parent.atomic_selector
64
- _root.collection.find(selector).update(positionally(selector, atomic_inserts))
64
+ _root.collection.find(selector).update_one(atomic_inserts)
65
65
  end
66
66
  end
67
67
 
@@ -76,7 +76,7 @@ module Mongoid
76
76
  #
77
77
  # @since 4.0.0
78
78
  def insert_as_root
79
- collection.insert(as_document)
79
+ collection.insert_one(as_document)
80
80
  end
81
81
 
82
82
  # Post process an insert, which sets the new record attribute to false
@@ -62,7 +62,7 @@ module Mongoid
62
62
  _parent.remove_child(self) if notifying_parent?(options)
63
63
  if _parent.persisted?
64
64
  selector = _parent.atomic_selector
65
- _root.collection.find(selector).update(positionally(selector, atomic_deletes))
65
+ _root.collection.find(selector).update_one(atomic_deletes)
66
66
  end
67
67
  true
68
68
  end
@@ -78,7 +78,7 @@ module Mongoid
78
78
  #
79
79
  # @since 4.0.0
80
80
  def delete_as_root
81
- collection.find(atomic_selector).remove
81
+ collection.find(atomic_selector).delete_one
82
82
  true
83
83
  end
84
84
 
@@ -140,7 +140,7 @@ module Mongoid
140
140
  selector.merge!(_type: name) if hereditary?
141
141
  coll = collection
142
142
  deleted = coll.find(selector).count
143
- coll.find(selector).remove_all
143
+ coll.find(selector).delete_many
144
144
  deleted
145
145
  end
146
146
  end
@@ -17,7 +17,7 @@ module Mongoid
17
17
  #
18
18
  # @param [ Hash ] increments The field/inc increment pairs.
19
19
  #
20
- # @return [ true, false ] If the increment succeeded.
20
+ # @return [ Document ] The document.
21
21
  #
22
22
  # @since 4.0.0
23
23
  def inc(increments)
@@ -16,7 +16,7 @@ module Mongoid
16
16
  #
17
17
  # @param [ Hash ] operations The bitwise operations.
18
18
  #
19
- # @return [ true, false ] If the operation succeeded.
19
+ # @return [ Document ] The document.
20
20
  #
21
21
  # @since 4.0.0
22
22
  def bit(operations)
@@ -21,7 +21,7 @@ module Mongoid
21
21
  #
22
22
  # @param [ Hash ] pops The field/value pop operations.
23
23
  #
24
- # @return [ true, false ] If the operation succeeded.
24
+ # @return [ Document ] The document.
25
25
  #
26
26
  # @since 4.0.0
27
27
  def pop(pops)
@@ -17,7 +17,7 @@ module Mongoid
17
17
  #
18
18
  # @param [ Hash ] pulls The field/value pull pairs.
19
19
  #
20
- # @return [ true, false ] If the operation succeeded.
20
+ # @return [ Document ] The document.
21
21
  #
22
22
  # @since 4.0.0
23
23
  def pull(pulls)
@@ -37,7 +37,7 @@ module Mongoid
37
37
  #
38
38
  # @param [ Hash ] pulls The pull all operations.
39
39
  #
40
- # @return [ true, false ] If the operation succeeded.
40
+ # @return [ Document ] The document.
41
41
  #
42
42
  # @since 4.0.0
43
43
  def pull_all(pulls)
@@ -16,7 +16,7 @@ module Mongoid
16
16
  #
17
17
  # @param [ Hash ] adds The field/value pairs to add.
18
18
  #
19
- # @return [ true, false ] If the operation succeeded.
19
+ # @return [ Document ] The document.
20
20
  #
21
21
  # @since 4.0.0
22
22
  def add_to_set(adds)
@@ -43,7 +43,7 @@ module Mongoid
43
43
  #
44
44
  # @param [ Hash ] pushes The $push operations.
45
45
  #
46
- # @return [ true, false ] If the operation succeeded.
46
+ # @return [ Document ] The document.
47
47
  #
48
48
  # @since 4.0.0
49
49
  def push(pushes)
@@ -17,7 +17,7 @@ module Mongoid
17
17
  #
18
18
  # @param [ Hash ] renames The rename pairs of old name/new name.
19
19
  #
20
- # @return [ true, false ] If the rename suceeded.
20
+ # @return [ Document ] The document.
21
21
  #
22
22
  # @since 4.0.0
23
23
  def rename(renames)
@@ -16,7 +16,7 @@ module Mongoid
16
16
  #
17
17
  # @param [ Hash ] setters The field/value pairs to set.
18
18
  #
19
- # @return [ true ] If the operation succeeded.
19
+ # @return [ Document ] The document.
20
20
  #
21
21
  # @since 4.0.0
22
22
  def set(setters)
@@ -17,7 +17,7 @@ module Mongoid
17
17
  # @param [ Array<String, Symbol> ] fields The names of the fields to
18
18
  # unset.
19
19
  #
20
- # @return [ true ] If the operation succeeded.
20
+ # @return [ Document ] The document.
21
21
  #
22
22
  # @since 4.0.0
23
23
  def unset(*fields)
@@ -141,9 +141,9 @@ module Mongoid
141
141
  unless updates.empty?
142
142
  coll = _root.collection
143
143
  selector = atomic_selector
144
- coll.find(selector).update(positionally(selector, updates))
144
+ coll.find(selector).update_one(updates)
145
145
  conflicts.each_pair do |key, value|
146
- coll.find(selector).update(positionally(selector, { key => value }))
146
+ coll.find(selector).update_one({ key => value })
147
147
  end
148
148
  end
149
149
  end
@@ -21,7 +21,7 @@ module Mongoid
21
21
  # @since 3.0.0
22
22
  def upsert(options = {})
23
23
  prepare_upsert(options) do
24
- collection.find(atomic_selector).update(as_document, [ :upsert ])
24
+ collection.find(atomic_selector).update_one(as_document, upsert: true)
25
25
  end
26
26
  end
27
27
 
@@ -107,149 +107,143 @@ module Mongoid
107
107
  end
108
108
  end
109
109
 
110
- module Base # :nodoc:
111
-
112
- def alias_query_cache_clear(*method_names)
113
- method_names.each do |method_name|
114
- class_eval <<-CODE, __FILE__, __LINE__ + 1
115
- def #{method_name}_with_clear_cache(*args) # def upsert_with_clear_cache(*args)
116
- QueryCache.clear_cache # QueryCache.clear_cache
117
- #{method_name}_without_clear_cache(*args) # upsert_without_clear_cache(*args)
118
- end # end
119
- CODE
110
+ # A Cursor that attempts to load documents from memory first before hitting
111
+ # the database if the same query has already been executed.
112
+ #
113
+ # @since 5.0.0
114
+ class CachedCursor < Mongo::Cursor
120
115
 
121
- alias_method_chain method_name, :clear_cache
116
+ # We iterate over the cached documents if they exist already in the
117
+ # cursor otherwise proceed as normal.
118
+ #
119
+ # @example Iterate over the documents.
120
+ # cursor.each do |doc|
121
+ # # ...
122
+ # end
123
+ #
124
+ # @since 5.0.0
125
+ def each
126
+ if @cached_documents
127
+ @cached_documents.each{ |doc| yield doc }
128
+ else
129
+ super
122
130
  end
123
131
  end
132
+
133
+ # Get a human-readable string representation of +Cursor+.
134
+ #
135
+ # @example Inspect the cursor.
136
+ # cursor.inspect
137
+ #
138
+ # @return [ String ] A string representation of a +Cursor+ instance.
139
+ #
140
+ # @since 2.0.0
141
+ def inspect
142
+ "#<Mongoid::QueryCache::CachedCursor:0x#{object_id} @view=#{@view.inspect}>"
143
+ end
144
+
145
+ private
146
+
147
+ def process(result)
148
+ @remaining -= result.returned_count if limited?
149
+ @cursor_id = result.cursor_id
150
+ @coll_name ||= result.namespace.sub("#{database.name}.", '') if result.namespace
151
+ documents = result.documents
152
+ (@cached_documents ||= []).concat(documents)
153
+ documents
154
+ end
124
155
  end
125
156
 
126
- # Module to include in objects which need to wrap caching behaviour around
127
- # them.
157
+ # Included to add behaviour for clearing out the query cache on certain
158
+ # operations.
128
159
  #
129
160
  # @since 4.0.0
130
- module Cacheable
161
+ module Base
131
162
 
132
- private
163
+ def alias_query_cache_clear(*method_names)
164
+ method_names.each do |method_name|
165
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
166
+ def #{method_name}_with_clear_cache(*args)
167
+ QueryCache.clear_cache
168
+ #{method_name}_without_clear_cache(*args)
169
+ end
170
+ CODE
133
171
 
134
- def with_cache(context = :cursor, more = false, &block)
135
- return yield unless QueryCache.enabled?
136
- return yield if system_collection?
137
- key = cache_key.push(context)
138
-
139
- if more
140
- docs = yield
141
- QueryCache.cache_table[key].push(*docs)
142
- docs
143
- elsif QueryCache.cache_table.has_key?(key)
144
- instrument(key) { QueryCache.cache_table[key] }
145
- else
146
- QueryCache.cache_table[key] = yield
172
+ alias_method_chain method_name, :clear_cache
147
173
  end
148
174
  end
149
-
150
- def instrument(key, &block)
151
- ActiveSupport::Notifications.instrument("query_cache.mongoid", key: key, &block)
152
- end
153
175
  end
154
176
 
155
- # Adds behaviour around caching to a Moped Query object.
177
+ # Contains enhancements to the Mongo::Collection::View in order to get a
178
+ # cached cursor or a regular cursor on iteration.
156
179
  #
157
- # @since 4.0.0
158
- module Query
180
+ # @since 5.0.0
181
+ module View
159
182
  extend ActiveSupport::Concern
160
- include Cacheable
161
183
 
162
184
  included do
163
185
  extend QueryCache::Base
164
- alias_method_chain :cursor, :cache
165
- alias_method_chain :first, :cache
166
- alias_query_cache_clear :remove, :remove_all, :update, :update_all, :upsert
167
- end
168
-
169
- # Provide a wrapped query cache cursor.
170
- #
171
- # @example Get the wrapped caching cursor.
172
- # query.cursor_with_cache
173
- #
174
- # @return [ CachedCursor ] The cached cursor.
175
- #
176
- # @since 4.0.0
177
- def cursor_with_cache
178
- CachedCursor.new(session, operation)
179
- end
180
-
181
- # Override first with caching.
182
- #
183
- # @example Get the first with a cache.
184
- # query.first_with_cache
185
- #
186
- # @return [ Hash ] The first document.
187
- #
188
- # @since 4.0.0
189
- def first_with_cache
190
- with_cache(:first) do
191
- first_without_cache
186
+ alias_query_cache_clear :delete_one,
187
+ :delete_many,
188
+ :update_one,
189
+ :update_many,
190
+ :replace_one,
191
+ :find_one_and_delete,
192
+ :find_one_and_replace,
193
+ :find_one_and_update
194
+ end
195
+
196
+ # Override the default enumeration to handle if the cursor can be cached
197
+ # or not.
198
+ #
199
+ # @example Iterate over the view.
200
+ # view.each do |doc|
201
+ # # ...
202
+ # end
203
+ #
204
+ # @since 5.0.0
205
+ def each
206
+ if system_collection? || !QueryCache.enabled?
207
+ super
208
+ else
209
+ key = cache_key
210
+ cursor = QueryCache.cache_table[key]
211
+ unless cursor
212
+ server = read.select_server(cluster)
213
+ cursor = CachedCursor.new(view, send_initial_query(server), server)
214
+ QueryCache.cache_table[key] = cursor
215
+ end
216
+ cursor.each do |doc|
217
+ yield doc
218
+ end if block_given?
219
+ cursor
192
220
  end
193
221
  end
194
222
 
195
223
  private
196
224
 
197
225
  def cache_key
198
- [ operation.database, operation.collection, operation.selector, operation.limit, operation.skip, operation.fields ]
226
+ [ collection.namespace, selector, limit, skip, projection ]
199
227
  end
200
228
 
201
229
  def system_collection?
202
- operation.collection =~ /^system./
230
+ collection.namespace =~ /^system./
203
231
  end
204
232
  end
205
233
 
206
234
  # Adds behaviour to the query cache for collections.
207
235
  #
208
- # @since 4.0.0
236
+ # @since 5.0.0
209
237
  module Collection
210
238
  extend ActiveSupport::Concern
211
239
 
212
240
  included do
213
241
  extend QueryCache::Base
214
- alias_query_cache_clear :insert
215
- end
216
- end
217
-
218
- # A Cursor that attempts to load documents from memory first before hitting
219
- # the database if the same query has already been executed.
220
- #
221
- # @since 4.0.0
222
- class CachedCursor < Moped::Cursor
223
- include Cacheable
224
-
225
- # Override the loading of docs to attempt to fetch from the cache.
226
- #
227
- # @example Load the documents.
228
- # cursor.load_docs
229
- #
230
- # @return [ Array<Hash> ] The documents.
231
- #
232
- # @since 4.0.0
233
- def load_docs
234
- with_cache { super }
235
- end
236
-
237
- def get_more
238
- with_cache(:cursor, true) { super }
239
- end
240
-
241
- private
242
-
243
- def cache_key
244
- [ @database, @collection, @selector, @options[:limit], @options[:skip], @options[:fields] ]
245
- end
246
-
247
- def system_collection?
248
- @collection =~ /^system./
242
+ alias_query_cache_clear :insert_one, :insert_many
249
243
  end
250
244
  end
251
245
  end
252
246
  end
253
247
 
254
- Moped::Query.__send__(:include, Mongoid::QueryCache::Query)
255
- Moped::Collection.__send__(:include, Mongoid::QueryCache::Collection)
248
+ Mongo::Collection.__send__(:include, Mongoid::QueryCache::Collection)
249
+ Mongo::Collection::View.__send__(:include, Mongoid::QueryCache::View)