mongoid 2.8.1 → 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 +802 -58
  2. data/LICENSE +1 -1
  3. data/README.md +10 -11
  4. data/Rakefile +2 -8
  5. data/lib/config/locales/en.yml +441 -51
  6. data/lib/mongoid.rb +24 -39
  7. data/lib/mongoid/atomic.rb +16 -33
  8. data/lib/mongoid/atomic/modifiers.rb +2 -2
  9. data/lib/mongoid/atomic/paths/embedded.rb +4 -5
  10. data/lib/mongoid/atomic/paths/embedded/many.rb +6 -6
  11. data/lib/mongoid/atomic/paths/embedded/one.rb +5 -5
  12. data/lib/mongoid/atomic/paths/root.rb +4 -5
  13. data/lib/mongoid/attributes.rb +95 -32
  14. data/lib/mongoid/attributes/processing.rb +14 -10
  15. data/lib/mongoid/attributes/readonly.rb +56 -0
  16. data/lib/mongoid/callbacks.rb +90 -27
  17. data/lib/mongoid/collections/retry.rb +2 -3
  18. data/lib/mongoid/components.rb +11 -23
  19. data/lib/mongoid/config.rb +87 -233
  20. data/lib/mongoid/config/environment.rb +5 -6
  21. data/lib/mongoid/config/inflections.rb +6 -0
  22. data/lib/mongoid/config/options.rb +1 -1
  23. data/lib/mongoid/config/validators.rb +3 -0
  24. data/lib/mongoid/config/validators/option.rb +25 -0
  25. data/lib/mongoid/config/validators/session.rb +140 -0
  26. data/lib/mongoid/contextual.rb +50 -0
  27. data/lib/mongoid/contextual/aggregable/memory.rb +98 -0
  28. data/lib/mongoid/contextual/aggregable/mongo.rb +181 -0
  29. data/lib/mongoid/contextual/atomic.rb +179 -0
  30. data/lib/mongoid/contextual/command.rb +43 -0
  31. data/lib/mongoid/contextual/find_and_modify.rb +66 -0
  32. data/lib/mongoid/contextual/map_reduce.rb +273 -0
  33. data/lib/mongoid/contextual/memory.rb +383 -0
  34. data/lib/mongoid/contextual/mongo.rb +543 -0
  35. data/lib/mongoid/copyable.rb +3 -34
  36. data/lib/mongoid/criteria.rb +436 -250
  37. data/lib/mongoid/criterion/inspection.rb +14 -8
  38. data/lib/mongoid/criterion/scoping.rb +114 -44
  39. data/lib/mongoid/dirty.rb +152 -67
  40. data/lib/mongoid/document.rb +69 -50
  41. data/lib/mongoid/errors.rb +22 -1
  42. data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
  43. data/lib/mongoid/errors/callback.rb +5 -6
  44. data/lib/mongoid/errors/delete_restriction.rb +29 -0
  45. data/lib/mongoid/errors/document_not_found.rb +98 -17
  46. data/lib/mongoid/errors/eager_load.rb +3 -6
  47. data/lib/mongoid/errors/invalid_collection.rb +3 -3
  48. data/lib/mongoid/errors/invalid_config_option.rb +27 -0
  49. data/lib/mongoid/errors/invalid_database.rb +3 -3
  50. data/lib/mongoid/errors/invalid_field.rb +54 -8
  51. data/lib/mongoid/errors/invalid_field_option.rb +35 -0
  52. data/lib/mongoid/errors/invalid_find.rb +3 -3
  53. data/lib/mongoid/errors/invalid_index.rb +28 -0
  54. data/lib/mongoid/errors/invalid_options.rb +4 -4
  55. data/lib/mongoid/errors/invalid_scope.rb +24 -0
  56. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
  57. data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
  58. data/lib/mongoid/errors/invalid_time.rb +3 -6
  59. data/lib/mongoid/errors/inverse_not_found.rb +29 -0
  60. data/lib/mongoid/errors/mixed_relations.rb +4 -9
  61. data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
  62. data/lib/mongoid/errors/mongoid_error.rb +54 -3
  63. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
  64. data/lib/mongoid/errors/no_default_session.rb +23 -0
  65. data/lib/mongoid/errors/no_environment.rb +3 -3
  66. data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
  67. data/lib/mongoid/errors/no_parent.rb +24 -0
  68. data/lib/mongoid/errors/no_session_config.rb +22 -0
  69. data/lib/mongoid/errors/no_session_database.rb +27 -0
  70. data/lib/mongoid/errors/no_session_hosts.rb +27 -0
  71. data/lib/mongoid/errors/no_sessions_config.rb +20 -0
  72. data/lib/mongoid/errors/readonly_attribute.rb +25 -0
  73. data/lib/mongoid/errors/scope_overwrite.rb +4 -4
  74. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +4 -4
  75. data/lib/mongoid/errors/unknown_attribute.rb +25 -0
  76. data/lib/mongoid/errors/unsaved_document.rb +4 -8
  77. data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
  78. data/lib/mongoid/errors/unsupported_version.rb +4 -4
  79. data/lib/mongoid/errors/validations.rb +7 -6
  80. data/lib/mongoid/errors/versioning_not_on_root.rb +23 -0
  81. data/lib/mongoid/extensions.rb +28 -76
  82. data/lib/mongoid/extensions/array.rb +127 -0
  83. data/lib/mongoid/extensions/big_decimal.rb +42 -0
  84. data/lib/mongoid/extensions/boolean.rb +24 -0
  85. data/lib/mongoid/extensions/date.rb +70 -0
  86. data/lib/mongoid/extensions/date_time.rb +68 -0
  87. data/lib/mongoid/extensions/false_class.rb +26 -0
  88. data/lib/mongoid/extensions/float.rb +44 -0
  89. data/lib/mongoid/extensions/hash.rb +91 -0
  90. data/lib/mongoid/extensions/integer.rb +54 -0
  91. data/lib/mongoid/extensions/module.rb +28 -0
  92. data/lib/mongoid/extensions/nil_class.rb +21 -0
  93. data/lib/mongoid/extensions/object.rb +188 -0
  94. data/lib/mongoid/extensions/object_id.rb +53 -0
  95. data/lib/mongoid/extensions/range.rb +55 -0
  96. data/lib/mongoid/extensions/regexp.rb +27 -0
  97. data/lib/mongoid/extensions/set.rb +55 -0
  98. data/lib/mongoid/extensions/string.rb +155 -0
  99. data/lib/mongoid/extensions/symbol.rb +54 -0
  100. data/lib/mongoid/extensions/time.rb +78 -0
  101. data/lib/mongoid/extensions/time_with_zone.rb +55 -0
  102. data/lib/mongoid/extensions/true_class.rb +26 -0
  103. data/lib/mongoid/factory.rb +1 -1
  104. data/lib/mongoid/fields.rb +129 -194
  105. data/lib/mongoid/fields/foreign_key.rb +134 -0
  106. data/lib/mongoid/fields/localized.rb +73 -0
  107. data/lib/mongoid/fields/standard.rb +268 -0
  108. data/lib/mongoid/fields/validators.rb +2 -0
  109. data/lib/mongoid/fields/validators/macro.rb +83 -0
  110. data/lib/mongoid/finders.rb +42 -43
  111. data/lib/mongoid/hierarchy.rb +25 -14
  112. data/lib/mongoid/identity_map.rb +31 -19
  113. data/lib/mongoid/indexes.rb +66 -15
  114. data/lib/mongoid/indexes/validators/options.rb +80 -0
  115. data/lib/mongoid/inspection.rb +1 -1
  116. data/lib/mongoid/javascript.rb +1 -1
  117. data/lib/mongoid/json.rb +2 -2
  118. data/lib/mongoid/loggable.rb +69 -0
  119. data/lib/mongoid/matchers.rb +1 -1
  120. data/lib/mongoid/matchers/all.rb +7 -8
  121. data/lib/mongoid/matchers/and.rb +3 -3
  122. data/lib/mongoid/matchers/default.rb +6 -4
  123. data/lib/mongoid/matchers/exists.rb +2 -2
  124. data/lib/mongoid/matchers/gt.rb +2 -2
  125. data/lib/mongoid/matchers/gte.rb +2 -2
  126. data/lib/mongoid/matchers/in.rb +3 -7
  127. data/lib/mongoid/matchers/lt.rb +2 -2
  128. data/lib/mongoid/matchers/lte.rb +2 -2
  129. data/lib/mongoid/matchers/ne.rb +2 -2
  130. data/lib/mongoid/matchers/nin.rb +2 -2
  131. data/lib/mongoid/matchers/or.rb +2 -2
  132. data/lib/mongoid/matchers/size.rb +2 -2
  133. data/lib/mongoid/matchers/strategies.rb +3 -3
  134. data/lib/mongoid/multi_parameter_attributes.rb +8 -10
  135. data/lib/mongoid/nested_attributes.rb +17 -9
  136. data/lib/mongoid/observer.rb +1 -2
  137. data/lib/mongoid/paranoia.rb +13 -18
  138. data/lib/mongoid/persistence.rb +43 -39
  139. data/lib/mongoid/persistence/atomic.rb +2 -2
  140. data/lib/mongoid/persistence/atomic/add_to_set.rb +5 -9
  141. data/lib/mongoid/persistence/atomic/bit.rb +5 -7
  142. data/lib/mongoid/persistence/atomic/inc.rb +5 -7
  143. data/lib/mongoid/persistence/atomic/operation.rb +45 -6
  144. data/lib/mongoid/persistence/atomic/pop.rb +5 -7
  145. data/lib/mongoid/persistence/atomic/pull.rb +5 -7
  146. data/lib/mongoid/persistence/atomic/pull_all.rb +5 -7
  147. data/lib/mongoid/persistence/atomic/push.rb +4 -10
  148. data/lib/mongoid/persistence/atomic/push_all.rb +4 -10
  149. data/lib/mongoid/persistence/atomic/rename.rb +6 -7
  150. data/lib/mongoid/persistence/atomic/sets.rb +5 -7
  151. data/lib/mongoid/persistence/atomic/unset.rb +4 -5
  152. data/lib/mongoid/persistence/deletion.rb +2 -2
  153. data/lib/mongoid/persistence/insertion.rb +10 -16
  154. data/lib/mongoid/persistence/modification.rb +5 -9
  155. data/lib/mongoid/persistence/operations.rb +6 -19
  156. data/lib/mongoid/persistence/operations/embedded/insert.rb +7 -6
  157. data/lib/mongoid/persistence/operations/embedded/remove.rb +5 -5
  158. data/lib/mongoid/persistence/operations/insert.rb +4 -4
  159. data/lib/mongoid/persistence/operations/remove.rb +4 -4
  160. data/lib/mongoid/persistence/operations/update.rb +5 -5
  161. data/lib/mongoid/railtie.rb +26 -11
  162. data/lib/mongoid/railties/database.rake +22 -108
  163. data/lib/mongoid/relations.rb +4 -6
  164. data/lib/mongoid/relations/accessors.rb +119 -19
  165. data/lib/mongoid/relations/auto_save.rb +59 -5
  166. data/lib/mongoid/relations/binding.rb +211 -2
  167. data/lib/mongoid/relations/bindings/embedded/in.rb +16 -22
  168. data/lib/mongoid/relations/bindings/embedded/many.rb +9 -50
  169. data/lib/mongoid/relations/bindings/embedded/one.rb +10 -16
  170. data/lib/mongoid/relations/bindings/referenced/in.rb +31 -57
  171. data/lib/mongoid/relations/bindings/referenced/many.rb +8 -20
  172. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +15 -19
  173. data/lib/mongoid/relations/bindings/referenced/one.rb +10 -24
  174. data/lib/mongoid/relations/builder.rb +3 -3
  175. data/lib/mongoid/relations/builders.rb +19 -16
  176. data/lib/mongoid/relations/builders/embedded/in.rb +5 -5
  177. data/lib/mongoid/relations/builders/embedded/many.rb +12 -12
  178. data/lib/mongoid/relations/builders/embedded/one.rb +6 -6
  179. data/lib/mongoid/relations/builders/nested_attributes/many.rb +8 -8
  180. data/lib/mongoid/relations/builders/nested_attributes/one.rb +4 -4
  181. data/lib/mongoid/relations/builders/referenced/in.rb +4 -4
  182. data/lib/mongoid/relations/builders/referenced/many.rb +5 -5
  183. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +7 -5
  184. data/lib/mongoid/relations/builders/referenced/one.rb +5 -5
  185. data/lib/mongoid/relations/cascading.rb +6 -4
  186. data/lib/mongoid/relations/cascading/delete.rb +3 -5
  187. data/lib/mongoid/relations/cascading/destroy.rb +3 -3
  188. data/lib/mongoid/relations/cascading/nullify.rb +3 -3
  189. data/lib/mongoid/relations/cascading/restrict.rb +37 -0
  190. data/lib/mongoid/relations/constraint.rb +4 -3
  191. data/lib/mongoid/relations/conversions.rb +5 -6
  192. data/lib/mongoid/relations/cyclic.rb +7 -7
  193. data/lib/mongoid/relations/embedded/batchable.rb +346 -0
  194. data/lib/mongoid/relations/embedded/in.rb +23 -12
  195. data/lib/mongoid/relations/embedded/many.rb +99 -161
  196. data/lib/mongoid/relations/embedded/one.rb +25 -14
  197. data/lib/mongoid/relations/macros.rb +105 -61
  198. data/lib/mongoid/relations/many.rb +93 -14
  199. data/lib/mongoid/relations/metadata.rb +200 -45
  200. data/lib/mongoid/relations/nested_builder.rb +3 -5
  201. data/lib/mongoid/relations/one.rb +2 -2
  202. data/lib/mongoid/relations/options.rb +2 -2
  203. data/lib/mongoid/relations/polymorphic.rb +9 -9
  204. data/lib/mongoid/relations/proxy.rb +60 -31
  205. data/lib/mongoid/relations/referenced/in.rb +40 -15
  206. data/lib/mongoid/relations/referenced/many.rb +117 -132
  207. data/lib/mongoid/relations/referenced/many_to_many.rb +101 -46
  208. data/lib/mongoid/relations/referenced/one.rb +34 -13
  209. data/lib/mongoid/relations/reflections.rb +3 -3
  210. data/lib/mongoid/relations/synchronization.rb +19 -23
  211. data/lib/mongoid/relations/targets/enumerable.rb +86 -57
  212. data/lib/mongoid/reloading.rb +12 -14
  213. data/lib/mongoid/scoping.rb +329 -0
  214. data/lib/mongoid/serialization.rb +8 -27
  215. data/lib/mongoid/sessions.rb +359 -0
  216. data/lib/mongoid/sessions/factory.rb +106 -0
  217. data/lib/mongoid/sessions/mongo_uri.rb +93 -0
  218. data/lib/mongoid/sessions/validators.rb +2 -0
  219. data/lib/mongoid/sessions/validators/storage.rb +49 -0
  220. data/lib/mongoid/sharding.rb +6 -6
  221. data/lib/mongoid/state.rb +6 -7
  222. data/lib/mongoid/threaded.rb +167 -59
  223. data/lib/mongoid/threaded/lifecycle.rb +21 -22
  224. data/lib/mongoid/threaded/sessions.rb +0 -0
  225. data/lib/mongoid/timestamps.rb +1 -1
  226. data/lib/mongoid/timestamps/created.rb +8 -4
  227. data/lib/mongoid/timestamps/timeless.rb +6 -4
  228. data/lib/mongoid/timestamps/updated.rb +3 -3
  229. data/lib/mongoid/unit_of_work.rb +61 -0
  230. data/lib/mongoid/validations.rb +27 -19
  231. data/lib/mongoid/validations/associated.rb +2 -2
  232. data/lib/mongoid/validations/format.rb +2 -2
  233. data/lib/mongoid/validations/presence.rb +31 -5
  234. data/lib/mongoid/validations/uniqueness.rb +9 -12
  235. data/lib/mongoid/version.rb +2 -2
  236. data/lib/mongoid/versioning.rb +25 -26
  237. data/lib/rack/mongoid/middleware/identity_map.rb +3 -3
  238. data/lib/rails/generators/mongoid/config/config_generator.rb +1 -1
  239. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +59 -19
  240. data/lib/rails/generators/mongoid/model/model_generator.rb +7 -7
  241. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +2 -2
  242. data/lib/rails/generators/mongoid/observer/observer_generator.rb +4 -4
  243. data/lib/rails/generators/mongoid_generator.rb +5 -5
  244. data/lib/rails/mongoid.rb +69 -25
  245. metadata +110 -137
  246. checksums.yaml +0 -7
  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.rb +0 -120
  269. data/lib/mongoid/collections/master.rb +0 -45
  270. data/lib/mongoid/collections/operations.rb +0 -44
  271. data/lib/mongoid/config/database.rb +0 -181
  272. data/lib/mongoid/config/replset_database.rb +0 -80
  273. data/lib/mongoid/contexts.rb +0 -25
  274. data/lib/mongoid/contexts/enumerable.rb +0 -313
  275. data/lib/mongoid/contexts/enumerable/sort.rb +0 -43
  276. data/lib/mongoid/contexts/mongo.rb +0 -487
  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 -110
  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 -77
  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 -36
  341. data/lib/mongoid/named_scope.rb +0 -166
  342. data/lib/mongoid/relations/embedded/atomic.rb +0 -89
  343. data/lib/mongoid/relations/embedded/atomic/operation.rb +0 -63
  344. data/lib/mongoid/relations/embedded/atomic/pull.rb +0 -65
  345. data/lib/mongoid/relations/embedded/atomic/push_all.rb +0 -59
  346. data/lib/mongoid/relations/embedded/atomic/set.rb +0 -61
  347. data/lib/mongoid/relations/embedded/atomic/unset.rb +0 -41
  348. data/lib/mongoid/relations/referenced/batch.rb +0 -73
  349. data/lib/mongoid/relations/referenced/batch/insert.rb +0 -57
  350. data/lib/mongoid/safety.rb +0 -105
  351. data/lib/mongoid/scope.rb +0 -31
@@ -1,259 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Criterion #:nodoc:
4
- module Optional
5
-
6
- # Adds fields to be sorted in ascending order. Will add them in the order
7
- # they were passed into the method.
8
- #
9
- # @example Sort in ascending order.
10
- # criteria.ascending(:title, :dob)
11
- # criteria.asc(:title, :dob)
12
- #
13
- # @param [ Array<Symbol> ] fields The fields to sort on.
14
- #
15
- # @return [ Criteria ] The cloned criteria.
16
- def ascending(*fields)
17
- clone.tap do |crit|
18
- setup_sort_options(crit.options) unless fields.first.nil?
19
- fields.flatten.each { |field| merge_options(crit.options[:sort], [ localize(field), :asc ]) }
20
- end
21
- end
22
- alias :asc :ascending
23
-
24
- # Tells the criteria that the cursor that gets returned needs to be
25
- # cached. This is so multiple iterations don't hit the database multiple
26
- # times, however this is not advisable when working with large data sets
27
- # as the entire results will get stored in memory.
28
- #
29
- # @example Flag the criteria as cached.
30
- # criteria.cache
31
- #
32
- # @return [ Criteria ] The cloned criteria.
33
- def cache
34
- clone.tap { |crit| crit.options.merge!(:cache => true) }
35
- end
36
-
37
- # Will return true if the cache option has been set.
38
- #
39
- # @example Is the criteria cached?
40
- # criteria.cached?
41
- #
42
- # @return [ true, false ] If the criteria is flagged as cached.
43
- def cached?
44
- options[:cache] == true
45
- end
46
-
47
- # Adds fields to be sorted in descending order. Will add them in the order
48
- # they were passed into the method.
49
- #
50
- # @example Sort the criteria in descending order.
51
- # criteria.descending(:title, :dob)
52
- # criteria.desc(:title, :dob)
53
- #
54
- # @param [ Array<Symbol> ] fields The fields to sort on.
55
- #
56
- # @return [ Criteria ] The cloned criteria.
57
- def descending(*fields)
58
- clone.tap do |crit|
59
- setup_sort_options(crit.options) unless fields.first.nil?
60
- fields.flatten.each { |field| merge_options(crit.options[:sort], [ localize(field), :desc ]) }
61
- end
62
- end
63
- alias :desc :descending
64
-
65
- # Adds a criterion to the +Criteria+ that specifies additional options
66
- # to be passed to the Ruby driver, in the exact format for the driver.
67
- #
68
- # @example Add extra params to the criteria.
69
- # criteria.extras(:limit => 20, :skip => 40)
70
- #
71
- # @param [ Hash ] extras The extra driver options.
72
- #
73
- # @return [ Criteria ] The cloned criteria.
74
- def extras(extras)
75
- clone.tap do |crit|
76
- crit.options.merge!(extras)
77
- end
78
- end
79
-
80
- # Adds a criterion to the +Criteria+ that specifies an id that must be matched.
81
- #
82
- # @example Add a single id criteria.
83
- # criteria.for_ids("4ab2bc4b8ad548971900005c")
84
- #
85
- # @example Add multiple id criteria.
86
- # criteria.for_ids(["4ab2bc4b8ad548971900005c", "4c454e7ebf4b98032d000001"])
87
- #
88
- # @param [ Array ] ids: A single id or an array of ids.
89
- #
90
- # @return [ Criteria ] The cloned criteria.
91
- def for_ids(*ids)
92
- field = klass.fields["_id"]
93
- ids.flatten!
94
- if ids.size > 1
95
- any_in(:_id => ids.map{ |id| field.serialize(id) })
96
- else
97
- where(:_id => field.serialize(ids.first))
98
- end
99
- end
100
-
101
- # Adds a criterion to the +Criteria+ that specifies the maximum number of
102
- # results to return. This is mostly used in conjunction with skip()
103
- # to handle paginated results.
104
- #
105
- # @example Limit the result set size.
106
- # criteria.limit(100)
107
- #
108
- # @param [ Integer ] value The max number of results.
109
- #
110
- # @return [ Criteria ] The cloned criteria.
111
- def limit(value = 20)
112
- clone.tap { |crit| crit.options[:limit] = value.to_i }
113
- end
114
-
115
- # Returns the offset option. If a per_page option is in the list then it
116
- # will replace it with a skip parameter and return the same value. Defaults
117
- # to 20 if nothing was provided.
118
- #
119
- # @example Get the offset.
120
- # criteria.offset(10)
121
- #
122
- # @return [ Integer ] The number of documents to skip.
123
- def offset(*args)
124
- args.size > 0 ? skip(args.first) : options[:skip]
125
- end
126
-
127
- # Adds a criterion to the +Criteria+ that specifies the sort order of
128
- # the returned documents in the database. Similar to a SQL "ORDER BY".
129
- #
130
- # @example Order by specific fields.
131
- # criteria.order_by([[:field1, :asc], [:field2, :desc]])
132
- #
133
- # @param [ Array ] params: An +Array+ of [field, direction] sorting pairs.
134
- #
135
- # @return [ Criteria ] The cloned criteria.
136
- def order_by(*args)
137
- clone.tap do |crit|
138
- arguments = args.size == 1 ? args.first : args
139
- setup_sort_options(crit.options) unless args.first.nil?
140
- if arguments.is_a?(Array)
141
- #[:name, :asc]
142
- if arguments.size == 2 && (arguments.first.is_a?(Symbol) || arguments.first.is_a?(String))
143
- build_order_options(arguments, crit)
144
- else
145
- arguments.each { |argument| build_order_options(argument, crit) }
146
- end
147
- else
148
- build_order_options(arguments, crit)
149
- end
150
- end
151
- end
152
- alias :order :order_by
153
-
154
- # Adds a criterion to the +Criteria+ that specifies how many results to skip
155
- # when returning Documents. This is mostly used in conjunction with
156
- # limit() to handle paginated results, and is similar to the
157
- # traditional "offset" parameter.
158
- #
159
- # @example Skip a specified number of documents.
160
- # criteria.skip(20)
161
- #
162
- # @param [ Integer ] value The number of results to skip.
163
- #
164
- # @return [ Criteria ] The cloned criteria.
165
- def skip(value = 0)
166
- clone.tap { |crit| crit.options[:skip] = value.to_i }
167
- end
168
-
169
- # Adds a criterion to the +Criteria+ that specifies a type or an Array of
170
- # types that must be matched.
171
- #
172
- # @example Match only specific models.
173
- # criteria.type('Browser')
174
- # criteria.type(['Firefox', 'Browser'])
175
- #
176
- # @param [ Array<String> ] types The types to match against.
177
- #
178
- # @return [ Criteria ] The cloned criteria.
179
- def type(types)
180
- types = [types] unless types.is_a?(Array)
181
- any_in(:_type => types)
182
- end
183
-
184
- private
185
-
186
- # Build ordering options from given arguments on given criteria
187
- #
188
- # @example build order options
189
- # criteria.build_order_options(:name.asc, criteria)
190
- #
191
- #
192
- # @param [ <Hash>, <Array>, <Complex> ] argument to build criteria from
193
- # @param [ Criterion ] criterion to change
194
- def build_order_options(arguments, crit)
195
- case arguments
196
- when Hash
197
- if arguments.size > 1
198
- raise ArgumentError, "Please don't use hash to define multiple orders " +
199
- "due to the fact that hash doesn't have order this may cause unpredictable results"
200
- end
201
- arguments.each_pair do |field, direction|
202
- merge_options(crit.options[:sort], [ localize(field), direction ])
203
- end
204
- when Array
205
- merge_options(crit.options[:sort], arguments.map{ |field| localize(field) })
206
- when Complex
207
- merge_options(crit.options[:sort], [ localize(arguments.key), arguments.operator.to_sym ])
208
- end
209
- end
210
-
211
- # Merge options for order_by criterion
212
- # Allow only one order direction for same field
213
- #
214
- # @example Merge ordering options
215
- # criteria.merge_options([[:title, :asc], [:created_at, :asc]], [:title, :desc])
216
- #
217
- #
218
- # @param [ Array<Array> ] Existing options
219
- # @param [ Array ] New option for merge.
220
- #
221
- # @since 2.1.0
222
- def merge_options(options, new_option)
223
- old_option = options.assoc(new_option.first)
224
-
225
- if old_option
226
- options[options.index(old_option)] = new_option.flatten
227
- else
228
- options << new_option.flatten
229
- end
230
- end
231
-
232
- # Initialize the sort options
233
- # Set options[:sort] to an empty array if it does not exist, or dup it if
234
- # it already has been defined
235
- #
236
- # @example criteria.setup_sort_options(crit.options)
237
- #
238
- # @param [ Array<Array> ] Existing options
239
- #
240
- # @since 2.4.0
241
- def setup_sort_options(options)
242
- options[:sort] = options[:sort] ? options[:sort].dup : []
243
- end
244
-
245
- # Check if field is localized and return localized version if it is.
246
- #
247
- # @example localize
248
- # criteria.localize(:description)
249
- #
250
- # @param [ <Symbol> ] field to localize
251
- def localize(field)
252
- if klass.fields[field.to_s].try(:localized?)
253
- field = "#{field}.#{::I18n.locale}".to_sym
254
- end
255
- field
256
- end
257
- end
258
- end
259
- end
@@ -1,177 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Criterion #:nodoc:
4
-
5
- # The selector is a hash-like object that has special behaviour for merging
6
- # mongoid criteria selectors.
7
- class Selector < Hash
8
-
9
- attr_reader :aliased_fields, :fields, :klass
10
-
11
- # Create the new selector.
12
- #
13
- # @example Create the selector.
14
- # Selector.new(Person)
15
- #
16
- # @param [ Class ] klass The class the selector is for.
17
- #
18
- # @since 1.0.0
19
- def initialize(klass)
20
- @aliased_fields, @fields, @klass =
21
- klass.aliased_fields, klass.fields.except("_id", "_type"), klass
22
- end
23
-
24
- # Set the value for the supplied key, attempting to typecast the value.
25
- #
26
- # @example Set the value for the key.
27
- # selector["$ne"] = { :name => "Zorg" }
28
- #
29
- # @param [ String, Symbol ] key The hash key.
30
- # @param [ Object ] value The value to set.
31
- #
32
- # @since 2.0.0
33
- def []=(key, value)
34
- key = "#{key}.#{::I18n.locale}" if klass.fields[key.to_s].try(:localized?)
35
- super(key, try_to_typecast(key, value))
36
- end
37
-
38
- # Merge the selector with another hash.
39
- #
40
- # @example Merge the objects.
41
- # selector.merge!({ :key => "value" })
42
- #
43
- # @param [ Hash, Selector ] other The object to merge with.
44
- #
45
- # @return [ Selector ] The merged selector.
46
- #
47
- # @since 1.0.0
48
- def merge!(other)
49
- tap do |selector|
50
- other.each_pair do |key, value|
51
- selector[key] = value
52
- end
53
- end
54
- end
55
- alias :update :merge!
56
-
57
- if RUBY_VERSION < '1.9'
58
-
59
- # Generate pretty inspection for old ruby versions.
60
- #
61
- # @example Inspect the selector.
62
- # selector.inspect
63
- #
64
- # @return [ String ] The inspected selector.
65
- def inspect
66
- ret = self.keys.inject([]) do |ret, key|
67
- ret << "#{key.inspect}=>#{self[key].inspect}"
68
- end
69
- "{#{ret.sort.join(', ')}}"
70
- end
71
- end
72
-
73
- private
74
-
75
- # If the key is defined as a field, then attempt to typecast it.
76
- #
77
- # @example Try to cast.
78
- # selector.try_to_typecast(:id, 1)
79
- #
80
- # @param [ String, Symbol ] key The field name.
81
- # @param [ Object ] value The value.
82
- #
83
- # @return [ Object ] The typecasted value.
84
- #
85
- # @since 1.0.0
86
- def try_to_typecast(key, value)
87
- access = key.to_s
88
- if field = fields[key.to_s] || fields[aliased_fields[key.to_s]]
89
- typecast_value_for(field, value)
90
- elsif proper_and_or_value?(key, value)
91
- handle_and_or_value(value)
92
- else
93
- value
94
- end
95
- end
96
-
97
- def proper_and_or_value?(key, value)
98
- ["$and", "$or"].include?(key) &&
99
- value.is_a?(Array) &&
100
- value.all?{ |e| e.is_a?(Hash) }
101
- end
102
-
103
- def handle_and_or_value(values)
104
- [].tap do |result|
105
- result.push(*values.map do |value|
106
- Hash[value.map do |_key, _value|
107
- if klass.fields[_key.to_s].try(:localized?)
108
- _key = "#{_key}.#{::I18n.locale}"
109
- end
110
- [_key, try_to_typecast(_key, _value)]
111
- end]
112
- end)
113
- end
114
- end
115
-
116
- # Get the typecast value for the defined field.
117
- #
118
- # @example Get the typecast value.
119
- # selector.typecast_value_for(:name, "Corbin")
120
- #
121
- # @param [ Field ] field The defined field.
122
- # @param [ Object ] value The value to cast.
123
- #
124
- # @return [ Object ] The cast value.
125
- #
126
- # @since 1.0.0
127
- def typecast_value_for(field, value)
128
- return field.selection(value) if field.type === value
129
- case value
130
- when Hash
131
- value = value.dup
132
- value.each_pair do |k, v|
133
- value[k] = typecast_hash_value(field, k, v)
134
- end
135
- when Array
136
- value.map { |v| typecast_value_for(field, v) }
137
- when Regexp
138
- value
139
- when Range
140
- {
141
- "$gte" => typecast_value_for(field, value.first),
142
- "$lte" => typecast_value_for(field, value.last)
143
- }
144
- else
145
- if field.type == Array
146
- Serialization.mongoize(value, value.class)
147
- else
148
- field.selection(value)
149
- end
150
- end
151
- end
152
-
153
- # Typecast the value for booleans and integers in hashes.
154
- #
155
- # @example Typecast the hash values.
156
- # selector.typecast_hash_value(field, "$exists", "true")
157
- #
158
- # @param [ Field ] field The defined field.
159
- # @param [ String ] key The modifier key.
160
- # @param [ Object ] value The value to cast.
161
- #
162
- # @return [ Object ] The cast value.
163
- #
164
- # @since 1.0.0
165
- def typecast_hash_value(field, key, value)
166
- case key
167
- when "$exists"
168
- Serialization.mongoize(value, Boolean)
169
- when "$size"
170
- Serialization.mongoize(value, Integer)
171
- else
172
- typecast_value_for(field, value)
173
- end
174
- end
175
- end
176
- end
177
- end
@@ -1,88 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc
3
-
4
- # Mongoid wrapper of the Ruby Driver cursor.
5
- class Cursor
6
- include Mongoid::Collections::Retry
7
- include Enumerable
8
-
9
- # Operations on the Mongo::Cursor object that will not get overriden by the
10
- # Mongoid::Cursor are defined here.
11
- OPERATIONS = [
12
- :close,
13
- :closed?,
14
- :count,
15
- :explain,
16
- :fields,
17
- :full_collection_name,
18
- :hint,
19
- :limit,
20
- :order,
21
- :query_options_hash,
22
- :query_opts,
23
- :selector,
24
- :skip,
25
- :snapshot,
26
- :sort,
27
- :timeout
28
- ]
29
-
30
- attr_reader :collection, :cursor, :klass
31
-
32
- # The operations above will all delegate to the proxied Mongo::Cursor.
33
- OPERATIONS.each do |name|
34
- class_eval <<-EOS, __FILE__, __LINE__
35
- def #{name}(*args)
36
- retry_on_connection_failure do
37
- cursor.#{name}(*args)
38
- end
39
- end
40
- EOS
41
- end
42
-
43
- # Iterate over each document in the cursor and yield to it.
44
- #
45
- # @example Iterate over the cursor.
46
- # cursor.each { |doc| p doc.title }
47
- def each
48
- retry_on_connection_failure do
49
- while document = cursor.next_document
50
- yield Factory.from_db(klass, document)
51
- end
52
- end
53
- end
54
-
55
- # Create the new +Mongoid::Cursor+.
56
- #
57
- # @example Instantiate the cursor.
58
- # Mongoid::Cursor.new(Person, cursor)
59
- #
60
- # @param [ Class ] klass The class associated with the cursor.
61
- # @param [ Collection ] collection The Mongoid::Collection instance.
62
- # @param [ Mongo::Cursor ] cursor The Mongo::Cursor to be proxied.
63
- def initialize(klass, collection, cursor)
64
- @klass, @collection, @cursor = klass, collection, cursor
65
- end
66
-
67
- # Return the next document in the cursor. Will instantiate a new Mongoid
68
- # document with the attributes.
69
- #
70
- # @example Get the next document.
71
- # cursor.next_document
72
- #
73
- # @return [ Document ] The next document in the cursor.
74
- def next_document
75
- Mongoid::Factory.from_db(klass, cursor.next_document)
76
- end
77
-
78
- # Returns an array of all the documents in the cursor.
79
- #
80
- # @example Get the cursor as an array.
81
- # cursor.to_a
82
- #
83
- # @return [ Array<Document> ] An array of documents.
84
- def to_a
85
- cursor.to_a.collect { |attrs| Mongoid::Factory.from_db(klass, attrs) }
86
- end
87
- end
88
- end