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,92 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ class Identity #:nodoc:
4
+
5
+ attr_reader :document
6
+
7
+ # Create the identity for the document. The id will be set in either in
8
+ # the form of a Mongo object id or a composite key set up by defining
9
+ # a key on the document. The _type will be set to the document's class
10
+ # name.
11
+ #
12
+ # @example Create the id and set the type.
13
+ # identity.create
14
+ def create
15
+ identify.tap { type }
16
+ end
17
+
18
+ # Create the new identity generator - this will be expanded in the future
19
+ # to support pk generators.
20
+ #
21
+ # @example
22
+ # Identity.new(document)
23
+ #
24
+ # @param [ Document ] document The document to generate an id for.
25
+ #
26
+ # @return [ Identity ] The new identity object.
27
+ def initialize(document)
28
+ @document = document
29
+ end
30
+
31
+ private
32
+
33
+ # Return the proper id for the document. Will be an object id or its string
34
+ # representation depending on the configuration.
35
+ #
36
+ # @example Generate the id.
37
+ # identity.generate_id
38
+ #
39
+ # @return [ Object ] The bson object id or its string equivalent.
40
+ def generate_id
41
+ id = BSON::ObjectId.new
42
+ document.using_object_ids? ? id : id.to_s
43
+ end
44
+
45
+ # Sets the id on the document. Will either set a newly generated id or
46
+ # build the composite key.
47
+ #
48
+ # @example Set the id.
49
+ # identity.identify
50
+ def identify
51
+ document.id = compose.join(" ").identify if document.primary_key
52
+ document.id = generate_id if document.id.blank?
53
+ document.id
54
+ end
55
+
56
+ # Set the _type field on the document if the document is hereditary or in a
57
+ # polymorphic relation.
58
+ #
59
+ # @example Set the type.
60
+ # identity.type
61
+ def type
62
+ document._type = document.class.name if typed?
63
+ end
64
+
65
+ # Generates the array of keys to build the id.
66
+ #
67
+ # @example Build the array for the keys.
68
+ # identity.compose.
69
+ #
70
+ # @return [ Array<Object> ] The array of keys.
71
+ def compose
72
+ kf = document.key_formatter
73
+ document.primary_key.collect do |key|
74
+ val = document.attributes[key.to_s]
75
+ val && kf ? kf.call(val) : val
76
+ end.compact
77
+ end
78
+
79
+ # Determines if the document stores the type information. This is if it is
80
+ # in a hierarchy, has subclasses, or is in a polymorphic relation.
81
+ #
82
+ # @example Check if the document is typed.
83
+ # identity.typed?
84
+ #
85
+ # @return [ true, false ] True if typed, false if not.
86
+ def typed?
87
+ document.hereditary? ||
88
+ document.class.descendants.any? ||
89
+ document.polymorphic?
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,119 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+
4
+ # Defines behaviour for the identity map in Mongoid.
5
+ class IdentityMap < Hash
6
+
7
+ # Get a document from the identity map by its id.
8
+ #
9
+ # @example Get the document from the map.
10
+ # map.get(Person, id)
11
+ #
12
+ # @param [ Class ] klass The class of the document.
13
+ # @param [ Object, Hash ] idenfier The document id or selector.
14
+ #
15
+ # @return [ Document ] The matching document.
16
+ #
17
+ # @since 2.1.0
18
+ def get(klass, identifier)
19
+ return nil unless Mongoid.identity_map_enabled?
20
+ documents_for(klass)[identifier]
21
+ end
22
+
23
+ # Remove the document from the identity map.
24
+ #
25
+ # @example Remove the document.
26
+ # map.removed(person)
27
+ #
28
+ # @param [ Document ] document The document to remove.
29
+ #
30
+ # @return [ Document, nil ] The removed document.
31
+ #
32
+ # @since 2.1.0
33
+ def remove(document)
34
+ return nil unless Mongoid.identity_map_enabled? && document && document.id
35
+ documents_for(document.class).delete(document.id)
36
+ end
37
+
38
+ # Puts a document in the identity map, accessed by it's id.
39
+ #
40
+ # @example Put the document in the map.
41
+ # identity_map.set(document)
42
+ #
43
+ # @param [ Document ] document The document to place in the map.
44
+ #
45
+ # @return [ Document ] The provided document.
46
+ #
47
+ # @since 2.1.0
48
+ def set(document)
49
+ return nil unless Mongoid.identity_map_enabled? && document && document.id
50
+ documents_for(document.class)[document.id] = document
51
+ end
52
+
53
+ # Set a document in the identity map for the provided selector.
54
+ #
55
+ # @example Set the document in the map.
56
+ # identity_map.set_selector(document, { :person_id => person.id })
57
+ #
58
+ # @param [ Document ] document The document to set.
59
+ # @param [ Hash ] selector The selector to identify it.
60
+ #
61
+ # @return [ Array<Document> ] The documents.
62
+ #
63
+ # @since 2.2.0
64
+ def set_many(document, selector)
65
+ (documents_for(document.class)[selector] ||= []).push(document)
66
+ end
67
+
68
+ # Set a document in the identity map for the provided selector.
69
+ #
70
+ # @example Set the document in the map.
71
+ # identity_map.set_selector(document, { :person_id => person.id })
72
+ #
73
+ # @param [ Document ] document The document to set.
74
+ # @param [ Hash ] selector The selector to identify it.
75
+ #
76
+ # @return [ Document ] The matching document.
77
+ #
78
+ # @since 2.2.0
79
+ def set_one(document, selector)
80
+ documents_for(document.class)[selector] = document
81
+ end
82
+
83
+ private
84
+
85
+ # Get the documents in the identity map for a specific class.
86
+ #
87
+ # @example Get the documents for the class.
88
+ # map.documents_for(Person)
89
+ #
90
+ # @param [ Class ] klass The class to retrieve.
91
+ #
92
+ # @return [ Hash ] The documents.
93
+ #
94
+ # @since 2.1.0
95
+ def documents_for(klass)
96
+ self[klass] ||= {}
97
+ end
98
+
99
+ class << self
100
+
101
+ # For ease of access we provide the same API to the identity map on the
102
+ # class level, which in turn just gets the identity map that is on the
103
+ # current thread.
104
+ #
105
+ # @example Get a document from the current identity map by id.
106
+ # IdentityMap.get(id)
107
+ #
108
+ # @example Set a document in the current identity map.
109
+ # IdentityMap.set(document)
110
+ #
111
+ # @since 2.1.0
112
+ delegate *(
113
+ Hash.public_instance_methods(false) +
114
+ IdentityMap.public_instance_methods(false) <<
115
+ { :to => :"Mongoid::Threaded.identity_map" }
116
+ )
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ module Indexes #:nodoc
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ cattr_accessor :index_options
8
+ self.index_options = {}
9
+ end
10
+
11
+ module ClassMethods #:nodoc
12
+
13
+ # Send the actual index creation comments to the MongoDB driver
14
+ #
15
+ # @example Create the indexes for the class.
16
+ # Person.create_indexes
17
+ def create_indexes
18
+ return unless index_options
19
+ current_collection = self._collection || set_collection
20
+ index_options.each_pair do |name, options|
21
+ current_collection.create_index(name, options)
22
+ end
23
+ end
24
+
25
+ # Add the default indexes to the root document if they do not already
26
+ # exist. Currently this is only _type.
27
+ #
28
+ # @example Add Mongoid internal indexes.
29
+ # Person.add_indexes
30
+ def add_indexes
31
+ if hereditary? && !index_options[:_type]
32
+ self.index_options[:_type] = {:unique => false, :background => true}
33
+ end
34
+ create_indexes if Mongoid.autocreate_indexes
35
+ end
36
+
37
+ # Adds an index on the field specified. Options can be :unique => true or
38
+ # :unique => false. It will default to the latter.
39
+ #
40
+ # @example Create a basic index.
41
+ # class Person
42
+ # include Mongoid::Document
43
+ # field :name, :type => String
44
+ # index :name, :background => true
45
+ #
46
+ # @param [ Symbol ] name The name of the field.
47
+ # @param [ Hash ] options The index options.
48
+ def index(name, options = { :unique => false })
49
+ self.index_options[name] = options
50
+ create_indexes if Mongoid.autocreate_indexes
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+
4
+ # Contains the bahviour around inspecting documents via
5
+ # <tt>Object#inspect</tt>.
6
+ module Inspection
7
+
8
+ # Returns the class name plus its attributes. If using dynamic fields will
9
+ # include those as well.
10
+ #
11
+ # @example Inspect the document.
12
+ # person.inspect
13
+ #
14
+ # @return [ String ] A nice pretty string to look at.
15
+ def inspect
16
+ inspection = []
17
+ inspection.concat(inspect_fields).concat(inspect_dynamic_fields)
18
+ "#<#{self.class.name} _id: #{id}, #{inspection * ', '}>"
19
+ end
20
+
21
+ private
22
+
23
+ # Get an array of inspected fields for the document.
24
+ #
25
+ # @example Inspect the defined fields.
26
+ # document.inspect_fields
27
+ #
28
+ # @return [ String ] An array of pretty printed field values.
29
+ def inspect_fields
30
+ fields.map do |name, field|
31
+ unless name == "_id"
32
+ "#{name}: #{@attributes[name].inspect}"
33
+ end
34
+ end.compact
35
+ end
36
+
37
+ # Get an array of inspected dynamic fields for the document.
38
+ #
39
+ # @example Inspect the dynamic fields.
40
+ # document.inspect_dynamic_fields
41
+ #
42
+ # @return [ String ] An array of pretty printed dynamic field values.
43
+ def inspect_dynamic_fields
44
+ if Mongoid.allow_dynamic_fields
45
+ keys = @attributes.keys - fields.keys - relations.keys - ["_id", "_type"]
46
+ return keys.map do |name|
47
+ "#{name}: #{@attributes[name].inspect}"
48
+ end
49
+ else
50
+ []
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ class Javascript
4
+ # Constant for the file that defines all the js functions.
5
+ FUNCTIONS = File.join(File.dirname(__FILE__), "javascript", "functions.yml")
6
+
7
+ # Load the javascript functions and define a class method for each one,
8
+ # that memoizes the value.
9
+ #
10
+ # @example Get the function.
11
+ # Mongoid::Javascript.aggregate
12
+ YAML.load(File.read(FUNCTIONS)).each_pair do |key, function|
13
+ (class << self; self; end).class_eval <<-EOT
14
+ def #{key}
15
+ @#{key} ||= "#{function}"
16
+ end
17
+ EOT
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,63 @@
1
+ aggregate:
2
+ "function(obj, prev) {
3
+ prev.count++;
4
+ }"
5
+
6
+ group:
7
+ "function(obj, prev) {
8
+ prev.group.push(obj);
9
+ }"
10
+
11
+ max:
12
+ "function(obj, prev) {
13
+ if (obj.[field] && prev.max == 'start') {
14
+ prev.max = obj.[field];
15
+ }
16
+ if (obj.[field] && prev.max < obj.[field]) {
17
+ prev.max = obj.[field];
18
+ }
19
+ }"
20
+
21
+ max_finalize:
22
+ "function(obj) {
23
+ if (obj.max == 'start' || isNaN(obj.max)) {
24
+ obj.max = 0;
25
+ }
26
+ return obj;
27
+ }"
28
+
29
+ min:
30
+ "function(obj, prev) {
31
+ if (obj.[field] && prev.min == 'start') {
32
+ prev.min = obj.[field];
33
+ }
34
+ if (obj.[field] && prev.min > obj.[field]) {
35
+ prev.min = obj.[field];
36
+ }
37
+ }"
38
+
39
+ min_finalize:
40
+ "function(obj) {
41
+ if (obj.min == 'start' || isNaN(obj.min)) {
42
+ obj.min = 0;
43
+ }
44
+ return obj;
45
+ }"
46
+
47
+ sum:
48
+ "function(obj, prev) {
49
+ if (prev.sum == 'start') {
50
+ prev.sum = 0;
51
+ }
52
+ if (obj.[field]) {
53
+ prev.sum += obj.[field];
54
+ }
55
+ }"
56
+
57
+ sum_finalize:
58
+ "function(obj) {
59
+ if (obj.sum == 'start' || isNaN(obj.sum)) {
60
+ obj.sum = 0;
61
+ }
62
+ return obj;
63
+ }"
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ # This module is for hooking in to +ActiveModel+s serialization to let
4
+ # configuring the ability to include the root in JSON happen from the Mongoid
5
+ # config.
6
+ module JSON
7
+ extend ActiveSupport::Concern
8
+
9
+ # We need to redefine where the JSON configuration is getting defined,
10
+ # similar to +ActiveRecord+.
11
+ included do
12
+ undef_method :include_root_in_json
13
+ delegate :include_root_in_json, :to => ::Mongoid
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,144 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+
4
+ # This module defines the behaviour for overriding the default ids on
5
+ # documents.
6
+ module Keys
7
+ extend ActiveSupport::Concern
8
+
9
+ attr_reader :identifier
10
+
11
+ included do
12
+ cattr_accessor :primary_key, :using_object_ids, :key_formatter
13
+ self.using_object_ids = true
14
+ end
15
+
16
+ # Get the document's primary key.
17
+ #
18
+ # @note Refactored from using delegate for class load performance.
19
+ #
20
+ # @example Get the primary key.
21
+ # model.primary_key
22
+ #
23
+ # @return [ Array ] The primary key
24
+ def primary_key
25
+ self.class.primary_key
26
+ end
27
+
28
+ # Is the document using object ids?
29
+ #
30
+ # @note Refactored from using delegate for class load performance.
31
+ #
32
+ # @example Is the document using object ids?
33
+ # model.using_object_ids?
34
+ #
35
+ # @return [ true, false ] Using object ids.
36
+ def using_object_ids?
37
+ self.class.using_object_ids?
38
+ end
39
+
40
+ private
41
+
42
+ # Determines if any field that the document id is composed of has changed.
43
+ #
44
+ # @example Has any key field changed?
45
+ # document.key_field_changed?
46
+ #
47
+ # @return [ true, false ] Has a key field changed?
48
+ #
49
+ # @since 2.0.0
50
+ def key_field_changed?
51
+ primary_key.any? { |field| changed.include?(field.to_s) }
52
+ end
53
+
54
+ # Sits around a save when composite keys are in play to handle the id magic
55
+ # if a key field has changed.
56
+ #
57
+ # @example Set the composite key.
58
+ # document.set_composite_key
59
+ #
60
+ # @param [ Proc ] block The block this surrounds.
61
+ #
62
+ # @since 2.0.0
63
+ def set_composite_key(&block)
64
+ if persisted? && key_field_changed?
65
+ swap_composite_keys(&block)
66
+ else
67
+ identify and block.call
68
+ end
69
+ end
70
+
71
+ # Swap out the composite key only after the document has been saved.
72
+ #
73
+ # @example Swap out the keys.
74
+ # document.swap_composite_keys
75
+ #
76
+ # @param [ Proc ] block The save block getting called.
77
+ #
78
+ # @since 2.0.0
79
+ def swap_composite_keys(&block)
80
+ @identifier, new_id = id.dup, identify
81
+ block.call
82
+ @identifier = nil
83
+ end
84
+
85
+ module ClassMethods #:nodoc:
86
+
87
+ # Used for telling Mongoid on a per model basis whether to override the
88
+ # default +BSON::ObjectId+ and use a different type. This will be
89
+ # expanded in the future for requiring a PkFactory if the type is not a
90
+ # +BSON::ObjectId+ or +String+.
91
+ #
92
+ # @example Change the documents key type.
93
+ # class Person
94
+ # include Mongoid::Document
95
+ # identity :type => String
96
+ # end
97
+ #
98
+ # @param [ Hash ] options The options.
99
+ #
100
+ # @option options [ Class ] :type The type of the id.
101
+ #
102
+ # @since 2.0.0.beta.1
103
+ def identity(options = {})
104
+ type = options[:type]
105
+ replace_field("_id", type)
106
+ self.using_object_ids = (type == BSON::ObjectId)
107
+ end
108
+
109
+ # Defines the field that will be used for the id of this +Document+. This
110
+ # set the id of this +Document+ before save to a parameterized version of
111
+ # the field that was supplied. This is good for use for readable URLS in
112
+ # web applications.
113
+ #
114
+ # @example Create a composite id.
115
+ # class Person
116
+ # include Mongoid::Document
117
+ # key :first_name, :last_name
118
+ # end
119
+ #
120
+ # @param [ Array<Symbol> ] The fields the key is composed of.
121
+ #
122
+ # @since 1.0.0
123
+ def key(*fields)
124
+ self.primary_key = fields
125
+ self.key_formatter = block_given? ? Proc.new : nil
126
+ identity(:type => String)
127
+ set_callback(:save, :around, :set_composite_key)
128
+ end
129
+
130
+ # Convenience method for determining if we are using +BSON::ObjectIds+ as
131
+ # our id.
132
+ #
133
+ # @example Does this class use object ids?
134
+ # person.using_object_ids?
135
+ #
136
+ # @return [ true, false ] If the class uses BSON::ObjectIds for the id.
137
+ #
138
+ # @since 1.0.0
139
+ def using_object_ids?
140
+ using_object_ids
141
+ end
142
+ end
143
+ end
144
+ end