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,91 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ # This module handles reloading behaviour of documents.
4
+ module Reloading
5
+
6
+ # Reloads the +Document+ attributes from the database. If the document has
7
+ # not been saved then an error will get raised if the configuration option
8
+ # was set. This can reload root documents or embedded documents.
9
+ #
10
+ # @example Reload the document.
11
+ # person.reload
12
+ #
13
+ # @raise [ Errors::DocumentNotFound ] If the document was deleted.
14
+ #
15
+ # @return [ Document ] The document, reloaded.
16
+ #
17
+ # @since 1.0.0
18
+ def reload
19
+ _reload.tap do |reloaded|
20
+ if Mongoid.raise_not_found_error && reloaded.empty?
21
+ raise Errors::DocumentNotFound.new(self.class, id)
22
+ end
23
+ @attributes = reloaded
24
+ end
25
+ tap do |doc|
26
+ doc.changed_attributes.clear
27
+ doc.apply_defaults
28
+ doc.reload_relations
29
+ doc.run_callbacks(:initialize)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ # Reload the document, determining if it's embedded or not and what
36
+ # behaviour to use.
37
+ #
38
+ # @example Reload the document.
39
+ # document._reload
40
+ #
41
+ # @return [ Hash ] The reloaded attributes.
42
+ #
43
+ # @since 2.3.2
44
+ def _reload
45
+ embedded? ? reload_embedded_document : reload_root_document
46
+ end
47
+
48
+ # Reload the root document.
49
+ #
50
+ # @example Reload the document.
51
+ # document.reload_root_document
52
+ #
53
+ # @return [ Hash ] The reloaded attributes.
54
+ #
55
+ # @since 2.3.2
56
+ def reload_root_document
57
+ {}.merge(collection.find_one(:_id => id) || {})
58
+ end
59
+
60
+ # Reload the embedded document.
61
+ #
62
+ # @example Reload the document.
63
+ # document.reload_embedded_document
64
+ #
65
+ # @return [ Hash ] The reloaded attributes.
66
+ #
67
+ # @since 2.3.2
68
+ def reload_embedded_document
69
+ extract_embedded_attributes({}.merge(
70
+ _root.collection.find_one(:_id => _root.id)
71
+ ))
72
+ end
73
+
74
+ # Extract only the desired embedded document from the attributes.
75
+ #
76
+ # @example Extract the embedded document.
77
+ # document.extract_embedded_attributes(attributes)
78
+ #
79
+ # @param [ Hash ] attributes The document in the db.
80
+ #
81
+ # @return [ Hash ] The document's extracted attributes.
82
+ #
83
+ # @since 2.3.2
84
+ def extract_embedded_attributes(attributes)
85
+ atomic_position.split(".").inject(attributes) do |attrs, part|
86
+ attrs = attrs[part =~ /\d/ ? part.to_i : part]
87
+ attrs
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+
4
+ # The +Safety+ module is used to provide a DSL to execute database operations
5
+ # in safe mode on a per query basis, either from the +Document+ class level
6
+ # or instance level.
7
+ module Safety
8
+ extend ActiveSupport::Concern
9
+
10
+ # Execute the following instance-level persistence operation in safe mode.
11
+ #
12
+ # @example Upsert in safe mode.
13
+ # person.safely.upsert
14
+ #
15
+ # @example Destroy in safe mode with w and fsync options.
16
+ # person.safely(:w => 2, :fsync => true).destroy
17
+ #
18
+ # @param [ Hash ] options The safe mode options.
19
+ #
20
+ # @option options [ Integer ] :w The number of nodes to write to.
21
+ # @option options [ Integer ] :wtimeout Time to wait for return from all
22
+ # nodes.
23
+ # @option options [ true, false ] :fsync Should a fsync occur.
24
+ #
25
+ # @return [ Proxy ] The safety proxy.
26
+ def safely(safety = true)
27
+ tap { Threaded.safety_options = safety }
28
+ end
29
+
30
+ # Execute the following instance-level persistence operation without safe mode.
31
+ # Allows per-request overriding of safe mode when the persist_in_safe_mode
32
+ # config option is turned on.
33
+ #
34
+ # @example Upsert in safe mode.
35
+ # person.unsafely.upsert
36
+ #
37
+ # @return [ Proxy ] The safety proxy.
38
+ def unsafely
39
+ tap { Threaded.safety_options = false }
40
+ end
41
+
42
+ class << self
43
+
44
+ # Static class method of easily getting the desired safe mode options
45
+ # from anywhere in the framework.
46
+ #
47
+ # @example Get the options with safe mode included.
48
+ # Safety.merge_safety_options({ :safe => false })
49
+ #
50
+ # @param [ Hash ] options The persistence options.
51
+ #
52
+ # @return [ Hash ] The options hash.
53
+ #
54
+ # @since 2.1.0
55
+ def merge_safety_options(options = {})
56
+ options ||= {}
57
+ return options if options[:safe]
58
+
59
+ unless Threaded.safety_options.nil?
60
+ safety = Threaded.safety_options
61
+ else
62
+ safety = Mongoid.persist_in_safe_mode
63
+ end
64
+ options.merge!({ :safe => safety })
65
+ end
66
+ end
67
+
68
+ module ClassMethods #:nodoc:
69
+
70
+ # Execute the following class-level persistence operation in safe mode.
71
+ #
72
+ # @example Create in safe mode.
73
+ # Person.safely.create(:name => "John")
74
+ #
75
+ # @example Delete all in safe mode with options.
76
+ # Person.safely(:w => 2, :fsync => true).delete_all
77
+ #
78
+ # @param [ Hash ] options The safe mode options.
79
+ #
80
+ # @option options [ Integer ] :w The number of nodes to write to.
81
+ # @option options [ Integer ] :wtimeout Time to wait for return from all
82
+ # nodes.
83
+ # @option options [ true, false ] :fsync Should a fsync occur.
84
+ #
85
+ # @return [ Proxy ] The safety proxy.
86
+ def safely(safety = true)
87
+ tap { Threaded.safety_options = safety }
88
+ end
89
+
90
+ # Execute the following class-level persistence operation without safe mode.
91
+ # Allows per-request overriding of safe mode when the persist_in_safe_mode
92
+ # config option is turned on.
93
+ #
94
+ # @example Upsert in safe mode.
95
+ # Person.unsafely.create(:name => "John")
96
+ #
97
+ # @return [ Proxy ] The safety proxy.
98
+ #
99
+ # @since 2.3.0
100
+ def unsafely
101
+ tap { Threaded.safety_options = false }
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ # This module handles behaviour for defining scopes on classes.
4
+ class Scope
5
+ attr_reader :conditions, :extensions
6
+
7
+ # Create the new +Scope+. If a block is passed in, this Scope will store
8
+ # the block for future calls to #extend.
9
+ #
10
+ # @example Create a new scope.
11
+ # Scope.new(:title => "Sir")
12
+ #
13
+ # @param [ Hash ] conditions The scoping limitations.
14
+ def initialize(conditions = {}, &block)
15
+ @conditions = conditions
16
+ @extensions = Module.new(&block) if block_given?
17
+ end
18
+
19
+ # Extend a supplied criteria.
20
+ #
21
+ # @example Extend the criteria.
22
+ # scope.extend(criteria)
23
+ #
24
+ # @param [ Criteria } criteria A mongoid criteria to extend.
25
+ #
26
+ # @return [ Criteria ] The new criteria object.
27
+ def extend(criteria)
28
+ extensions ? criteria.extend(extensions) : criteria
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,134 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+
4
+ # This module provides the extra behaviour for including relations in JSON
5
+ # and XML serialization.
6
+ module Serialization
7
+ extend ActiveSupport::Concern
8
+
9
+ # Gets the document as a serializable hash, used by ActiveModel's JSON
10
+ # serializer.
11
+ #
12
+ # @example Get the serializable hash.
13
+ # document.serializable_hash
14
+ #
15
+ # @example Get the serializable hash with options.
16
+ # document.serializable_hash(:include => :addresses)
17
+ #
18
+ # @param [ Hash ] options The options to pass.
19
+ #
20
+ # @option options [ Symbol ] :include What relations to include.
21
+ # @option options [ Symbol ] :only Limit the fields to only these.
22
+ # @option options [ Symbol ] :except Dont include these fields.
23
+ # @option options [ Symbol ] :methods What methods to include.
24
+ #
25
+ # @return [ Hash ] The document, ready to be serialized.
26
+ #
27
+ # @since 2.0.0.rc.6
28
+ def serializable_hash(options = nil)
29
+ options ||= {}
30
+
31
+ only = Array.wrap(options[:only]).map(&:to_s)
32
+ except = Array.wrap(options[:except]).map(&:to_s)
33
+
34
+ except |= ['_type']
35
+
36
+ field_names = fields.keys.map { |field| field.to_s }
37
+ attribute_names = (attributes.keys + field_names).sort
38
+ if only.any?
39
+ attribute_names &= only
40
+ elsif except.any?
41
+ attribute_names -= except
42
+ end
43
+
44
+ method_names = Array.wrap(options[:methods]).map { |n| n.to_s if respond_to?(n.to_s) }.compact
45
+ Hash[(attribute_names + method_names).map { |n| [n, send(n)] }].tap do |attrs|
46
+ serialize_relations(attrs, options) if options[:include]
47
+ end
48
+ end
49
+
50
+ class << self
51
+
52
+ # Serialize the provided object into a Mongo friendly value, using the
53
+ # field serialization method for the passed in type. If no type is
54
+ # given then we assume generic object serialization, which just returns
55
+ # the value itself.
56
+ #
57
+ # @example Mongoize the object.
58
+ # Mongoid::Serialization.mongoize(time, Time)
59
+ #
60
+ # @param [ Object ] object The object to convert.
61
+ # @param [ Class ] klass The type of the object.
62
+ #
63
+ # @return [ Object ] The converted object.
64
+ #
65
+ # @since 2.1.0
66
+ def mongoize(object, klass = Object)
67
+ Fields::Mappings.for(klass).instantiate(:mongoize).serialize(object)
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ # For each of the provided include options, get the relation needed and
74
+ # provide it in the hash.
75
+ #
76
+ # @example Serialize the included relations.
77
+ # document.serialize_relations({}, :include => :addresses)
78
+ #
79
+ # @param [ Hash ] attributes The attributes to serialize.
80
+ # @param [ Hash ] options The serialization options.
81
+ #
82
+ # @option options [ Symbol ] :include What relations to include
83
+ # @option options [ Symbol ] :only Limit the fields to only these.
84
+ # @option options [ Symbol ] :except Dont include these fields.
85
+ #
86
+ # @since 2.0.0.rc.6
87
+ def serialize_relations(attributes = {}, options = {})
88
+ inclusions = options[:include]
89
+ relation_names(inclusions).each do |name|
90
+ metadata = relations[name.to_s]
91
+ relation = send(metadata.name)
92
+ if relation
93
+ attributes[metadata.name.to_s] =
94
+ relation.serializable_hash(relation_options(inclusions, options, name))
95
+ end
96
+ end
97
+ end
98
+
99
+ # Since the inclusions can be a hash, symbol, or array of symbols, this is
100
+ # provided as a convenience to parse out the names.
101
+ #
102
+ # @example Get the relation names.
103
+ # document.relation_names(:include => [ :addresses ])
104
+ #
105
+ # @param [ Hash, Symbol, Array<Symbol ] inclusions The inclusions.
106
+ #
107
+ # @return [ Array<Symbol> ] The names of the included relations.
108
+ #
109
+ # @since 2.0.0.rc.6
110
+ def relation_names(inclusions)
111
+ inclusions.is_a?(Hash) ? inclusions.keys : Array.wrap(inclusions)
112
+ end
113
+
114
+ # Since the inclusions can be a hash, symbol, or array of symbols, this is
115
+ # provided as a convenience to parse out the options.
116
+ #
117
+ # @example Get the relation options.
118
+ # document.relation_names(:include => [ :addresses ])
119
+ #
120
+ # @param [ Hash, Symbol, Array<Symbol ] inclusions The inclusions.
121
+ # @param [ Symbol ] name The name of the relation.
122
+ #
123
+ # @return [ Hash ] The options for the relation.
124
+ #
125
+ # @since 2.0.0.rc.6
126
+ def relation_options(inclusions, options, name)
127
+ if inclusions.is_a?(Hash)
128
+ inclusions[name]
129
+ else
130
+ { :except => options[:except], :only => options[:only] }
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+
4
+ # This module contains behaviour for adding shard key fields to updates.
5
+ module Sharding
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ cattr_accessor :shard_key_fields
10
+ self.shard_key_fields = []
11
+ end
12
+
13
+ # Get the shard key fields.
14
+ #
15
+ # @note Refactored from using delegate for class load performance.
16
+ #
17
+ # @example Get the shard key fields.
18
+ # model.shard_key_fields
19
+ #
20
+ # @return [ Array<String> ] The shard key field names.
21
+ def shard_key_fields
22
+ self.class.shard_key_fields
23
+ end
24
+
25
+ # Get the document selector with the defined shard keys.
26
+ #
27
+ # @example Get the selector for the shard keys.
28
+ # person.shard_key_selector
29
+ #
30
+ # @return [ Hash ] The shard key selector.
31
+ #
32
+ # @since 2.0.0
33
+ def shard_key_selector
34
+ {}.tap do |selector|
35
+ shard_key_fields.each do |field|
36
+ selector[field.to_s] = send(field)
37
+ end
38
+ end
39
+ end
40
+
41
+ module ClassMethods #:nodoc
42
+
43
+ # Specifies a shard key with the field(s) specified.
44
+ #
45
+ # @example Specify the shard key.
46
+ #
47
+ # class Person
48
+ # include Mongoid::Document
49
+ # field :first_name, :type => String
50
+ # field :last_name, :type => String
51
+ #
52
+ # shard_key :first_name, :last_name
53
+ # end
54
+ #
55
+ # @since 2.0.0
56
+ def shard_key(*names)
57
+ self.shard_key_fields = names
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,97 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+
4
+ # This module contains the behaviour for getting the various states a
5
+ # document can transition through.
6
+ module State
7
+
8
+ attr_writer :destroyed, :flagged_for_destroy, :new_record
9
+
10
+ # Returns true if the +Document+ has not been persisted to the database,
11
+ # false if it has. This is determined by the variable @new_record
12
+ # and NOT if the object has an id.
13
+ #
14
+ # @example Is the document new?
15
+ # person.new_record?
16
+ #
17
+ # @return [ true, false ] True if new, false if not.
18
+ def new_record?
19
+ @new_record == true
20
+ end
21
+ alias :new? :new_record?
22
+
23
+ # Checks if the document has been saved to the database. Returns false
24
+ # if the document has been destroyed.
25
+ #
26
+ # @example Is the document persisted?
27
+ # person.persisted?
28
+ #
29
+ # @return [ true, false ] True if persisted, false if not.
30
+ def persisted?
31
+ !new_record? && !destroyed?
32
+ end
33
+
34
+ # Returns whether or not the document has been flagged for deletion, but
35
+ # not destroyed yet. Used for atomic pulls of child documents.
36
+ #
37
+ # @example Is the document flagged?
38
+ # document.flagged_for_destroy?
39
+ #
40
+ # @return [ true, false ] If the document is flagged.
41
+ #
42
+ # @since 2.3.2
43
+ def flagged_for_destroy?
44
+ !!@flagged_for_destroy
45
+ end
46
+
47
+ # Returns true if the +Document+ has been succesfully destroyed, and false
48
+ # if it hasn't. This is determined by the variable @destroyed and NOT
49
+ # by checking the database.
50
+ #
51
+ # @example Is the document destroyed?
52
+ # person.destroyed?
53
+ #
54
+ # @return [ true, false ] True if destroyed, false if not.
55
+ def destroyed?
56
+ @destroyed == true
57
+ end
58
+ alias :deleted? :destroyed?
59
+
60
+ # Determine if the document can be pushed.
61
+ #
62
+ # @example Is this pushable?
63
+ # person.pushable?
64
+ #
65
+ # @return [ true, false ] Is the document new and embedded?
66
+ def pushable?
67
+ new? &&
68
+ embedded_many? &&
69
+ _parent.persisted? &&
70
+ !_parent.delayed_atomic_sets[atomic_path]
71
+ end
72
+
73
+ # Determine if the document can be set.
74
+ #
75
+ # @example Is this settable?
76
+ # person.settable?
77
+ #
78
+ # @return [ true, false ] Is this document a new embeds one?
79
+ #
80
+ # @since 2.1.0
81
+ def settable?
82
+ new? && embedded_one? && _parent.persisted?
83
+ end
84
+
85
+ # Is the document updateable?
86
+ #
87
+ # @example Is the document updateable?
88
+ # person.updateable?
89
+ #
90
+ # @return [ true, false ] If the document is changed and persisted.
91
+ #
92
+ # @since 2.1.0
93
+ def updateable?
94
+ persisted? && changed?
95
+ end
96
+ end
97
+ end