mongoid-multi-db 3.0.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 (276) hide show
  1. data/CHANGELOG.md +615 -0
  2. data/LICENSE +20 -0
  3. data/README.md +62 -0
  4. data/Rakefile +49 -0
  5. data/lib/config/locales/bg.yml +54 -0
  6. data/lib/config/locales/de.yml +54 -0
  7. data/lib/config/locales/en-GB.yml +55 -0
  8. data/lib/config/locales/en.yml +55 -0
  9. data/lib/config/locales/es.yml +52 -0
  10. data/lib/config/locales/fr.yml +55 -0
  11. data/lib/config/locales/hi.yml +46 -0
  12. data/lib/config/locales/hu.yml +57 -0
  13. data/lib/config/locales/id.yml +55 -0
  14. data/lib/config/locales/it.yml +52 -0
  15. data/lib/config/locales/ja.yml +50 -0
  16. data/lib/config/locales/kr.yml +47 -0
  17. data/lib/config/locales/nl.yml +52 -0
  18. data/lib/config/locales/pl.yml +52 -0
  19. data/lib/config/locales/pt-BR.yml +53 -0
  20. data/lib/config/locales/pt.yml +53 -0
  21. data/lib/config/locales/ro.yml +59 -0
  22. data/lib/config/locales/ru.yml +54 -0
  23. data/lib/config/locales/sv.yml +53 -0
  24. data/lib/config/locales/vi.yml +55 -0
  25. data/lib/config/locales/zh-CN.yml +46 -0
  26. data/lib/mongoid.rb +148 -0
  27. data/lib/mongoid/atomic.rb +230 -0
  28. data/lib/mongoid/atomic/modifiers.rb +243 -0
  29. data/lib/mongoid/atomic/paths.rb +3 -0
  30. data/lib/mongoid/atomic/paths/embedded.rb +43 -0
  31. data/lib/mongoid/atomic/paths/embedded/many.rb +44 -0
  32. data/lib/mongoid/atomic/paths/embedded/one.rb +43 -0
  33. data/lib/mongoid/atomic/paths/root.rb +40 -0
  34. data/lib/mongoid/attributes.rb +234 -0
  35. data/lib/mongoid/attributes/processing.rb +146 -0
  36. data/lib/mongoid/callbacks.rb +135 -0
  37. data/lib/mongoid/collection.rb +153 -0
  38. data/lib/mongoid/collection_proxy.rb +59 -0
  39. data/lib/mongoid/collections.rb +120 -0
  40. data/lib/mongoid/collections/master.rb +45 -0
  41. data/lib/mongoid/collections/operations.rb +44 -0
  42. data/lib/mongoid/collections/retry.rb +46 -0
  43. data/lib/mongoid/components.rb +96 -0
  44. data/lib/mongoid/config.rb +347 -0
  45. data/lib/mongoid/config/database.rb +186 -0
  46. data/lib/mongoid/config/replset_database.rb +82 -0
  47. data/lib/mongoid/connection_proxy.rb +30 -0
  48. data/lib/mongoid/contexts.rb +25 -0
  49. data/lib/mongoid/contexts/enumerable.rb +288 -0
  50. data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
  51. data/lib/mongoid/contexts/mongo.rb +409 -0
  52. data/lib/mongoid/copyable.rb +48 -0
  53. data/lib/mongoid/criteria.rb +418 -0
  54. data/lib/mongoid/criterion/builder.rb +34 -0
  55. data/lib/mongoid/criterion/complex.rb +84 -0
  56. data/lib/mongoid/criterion/creational.rb +34 -0
  57. data/lib/mongoid/criterion/exclusion.rb +108 -0
  58. data/lib/mongoid/criterion/inclusion.rb +305 -0
  59. data/lib/mongoid/criterion/inspection.rb +22 -0
  60. data/lib/mongoid/criterion/optional.rb +232 -0
  61. data/lib/mongoid/criterion/selector.rb +153 -0
  62. data/lib/mongoid/cursor.rb +86 -0
  63. data/lib/mongoid/database_proxy.rb +97 -0
  64. data/lib/mongoid/default_scope.rb +36 -0
  65. data/lib/mongoid/dirty.rb +110 -0
  66. data/lib/mongoid/document.rb +280 -0
  67. data/lib/mongoid/errors.rb +17 -0
  68. data/lib/mongoid/errors/callback.rb +26 -0
  69. data/lib/mongoid/errors/document_not_found.rb +28 -0
  70. data/lib/mongoid/errors/eager_load.rb +25 -0
  71. data/lib/mongoid/errors/invalid_collection.rb +18 -0
  72. data/lib/mongoid/errors/invalid_database.rb +19 -0
  73. data/lib/mongoid/errors/invalid_field.rb +18 -0
  74. data/lib/mongoid/errors/invalid_find.rb +19 -0
  75. data/lib/mongoid/errors/invalid_options.rb +28 -0
  76. data/lib/mongoid/errors/invalid_time.rb +25 -0
  77. data/lib/mongoid/errors/invalid_type.rb +25 -0
  78. data/lib/mongoid/errors/mixed_relations.rb +37 -0
  79. data/lib/mongoid/errors/mongoid_error.rb +26 -0
  80. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
  81. data/lib/mongoid/errors/unsaved_document.rb +23 -0
  82. data/lib/mongoid/errors/unsupported_version.rb +20 -0
  83. data/lib/mongoid/errors/validations.rb +23 -0
  84. data/lib/mongoid/extensions.rb +82 -0
  85. data/lib/mongoid/extensions/array/deletion.rb +29 -0
  86. data/lib/mongoid/extensions/false_class/equality.rb +26 -0
  87. data/lib/mongoid/extensions/hash/criteria_helpers.rb +45 -0
  88. data/lib/mongoid/extensions/hash/scoping.rb +25 -0
  89. data/lib/mongoid/extensions/integer/checks.rb +23 -0
  90. data/lib/mongoid/extensions/nil/collectionization.rb +23 -0
  91. data/lib/mongoid/extensions/object/checks.rb +29 -0
  92. data/lib/mongoid/extensions/object/reflections.rb +48 -0
  93. data/lib/mongoid/extensions/object/substitutable.rb +15 -0
  94. data/lib/mongoid/extensions/object/yoda.rb +44 -0
  95. data/lib/mongoid/extensions/object_id/conversions.rb +60 -0
  96. data/lib/mongoid/extensions/proc/scoping.rb +25 -0
  97. data/lib/mongoid/extensions/string/checks.rb +36 -0
  98. data/lib/mongoid/extensions/string/conversions.rb +22 -0
  99. data/lib/mongoid/extensions/string/inflections.rb +118 -0
  100. data/lib/mongoid/extensions/symbol/checks.rb +23 -0
  101. data/lib/mongoid/extensions/symbol/inflections.rb +66 -0
  102. data/lib/mongoid/extensions/true_class/equality.rb +26 -0
  103. data/lib/mongoid/extras.rb +31 -0
  104. data/lib/mongoid/factory.rb +46 -0
  105. data/lib/mongoid/fields.rb +332 -0
  106. data/lib/mongoid/fields/mappings.rb +41 -0
  107. data/lib/mongoid/fields/serializable.rb +201 -0
  108. data/lib/mongoid/fields/serializable/array.rb +49 -0
  109. data/lib/mongoid/fields/serializable/big_decimal.rb +42 -0
  110. data/lib/mongoid/fields/serializable/bignum.rb +10 -0
  111. data/lib/mongoid/fields/serializable/binary.rb +11 -0
  112. data/lib/mongoid/fields/serializable/boolean.rb +43 -0
  113. data/lib/mongoid/fields/serializable/date.rb +51 -0
  114. data/lib/mongoid/fields/serializable/date_time.rb +28 -0
  115. data/lib/mongoid/fields/serializable/fixnum.rb +10 -0
  116. data/lib/mongoid/fields/serializable/float.rb +32 -0
  117. data/lib/mongoid/fields/serializable/foreign_keys/array.rb +42 -0
  118. data/lib/mongoid/fields/serializable/foreign_keys/object.rb +47 -0
  119. data/lib/mongoid/fields/serializable/hash.rb +11 -0
  120. data/lib/mongoid/fields/serializable/integer.rb +44 -0
  121. data/lib/mongoid/fields/serializable/localized.rb +41 -0
  122. data/lib/mongoid/fields/serializable/nil_class.rb +38 -0
  123. data/lib/mongoid/fields/serializable/object.rb +11 -0
  124. data/lib/mongoid/fields/serializable/object_id.rb +31 -0
  125. data/lib/mongoid/fields/serializable/range.rb +42 -0
  126. data/lib/mongoid/fields/serializable/set.rb +42 -0
  127. data/lib/mongoid/fields/serializable/string.rb +27 -0
  128. data/lib/mongoid/fields/serializable/symbol.rb +27 -0
  129. data/lib/mongoid/fields/serializable/time.rb +23 -0
  130. data/lib/mongoid/fields/serializable/time_with_zone.rb +23 -0
  131. data/lib/mongoid/fields/serializable/timekeeping.rb +106 -0
  132. data/lib/mongoid/finders.rb +152 -0
  133. data/lib/mongoid/hierarchy.rb +120 -0
  134. data/lib/mongoid/identity.rb +92 -0
  135. data/lib/mongoid/identity_map.rb +119 -0
  136. data/lib/mongoid/indexes.rb +54 -0
  137. data/lib/mongoid/inspection.rb +54 -0
  138. data/lib/mongoid/javascript.rb +20 -0
  139. data/lib/mongoid/javascript/functions.yml +63 -0
  140. data/lib/mongoid/json.rb +16 -0
  141. data/lib/mongoid/keys.rb +144 -0
  142. data/lib/mongoid/logger.rb +39 -0
  143. data/lib/mongoid/matchers.rb +32 -0
  144. data/lib/mongoid/matchers/all.rb +21 -0
  145. data/lib/mongoid/matchers/and.rb +30 -0
  146. data/lib/mongoid/matchers/default.rb +70 -0
  147. data/lib/mongoid/matchers/exists.rb +23 -0
  148. data/lib/mongoid/matchers/gt.rb +21 -0
  149. data/lib/mongoid/matchers/gte.rb +21 -0
  150. data/lib/mongoid/matchers/in.rb +21 -0
  151. data/lib/mongoid/matchers/lt.rb +21 -0
  152. data/lib/mongoid/matchers/lte.rb +21 -0
  153. data/lib/mongoid/matchers/ne.rb +21 -0
  154. data/lib/mongoid/matchers/nin.rb +21 -0
  155. data/lib/mongoid/matchers/or.rb +33 -0
  156. data/lib/mongoid/matchers/size.rb +21 -0
  157. data/lib/mongoid/matchers/strategies.rb +93 -0
  158. data/lib/mongoid/multi_database.rb +31 -0
  159. data/lib/mongoid/multi_parameter_attributes.rb +106 -0
  160. data/lib/mongoid/named_scope.rb +146 -0
  161. data/lib/mongoid/nested_attributes.rb +54 -0
  162. data/lib/mongoid/observer.rb +170 -0
  163. data/lib/mongoid/paranoia.rb +158 -0
  164. data/lib/mongoid/persistence.rb +264 -0
  165. data/lib/mongoid/persistence/atomic.rb +223 -0
  166. data/lib/mongoid/persistence/atomic/add_to_set.rb +35 -0
  167. data/lib/mongoid/persistence/atomic/bit.rb +37 -0
  168. data/lib/mongoid/persistence/atomic/inc.rb +31 -0
  169. data/lib/mongoid/persistence/atomic/operation.rb +85 -0
  170. data/lib/mongoid/persistence/atomic/pop.rb +34 -0
  171. data/lib/mongoid/persistence/atomic/pull.rb +34 -0
  172. data/lib/mongoid/persistence/atomic/pull_all.rb +34 -0
  173. data/lib/mongoid/persistence/atomic/push.rb +31 -0
  174. data/lib/mongoid/persistence/atomic/push_all.rb +31 -0
  175. data/lib/mongoid/persistence/atomic/rename.rb +31 -0
  176. data/lib/mongoid/persistence/atomic/sets.rb +30 -0
  177. data/lib/mongoid/persistence/atomic/unset.rb +28 -0
  178. data/lib/mongoid/persistence/deletion.rb +32 -0
  179. data/lib/mongoid/persistence/insertion.rb +41 -0
  180. data/lib/mongoid/persistence/modification.rb +37 -0
  181. data/lib/mongoid/persistence/operations.rb +211 -0
  182. data/lib/mongoid/persistence/operations/embedded/insert.rb +42 -0
  183. data/lib/mongoid/persistence/operations/embedded/remove.rb +40 -0
  184. data/lib/mongoid/persistence/operations/insert.rb +34 -0
  185. data/lib/mongoid/persistence/operations/remove.rb +33 -0
  186. data/lib/mongoid/persistence/operations/update.rb +64 -0
  187. data/lib/mongoid/railtie.rb +126 -0
  188. data/lib/mongoid/railties/database.rake +182 -0
  189. data/lib/mongoid/railties/document.rb +12 -0
  190. data/lib/mongoid/relations.rb +144 -0
  191. data/lib/mongoid/relations/accessors.rb +138 -0
  192. data/lib/mongoid/relations/auto_save.rb +38 -0
  193. data/lib/mongoid/relations/binding.rb +26 -0
  194. data/lib/mongoid/relations/bindings.rb +9 -0
  195. data/lib/mongoid/relations/bindings/embedded/in.rb +69 -0
  196. data/lib/mongoid/relations/bindings/embedded/many.rb +93 -0
  197. data/lib/mongoid/relations/bindings/embedded/one.rb +61 -0
  198. data/lib/mongoid/relations/bindings/referenced/in.rb +76 -0
  199. data/lib/mongoid/relations/bindings/referenced/many.rb +54 -0
  200. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +51 -0
  201. data/lib/mongoid/relations/bindings/referenced/one.rb +58 -0
  202. data/lib/mongoid/relations/builder.rb +57 -0
  203. data/lib/mongoid/relations/builders.rb +83 -0
  204. data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
  205. data/lib/mongoid/relations/builders/embedded/many.rb +40 -0
  206. data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
  207. data/lib/mongoid/relations/builders/nested_attributes/many.rb +110 -0
  208. data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
  209. data/lib/mongoid/relations/builders/referenced/in.rb +26 -0
  210. data/lib/mongoid/relations/builders/referenced/many.rb +27 -0
  211. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +38 -0
  212. data/lib/mongoid/relations/builders/referenced/one.rb +26 -0
  213. data/lib/mongoid/relations/cascading.rb +56 -0
  214. data/lib/mongoid/relations/cascading/delete.rb +19 -0
  215. data/lib/mongoid/relations/cascading/destroy.rb +26 -0
  216. data/lib/mongoid/relations/cascading/nullify.rb +18 -0
  217. data/lib/mongoid/relations/cascading/strategy.rb +26 -0
  218. data/lib/mongoid/relations/constraint.rb +42 -0
  219. data/lib/mongoid/relations/conversions.rb +35 -0
  220. data/lib/mongoid/relations/cyclic.rb +103 -0
  221. data/lib/mongoid/relations/embedded/atomic.rb +89 -0
  222. data/lib/mongoid/relations/embedded/atomic/operation.rb +63 -0
  223. data/lib/mongoid/relations/embedded/atomic/pull.rb +65 -0
  224. data/lib/mongoid/relations/embedded/atomic/push_all.rb +59 -0
  225. data/lib/mongoid/relations/embedded/atomic/set.rb +61 -0
  226. data/lib/mongoid/relations/embedded/atomic/unset.rb +41 -0
  227. data/lib/mongoid/relations/embedded/in.rb +220 -0
  228. data/lib/mongoid/relations/embedded/many.rb +560 -0
  229. data/lib/mongoid/relations/embedded/one.rb +206 -0
  230. data/lib/mongoid/relations/embedded/sort.rb +31 -0
  231. data/lib/mongoid/relations/macros.rb +310 -0
  232. data/lib/mongoid/relations/many.rb +135 -0
  233. data/lib/mongoid/relations/metadata.rb +919 -0
  234. data/lib/mongoid/relations/nested_builder.rb +75 -0
  235. data/lib/mongoid/relations/one.rb +36 -0
  236. data/lib/mongoid/relations/options.rb +47 -0
  237. data/lib/mongoid/relations/polymorphic.rb +40 -0
  238. data/lib/mongoid/relations/proxy.rb +145 -0
  239. data/lib/mongoid/relations/referenced/batch.rb +72 -0
  240. data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
  241. data/lib/mongoid/relations/referenced/in.rb +262 -0
  242. data/lib/mongoid/relations/referenced/many.rb +623 -0
  243. data/lib/mongoid/relations/referenced/many_to_many.rb +396 -0
  244. data/lib/mongoid/relations/referenced/one.rb +272 -0
  245. data/lib/mongoid/relations/reflections.rb +62 -0
  246. data/lib/mongoid/relations/synchronization.rb +153 -0
  247. data/lib/mongoid/relations/targets.rb +2 -0
  248. data/lib/mongoid/relations/targets/enumerable.rb +372 -0
  249. data/lib/mongoid/reloading.rb +91 -0
  250. data/lib/mongoid/safety.rb +105 -0
  251. data/lib/mongoid/scope.rb +31 -0
  252. data/lib/mongoid/serialization.rb +134 -0
  253. data/lib/mongoid/sharding.rb +61 -0
  254. data/lib/mongoid/state.rb +97 -0
  255. data/lib/mongoid/threaded.rb +530 -0
  256. data/lib/mongoid/threaded/lifecycle.rb +192 -0
  257. data/lib/mongoid/timestamps.rb +15 -0
  258. data/lib/mongoid/timestamps/created.rb +24 -0
  259. data/lib/mongoid/timestamps/timeless.rb +50 -0
  260. data/lib/mongoid/timestamps/updated.rb +26 -0
  261. data/lib/mongoid/validations.rb +140 -0
  262. data/lib/mongoid/validations/associated.rb +46 -0
  263. data/lib/mongoid/validations/uniqueness.rb +145 -0
  264. data/lib/mongoid/version.rb +4 -0
  265. data/lib/mongoid/versioning.rb +185 -0
  266. data/lib/rack/mongoid.rb +2 -0
  267. data/lib/rack/mongoid/middleware/identity_map.rb +38 -0
  268. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  269. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +20 -0
  270. data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
  271. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +19 -0
  272. data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
  273. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +4 -0
  274. data/lib/rails/generators/mongoid_generator.rb +70 -0
  275. data/lib/rails/mongoid.rb +91 -0
  276. metadata +465 -0
@@ -0,0 +1,135 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+
4
+ # This module contains all the callback hooks for Mongoid.
5
+ module Callbacks
6
+ extend ActiveSupport::Concern
7
+
8
+ CALLBACKS = [
9
+ :before_validation, :after_validation,
10
+ :after_initialize,
11
+ :before_create, :around_create, :after_create,
12
+ :before_destroy, :around_destroy, :after_destroy,
13
+ :before_save, :around_save, :after_save,
14
+ :before_update, :around_update, :after_update,
15
+ ]
16
+
17
+ included do
18
+ extend ActiveModel::Callbacks
19
+ include ActiveModel::Validations::Callbacks
20
+
21
+ define_model_callbacks :initialize, :only => :after
22
+ define_model_callbacks :create, :destroy, :save, :update
23
+ end
24
+
25
+ # Run the callbacks for the document. This overrides active support's
26
+ # functionality to cascade callbacks to embedded documents that have been
27
+ # flagged as such.
28
+ #
29
+ # @example Run the callbacks.
30
+ # run_callbacks :save do
31
+ # save!
32
+ # end
33
+ #
34
+ # @param [ Symbol ] kind The type of callback to execute.
35
+ # @param [ Array ] *args Any options.
36
+ #
37
+ # @return [ Document ] The document
38
+ #
39
+ # @since 2.3.0
40
+ def run_callbacks(kind, *args, &block)
41
+ run_cascading_callbacks(cascadable_children(kind), kind, *args) do
42
+ super(kind, *args, &block)
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ # Execute the callbacks, including all children that have cascade callbacks
49
+ # set to true.
50
+ #
51
+ # @example Run the cascading callbacks.
52
+ # document.run_cascading_callbacks([], :update)
53
+ #
54
+ # @param [ Array<Document> ] children The cascading children.
55
+ # @param [ Symbol ] kind The callback type.
56
+ # @param [ Array ] args The options.
57
+ #
58
+ # @since 2.3.0
59
+ def run_cascading_callbacks(children, kind, *args, &block)
60
+ if child = children.pop
61
+ run_cascading_callbacks(children, kind, *args) do
62
+ child.run_callbacks(child_callback_type(kind, child), *args) do
63
+ block.call
64
+ end
65
+ end
66
+ else
67
+ block.call
68
+ end
69
+ end
70
+
71
+ # Get all the child embedded documents that are flagged as cascadable.
72
+ #
73
+ # @example Get all the cascading children.
74
+ # document.cascadable_children(:update)
75
+ #
76
+ # @param [ Symbol ] kind The type of callback.
77
+ #
78
+ # @return [ Array<Document> ] The children.
79
+ #
80
+ # @since 2.3.0
81
+ def cascadable_children(kind)
82
+ [].tap do |children|
83
+ relations.each_pair do |name, metadata|
84
+ next unless metadata.cascading_callbacks?
85
+ delayed_pulls = delayed_atomic_pulls[name]
86
+ children.concat(delayed_pulls) if delayed_pulls
87
+ child = send(name)
88
+ Array.wrap(child).each do |doc|
89
+ children.push(doc) if cascadable_child?(kind, doc)
90
+ children.concat(doc.send(:cascadable_children, kind))
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ # Determine if the child should fire the callback.
97
+ #
98
+ # @example Should the child fire the callback?
99
+ # document.cascadable_child?(:update, doc)
100
+ #
101
+ # @param [ Symbol ] kind The type of callback.
102
+ # @param [ Document ] child The child document.
103
+ #
104
+ # @return [ true, false ] If the child should fire the callback.
105
+ #
106
+ # @since 2.3.0
107
+ def cascadable_child?(kind, child)
108
+ [ :create, :destroy ].include?(kind) || child.changed? || child.new_record?
109
+ end
110
+
111
+ # Get the name of the callback that the child should fire. This changes
112
+ # depending on whether or not the child is new. A persisted parent with a
113
+ # new child would fire :update from the parent, but needs to fire :create
114
+ # on the child.
115
+ #
116
+ # @example Get the callback type.
117
+ # document.child_callback_type(:update, doc)
118
+ #
119
+ # @param [ Symbol ] kind The type of callback.
120
+ # @param [ Document ] child The child document
121
+ #
122
+ # @return [ Symbol ] The name of the callback.
123
+ #
124
+ # @since 2.3.0
125
+ def child_callback_type(kind, child)
126
+ if kind == :update
127
+ return :create if child.new_record?
128
+ return :destroy if child.flagged_for_destroy?
129
+ kind
130
+ else
131
+ kind
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,153 @@
1
+ # encoding: utf-8
2
+ require "mongoid/collections/retry"
3
+ require "mongoid/collections/operations"
4
+ require "mongoid/collections/master"
5
+
6
+ module Mongoid #:nodoc
7
+
8
+ # This class is the Mongoid wrapper to the Mongo Ruby driver's collection
9
+ # object.
10
+ class Collection
11
+ attr_reader :counter, :klass, :name
12
+
13
+ # All write operations should delegate to the master connection. These
14
+ # operations mimic the methods on a Mongo:Collection.
15
+ #
16
+ # @example Delegate the operation.
17
+ # collection.save({ :name => "Al" })
18
+ delegate *(Collections::Operations::PROXIED.dup << {:to => :master})
19
+
20
+ # Get the unwrapped driver collection for this mongoid collection.
21
+ #
22
+ # @example Get the driver collection.
23
+ # collection.driver
24
+ #
25
+ # @return [ Mongo::Collection ] The driver collection.
26
+ #
27
+ # @since 2.2.0
28
+ def driver
29
+ master.collection
30
+ end
31
+
32
+ # Find documents from the database given a selector and options.
33
+ #
34
+ # @example Find documents in the collection.
35
+ # collection.find({ :test => "value" })
36
+ #
37
+ # @param [ Hash ] selector The query selector.
38
+ # @param [ Hash ] options The options to pass to the db.
39
+ #
40
+ # @return [ Cursor ] The results.
41
+ def find(selector = {}, options = {})
42
+ cursor = Mongoid::Cursor.new(klass, self, master(options).find(selector, options))
43
+ if block_given?
44
+ yield cursor; cursor.close
45
+ else
46
+ cursor
47
+ end
48
+ end
49
+
50
+ # Find the first document from the database given a selector and options.
51
+ #
52
+ # @example Find one document.
53
+ # collection.find_one({ :test => "value" })
54
+ #
55
+ # @param [ Hash ] selector The query selector.
56
+ # @param [ Hash ] options The options to pass to the db.
57
+ #
58
+ # @return [ Document, nil ] A matching document or nil if none found.
59
+ def find_one(selector = {}, options = {})
60
+ master(options).find_one(selector, options)
61
+ end
62
+
63
+ # Initialize a new Mongoid::Collection, setting up the master, slave, and
64
+ # name attributes. Masters will be used for writes, slaves for reads.
65
+ #
66
+ # @example Create the new collection.
67
+ # Collection.new(masters, slaves, "test")
68
+ #
69
+ # @param [ Class ] klass The class the collection is for.
70
+ # @param [ String ] name The name of the collection.
71
+ # @param [ Hash ] options The collection options.
72
+ #
73
+ # @option options [ true, false ] :capped If the collection is capped.
74
+ # @option options [ Integer ] :size The capped collection size.
75
+ # @option options [ Integer ] :max The maximum number of docs in the
76
+ # capped collection.
77
+ def initialize(klass, name, options = {})
78
+ @klass, @name, @options = klass, name, options || {}
79
+ end
80
+
81
+ # Inserts one or more documents in the collection.
82
+ #
83
+ # @example Insert documents.
84
+ # collection.insert(
85
+ # { "field" => "value" },
86
+ # :safe => true
87
+ # )
88
+ #
89
+ # @param [ Hash, Array<Hash> ] documents A single document or multiples.
90
+ # @param [ Hash ] options The options.
91
+ #
92
+ # @since 2.0.2, batch-relational-insert
93
+ def insert(documents, options = {})
94
+ consumer = Threaded.insert
95
+ if consumer
96
+ consumer.consume(documents, options)
97
+ else
98
+ master(options).insert(documents, options)
99
+ end
100
+ end
101
+
102
+ # Perform a map/reduce on the documents.
103
+ #
104
+ # @example Perform the map/reduce.
105
+ # collection.map_reduce(map, reduce)
106
+ #
107
+ # @param [ String ] map The map javascript function.
108
+ # @param [ String ] reduce The reduce javascript function.
109
+ # @param [ Hash ] options The options to pass to the db.
110
+ #
111
+ # @return [ Cursor ] The results.
112
+ def map_reduce(map, reduce, options = {})
113
+ master(options).map_reduce(map, reduce, options)
114
+ end
115
+ alias :mapreduce :map_reduce
116
+
117
+ # Return the object responsible for writes to the database. This will
118
+ # always return a collection associated with the Master DB.
119
+ #
120
+ # @example Get the master connection.
121
+ # collection.master
122
+ #
123
+ # @return [ Master ] The master connection.
124
+ def master(options = {})
125
+ options.delete(:cache)
126
+ db = Mongoid.databases[klass.database] || Mongoid.master
127
+ @master ||= Collections::Master.new(db, @name, @options)
128
+ end
129
+
130
+ # Updates one or more documents in the collection.
131
+ #
132
+ # @example Update documents.
133
+ # collection.update(
134
+ # { "_id" => BSON::OjectId.new },
135
+ # { "$push" => { "addresses" => { "_id" => "street" } } },
136
+ # :safe => true
137
+ # )
138
+ #
139
+ # @param [ Hash ] selector The document selector.
140
+ # @param [ Hash ] document The modifier.
141
+ # @param [ Hash ] options The options.
142
+ #
143
+ # @since 2.0.0
144
+ def update(selector, document, options = {})
145
+ updater = Threaded.update_consumer(klass)
146
+ if updater
147
+ updater.consume(selector, document, options)
148
+ else
149
+ master(options).update(selector, document, options)
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,59 @@
1
+ require 'thread'
2
+
3
+ #
4
+ # Proxy that enables runtime swapping of a MongoDB collection, as it
5
+ # appears to be cached at several points within Mongoid.
6
+ #
7
+ # This proxy is generated by the DatabaseProxy when asked for a
8
+ # specific collection.
9
+ #
10
+ class CollectionProxy
11
+ #
12
+ # Class-level instance variables.
13
+ #
14
+ @mutex = Mutex.new
15
+ @pool = Hash.new
16
+
17
+ #
18
+ # Accessor for class-level instance variable that holds all the
19
+ # db-collection pairs that we know about, so that we can switch all
20
+ # of them globally.
21
+ #
22
+ def CollectionProxy.pool
23
+ @pool
24
+ end
25
+
26
+ #
27
+ # Collection-global mutex... for great thread safety!
28
+ #
29
+ def CollectionProxy.mutex
30
+ @mutex
31
+ end
32
+
33
+ #
34
+ # Set our default connection and name.
35
+ #
36
+ def initialize(db, name, opts)
37
+ @db, @name, @opts = db, name, opts
38
+ end
39
+
40
+ #
41
+ # Convenience method for synchronizing threads.
42
+ #
43
+ def synchronize(&block)
44
+ CollectionProxy.mutex.synchronize(&block)
45
+ end
46
+
47
+ #
48
+ # Proxy methods to the correct collection. We do this by trying to
49
+ # find a matching collection in our pool, and if not, we create one
50
+ # using the _name_ and _opts_ initially passed to initialize.
51
+ #
52
+ def method_missing(*args, &block)
53
+ collection = synchronize do
54
+ pool = (CollectionProxy.pool[@db.target] ||= {})
55
+ pool[@name] ||= @db.target.create_collection(@name, @opts)
56
+ end
57
+ collection.send(*args, &block)
58
+ end
59
+ end
@@ -0,0 +1,120 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+
4
+ # The collections module is used for providing functionality around setting
5
+ # up and updating collections.
6
+ module Collections
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ cattr_accessor :_collection, :collection_name
11
+ self.collection_name = self.name.collectionize
12
+ end
13
+
14
+ # Get the collection for the class.
15
+ #
16
+ # @note Defining methods instead of delegate to avoid calls to
17
+ # Kernel.caller for class load performance reasons.
18
+ #
19
+ # @example Get the collection.
20
+ # person.collection
21
+ #
22
+ # @return [ Collection ] The class collection.
23
+ #
24
+ # @since 1.0.0
25
+ def collection
26
+ self.class.collection
27
+ end
28
+
29
+ # Get the database for the class.
30
+ #
31
+ # @note Defining methods instead of delegate to avoid calls to
32
+ # Kernel.caller for class load performance reasons.
33
+ #
34
+ # @example Get the database.
35
+ # person.db
36
+ #
37
+ # @return [ DB ] The class db.
38
+ #
39
+ # @since 1.0.0
40
+ def db
41
+ self.class.db
42
+ end
43
+
44
+ module ClassMethods #:nodoc:
45
+
46
+ # Returns the collection associated with this +Document+. If the
47
+ # document is embedded, there will be no collection associated
48
+ # with it unless it's in a cyclic relation.
49
+ #
50
+ # @example Get the collection.
51
+ # Model.collection
52
+ #
53
+ # @return [ Collection ] The Mongoid collection wrapper.
54
+ def collection
55
+ raise Errors::InvalidCollection.new(self) if embedded? && !cyclic
56
+ self._collection || set_collection
57
+ add_indexes; self._collection
58
+ end
59
+
60
+ # Return the database associated with this collection.
61
+ #
62
+ # @example Get the database object.
63
+ # Model.db
64
+ #
65
+ # @return [ Mongo::DB ] The Mongo daatabase object.
66
+ def db
67
+ collection.db
68
+ end
69
+
70
+ # Convenience method for getting index information from the collection.
71
+ #
72
+ # @example Get the index information from the collection.
73
+ # Model.index_information
74
+ #
75
+ # @return [ Array ] The collection index information.
76
+ def index_information
77
+ collection.index_information
78
+ end
79
+
80
+ # Macro for setting the collection name to store in.
81
+ #
82
+ # @example Store in a separate collection than the default.
83
+ # Model.store_in :population
84
+ #
85
+ # @example Store in a capped collection.
86
+ # Model.store_in :population, :capped => true, :max => 10000
87
+ #
88
+ # @param [ Symbol ] name The name of the collection.
89
+ # @param [ Hash ] options The collection options.
90
+ #
91
+ # @option options [ true, false ] :capped If the collection is capped.
92
+ # @option options [ Integer ] :size The capped collection size.
93
+ # @option options [ Integer ] :max The maximum number of docs in the
94
+ # capped collection.
95
+ def store_in(name, options = {})
96
+ self.collection_name = name.to_s
97
+ set_collection(options)
98
+ end
99
+
100
+ protected
101
+
102
+ # Set the collection on the class.
103
+ #
104
+ # @example Set the collection.
105
+ # Model.set_collection
106
+ #
107
+ # @param [ Hash ] options The collection options.
108
+ #
109
+ # @option options [ true, false ] :capped If the collection is capped.
110
+ # @option options [ Integer ] :size The capped collection size.
111
+ # @option options [ Integer ] :max The maximum number of docs in the
112
+ # capped collection.
113
+
114
+ # @return [ Collection ] The Mongoid collection wrapper.
115
+ def set_collection(options = {})
116
+ self._collection = Collection.new(self, self.collection_name, options)
117
+ end
118
+ end
119
+ end
120
+ end