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,27 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Fields #:nodoc:
4
+ module Serializable #:nodoc:
5
+
6
+ # Defines the behaviour for symbol fields.
7
+ class Symbol
8
+ include Serializable
9
+
10
+ # Serialize the object from the type defined in the model to a MongoDB
11
+ # compatible object to store.
12
+ #
13
+ # @example Serialize the field.
14
+ # field.serialize(object)
15
+ #
16
+ # @param [ Object ] object The object to cast.
17
+ #
18
+ # @return [ Symbol ] The converted symbol.
19
+ #
20
+ # @since 2.1.0
21
+ def serialize(object)
22
+ object.blank? ? nil : object.to_sym
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Fields #:nodoc:
4
+ module Serializable #:nodoc:
5
+ # Defines the behaviour for date fields.
6
+ class Time
7
+ include Serializable
8
+ include Timekeeping
9
+
10
+ # When reading the field do we need to cast the value? This holds true when
11
+ # times are stored or for big decimals which are stored as strings.
12
+ #
13
+ # @example Typecast on a read?
14
+ # field.cast_on_read?
15
+ #
16
+ # @return [ true ] Date fields cast on read.
17
+ #
18
+ # @since 2.1.0
19
+ def cast_on_read?; true; end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Fields #:nodoc:
4
+ module Serializable #:nodoc:
5
+ # Defines the behaviour for time with zone fields.
6
+ class TimeWithZone
7
+ include Serializable
8
+ include Timekeeping
9
+
10
+ # When reading the field do we need to cast the value? This holds true when
11
+ # times are stored or for big decimals which are stored as strings.
12
+ #
13
+ # @example Typecast on a read?
14
+ # field.cast_on_read?
15
+ #
16
+ # @return [ true ] Date fields cast on read.
17
+ #
18
+ # @since 2.1.0
19
+ def cast_on_read?; true; end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,106 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Fields #:nodoc:
4
+ module Serializable #:nodoc:
5
+
6
+ # This module contains shared behaviour for date conversions.
7
+ module Timekeeping
8
+
9
+ # When reading the field do we need to cast the value? This holds true when
10
+ # times are stored or for big decimals which are stored as strings.
11
+ #
12
+ # @example Typecast on a read?
13
+ # field.cast_on_read?
14
+ #
15
+ # @return [ true ] Date fields cast on read.
16
+ #
17
+ # @since 2.1.0
18
+ def cast_on_read?; true; end
19
+
20
+ # Deserialize this field from the type stored in MongoDB to the type
21
+ # defined on the model.
22
+ #
23
+ # @example Deserialize the field.
24
+ # field.deserialize(object)
25
+ #
26
+ # @param [ Object ] object The object to cast.
27
+ #
28
+ # @return [ Time ] The converted time.
29
+ #
30
+ # @since 2.1.0
31
+ def deserialize(object)
32
+ return nil if object.blank?
33
+ object = object.getlocal unless Mongoid::Config.use_utc?
34
+ if Mongoid::Config.use_activesupport_time_zone?
35
+ time_zone = Mongoid::Config.use_utc? ? 'UTC' : ::Time.zone
36
+ object = object.in_time_zone(time_zone)
37
+ end
38
+ object
39
+ end
40
+
41
+ # Serialize the object from the type defined in the model to a MongoDB
42
+ # compatible object to store.
43
+ #
44
+ # @example Serialize the field.
45
+ # field.serialize(object)
46
+ #
47
+ # @param [ Object ] object The object to cast.
48
+ #
49
+ # @return [ Time ] The converted UTC time.
50
+ #
51
+ # @since 2.1.0
52
+ def serialize(object)
53
+ return nil if object.blank?
54
+ begin
55
+ time = convert_to_time(object)
56
+ strip_milliseconds(time).utc
57
+ rescue ArgumentError
58
+ raise Errors::InvalidTime.new(object)
59
+ end
60
+ end
61
+
62
+ # Convert the provided object to a UTC time to store in the database.
63
+ #
64
+ # @example Set the time.
65
+ # Time.convert_to_time(Date.today)
66
+ #
67
+ # @param [ String, Date, DateTime, Array ] value The object to cast.
68
+ #
69
+ # @return [ Time ] The object as a UTC time.
70
+ #
71
+ # @since 1.0.0
72
+ def convert_to_time(value)
73
+ time = Mongoid::Config.use_activesupport_time_zone? ? ::Time.zone : ::Time
74
+ case value
75
+ when ::String
76
+ time.parse(value)
77
+ when ::DateTime
78
+ time.local(value.year, value.month, value.day, value.hour, value.min, value.sec)
79
+ when ::Date
80
+ time.local(value.year, value.month, value.day)
81
+ when ::Array
82
+ time.local(*value)
83
+ else
84
+ value
85
+ end
86
+ end
87
+
88
+ # Strip the milliseconds off the time.
89
+ #
90
+ # @todo Durran: Why is this here? Still need time refactoring.
91
+ #
92
+ # @example Strip.
93
+ # Time.strip_millseconds(Time.now)
94
+ #
95
+ # @param [ Time ] time The time to strip.
96
+ #
97
+ # @return [ Time ] The time without millis.
98
+ #
99
+ # @since 2.1.0
100
+ def strip_milliseconds(time)
101
+ ::Time.at(time.to_i)
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,152 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+
4
+ # This module defines the finder methods that hang off the document at the
5
+ # class level.
6
+ module Finders
7
+
8
+ # Delegate to the criteria methods that are natural for creating a new
9
+ # criteria.
10
+ critera_methods = [ :all_in, :all_of, :any_in, :any_of, :asc, :ascending,
11
+ :avg, :desc, :descending, :excludes,
12
+ :includes, :limit, :max, :min, :not_in, :only,
13
+ :order_by, :search, :skip, :sum, :without, :where,
14
+ :update, :update_all, :near ]
15
+ delegate *(critera_methods.dup << { :to => :criteria })
16
+
17
+ # Find all documents that match the given conditions.
18
+ #
19
+ # @example Find all matching documents given conditions.
20
+ # Person.all(:conditions => { :attribute => "value" })
21
+ #
22
+ # @param [ Array ] args The conditions with options.
23
+ #
24
+ # @return [ Criteria ] The matching documents.
25
+ def all(*args)
26
+ find(:all, *args)
27
+ end
28
+
29
+ # Returns a count of matching records in the database based on the
30
+ # provided arguments.
31
+ #
32
+ # @example Get the count of matching documents.
33
+ # Person.count(:conditions => { :attribute => "value" })
34
+ #
35
+ # @param [ Array ] args The conditions.
36
+ #
37
+ # @return [ Integer ] The number of matching documents.
38
+ def count(*args)
39
+ find(:all, *args).count
40
+ end
41
+
42
+ # Returns true if count is zero
43
+ #
44
+ # @example Are there no saved documents for this model?
45
+ # Person.empty?
46
+ #
47
+ # @return [ true, false ] If the collection is empty.
48
+ def empty?
49
+ count == 0
50
+ end
51
+
52
+ # Returns true if there are on document in database based on the
53
+ # provided arguments.
54
+ #
55
+ # @example Do any documents exist for the conditions?
56
+ # Person.exists?(:conditions => { :attribute => "value" })
57
+ #
58
+ # @param [ Array ] args The conditions.
59
+ def exists?(*args)
60
+ find(:all, *args).count > 0
61
+ end
62
+
63
+ # Find a +Document+ in several different ways.
64
+ #
65
+ # If a +String+ is provided, it will be assumed that it is a
66
+ # representation of a Mongo::ObjectID and will attempt to find a single
67
+ # +Document+ based on that id. If a +Symbol+ and +Hash+ is provided then
68
+ # it will attempt to find either a single +Document+ or multiples based
69
+ # on the conditions provided and the first parameter.
70
+ #
71
+ # @example Find the first matching document.
72
+ # Person.find(:first, :conditions => { :attribute => "value" })
73
+ #
74
+ # @example Find all matching documents.
75
+ # Person.find(:all, :conditions => { :attribute => "value" })
76
+ #
77
+ # @example Find a single document by an id.
78
+ # Person.find(BSON::ObjectId)
79
+ #
80
+ # @param [ Array ] args An assortment of finder options.
81
+ #
82
+ # @return [ Document, nil, Criteria ] A document or matching documents.
83
+ def find(*args)
84
+ criteria.find(*args)
85
+ end
86
+
87
+ # Find the first +Document+ given the conditions, or creates a new document
88
+ # with the conditions that were supplied.
89
+ #
90
+ # @example Find or create the document.
91
+ # Person.find_or_create_by(:attribute => "value")
92
+ #
93
+ # @param [ Hash ] attrs The attributes to check.
94
+ #
95
+ # @return [ Document ] A matching or newly created document.
96
+ def find_or_create_by(attrs = {}, &block)
97
+ find_or(:create, attrs, &block)
98
+ end
99
+
100
+ # Find the first +Document+ given the conditions, or initializes a new document
101
+ # with the conditions that were supplied.
102
+ #
103
+ # @example Find or initialize the document.
104
+ # Person.find_or_initialize_by(:attribute => "value")
105
+ #
106
+ # @param [ Hash ] attrs The attributes to check.
107
+ #
108
+ # @return [ Document ] A matching or newly initialized document.
109
+ def find_or_initialize_by(attrs = {}, &block)
110
+ find_or(:new, attrs, &block)
111
+ end
112
+
113
+ # Find the first +Document+ given the conditions.
114
+ #
115
+ # @example Find the first document.
116
+ # Person.first(:conditions => { :attribute => "value" })
117
+ #
118
+ # @param [ Array ] args The conditions with options.
119
+ #
120
+ # @return [ Document ] The first matching document.
121
+ def first(*args)
122
+ find(:first, *args)
123
+ end
124
+
125
+ # Find the last +Document+ given the conditions.
126
+ #
127
+ # @example Find the last document.
128
+ # Person.last(:conditions => { :attribute => "value" })
129
+ #
130
+ # @param [ Array ] args The conditions with options.
131
+ #
132
+ # @return [ Document ] The last matching document.
133
+ def last(*args)
134
+ find(:last, *args)
135
+ end
136
+
137
+ protected
138
+
139
+ # Find the first object or create/initialize it.
140
+ #
141
+ # @example Find or perform an action.
142
+ # Person.find_or(:create, :name => "Dev")
143
+ #
144
+ # @param [ Symbol ] method The method to invoke.
145
+ # @param [ Hash ] attrs The attributes to query or set.
146
+ #
147
+ # @return [ Document ] The first or new document.
148
+ def find_or(method, attrs = {}, &block)
149
+ first(:conditions => attrs) || send(method, attrs, &block)
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,120 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ module Hierarchy #:nodoc
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ attr_accessor :_parent
8
+ end
9
+
10
+ module ClassMethods #:nodoc:
11
+
12
+ # Determines if the document is a subclass of another document.
13
+ #
14
+ # @example Check if the document is a subclass.
15
+ # Square.hereditary?
16
+ #
17
+ # @return [ true, false ] True if hereditary, false if not.
18
+ def hereditary?
19
+ Mongoid::Document > superclass
20
+ end
21
+ end
22
+
23
+ module InstanceMethods #:nodoc:
24
+
25
+ # Get all child +Documents+ to this +Document+, going n levels deep if
26
+ # necessary. This is used when calling update persistence operations from
27
+ # the root document, where changes in the entire tree need to be
28
+ # determined. Note that persistence from the embedded documents will
29
+ # always be preferred, since they are optimized calls... This operation
30
+ # can get expensive in domains with large hierarchies.
31
+ #
32
+ # @example Get all the document's children.
33
+ # person._children
34
+ #
35
+ # @return [ Array<Document> ] All child documents in the hierarchy.
36
+ def _children
37
+ @_children ||=
38
+ [].tap do |children|
39
+ relations.each_pair do |name, metadata|
40
+ if metadata.embedded?
41
+ child = send(name)
42
+ child.to_a.each do |doc|
43
+ children.push(doc)
44
+ children.concat(doc._children) unless metadata.versioned?
45
+ end if child
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ # Determines if the document is a subclass of another document.
52
+ #
53
+ # @example Check if the document is a subclass
54
+ # Square.new.hereditary?
55
+ #
56
+ # @return [ true, false ] True if hereditary, false if not.
57
+ def hereditary?
58
+ self.class.hereditary?
59
+ end
60
+
61
+ # Sets up a child/parent association. This is used for newly created
62
+ # objects so they can be properly added to the graph.
63
+ #
64
+ # @example Set the parent document.
65
+ # document.parentize(parent)
66
+ #
67
+ # @param [ Document ] document The parent document.
68
+ #
69
+ # @return [ Document ] The parent document.
70
+ def parentize(document)
71
+ self._parent = document
72
+ end
73
+
74
+ # Remove a child document from this parent. If an embeds one then set to
75
+ # nil, otherwise remove from the embeds many.
76
+ #
77
+ # This is called from the +RemoveEmbedded+ persistence command.
78
+ #
79
+ # @example Remove the child.
80
+ # document.remove_child(child)
81
+ #
82
+ # @param [ Document ] child The child (embedded) document to remove.
83
+ #
84
+ # @since 2.0.0.beta.1
85
+ def remove_child(child)
86
+ name = child.metadata.name
87
+ child.embedded_one? ? remove_ivar(name) : send(name).delete_one(child)
88
+ end
89
+
90
+ # After children are persisted we can call this to move all their changes
91
+ # and flag them as persisted in one call.
92
+ #
93
+ # @example Reset the children.
94
+ # document.reset_persisted_children
95
+ #
96
+ # @return [ Array<Document> ] The children.
97
+ #
98
+ # @since 2.1.0
99
+ def reset_persisted_children
100
+ _children.each do |child|
101
+ child.move_changes
102
+ child.new_record = false
103
+ end
104
+ end
105
+
106
+ # Return the root document in the object graph. If the current document
107
+ # is the root object in the graph it will return self.
108
+ #
109
+ # @example Get the root document in the hierarchy.
110
+ # document._root
111
+ #
112
+ # @return [ Document ] The root document in the hierarchy.
113
+ def _root
114
+ object = self
115
+ while (object._parent) do object = object._parent; end
116
+ object || self
117
+ end
118
+ end
119
+ end
120
+ end