mongoid 2.4.9 → 3.0.0.rc

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 (351) hide show
  1. data/CHANGELOG.md +869 -8
  2. data/LICENSE +1 -1
  3. data/README.md +10 -11
  4. data/Rakefile +2 -17
  5. data/lib/config/locales/en.yml +441 -51
  6. data/lib/mongoid/atomic/modifiers.rb +2 -2
  7. data/lib/mongoid/atomic/paths/embedded/many.rb +6 -6
  8. data/lib/mongoid/atomic/paths/embedded/one.rb +5 -5
  9. data/lib/mongoid/atomic/paths/embedded.rb +4 -5
  10. data/lib/mongoid/atomic/paths/root.rb +4 -5
  11. data/lib/mongoid/atomic.rb +16 -6
  12. data/lib/mongoid/attributes/processing.rb +14 -10
  13. data/lib/mongoid/attributes/readonly.rb +56 -0
  14. data/lib/mongoid/attributes.rb +95 -32
  15. data/lib/mongoid/callbacks.rb +100 -42
  16. data/lib/mongoid/collections/retry.rb +2 -3
  17. data/lib/mongoid/components.rb +10 -22
  18. data/lib/mongoid/config/environment.rb +4 -3
  19. data/lib/mongoid/config/inflections.rb +6 -0
  20. data/lib/mongoid/config/options.rb +1 -1
  21. data/lib/mongoid/config/validators/option.rb +25 -0
  22. data/lib/mongoid/config/validators/session.rb +140 -0
  23. data/lib/mongoid/config/validators.rb +3 -0
  24. data/lib/mongoid/config.rb +87 -233
  25. data/lib/mongoid/contextual/aggregable/memory.rb +98 -0
  26. data/lib/mongoid/contextual/aggregable/mongo.rb +181 -0
  27. data/lib/mongoid/contextual/atomic.rb +179 -0
  28. data/lib/mongoid/contextual/command.rb +43 -0
  29. data/lib/mongoid/contextual/find_and_modify.rb +66 -0
  30. data/lib/mongoid/contextual/map_reduce.rb +273 -0
  31. data/lib/mongoid/contextual/memory.rb +383 -0
  32. data/lib/mongoid/contextual/mongo.rb +543 -0
  33. data/lib/mongoid/contextual.rb +50 -0
  34. data/lib/mongoid/copyable.rb +2 -2
  35. data/lib/mongoid/criteria.rb +436 -248
  36. data/lib/mongoid/criterion/inspection.rb +14 -8
  37. data/lib/mongoid/criterion/scoping.rb +114 -44
  38. data/lib/mongoid/dirty.rb +152 -67
  39. data/lib/mongoid/document.rb +68 -49
  40. data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
  41. data/lib/mongoid/errors/callback.rb +5 -6
  42. data/lib/mongoid/errors/delete_restriction.rb +29 -0
  43. data/lib/mongoid/errors/document_not_found.rb +98 -17
  44. data/lib/mongoid/errors/eager_load.rb +3 -6
  45. data/lib/mongoid/errors/invalid_collection.rb +3 -3
  46. data/lib/mongoid/errors/invalid_config_option.rb +27 -0
  47. data/lib/mongoid/errors/invalid_database.rb +3 -3
  48. data/lib/mongoid/errors/invalid_field.rb +54 -8
  49. data/lib/mongoid/errors/invalid_field_option.rb +35 -0
  50. data/lib/mongoid/errors/invalid_find.rb +3 -3
  51. data/lib/mongoid/errors/invalid_index.rb +28 -0
  52. data/lib/mongoid/errors/invalid_options.rb +4 -4
  53. data/lib/mongoid/errors/invalid_scope.rb +24 -0
  54. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
  55. data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
  56. data/lib/mongoid/errors/invalid_time.rb +3 -6
  57. data/lib/mongoid/errors/inverse_not_found.rb +29 -0
  58. data/lib/mongoid/errors/mixed_relations.rb +4 -9
  59. data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
  60. data/lib/mongoid/errors/mongoid_error.rb +54 -3
  61. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
  62. data/lib/mongoid/errors/no_default_session.rb +23 -0
  63. data/lib/mongoid/errors/no_environment.rb +3 -3
  64. data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
  65. data/lib/mongoid/errors/no_parent.rb +24 -0
  66. data/lib/mongoid/errors/no_session_config.rb +22 -0
  67. data/lib/mongoid/errors/no_session_database.rb +27 -0
  68. data/lib/mongoid/errors/no_session_hosts.rb +27 -0
  69. data/lib/mongoid/errors/no_sessions_config.rb +20 -0
  70. data/lib/mongoid/errors/readonly_attribute.rb +25 -0
  71. data/lib/mongoid/errors/scope_overwrite.rb +4 -4
  72. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +4 -4
  73. data/lib/mongoid/errors/unknown_attribute.rb +25 -0
  74. data/lib/mongoid/errors/unsaved_document.rb +4 -8
  75. data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
  76. data/lib/mongoid/errors/unsupported_version.rb +4 -4
  77. data/lib/mongoid/errors/validations.rb +7 -6
  78. data/lib/mongoid/errors/versioning_not_on_root.rb +23 -0
  79. data/lib/mongoid/errors.rb +22 -1
  80. data/lib/mongoid/extensions/array.rb +127 -0
  81. data/lib/mongoid/extensions/big_decimal.rb +42 -0
  82. data/lib/mongoid/extensions/boolean.rb +24 -0
  83. data/lib/mongoid/extensions/date.rb +70 -0
  84. data/lib/mongoid/extensions/date_time.rb +68 -0
  85. data/lib/mongoid/extensions/false_class.rb +26 -0
  86. data/lib/mongoid/extensions/float.rb +44 -0
  87. data/lib/mongoid/extensions/hash.rb +91 -0
  88. data/lib/mongoid/extensions/integer.rb +54 -0
  89. data/lib/mongoid/extensions/module.rb +28 -0
  90. data/lib/mongoid/extensions/nil_class.rb +21 -0
  91. data/lib/mongoid/extensions/object.rb +188 -0
  92. data/lib/mongoid/extensions/object_id.rb +53 -0
  93. data/lib/mongoid/extensions/range.rb +55 -0
  94. data/lib/mongoid/extensions/regexp.rb +27 -0
  95. data/lib/mongoid/extensions/set.rb +55 -0
  96. data/lib/mongoid/extensions/string.rb +155 -0
  97. data/lib/mongoid/extensions/symbol.rb +54 -0
  98. data/lib/mongoid/extensions/time.rb +78 -0
  99. data/lib/mongoid/extensions/time_with_zone.rb +55 -0
  100. data/lib/mongoid/extensions/true_class.rb +26 -0
  101. data/lib/mongoid/extensions.rb +28 -76
  102. data/lib/mongoid/factory.rb +4 -4
  103. data/lib/mongoid/fields/foreign_key.rb +134 -0
  104. data/lib/mongoid/fields/localized.rb +73 -0
  105. data/lib/mongoid/fields/standard.rb +268 -0
  106. data/lib/mongoid/fields/validators/macro.rb +83 -0
  107. data/lib/mongoid/fields/validators.rb +2 -0
  108. data/lib/mongoid/fields.rb +129 -194
  109. data/lib/mongoid/finders.rb +42 -43
  110. data/lib/mongoid/hierarchy.rb +25 -14
  111. data/lib/mongoid/identity_map.rb +39 -12
  112. data/lib/mongoid/indexes/validators/options.rb +80 -0
  113. data/lib/mongoid/indexes.rb +66 -15
  114. data/lib/mongoid/inspection.rb +1 -1
  115. data/lib/mongoid/javascript.rb +1 -1
  116. data/lib/mongoid/json.rb +2 -2
  117. data/lib/mongoid/loggable.rb +69 -0
  118. data/lib/mongoid/matchers/all.rb +7 -8
  119. data/lib/mongoid/matchers/and.rb +3 -3
  120. data/lib/mongoid/matchers/default.rb +6 -4
  121. data/lib/mongoid/matchers/exists.rb +2 -2
  122. data/lib/mongoid/matchers/gt.rb +2 -2
  123. data/lib/mongoid/matchers/gte.rb +2 -2
  124. data/lib/mongoid/matchers/in.rb +3 -7
  125. data/lib/mongoid/matchers/lt.rb +2 -2
  126. data/lib/mongoid/matchers/lte.rb +2 -2
  127. data/lib/mongoid/matchers/ne.rb +2 -2
  128. data/lib/mongoid/matchers/nin.rb +2 -2
  129. data/lib/mongoid/matchers/or.rb +2 -2
  130. data/lib/mongoid/matchers/size.rb +2 -2
  131. data/lib/mongoid/matchers/strategies.rb +3 -3
  132. data/lib/mongoid/matchers.rb +1 -1
  133. data/lib/mongoid/multi_parameter_attributes.rb +8 -10
  134. data/lib/mongoid/nested_attributes.rb +17 -9
  135. data/lib/mongoid/observer.rb +1 -2
  136. data/lib/mongoid/paranoia.rb +13 -18
  137. data/lib/mongoid/persistence/atomic/add_to_set.rb +5 -9
  138. data/lib/mongoid/persistence/atomic/bit.rb +5 -7
  139. data/lib/mongoid/persistence/atomic/inc.rb +5 -7
  140. data/lib/mongoid/persistence/atomic/operation.rb +45 -6
  141. data/lib/mongoid/persistence/atomic/pop.rb +5 -7
  142. data/lib/mongoid/persistence/atomic/pull.rb +5 -7
  143. data/lib/mongoid/persistence/atomic/pull_all.rb +5 -7
  144. data/lib/mongoid/persistence/atomic/push.rb +4 -10
  145. data/lib/mongoid/persistence/atomic/push_all.rb +4 -10
  146. data/lib/mongoid/persistence/atomic/rename.rb +6 -7
  147. data/lib/mongoid/persistence/atomic/sets.rb +5 -7
  148. data/lib/mongoid/persistence/atomic/unset.rb +4 -5
  149. data/lib/mongoid/persistence/atomic.rb +2 -2
  150. data/lib/mongoid/persistence/deletion.rb +2 -2
  151. data/lib/mongoid/persistence/insertion.rb +10 -16
  152. data/lib/mongoid/persistence/modification.rb +5 -9
  153. data/lib/mongoid/persistence/operations/embedded/insert.rb +7 -6
  154. data/lib/mongoid/persistence/operations/embedded/remove.rb +5 -5
  155. data/lib/mongoid/persistence/operations/insert.rb +4 -4
  156. data/lib/mongoid/persistence/operations/remove.rb +4 -4
  157. data/lib/mongoid/persistence/operations/update.rb +5 -5
  158. data/lib/mongoid/persistence/operations.rb +6 -19
  159. data/lib/mongoid/persistence.rb +64 -27
  160. data/lib/mongoid/railtie.rb +26 -11
  161. data/lib/mongoid/railties/database.rake +22 -108
  162. data/lib/mongoid/relations/accessors.rb +119 -19
  163. data/lib/mongoid/relations/auto_save.rb +59 -5
  164. data/lib/mongoid/relations/binding.rb +211 -2
  165. data/lib/mongoid/relations/bindings/embedded/in.rb +16 -22
  166. data/lib/mongoid/relations/bindings/embedded/many.rb +9 -50
  167. data/lib/mongoid/relations/bindings/embedded/one.rb +10 -16
  168. data/lib/mongoid/relations/bindings/referenced/in.rb +31 -57
  169. data/lib/mongoid/relations/bindings/referenced/many.rb +8 -20
  170. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +15 -19
  171. data/lib/mongoid/relations/bindings/referenced/one.rb +10 -24
  172. data/lib/mongoid/relations/builder.rb +3 -3
  173. data/lib/mongoid/relations/builders/embedded/in.rb +5 -5
  174. data/lib/mongoid/relations/builders/embedded/many.rb +12 -12
  175. data/lib/mongoid/relations/builders/embedded/one.rb +6 -6
  176. data/lib/mongoid/relations/builders/nested_attributes/many.rb +8 -8
  177. data/lib/mongoid/relations/builders/nested_attributes/one.rb +4 -4
  178. data/lib/mongoid/relations/builders/referenced/in.rb +4 -4
  179. data/lib/mongoid/relations/builders/referenced/many.rb +5 -5
  180. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +7 -5
  181. data/lib/mongoid/relations/builders/referenced/one.rb +5 -5
  182. data/lib/mongoid/relations/builders.rb +19 -16
  183. data/lib/mongoid/relations/cascading/delete.rb +12 -4
  184. data/lib/mongoid/relations/cascading/destroy.rb +3 -3
  185. data/lib/mongoid/relations/cascading/nullify.rb +3 -3
  186. data/lib/mongoid/relations/cascading/restrict.rb +37 -0
  187. data/lib/mongoid/relations/cascading.rb +6 -4
  188. data/lib/mongoid/relations/constraint.rb +4 -3
  189. data/lib/mongoid/relations/conversions.rb +5 -6
  190. data/lib/mongoid/relations/cyclic.rb +7 -7
  191. data/lib/mongoid/relations/embedded/batchable.rb +346 -0
  192. data/lib/mongoid/relations/embedded/in.rb +23 -12
  193. data/lib/mongoid/relations/embedded/many.rb +99 -148
  194. data/lib/mongoid/relations/embedded/one.rb +25 -14
  195. data/lib/mongoid/relations/macros.rb +105 -60
  196. data/lib/mongoid/relations/many.rb +93 -14
  197. data/lib/mongoid/relations/metadata.rb +231 -45
  198. data/lib/mongoid/relations/nested_builder.rb +3 -5
  199. data/lib/mongoid/relations/one.rb +14 -2
  200. data/lib/mongoid/relations/options.rb +2 -2
  201. data/lib/mongoid/relations/polymorphic.rb +9 -9
  202. data/lib/mongoid/relations/proxy.rb +60 -31
  203. data/lib/mongoid/relations/referenced/in.rb +40 -15
  204. data/lib/mongoid/relations/referenced/many.rb +116 -122
  205. data/lib/mongoid/relations/referenced/many_to_many.rb +101 -46
  206. data/lib/mongoid/relations/referenced/one.rb +34 -13
  207. data/lib/mongoid/relations/reflections.rb +3 -3
  208. data/lib/mongoid/relations/synchronization.rb +19 -23
  209. data/lib/mongoid/relations/targets/enumerable.rb +86 -57
  210. data/lib/mongoid/relations/touchable.rb +32 -0
  211. data/lib/mongoid/relations.rb +6 -6
  212. data/lib/mongoid/reloading.rb +12 -14
  213. data/lib/mongoid/scoping.rb +329 -0
  214. data/lib/mongoid/serialization.rb +13 -30
  215. data/lib/mongoid/sessions/factory.rb +106 -0
  216. data/lib/mongoid/sessions/mongo_uri.rb +93 -0
  217. data/lib/mongoid/sessions/validators/storage.rb +49 -0
  218. data/lib/mongoid/sessions/validators.rb +2 -0
  219. data/lib/mongoid/sessions.rb +359 -0
  220. data/lib/mongoid/sharding.rb +6 -6
  221. data/lib/mongoid/state.rb +6 -7
  222. data/lib/mongoid/threaded/lifecycle.rb +21 -21
  223. data/lib/mongoid/threaded/sessions.rb +0 -0
  224. data/lib/mongoid/threaded.rb +167 -59
  225. data/lib/mongoid/timestamps/created.rb +8 -4
  226. data/lib/mongoid/timestamps/timeless.rb +6 -4
  227. data/lib/mongoid/timestamps/updated.rb +3 -3
  228. data/lib/mongoid/timestamps.rb +1 -1
  229. data/lib/mongoid/unit_of_work.rb +61 -0
  230. data/lib/mongoid/validations/associated.rb +2 -2
  231. data/lib/mongoid/validations/format.rb +2 -2
  232. data/lib/mongoid/validations/presence.rb +34 -4
  233. data/lib/mongoid/validations/uniqueness.rb +103 -25
  234. data/lib/mongoid/validations.rb +62 -20
  235. data/lib/mongoid/version.rb +2 -2
  236. data/lib/mongoid/versioning.rb +25 -26
  237. data/lib/mongoid.rb +24 -39
  238. data/lib/rack/mongoid/middleware/identity_map.rb +3 -3
  239. data/lib/rails/generators/mongoid/config/config_generator.rb +1 -1
  240. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +59 -19
  241. data/lib/rails/generators/mongoid/model/model_generator.rb +7 -7
  242. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +2 -2
  243. data/lib/rails/generators/mongoid/observer/observer_generator.rb +4 -4
  244. data/lib/rails/generators/mongoid_generator.rb +5 -5
  245. data/lib/rails/mongoid.rb +69 -25
  246. metadata +93 -155
  247. data/lib/config/locales/bg.yml +0 -61
  248. data/lib/config/locales/de.yml +0 -61
  249. data/lib/config/locales/en-GB.yml +0 -64
  250. data/lib/config/locales/es.yml +0 -59
  251. data/lib/config/locales/fr.yml +0 -62
  252. data/lib/config/locales/hi.yml +0 -53
  253. data/lib/config/locales/hu.yml +0 -64
  254. data/lib/config/locales/id.yml +0 -62
  255. data/lib/config/locales/it.yml +0 -59
  256. data/lib/config/locales/ja.yml +0 -57
  257. data/lib/config/locales/kr.yml +0 -54
  258. data/lib/config/locales/nl.yml +0 -61
  259. data/lib/config/locales/pl.yml +0 -59
  260. data/lib/config/locales/pt-BR.yml +0 -60
  261. data/lib/config/locales/pt.yml +0 -60
  262. data/lib/config/locales/ro.yml +0 -66
  263. data/lib/config/locales/ru.yml +0 -61
  264. data/lib/config/locales/sv.yml +0 -60
  265. data/lib/config/locales/vi.yml +0 -62
  266. data/lib/config/locales/zh-CN.yml +0 -53
  267. data/lib/mongoid/collection.rb +0 -157
  268. data/lib/mongoid/collections/master.rb +0 -45
  269. data/lib/mongoid/collections/operations.rb +0 -44
  270. data/lib/mongoid/collections.rb +0 -120
  271. data/lib/mongoid/config/database.rb +0 -181
  272. data/lib/mongoid/config/replset_database.rb +0 -80
  273. data/lib/mongoid/contexts/enumerable/sort.rb +0 -43
  274. data/lib/mongoid/contexts/enumerable.rb +0 -313
  275. data/lib/mongoid/contexts/mongo.rb +0 -485
  276. data/lib/mongoid/contexts.rb +0 -25
  277. data/lib/mongoid/criterion/builder.rb +0 -34
  278. data/lib/mongoid/criterion/complex.rb +0 -84
  279. data/lib/mongoid/criterion/creational.rb +0 -34
  280. data/lib/mongoid/criterion/exclusion.rb +0 -108
  281. data/lib/mongoid/criterion/inclusion.rb +0 -290
  282. data/lib/mongoid/criterion/optional.rb +0 -259
  283. data/lib/mongoid/criterion/selector.rb +0 -177
  284. data/lib/mongoid/cursor.rb +0 -88
  285. data/lib/mongoid/default_scope.rb +0 -36
  286. data/lib/mongoid/errors/invalid_type.rb +0 -25
  287. data/lib/mongoid/extensions/array/deep_copy.rb +0 -25
  288. data/lib/mongoid/extensions/array/deletion.rb +0 -29
  289. data/lib/mongoid/extensions/false_class/equality.rb +0 -26
  290. data/lib/mongoid/extensions/hash/criteria_helpers.rb +0 -47
  291. data/lib/mongoid/extensions/hash/deep_copy.rb +0 -25
  292. data/lib/mongoid/extensions/hash/scoping.rb +0 -25
  293. data/lib/mongoid/extensions/integer/checks.rb +0 -23
  294. data/lib/mongoid/extensions/nil/collectionization.rb +0 -23
  295. data/lib/mongoid/extensions/object/checks.rb +0 -29
  296. data/lib/mongoid/extensions/object/deep_copy.rb +0 -21
  297. data/lib/mongoid/extensions/object/reflections.rb +0 -48
  298. data/lib/mongoid/extensions/object/substitutable.rb +0 -15
  299. data/lib/mongoid/extensions/object/yoda.rb +0 -44
  300. data/lib/mongoid/extensions/object_id/conversions.rb +0 -60
  301. data/lib/mongoid/extensions/proc/scoping.rb +0 -25
  302. data/lib/mongoid/extensions/string/checks.rb +0 -36
  303. data/lib/mongoid/extensions/string/conversions.rb +0 -22
  304. data/lib/mongoid/extensions/string/inflections.rb +0 -118
  305. data/lib/mongoid/extensions/symbol/checks.rb +0 -23
  306. data/lib/mongoid/extensions/symbol/inflections.rb +0 -67
  307. data/lib/mongoid/extensions/true_class/equality.rb +0 -26
  308. data/lib/mongoid/extras.rb +0 -31
  309. data/lib/mongoid/fields/internal/array.rb +0 -76
  310. data/lib/mongoid/fields/internal/big_decimal.rb +0 -63
  311. data/lib/mongoid/fields/internal/bignum.rb +0 -10
  312. data/lib/mongoid/fields/internal/binary.rb +0 -11
  313. data/lib/mongoid/fields/internal/boolean.rb +0 -58
  314. data/lib/mongoid/fields/internal/date.rb +0 -51
  315. data/lib/mongoid/fields/internal/date_time.rb +0 -28
  316. data/lib/mongoid/fields/internal/false_class.rb +0 -10
  317. data/lib/mongoid/fields/internal/fixnum.rb +0 -10
  318. data/lib/mongoid/fields/internal/float.rb +0 -47
  319. data/lib/mongoid/fields/internal/foreign_keys/array.rb +0 -88
  320. data/lib/mongoid/fields/internal/foreign_keys/object.rb +0 -56
  321. data/lib/mongoid/fields/internal/hash.rb +0 -11
  322. data/lib/mongoid/fields/internal/integer.rb +0 -59
  323. data/lib/mongoid/fields/internal/localized.rb +0 -62
  324. data/lib/mongoid/fields/internal/nil_class.rb +0 -53
  325. data/lib/mongoid/fields/internal/object.rb +0 -11
  326. data/lib/mongoid/fields/internal/object_id.rb +0 -46
  327. data/lib/mongoid/fields/internal/range.rb +0 -61
  328. data/lib/mongoid/fields/internal/set.rb +0 -57
  329. data/lib/mongoid/fields/internal/string.rb +0 -42
  330. data/lib/mongoid/fields/internal/symbol.rb +0 -43
  331. data/lib/mongoid/fields/internal/time.rb +0 -23
  332. data/lib/mongoid/fields/internal/time_with_zone.rb +0 -23
  333. data/lib/mongoid/fields/internal/timekeeping.rb +0 -122
  334. data/lib/mongoid/fields/internal/true_class.rb +0 -10
  335. data/lib/mongoid/fields/mappings.rb +0 -42
  336. data/lib/mongoid/fields/serializable.rb +0 -270
  337. data/lib/mongoid/identity.rb +0 -92
  338. data/lib/mongoid/keys.rb +0 -144
  339. data/lib/mongoid/logger.rb +0 -45
  340. data/lib/mongoid/multi_database.rb +0 -31
  341. data/lib/mongoid/named_scope.rb +0 -166
  342. data/lib/mongoid/relations/embedded/atomic/operation.rb +0 -63
  343. data/lib/mongoid/relations/embedded/atomic/pull.rb +0 -65
  344. data/lib/mongoid/relations/embedded/atomic/push_all.rb +0 -59
  345. data/lib/mongoid/relations/embedded/atomic/set.rb +0 -61
  346. data/lib/mongoid/relations/embedded/atomic/unset.rb +0 -41
  347. data/lib/mongoid/relations/embedded/atomic.rb +0 -89
  348. data/lib/mongoid/relations/referenced/batch/insert.rb +0 -57
  349. data/lib/mongoid/relations/referenced/batch.rb +0 -73
  350. data/lib/mongoid/safety.rb +0 -105
  351. data/lib/mongoid/scope.rb +0 -31
@@ -0,0 +1,98 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Contextual
4
+ module Aggregable
5
+ # Contains behaviour for aggregating values in memory.
6
+ module Memory
7
+
8
+ # Get the average value of the provided field.
9
+ #
10
+ # @example Get the average of a single field.
11
+ # aggregable.avg(:likes)
12
+ #
13
+ # @param [ Symbol ] field The field to average.
14
+ #
15
+ # @return [ Float ] The average.
16
+ #
17
+ # @since 3.0.0
18
+ def avg(field)
19
+ count > 0 ? sum(field).to_f / count.to_f : nil
20
+ end
21
+
22
+ # Get the max value of the provided field. If provided a block, will
23
+ # return the Document with the greatest value for the field, in
24
+ # accordance with Ruby's enumerable API.
25
+ #
26
+ # @example Get the max of a single field.
27
+ # aggregable.max(:likes)
28
+ #
29
+ # @example Get the document with the max value.
30
+ # aggregable.max do |a, b|
31
+ # a.likes <=> b.likes
32
+ # end
33
+ #
34
+ # @param [ Symbol ] field The field to max.
35
+ #
36
+ # @return [ Float, Document ] The max value or document with the max
37
+ # value.
38
+ #
39
+ # @since 3.0.0
40
+ def max(field = nil)
41
+ if block_given?
42
+ super()
43
+ else
44
+ count > 0 ? max_by { |doc| doc.send(field) }.send(field) : nil
45
+ end
46
+ end
47
+
48
+ # Get the min value of the provided field. If provided a block, will
49
+ # return the Document with the smallest value for the field, in
50
+ # accordance with Ruby's enumerable API.
51
+ #
52
+ # @example Get the min of a single field.
53
+ # aggregable.min(:likes)
54
+ #
55
+ # @example Get the document with the min value.
56
+ # aggregable.min do |a, b|
57
+ # a.likes <=> b.likes
58
+ # end
59
+ #
60
+ # @param [ Symbol ] field The field to min.
61
+ #
62
+ # @return [ Float, Document ] The min value or document with the min
63
+ # value.
64
+ #
65
+ # @since 3.0.0
66
+ def min(field = nil)
67
+ if block_given?
68
+ super()
69
+ else
70
+ count > 0 ? min_by { |doc| doc.send(field) }.send(field) : nil
71
+ end
72
+ end
73
+
74
+ # Get the sum value of the provided field. If provided a block, will
75
+ # return the sum in accordance with Ruby's enumerable API.
76
+ #
77
+ # @example Get the sum of a single field.
78
+ # aggregable.sum(:likes)
79
+ #
80
+ # @example Get the sum for the provided block.
81
+ # aggregable.sum(&:likes)
82
+ #
83
+ # @param [ Symbol ] field The field to sum.
84
+ #
85
+ # @return [ Float ] The sum value.
86
+ #
87
+ # @since 3.0.0
88
+ def sum(field = nil)
89
+ if block_given?
90
+ super()
91
+ else
92
+ count > 0 ? super(0) { |doc| doc.send(field) } : nil
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,181 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Contextual
4
+ module Aggregable
5
+ # Contains behaviour for aggregating values in Mongo.
6
+ module Mongo
7
+
8
+ # Get all the aggregate values for the provided field.
9
+ #
10
+ # @example Get all the aggregate values.
11
+ # aggregable.aggregates(:likes)
12
+ #
13
+ # @param [ String, Symbol ] field The field name.
14
+ #
15
+ # @return [ Hash ] The aggregate values in the form:
16
+ # {
17
+ # "count" => 2.0,
18
+ # "max" => 1000.0,
19
+ # "min" => 500.0,
20
+ # "sum" => 1500.0,
21
+ # "avg" => 750.0
22
+ # }
23
+ #
24
+ # @since 3.0.0
25
+ def aggregates(field)
26
+ if query.count > 0
27
+ map_reduce(mapper(field), reducer).
28
+ out(inline: 1).finalize(finalizer).first["value"]
29
+ else
30
+ { "count" => 0 }
31
+ end
32
+ end
33
+
34
+ # Get the average value of the provided field.
35
+ #
36
+ # @example Get the average of a single field.
37
+ # aggregable.avg(:likes)
38
+ #
39
+ # @param [ Symbol ] field The field to average.
40
+ #
41
+ # @return [ Float ] The average.
42
+ #
43
+ # @since 3.0.0
44
+ def avg(field)
45
+ aggregates(field)["avg"]
46
+ end
47
+
48
+ # Get the max value of the provided field. If provided a block, will
49
+ # return the Document with the greatest value for the field, in
50
+ # accordance with Ruby's enumerable API.
51
+ #
52
+ # @example Get the max of a single field.
53
+ # aggregable.max(:likes)
54
+ #
55
+ # @example Get the document with the max value.
56
+ # aggregable.max do |a, b|
57
+ # a.likes <=> b.likes
58
+ # end
59
+ #
60
+ # @param [ Symbol ] field The field to max.
61
+ #
62
+ # @return [ Float, Document ] The max value or document with the max
63
+ # value.
64
+ #
65
+ # @since 3.0.0
66
+ def max(field = nil)
67
+ block_given? ? super() : aggregates(field)["max"]
68
+ end
69
+
70
+ # Get the min value of the provided field. If provided a block, will
71
+ # return the Document with the smallest value for the field, in
72
+ # accordance with Ruby's enumerable API.
73
+ #
74
+ # @example Get the min of a single field.
75
+ # aggregable.min(:likes)
76
+ #
77
+ # @example Get the document with the min value.
78
+ # aggregable.min do |a, b|
79
+ # a.likes <=> b.likes
80
+ # end
81
+ #
82
+ # @param [ Symbol ] field The field to min.
83
+ #
84
+ # @return [ Float, Document ] The min value or document with the min
85
+ # value.
86
+ #
87
+ # @since 3.0.0
88
+ def min(field = nil)
89
+ block_given? ? super() : aggregates(field)["min"]
90
+ end
91
+
92
+ # Get the sum value of the provided field. If provided a block, will
93
+ # return the sum in accordance with Ruby's enumerable API.
94
+ #
95
+ # @example Get the sum of a single field.
96
+ # aggregable.sum(:likes)
97
+ #
98
+ # @example Get the sum for the provided block.
99
+ # aggregable.sum(&:likes)
100
+ #
101
+ # @param [ Symbol ] field The field to sum.
102
+ #
103
+ # @return [ Float ] The sum value.
104
+ #
105
+ # @since 3.0.0
106
+ def sum(field = nil)
107
+ block_given? ? super() : aggregates(field)["sum"]
108
+ end
109
+
110
+ private
111
+
112
+ # Get the finalize function.
113
+ #
114
+ # @api private
115
+ #
116
+ # @example Get the finalize function.
117
+ # aggregable.finalizer
118
+ #
119
+ # @return [ String ] The finalize JS function.
120
+ #
121
+ # @since 3.0.0
122
+ def finalizer
123
+ %Q{
124
+ function(key, agg) {
125
+ agg.avg = agg.sum / agg.count;
126
+ return agg;
127
+ }}
128
+ end
129
+
130
+ # Get the map function for the provided field.
131
+ #
132
+ # @api private
133
+ #
134
+ # @example Get the map function.
135
+ # aggregable.mapper(:likes)
136
+ #
137
+ # @param [ String, Symbol ] field The name of the field.
138
+ #
139
+ # @return [ String ] The map JS function.
140
+ #
141
+ # @since 3.0.0
142
+ def mapper(field)
143
+ %Q{
144
+ function() {
145
+ var agg = {
146
+ count: 1,
147
+ max: this.#{field},
148
+ min: this.#{field},
149
+ sum: this.#{field}
150
+ };
151
+ emit("#{field}", agg);
152
+ }}
153
+ end
154
+
155
+ # Get the reduce function for the provided field.
156
+ #
157
+ # @api private
158
+ #
159
+ # @example Get the reduce function.
160
+ # aggregable.reducer(:likes)
161
+ #
162
+ # @return [ String ] The reduce JS function.
163
+ #
164
+ # @since 3.0.0
165
+ def reducer
166
+ %Q{
167
+ function(key, values) {
168
+ var agg = { count: 0, max: null, min: null, sum: 0 };
169
+ values.forEach(function(val) {
170
+ if (agg.max == null || val.max > agg.max) agg.max = val.max;
171
+ if (agg.min == null || val.max < agg.min) agg.min = val.max;
172
+ agg.count += 1;
173
+ agg.sum += val.sum;
174
+ });
175
+ return agg;
176
+ }}
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,179 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Contextual
4
+ module Atomic
5
+
6
+ # Execute an atomic $addToSet on the matching documents.
7
+ #
8
+ # @example Add the value to the set.
9
+ # context.add_to_set(:members, "Dave")
10
+ #
11
+ # @param [ String, Symbol ] field The name of the field to add to.
12
+ # @param [ Object ] value The single value to add.
13
+ #
14
+ # @return [ nil ] Nil.
15
+ #
16
+ # @since 3.0.0
17
+ def add_to_set(field, value)
18
+ query.update_all("$addToSet" => { field => value })
19
+ end
20
+
21
+ # Perform an atomic $bit operation on the matching documents.
22
+ #
23
+ # @example Perform the bitwise op.
24
+ # context.bit(:likes, { and: 14, or: 4 })
25
+ #
26
+ # @param [ String, Symbol ] field The name of the field to operate on.
27
+ # @param [ Hash ] value The bitwise operations to perform. Keys may be
28
+ # "and" or "or" and must have numeric values.
29
+ #
30
+ # @return [ nil ] Nil.
31
+ #
32
+ # @since 3.0.0
33
+ def bit(field, value)
34
+ query.update_all("$bit" => { field => value })
35
+ end
36
+
37
+ # Perform an atomic $inc operation on the matching documents.
38
+ #
39
+ # @example Perform the atomic increment.
40
+ # context.inc(:likes, 10)
41
+ #
42
+ # @param [ String, Symbol ] field The field to increment.
43
+ # @param [ Integer ] value The amount to increment by.
44
+ #
45
+ # @return [ nil ] Nil.
46
+ #
47
+ # @since 3.0.0
48
+ def inc(field, value)
49
+ query.update_all("$inc" => { field => value })
50
+ end
51
+
52
+ # Perform an atomic $pop operation on the matching documents.
53
+ #
54
+ # @example Pop the first value on the matches.
55
+ # context.pop(:members, -1)
56
+ #
57
+ # @example Pop the last value on the matches.
58
+ # context.pop(:members, 1)
59
+ #
60
+ # @param [ String, Symbol ] field The name of the array field to pop
61
+ # from.
62
+ # @param [ Integer ] value 1 to pop from the end, -1 to pop from the
63
+ # front.
64
+ #
65
+ # @return [ nil ] Nil.
66
+ #
67
+ # @since 3.0.0
68
+ def pop(field, value)
69
+ query.update_all("$pop" => { field => value })
70
+ end
71
+
72
+ # Perform an atomic $pull operation on the matching documents.
73
+ #
74
+ # @example Pull the value from the matches.
75
+ # context.pull(:members, "Dave")
76
+ #
77
+ # @note Expression pulling is not yet supported.
78
+ #
79
+ # @param [ String, Symbol ] field The field to pull from.
80
+ # @param [ Object ] value The single value to pull.
81
+ #
82
+ # @return [ nil ] Nil.
83
+ #
84
+ # @since 3.0.0
85
+ def pull(field, value)
86
+ query.update_all("$pull" => { field => value })
87
+ end
88
+
89
+ # Perform an atomic $pullAll operation on the matching documents.
90
+ #
91
+ # @example Pull all the matching values from the matches.
92
+ # context.pull_all(:members, [ "Alan", "Vince" ])
93
+ #
94
+ # @param [ String, Symbol ] field The field to pull from.
95
+ # @param [ Array<Object> ] values The values to pull.
96
+ #
97
+ # @return [ nil ] Nil.
98
+ #
99
+ # @since 3.0.0
100
+ def pull_all(field, values)
101
+ query.update_all("$pullAll" => { field => values })
102
+ end
103
+
104
+ # Perform an atomic $push operation on the matching documents.
105
+ #
106
+ # @example Push the value to the matching docs.
107
+ # context.push(:members, "Alan")
108
+ #
109
+ # @param [ String, Symbol ] field The field to push to.
110
+ # @param [ Object ] value The value to push.
111
+ #
112
+ # @return [ nil ] Nil.
113
+ #
114
+ # @since 3.0.0
115
+ def push(field, value)
116
+ query.update_all("$push" => { field => value })
117
+ end
118
+
119
+ # Perform an atomic $pushAll operation on the matching documents.
120
+ #
121
+ # @example Push the values to the matching docs.
122
+ # context.push(:members, [ "Alan", "Fletch" ])
123
+ #
124
+ # @param [ String, Symbol ] field The field to push to.
125
+ # @param [ Array<Object> ] values The values to push.
126
+ #
127
+ # @return [ nil ] Nil.
128
+ #
129
+ # @since 3.0.0
130
+ def push_all(field, values)
131
+ query.update_all("$pushAll" => { field => values })
132
+ end
133
+
134
+ # Perform an atomic $rename of fields on the matching documents.
135
+ #
136
+ # @example Rename the fields on the matching documents.
137
+ # context.rename(:members, :artists)
138
+ #
139
+ # @param [ String, Symbol ] old_name The old field name.
140
+ # @param [ String, Symbol ] new_name The new field name.
141
+ #
142
+ # @return [ nil ] Nil.
143
+ #
144
+ # @since 3.0.0
145
+ def rename(old_name, new_name)
146
+ query.update_all("$rename" => { old_name.to_s => new_name.to_s })
147
+ end
148
+
149
+ # Perform an atomic $set of fields on the matching documents.
150
+ #
151
+ # @example Set the field value on the matches.
152
+ # context.set(:name, "Depeche Mode")
153
+ #
154
+ # @param [ String, Symbol ] field The name of the field.
155
+ # @param [ Object ] value The value to set.
156
+ #
157
+ # @return [ nil ] Nil.
158
+ #
159
+ # @since 3.0.0
160
+ def set(field, value)
161
+ query.update_all("$set" => { field => value })
162
+ end
163
+
164
+ # Perform an atomic $unset of a field on the matching documents.
165
+ #
166
+ # @example Unset the field on the matches.
167
+ # context.unset(:name)
168
+ #
169
+ # @param [ String, Symbol ] field The name of the field.
170
+ #
171
+ # @return [ nil ] Nil.
172
+ #
173
+ # @since 3.0.0
174
+ def unset(field)
175
+ query.update_all("$unset" => { field => true })
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Contextual
4
+ module Command
5
+
6
+ # The database command that is being built to send to the db.
7
+ #
8
+ # @example Get the command.
9
+ # command.command
10
+ #
11
+ # @return [ Hash ] The db command.
12
+ #
13
+ # @since 3.0.0
14
+ def command
15
+ @command ||= {}
16
+ end
17
+
18
+ # Get the criteria for the command.
19
+ #
20
+ # @example Get the criteria.
21
+ # command.criteria
22
+ #
23
+ # @return [ Criteria ] The criteria.
24
+ #
25
+ # @since 3.0.0
26
+ def criteria
27
+ @criteria
28
+ end
29
+
30
+ # Get the database session.
31
+ #
32
+ # @example Get the session.
33
+ # command.session
34
+ #
35
+ # @return [ Session ] The Moped session.
36
+ #
37
+ # @since 3.0.0
38
+ def session
39
+ criteria.klass.mongo_session
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Contextual
4
+ class FindAndModify
5
+ include Command
6
+
7
+ # Initialize the find and modify command, used for MongoDB's
8
+ # $findAndModify.
9
+ #
10
+ # @example Initialize the command.
11
+ # FindAndModify.new(criteria, { "$set" => { likes: 1 }})
12
+ #
13
+ # @param [ Criteria ] criteria The criteria.
14
+ # @param [ Hash ] update The updates.
15
+ # @param [ Hash ] options The command options.
16
+ #
17
+ # @option options [ true, false ] :new Return the updated document.
18
+ # @option options [ true, false ] :remove Delete the first document.
19
+ #
20
+ # @since 3.0.0
21
+ def initialize(criteria, update, options = {})
22
+ @criteria = criteria
23
+ command[:findandmodify] = criteria.klass.collection_name.to_s
24
+ command[:update] = update unless options[:remove]
25
+ command.merge!(options)
26
+ apply_criteria_options
27
+ end
28
+
29
+ # Get the result of the $findAndModify.
30
+ #
31
+ # @example Get the result.
32
+ # find_and_modify.result
33
+ #
34
+ # @return [ Hash ] The result of the command.
35
+ #
36
+ # @since 3.0.0
37
+ def result
38
+ session.with(consistency: :strong) do |session|
39
+ session.command(command)["value"]
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ # Apply criteria specific options - query, sort, fields.
46
+ #
47
+ # @api private
48
+ #
49
+ # @example Apply the criteria options
50
+ # map_reduce.apply_criteria_options
51
+ #
52
+ # @return [ nil ] Nothing.
53
+ #
54
+ # @since 3.0.0
55
+ def apply_criteria_options
56
+ command[:query] = criteria.selector
57
+ if sort = criteria.options[:sort]
58
+ command[:sort] = sort
59
+ end
60
+ if fields = criteria.options[:fields]
61
+ command[:fields] = fields
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end