mongoid 7.6.2 → 8.0.1

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 (333) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -0
  3. data/README.md +3 -3
  4. data/Rakefile +21 -85
  5. data/lib/config/locales/en.yml +46 -56
  6. data/lib/mongoid/association/accessors.rb +32 -3
  7. data/lib/mongoid/association/bindable.rb +48 -0
  8. data/lib/mongoid/association/builders.rb +4 -2
  9. data/lib/mongoid/association/depending.rb +4 -8
  10. data/lib/mongoid/association/eager_loadable.rb +29 -7
  11. data/lib/mongoid/association/embedded/batchable.rb +28 -5
  12. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  13. data/lib/mongoid/association/embedded/embedded_in.rb +2 -1
  14. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  15. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
  16. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +40 -18
  17. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
  18. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +21 -2
  19. data/lib/mongoid/association/macros.rb +2 -1
  20. data/lib/mongoid/association/many.rb +5 -0
  21. data/lib/mongoid/association/nested/many.rb +5 -39
  22. data/lib/mongoid/association/nested/nested_buildable.rb +0 -14
  23. data/lib/mongoid/association/proxy.rb +12 -0
  24. data/lib/mongoid/association/referenced/auto_save.rb +3 -2
  25. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  26. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  27. data/lib/mongoid/association/referenced/belongs_to.rb +1 -1
  28. data/lib/mongoid/association/referenced/counter_cache.rb +8 -8
  29. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +64 -11
  30. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +4 -1
  31. data/lib/mongoid/association/referenced/has_many/enumerable.rb +10 -18
  32. data/lib/mongoid/association/referenced/has_many/proxy.rb +11 -107
  33. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  34. data/lib/mongoid/association/referenced/has_one/proxy.rb +8 -11
  35. data/lib/mongoid/association/referenced/syncable.rb +2 -2
  36. data/lib/mongoid/association/relatable.rb +38 -4
  37. data/lib/mongoid/attributes/processing.rb +9 -2
  38. data/lib/mongoid/attributes.rb +30 -27
  39. data/lib/mongoid/cacheable.rb +2 -2
  40. data/lib/mongoid/changeable.rb +37 -2
  41. data/lib/mongoid/clients/factory.rb +0 -4
  42. data/lib/mongoid/clients/options.rb +4 -0
  43. data/lib/mongoid/clients/sessions.rb +2 -14
  44. data/lib/mongoid/config.rb +15 -73
  45. data/lib/mongoid/contextual/aggregable/memory.rb +22 -20
  46. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  47. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  48. data/lib/mongoid/contextual/memory.rb +63 -47
  49. data/lib/mongoid/contextual/mongo.rb +173 -287
  50. data/lib/mongoid/contextual/none.rb +33 -15
  51. data/lib/mongoid/copyable.rb +32 -8
  52. data/lib/mongoid/criteria/includable.rb +24 -20
  53. data/lib/mongoid/criteria/marshalable.rb +10 -2
  54. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -15
  55. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  56. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  57. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  58. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  59. data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -16
  60. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  61. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  62. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  63. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +1 -1
  64. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -1
  65. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  66. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  67. data/lib/mongoid/criteria/queryable/mergeable.rb +0 -12
  68. data/lib/mongoid/criteria/queryable/optional.rb +3 -9
  69. data/lib/mongoid/criteria/queryable/options.rb +1 -1
  70. data/lib/mongoid/criteria/queryable/selectable.rb +2 -133
  71. data/lib/mongoid/criteria/queryable/selector.rb +90 -5
  72. data/lib/mongoid/criteria/queryable/smash.rb +39 -6
  73. data/lib/mongoid/criteria/queryable/storable.rb +1 -1
  74. data/lib/mongoid/criteria/queryable.rb +11 -6
  75. data/lib/mongoid/criteria.rb +1 -28
  76. data/lib/mongoid/deprecable.rb +36 -0
  77. data/lib/mongoid/deprecation.rb +25 -0
  78. data/lib/mongoid/document.rb +88 -33
  79. data/lib/mongoid/equality.rb +4 -4
  80. data/lib/mongoid/errors/document_not_found.rb +6 -2
  81. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  82. data/lib/mongoid/errors/invalid_field.rb +5 -1
  83. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  84. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  85. data/lib/mongoid/errors.rb +2 -3
  86. data/lib/mongoid/extensions/array.rb +8 -6
  87. data/lib/mongoid/extensions/big_decimal.rb +29 -10
  88. data/lib/mongoid/extensions/binary.rb +42 -0
  89. data/lib/mongoid/extensions/boolean.rb +8 -2
  90. data/lib/mongoid/extensions/date.rb +26 -20
  91. data/lib/mongoid/extensions/date_time.rb +1 -1
  92. data/lib/mongoid/extensions/float.rb +4 -5
  93. data/lib/mongoid/extensions/hash.rb +13 -32
  94. data/lib/mongoid/extensions/integer.rb +4 -5
  95. data/lib/mongoid/extensions/object.rb +2 -0
  96. data/lib/mongoid/extensions/range.rb +41 -10
  97. data/lib/mongoid/extensions/regexp.rb +11 -4
  98. data/lib/mongoid/extensions/set.rb +11 -4
  99. data/lib/mongoid/extensions/string.rb +2 -13
  100. data/lib/mongoid/extensions/symbol.rb +3 -14
  101. data/lib/mongoid/extensions/time.rb +27 -16
  102. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  103. data/lib/mongoid/extensions.rb +1 -0
  104. data/lib/mongoid/factory.rb +42 -7
  105. data/lib/mongoid/fields/foreign_key.rb +7 -0
  106. data/lib/mongoid/fields/validators/macro.rb +3 -9
  107. data/lib/mongoid/fields.rb +49 -7
  108. data/lib/mongoid/findable.rb +21 -16
  109. data/lib/mongoid/indexable/specification.rb +1 -1
  110. data/lib/mongoid/indexable/validators/options.rb +4 -1
  111. data/lib/mongoid/interceptable.rb +69 -9
  112. data/lib/mongoid/matchable.rb +1 -6
  113. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +5 -3
  114. data/lib/mongoid/matcher/regex.rb +9 -8
  115. data/lib/mongoid/matcher.rb +0 -1
  116. data/lib/mongoid/persistable/creatable.rb +14 -5
  117. data/lib/mongoid/persistable/updatable.rb +12 -5
  118. data/lib/mongoid/persistence_context.rb +8 -42
  119. data/lib/mongoid/query_cache.rb +6 -258
  120. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  121. data/lib/mongoid/reloadable.rb +7 -3
  122. data/lib/mongoid/scopable.rb +9 -11
  123. data/lib/mongoid/selectable.rb +1 -2
  124. data/lib/mongoid/shardable.rb +11 -35
  125. data/lib/mongoid/stateful.rb +27 -1
  126. data/lib/mongoid/threaded.rb +0 -3
  127. data/lib/mongoid/timestamps/created.rb +1 -1
  128. data/lib/mongoid/timestamps/updated.rb +1 -1
  129. data/lib/mongoid/touchable.rb +2 -3
  130. data/lib/mongoid/traversable.rb +1 -0
  131. data/lib/mongoid/validatable/uniqueness.rb +2 -1
  132. data/lib/mongoid/version.rb +1 -5
  133. data/lib/mongoid/warnings.rb +3 -5
  134. data/lib/mongoid.rb +1 -0
  135. data/spec/config/mongoid.yml +16 -0
  136. data/spec/integration/app_spec.rb +8 -20
  137. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  138. data/spec/integration/associations/embedded_spec.rb +15 -0
  139. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  140. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  141. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  142. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  143. data/spec/integration/associations/has_one_spec.rb +97 -1
  144. data/spec/integration/associations/scope_option_spec.rb +1 -1
  145. data/spec/integration/callbacks_models.rb +95 -1
  146. data/spec/integration/callbacks_spec.rb +226 -4
  147. data/spec/integration/criteria/range_spec.rb +95 -1
  148. data/spec/integration/discriminator_key_spec.rb +115 -76
  149. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  150. data/spec/integration/i18n_fallbacks_spec.rb +1 -15
  151. data/spec/integration/matcher_examples_spec.rb +20 -13
  152. data/spec/integration/matcher_operator_data/regex.yml +0 -21
  153. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  154. data/spec/integration/matcher_operator_spec.rb +3 -5
  155. data/spec/integration/persistence/range_field_spec.rb +350 -0
  156. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  157. data/spec/mongoid/association/depending_spec.rb +9 -9
  158. data/spec/mongoid/association/eager_spec.rb +2 -1
  159. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  160. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  161. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  162. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  163. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +198 -8
  164. data/spec/mongoid/association/embedded/embeds_many_models.rb +36 -0
  165. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  166. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  167. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  168. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  169. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  170. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  171. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  172. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  173. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  174. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  175. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +36 -51
  176. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  177. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  178. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  179. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  180. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +60 -156
  181. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  182. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  183. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  184. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  185. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  186. data/spec/mongoid/association/syncable_spec.rb +14 -0
  187. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  188. data/spec/mongoid/attributes/nested_spec.rb +73 -198
  189. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  190. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  191. data/spec/mongoid/attributes_spec.rb +480 -27
  192. data/spec/mongoid/cacheable_spec.rb +3 -3
  193. data/spec/mongoid/changeable_spec.rb +130 -13
  194. data/spec/mongoid/clients/factory_spec.rb +22 -60
  195. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  196. data/spec/mongoid/clients_spec.rb +2 -2
  197. data/spec/mongoid/config_spec.rb +52 -15
  198. data/spec/mongoid/contextual/aggregable/memory_spec.rb +371 -231
  199. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  200. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  201. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  202. data/spec/mongoid/contextual/memory_spec.rb +467 -156
  203. data/spec/mongoid/contextual/mongo_spec.rb +566 -426
  204. data/spec/mongoid/contextual/none_spec.rb +11 -19
  205. data/spec/mongoid/copyable_spec.rb +451 -2
  206. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  207. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  208. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  209. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  210. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  211. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  212. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +1 -2
  213. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  214. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  215. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +1 -2
  216. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  217. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  218. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  219. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  220. data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
  221. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -2
  222. data/spec/mongoid/criteria/queryable/selectable_spec.rb +77 -85
  223. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +0 -200
  224. data/spec/mongoid/criteria/queryable/selector_spec.rb +16 -77
  225. data/spec/mongoid/criteria/queryable/storable_spec.rb +0 -72
  226. data/spec/mongoid/criteria_spec.rb +469 -1203
  227. data/spec/mongoid/document_fields_spec.rb +173 -24
  228. data/spec/mongoid/document_spec.rb +32 -41
  229. data/spec/mongoid/equality_spec.rb +12 -12
  230. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  231. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  232. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  233. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  234. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  235. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  236. data/spec/mongoid/extensions/array_spec.rb +16 -2
  237. data/spec/mongoid/extensions/big_decimal_spec.rb +697 -212
  238. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  239. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  240. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  241. data/spec/mongoid/extensions/date_spec.rb +71 -1
  242. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  243. data/spec/mongoid/extensions/float_spec.rb +48 -76
  244. data/spec/mongoid/extensions/hash_spec.rb +30 -236
  245. data/spec/mongoid/extensions/integer_spec.rb +45 -66
  246. data/spec/mongoid/extensions/range_spec.rb +255 -54
  247. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  248. data/spec/mongoid/extensions/set_spec.rb +106 -0
  249. data/spec/mongoid/extensions/string_spec.rb +53 -25
  250. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  251. data/spec/mongoid/extensions/time_spec.rb +634 -66
  252. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  253. data/spec/mongoid/factory_spec.rb +61 -1
  254. data/spec/mongoid/fields_spec.rb +321 -50
  255. data/spec/mongoid/findable_spec.rb +64 -29
  256. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  257. data/spec/mongoid/indexable_spec.rb +16 -19
  258. data/spec/mongoid/interceptable_spec.rb +584 -5
  259. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  260. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  261. data/spec/mongoid/mongoizable_spec.rb +285 -0
  262. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  263. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  264. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  265. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  266. data/spec/mongoid/persistence_context_spec.rb +24 -0
  267. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  268. data/spec/mongoid/query_cache_spec.rb +1 -156
  269. data/spec/mongoid/reloadable_spec.rb +35 -2
  270. data/spec/mongoid/scopable_spec.rb +36 -34
  271. data/spec/mongoid/serializable_spec.rb +14 -7
  272. data/spec/mongoid/shardable_models.rb +0 -14
  273. data/spec/mongoid/shardable_spec.rb +61 -153
  274. data/spec/mongoid/stateful_spec.rb +28 -0
  275. data/spec/mongoid/timestamps_spec.rb +390 -0
  276. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  277. data/spec/mongoid/touchable_spec.rb +116 -0
  278. data/spec/mongoid/touchable_spec_models.rb +12 -8
  279. data/spec/mongoid/traversable_spec.rb +4 -11
  280. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  281. data/spec/mongoid/validatable/uniqueness_spec.rb +60 -31
  282. data/spec/mongoid/warnings_spec.rb +35 -0
  283. data/spec/mongoid_spec.rb +1 -7
  284. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  285. data/spec/rails/mongoid_spec.rb +4 -16
  286. data/spec/shared/lib/mrss/cluster_config.rb +40 -5
  287. data/spec/shared/lib/mrss/constraints.rb +46 -7
  288. data/spec/shared/lib/mrss/docker_runner.rb +21 -17
  289. data/spec/shared/lib/mrss/eg_config_utils.rb +31 -0
  290. data/spec/shared/lib/mrss/event_subscriber.rb +5 -15
  291. data/spec/shared/lib/mrss/lite_constraints.rb +2 -10
  292. data/spec/shared/lib/mrss/server_version_registry.rb +29 -18
  293. data/spec/shared/lib/mrss/spec_organizer.rb +3 -32
  294. data/spec/shared/lib/mrss/utils.rb +6 -28
  295. data/spec/shared/share/Dockerfile.erb +114 -38
  296. data/spec/shared/shlib/distro.sh +0 -10
  297. data/spec/shared/shlib/server.sh +83 -64
  298. data/spec/shared/shlib/set_env.sh +81 -16
  299. data/spec/support/constraints.rb +24 -0
  300. data/spec/support/expectations.rb +17 -20
  301. data/spec/support/macros.rb +30 -0
  302. data/spec/support/models/augmentation.rb +12 -0
  303. data/spec/support/models/band.rb +3 -0
  304. data/spec/support/models/catalog.rb +24 -0
  305. data/spec/support/models/circus.rb +3 -0
  306. data/spec/support/models/fanatic.rb +8 -0
  307. data/spec/support/models/implant.rb +9 -0
  308. data/spec/support/models/label.rb +2 -0
  309. data/spec/support/models/passport.rb +9 -0
  310. data/spec/support/models/person.rb +1 -0
  311. data/spec/support/models/player.rb +2 -0
  312. data/spec/support/models/powerup.rb +12 -0
  313. data/spec/support/models/registry.rb +1 -0
  314. data/spec/support/models/school.rb +14 -0
  315. data/spec/support/models/shield.rb +18 -0
  316. data/spec/support/models/student.rb +14 -0
  317. data/spec/support/models/weapon.rb +12 -0
  318. data.tar.gz.sig +0 -0
  319. metadata +695 -650
  320. metadata.gz.sig +0 -0
  321. data/lib/mongoid/errors/eager_load.rb +0 -23
  322. data/lib/mongoid/errors/in_memory_regexp_timeout.rb +0 -26
  323. data/lib/mongoid/errors/invalid_value.rb +0 -17
  324. data/lib/mongoid/field_readable.rb +0 -70
  325. data/lib/mongoid/matcher/regexp_budget.rb +0 -389
  326. data/spec/integration/matcher_regexp_timeout_spec.rb +0 -215
  327. data/spec/integration/query_operator_guard_spec.rb +0 -89
  328. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
  329. data/spec/mongoid/matcher/regexp_budget_spec.rb +0 -570
  330. data/spec/shared/CANDIDATE.md +0 -28
  331. data/spec/shared/lib/mrss/release/candidate.rb +0 -287
  332. data/spec/shared/lib/mrss/release/product_data.rb +0 -144
  333. data/spec/shared/lib/tasks/candidate.rake +0 -64
@@ -227,19 +227,6 @@ module Mongoid
227
227
  __merge__(criterion)
228
228
  end
229
229
 
230
- # Alias for +geo_spatial+.
231
- #
232
- # @deprecated
233
- def geo_spacial(criterion)
234
- # Duplicate method body so that we can raise this exception with
235
- # geo_spacial as the indicated operator rather than geo_spatial.
236
- if criterion.nil?
237
- raise Errors::CriteriaArgumentRequired, :geo_spacial
238
- end
239
-
240
- __merge__(criterion)
241
- end
242
-
243
230
  key :intersects_line, :override, "$geoIntersects", "$geometry" do |value|
244
231
  { "type" => LINE_STRING, "coordinates" => value }
245
232
  end
@@ -679,16 +666,7 @@ module Mongoid
679
666
  end]
680
667
  end
681
668
  end
682
- # Should be able to do:
683
- #where('$or' => exprs)
684
- # But since that is broken do instead:
685
- clone.tap do |query|
686
- if query.selector['$or']
687
- query.selector.store('$or', query.selector['$or'] + exprs)
688
- else
689
- query.selector.store('$or', exprs)
690
- end
691
- end
669
+ self.and('$or' => exprs)
692
670
  end
693
671
  end
694
672
 
@@ -813,12 +791,6 @@ module Mongoid
813
791
  # only ever specify one criterion to #where.
814
792
  @criterion = criterion
815
793
  if criterion.is_a?(String)
816
- unless Mongoid.allow_unsafe_query_operators?
817
- raise Errors::InvalidQuery,
818
- "String criteria are not allowed because they compile to the '$where' operator, " \
819
- 'which is not allowed in a query expression. Set Mongoid.allow_unsafe_query_operators = true ' \
820
- 'to permit all operators.'
821
- end
822
794
  js_query(criterion)
823
795
  else
824
796
  expr_query(criterion)
@@ -828,19 +800,6 @@ module Mongoid
828
800
 
829
801
  private
830
802
 
831
- # Operators permitted at the top level of a query expression without
832
- # opt-in. Excludes $where (JS execution) and other operators not needed
833
- # for ordinary application queries.
834
- ALLOWED_QUERY_OPERATORS = %w[
835
- $and $or $nor $not $text $comment $expr $jsonSchema $alwaysFalse $alwaysTrue
836
- ].freeze
837
-
838
- # Operators that execute server-side JavaScript. These are rejected at
839
- # any depth, not just at the top level: the allowlist above permits
840
- # $expr and the logical operators, and their values are arbitrary
841
- # nested expressions that can carry $function or $where.
842
- JAVASCRIPT_QUERY_OPERATORS = %w[$where $function $accumulator].freeze
843
-
844
803
  # Adds the specified expression to the query.
845
804
  #
846
805
  # Criterion must be a hash in one of the following forms:
@@ -866,8 +825,6 @@ module Mongoid
866
825
  raise Errors::InvalidQuery, "Expression must be a Hash: #{Errors::InvalidQuery.truncate_expr(criterion)}"
867
826
  end
868
827
 
869
- # The operator guard is applied by _mongoid_expand_keys, which every
870
- # query method that accepts a user-supplied expression passes through.
871
828
  normalized = _mongoid_expand_keys(criterion)
872
829
  clone.tap do |query|
873
830
  normalized.each do |field, value|
@@ -883,94 +840,6 @@ module Mongoid
883
840
  end
884
841
  end
885
842
 
886
- # Enforces the operator rules governed by the
887
- # +allow_unsafe_query_operators+ configuration option against a
888
- # normalized query expression.
889
- #
890
- # Two rules apply, and both are skipped when the option is true:
891
- #
892
- # - An operator at the top level of the expression must appear in
893
- # ALLOWED_QUERY_OPERATORS.
894
- # - An operator in JAVASCRIPT_QUERY_OPERATORS is rejected at any depth.
895
- #
896
- # This is called from #_mongoid_expand_keys rather than from the
897
- # individual query methods, because that is the one point every query
898
- # method taking a user-supplied expression passes through on its way to
899
- # the selector.
900
- #
901
- # It deliberately does not cover the APIs that ask for JavaScript
902
- # outright, such as #js_query and Criteria#for_js: there the developer
903
- # has chosen server-side JavaScript, so there is nothing to guard
904
- # against. The same goes for the low-level Storable methods
905
- # (#add_field_expression, #add_operator_expression), which write to the
906
- # selector directly.
907
- #
908
- # @param [ Hash ] expr A normalized query expression.
909
- #
910
- # @raise [ Errors::InvalidQuery ] If a disallowed operator is present.
911
- #
912
- # @api private
913
- def _mongoid_validate_operators!(expr)
914
- return if Mongoid.allow_unsafe_query_operators?
915
-
916
- expr.each_key do |field|
917
- field_s = field.to_s
918
- next unless field_s.start_with?('$')
919
- next if ALLOWED_QUERY_OPERATORS.include?(field_s)
920
-
921
- raise Errors::InvalidQuery,
922
- "Operator '#{field_s}' is not allowed in a query expression. " \
923
- 'Set Mongoid.allow_unsafe_query_operators = true to permit all operators.'
924
- end
925
-
926
- _mongoid_validate_no_javascript!(expr)
927
- end
928
-
929
- # Walks a query expression looking for operators that execute
930
- # server-side JavaScript, descending through both hashes and arrays so
931
- # that nested forms such as {'$expr' => {'$function' => ...}} and
932
- # {'$or' => [ {'$where' => ...} ]} are caught.
933
- #
934
- # The walk does not distinguish operator position from value position,
935
- # so it also rejects queries where a JavaScript operator name appears as
936
- # data rather than as an operator. Server 5.0+ permits $-prefixed field
937
- # names in stored documents, which makes this reachable:
938
- #
939
- # Doc.where(payload: { '$eq' => { '$function' => 'abc' } })
940
- #
941
- # Here the $eq marks its argument as a literal value to compare, so the
942
- # server never evaluates it, but the guard raises anyway. The only
943
- # workaround today is the global allow_unsafe_query_operators flag.
944
- #
945
- # TODO: discuss whether to track operator position (skipping the subtree
946
- # under $eq, $ne, $in, $nin, and $elemMatch values) in a future
947
- # iteration. It removes the false positive but adds exactly the kind of
948
- # state that a real bypass could hide in, so it was left out for now.
949
- #
950
- # @param [ Object ] object A fragment of a query expression.
951
- #
952
- # @raise [ Errors::InvalidQuery ] If a JavaScript operator is present.
953
- #
954
- # @api private
955
- def _mongoid_validate_no_javascript!(object)
956
- case object
957
- when Hash
958
- object.each do |key, value|
959
- key_s = key.to_s
960
- if JAVASCRIPT_QUERY_OPERATORS.include?(key_s)
961
- raise Errors::InvalidQuery,
962
- "Operator '#{key_s}' executes server-side JavaScript and is not allowed " \
963
- 'anywhere in a query expression. Set Mongoid.allow_unsafe_query_operators = true ' \
964
- 'to permit all operators.'
965
- end
966
-
967
- _mongoid_validate_no_javascript!(value)
968
- end
969
- when Array
970
- object.each { |value| _mongoid_validate_no_javascript!(value) }
971
- end
972
- end
973
-
974
843
  # Force the values of the criterion to be evolved.
975
844
  #
976
845
  # @api private
@@ -983,7 +852,7 @@ module Mongoid
983
852
  # @param [ Hash ] criterion The criterion.
984
853
  def typed_override(criterion, operator)
985
854
  if criterion
986
- criterion.update_values do |value|
855
+ criterion.transform_values! do |value|
987
856
  yield(value)
988
857
  end
989
858
  end
@@ -20,7 +20,7 @@ module Mongoid
20
20
  other.each_pair do |key, value|
21
21
  if value.is_a?(Hash) && self[key.to_s].is_a?(Hash)
22
22
  value = self[key.to_s].merge(value) do |_key, old_val, new_val|
23
- case _key.to_s
23
+ case _key
24
24
  when '$in'
25
25
  new_val & old_val
26
26
  when '$nin'
@@ -53,8 +53,7 @@ module Mongoid
53
53
  store_name = name
54
54
  store_value = evolve_multi(value)
55
55
  else
56
- store_name = localized_key(name, serializer)
57
- store_value = evolve(serializer, value)
56
+ store_name, store_value = store_creds(name, serializer, value)
58
57
  end
59
58
  super(store_name, store_value)
60
59
  end
@@ -74,6 +73,24 @@ module Mongoid
74
73
 
75
74
  private
76
75
 
76
+ # Get the store name and store value. If the value is of type range,
77
+ # we need may need to change the store_name as well as the store_value,
78
+ # therefore, we cannot just use the evole method.
79
+ #
80
+ # @param [ String ] name The name of the field.
81
+ # @param [ Object ] serializer The optional serializer for the field.
82
+ # @param [ Object ] value The value to serialize.
83
+ #
84
+ # @return [ Array<String, String> ] The store name and store value.
85
+ def store_creds(name, serializer, value)
86
+ store_name = localized_key(name, serializer)
87
+ if Range === value
88
+ evolve_range(store_name, serializer, value)
89
+ else
90
+ [ store_name, evolve(serializer, value) ]
91
+ end
92
+ end
93
+
77
94
  # Evolves a multi-list selection, like an $and or $or criterion, and
78
95
  # performs the necessary serialization.
79
96
  #
@@ -103,11 +120,10 @@ module Mongoid
103
120
  # some reason, although per its documentation Smash supposedly
104
121
  # owns both.
105
122
  name, serializer = storage_pair(key)
106
- final_key = localized_key(name, serializer)
107
123
  # This performs type conversions on the value and transformations
108
124
  # that depend on the type of the field that the value is stored
109
125
  # in, but not transformations that have to do with query shape.
110
- evolved_value = evolve(serializer, value)
126
+ final_key, evolved_value = store_creds(name, serializer, value)
111
127
 
112
128
  # This builds a query shape around the value, when the query
113
129
  # involves complex keys. For example, {:foo.lt => 5} produces
@@ -139,6 +155,8 @@ module Mongoid
139
155
  evolve_hash(serializer, value)
140
156
  when Array
141
157
  evolve_array(serializer, value)
158
+ when Range
159
+ value.__evolve_range__(serializer: serializer)
142
160
  else
143
161
  (serializer || value.class).evolve(value)
144
162
  end
@@ -182,6 +200,73 @@ module Mongoid
182
200
  end
183
201
  end
184
202
 
203
+ # Evolve a single key selection with range values. This method traverses
204
+ # the association tree to build a query for the given value and
205
+ # serializer. There are three parts to the query here:
206
+ #
207
+ # (1) "klass.child.gchild" => {
208
+ # "$elemMatch" => {
209
+ # (2) "ggchild.field" => (3) { "$gte" => 6, "$lte" => 10 }
210
+ # }
211
+ # }
212
+ # (1) The first n fields are dotted together until the last
213
+ # embeds_many or field of type array. In the above case, gchild
214
+ # would be an embeds_many or Array, and ggchild would be an
215
+ # embeds_one or a hash.
216
+ # (2) The last fields are used inside the $elemMatch. This one is
217
+ # actually optional, and will be ignored if the last field is an
218
+ # array or embeds_many. If the last field is an array (1), (2) and
219
+ # (3) will look like:
220
+ #
221
+ # "klass.child.gchild.ggchild.field" => {
222
+ # { "$elemMatch" => { "$gte" => 6, "$lte" => 10 } }
223
+ # }
224
+ #
225
+ # (3) This is calculated by:
226
+ #
227
+ # value.__evolve_range__(serializer: serializer).
228
+ #
229
+ # @api private
230
+ #
231
+ # @param [ String ] key The to store the range for.
232
+ # @param [ Object ] serializer The optional serializer for the field.
233
+ # @param [ Range ] value The Range to serialize.
234
+ #
235
+ # @return [ Array<String, Hash> ] The store name and serialized Range.
236
+ def evolve_range(key, serializer, value)
237
+ v = value.__evolve_range__(serializer: serializer)
238
+ assocs = []
239
+ Fields.traverse_association_tree(key, serializers, associations, aliased_associations) do |meth, obj, is_field|
240
+ assocs.push([meth, obj, is_field])
241
+ end
242
+
243
+ # Iterate backwards until you get a field with type
244
+ # Array or an embeds_many association.
245
+ inner_key = ""
246
+ loop do
247
+ # If there are no arrays or embeds_many associations, just return
248
+ # the key and value without $elemMatch.
249
+ return [ key, v ] if assocs.empty?
250
+
251
+ meth, obj, is_field = assocs.last
252
+ break if (is_field && obj.type == Array) || (!is_field && obj.is_a?(Association::Embedded::EmbedsMany))
253
+
254
+ assocs.pop
255
+ inner_key = "#{meth}.#{inner_key}"
256
+ end
257
+
258
+ # If the last array or embeds_many association is the last field,
259
+ # the inner key (2) is ignored, and the outer key (1) is the original
260
+ # key.
261
+ if inner_key.blank?
262
+ [ key, { "$elemMatch" => v }]
263
+ else
264
+ store_key = assocs.map(&:first).join('.')
265
+ store_value = { "$elemMatch" => { inner_key.chop => v } }
266
+ [ store_key, store_value ]
267
+ end
268
+ end
269
+
185
270
  # Determines if the selection is a multi-select, like an $and or $or or $nor
186
271
  # selection.
187
272
  #
@@ -8,8 +8,16 @@ module Mongoid
8
8
  class Smash < Hash
9
9
 
10
10
  # @attribute [r] aliases The aliases.
11
+ attr_reader :aliases
12
+
11
13
  # @attribute [r] serializers The serializers.
12
- attr_reader :aliases, :serializers
14
+ attr_reader :serializers
15
+
16
+ # @attribute [r] associations The associations.
17
+ attr_reader :associations
18
+
19
+ # @attribute [r] aliased_associations The aliased_associations.
20
+ attr_reader :aliased_associations
13
21
 
14
22
  # Perform a deep copy of the smash.
15
23
  #
@@ -18,7 +26,7 @@ module Mongoid
18
26
  #
19
27
  # @return [ Smash ] The copied hash.
20
28
  def __deep_copy__
21
- self.class.new(aliases, serializers) do |copy|
29
+ self.class.new(aliases, serializers, associations, aliased_associations) do |copy|
22
30
  each_pair do |key, value|
23
31
  copy.store(key, value.__deep_copy__)
24
32
  end
@@ -36,8 +44,15 @@ module Mongoid
36
44
  # responsible for serializing values. The keys of the hash must be
37
45
  # strings that match the field name, and the values must respond to
38
46
  # #localized? and #evolve(object).
39
- def initialize(aliases = {}, serializers = {})
40
- @aliases, @serializers = aliases, serializers
47
+ # @param [ Hash ] associations An optional hash of names to association
48
+ # objects.
49
+ # @param [ Hash ] aliased_associations An optional hash of mappings from
50
+ # aliases for associations to their actual field names in the database.
51
+ def initialize(aliases = {}, serializers = {}, associations = {}, aliased_associations = {})
52
+ @aliases = aliases
53
+ @serializers = serializers
54
+ @associations = associations
55
+ @aliased_associations = aliased_associations
41
56
  yield(self) if block_given?
42
57
  end
43
58
 
@@ -86,8 +101,26 @@ module Mongoid
86
101
  # serializer.
87
102
  def storage_pair(key)
88
103
  field = key.to_s
89
- name = aliases[field] || field
90
- [ name, serializers[name] ]
104
+ name = Fields.database_field_name(field, associations, aliases, aliased_associations)
105
+ [ name, get_serializer(name) ]
106
+ end
107
+
108
+ private
109
+
110
+ # Retrieves the serializer for the given name. If the name exists in
111
+ # the serializers hash then return that immediately, otherwise
112
+ # recursively look through the associations and find the appropriate
113
+ # field.
114
+ #
115
+ # @param [ String ] name The name of the db field.
116
+ #
117
+ # @return [ Object ] The serializer.
118
+ def get_serializer(name)
119
+ if s = serializers[name]
120
+ s
121
+ else
122
+ Fields.traverse_association_tree(name, serializers, associations, aliased_associations)
123
+ end
91
124
  end
92
125
  end
93
126
  end
@@ -47,7 +47,7 @@ module Mongoid
47
47
  if value.is_a?(Hash) && selector[field].is_a?(Hash) &&
48
48
  value.keys.all? { |key|
49
49
  key_s = key.to_s
50
- key_s.start_with?('$') && !selector[field].keys.map(&:to_s).include?(key_s)
50
+ key_s.start_with?('$') && !selector[field].key?(key_s)
51
51
  }
52
52
  then
53
53
  # Multiple operators can be combined on the same field by
@@ -33,9 +33,10 @@ module Mongoid
33
33
  include Optional
34
34
 
35
35
  # @attribute [r] aliases The aliases.
36
- # @attribute [r] driver The Mongo driver being used.
36
+ attr_reader :aliases
37
+
37
38
  # @attribute [r] serializers The serializers.
38
- attr_reader :aliases, :driver, :serializers
39
+ attr_reader :serializers
39
40
 
40
41
  # Is this queryable equal to another object? Is true if the selector and
41
42
  # options are equal.
@@ -59,11 +60,15 @@ module Mongoid
59
60
  #
60
61
  # @param [ Hash ] aliases The optional field aliases.
61
62
  # @param [ Hash ] serializers The optional field serializers.
63
+ # @param [ Hash ] associations The optional associations.
64
+ # @param [ Hash ] aliased_associations The optional aliased associations.
62
65
  # @param [ Symbol ] driver The driver being used.
63
- def initialize(aliases = {}, serializers = {}, driver = :mongo)
64
- @aliases, @driver, @serializers = aliases, driver.to_sym, serializers
65
- @options = Options.new(aliases, serializers)
66
- @selector = Selector.new(aliases, serializers)
66
+ #
67
+ # @api private
68
+ def initialize(aliases = {}, serializers = {}, associations = {}, aliased_associations = {})
69
+ @aliases, @serializers = aliases, serializers
70
+ @options = Options.new(aliases, serializers, associations, aliased_associations)
71
+ @selector = Selector.new(aliases, serializers, associations, aliased_associations)
67
72
  @pipeline = Pipeline.new(aliases)
68
73
  @aggregating = nil
69
74
  yield(self) if block_given?
@@ -112,33 +112,6 @@ module Mongoid
112
112
  entries.as_json(options)
113
113
  end
114
114
 
115
- # Tells the criteria that the cursor that gets returned needs to be
116
- # cached. This is so multiple iterations don't hit the database multiple
117
- # times, however this is not advisable when working with large data sets
118
- # as the entire results will get stored in memory.
119
- #
120
- # @example Flag the criteria as cached.
121
- # criteria.cache
122
- #
123
- # @return [ Criteria ] The cloned criteria.
124
- def cache
125
- Mongoid::Warnings.warn_criteria_cache_deprecated
126
- crit = clone
127
- crit.options.merge!(cache: true)
128
- crit
129
- end
130
-
131
- # Will return true if the cache option has been set.
132
- #
133
- # @example Is the criteria cached?
134
- # criteria.cached?
135
- #
136
- # @return [ true, false ] If the criteria is flagged as cached.
137
- def cached?
138
- Mongoid::Warnings.warn_criteria_cache_deprecated
139
- options[:cache] == true
140
- end
141
-
142
115
  # Get the documents from the embedded criteria.
143
116
  #
144
117
  # @example Get the documents.
@@ -232,7 +205,7 @@ module Mongoid
232
205
  @klass = klass
233
206
  @embedded = nil
234
207
  @none = nil
235
- klass ? super(klass.aliased_fields, klass.fields) : super({}, {})
208
+ klass ? super(klass.aliased_fields, klass.fields, klass.relations, klass.aliased_associations) : super({}, {}, {}, {})
236
209
  end
237
210
 
238
211
  # Merges another object with this +Criteria+ and returns a new criteria.
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mongoid/deprecation"
4
+
5
+ module Mongoid
6
+
7
+ # Adds ability to declare Mongoid-specific deprecations.
8
+ #
9
+ # @api private
10
+ module Deprecable
11
+
12
+ # Declares method(s) as deprecated.
13
+ #
14
+ # @example Deprecate a method.
15
+ # Mongoid.deprecate(Cat, :meow); Cat.new.meow
16
+ # #=> Mongoid.logger.warn("meow is deprecated and will be removed from Mongoid 8.0")
17
+ #
18
+ # @example Deprecate a method and declare the replacement method.
19
+ # Mongoid.deprecate(Cat, meow: :speak); Cat.new.meow
20
+ # #=> Mongoid.logger.warn("meow is deprecated and will be removed from Mongoid 8.0 (use speak instead)")
21
+ #
22
+ # @example Deprecate a method and give replacement instructions.
23
+ # Mongoid.deprecate(Cat, meow: 'eat :catnip instead'); Cat.new.meow
24
+ # #=> Mongoid.logger.warn("meow is deprecated and will be removed from Mongoid 8.0 (eat :catnip instead)")
25
+ #
26
+ # @param [ Module ] target_module The parent which contains the method.
27
+ # @param [ Symbol | Hash<Symbol, [Symbol|String]> ] method_descriptors
28
+ # The methods to deprecate, with optional replacement instructions.
29
+ def deprecate(target_module, *method_descriptors)
30
+ Mongoid::Deprecation.deprecate_methods(target_module, *method_descriptors)
31
+ end
32
+ end
33
+ end
34
+
35
+ # Ensure Mongoid.deprecate can be used during initialization
36
+ Mongoid.extend(Mongoid::Deprecable)
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongoid
4
+
5
+ # Utility class for logging deprecation warnings.
6
+ class Deprecation < ::ActiveSupport::Deprecation
7
+
8
+ @gem_name = 'Mongoid'
9
+
10
+ # Per change policy, deprecations will be removed in the next major version.
11
+ @deprecation_horizon = "#{Mongoid::VERSION.split('.').first.to_i + 1}.0".freeze
12
+
13
+ # Overrides default ActiveSupport::Deprecation behavior
14
+ # to use Mongoid's logger.
15
+ #
16
+ # @return Array<Proc> The deprecation behavior.
17
+ def behavior
18
+ @behavior ||= Array(->(message, callstack, _deprecation_horizon, _gem_name) {
19
+ logger = Mongoid.logger
20
+ logger.warn(message)
21
+ logger.debug(callstack.join("\n ")) if debug
22
+ })
23
+ end
24
+ end
25
+ end