mongoid 2.8.1 → 3.0.0.rc

Sign up to get free protection for your applications and to get access to all the features.
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