mongoid_rails4 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3213 -0
- data/LICENSE +20 -0
- data/README.md +62 -0
- data/Rakefile +35 -0
- data/lib/config/locales/en.yml +448 -0
- data/lib/mongoid.rb +104 -0
- data/lib/mongoid/atomic.rb +384 -0
- data/lib/mongoid/atomic/modifiers.rb +317 -0
- data/lib/mongoid/atomic/paths.rb +3 -0
- data/lib/mongoid/atomic/paths/embedded.rb +28 -0
- data/lib/mongoid/atomic/paths/embedded/many.rb +44 -0
- data/lib/mongoid/atomic/paths/embedded/one.rb +43 -0
- data/lib/mongoid/atomic/paths/root.rb +39 -0
- data/lib/mongoid/attributes.rb +284 -0
- data/lib/mongoid/attributes/dynamic.rb +154 -0
- data/lib/mongoid/attributes/nested.rb +82 -0
- data/lib/mongoid/attributes/processing.rb +147 -0
- data/lib/mongoid/attributes/readonly.rb +56 -0
- data/lib/mongoid/changeable.rb +379 -0
- data/lib/mongoid/composable.rb +104 -0
- data/lib/mongoid/config.rb +263 -0
- data/lib/mongoid/config/environment.rb +44 -0
- data/lib/mongoid/config/options.rb +74 -0
- data/lib/mongoid/config/validators.rb +3 -0
- data/lib/mongoid/config/validators/option.rb +25 -0
- data/lib/mongoid/config/validators/session.rb +140 -0
- data/lib/mongoid/contextual.rb +54 -0
- data/lib/mongoid/contextual/aggregable/memory.rb +109 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +147 -0
- data/lib/mongoid/contextual/atomic.rb +180 -0
- data/lib/mongoid/contextual/command.rb +61 -0
- data/lib/mongoid/contextual/eager.rb +158 -0
- data/lib/mongoid/contextual/find_and_modify.rb +69 -0
- data/lib/mongoid/contextual/geo_near.rb +238 -0
- data/lib/mongoid/contextual/map_reduce.rb +324 -0
- data/lib/mongoid/contextual/memory.rb +440 -0
- data/lib/mongoid/contextual/mongo.rb +676 -0
- data/lib/mongoid/contextual/queryable.rb +25 -0
- data/lib/mongoid/contextual/text_search.rb +180 -0
- data/lib/mongoid/copyable.rb +67 -0
- data/lib/mongoid/criteria.rb +562 -0
- data/lib/mongoid/criteria/findable.rb +179 -0
- data/lib/mongoid/criteria/inspectable.rb +25 -0
- data/lib/mongoid/criteria/marshalable.rb +50 -0
- data/lib/mongoid/criteria/modifiable.rb +189 -0
- data/lib/mongoid/criteria/scopable.rb +158 -0
- data/lib/mongoid/document.rb +361 -0
- data/lib/mongoid/equality.rb +66 -0
- data/lib/mongoid/errors.rb +40 -0
- data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
- data/lib/mongoid/errors/callback.rb +25 -0
- data/lib/mongoid/errors/delete_restriction.rb +29 -0
- data/lib/mongoid/errors/document_not_found.rb +111 -0
- data/lib/mongoid/errors/eager_load.rb +22 -0
- data/lib/mongoid/errors/invalid_collection.rb +18 -0
- data/lib/mongoid/errors/invalid_config_option.rb +27 -0
- data/lib/mongoid/errors/invalid_field.rb +64 -0
- data/lib/mongoid/errors/invalid_field_option.rb +35 -0
- data/lib/mongoid/errors/invalid_find.rb +19 -0
- data/lib/mongoid/errors/invalid_includes.rb +32 -0
- data/lib/mongoid/errors/invalid_index.rb +28 -0
- data/lib/mongoid/errors/invalid_options.rb +28 -0
- data/lib/mongoid/errors/invalid_path.rb +21 -0
- data/lib/mongoid/errors/invalid_scope.rb +24 -0
- data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
- data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
- data/lib/mongoid/errors/invalid_time.rb +22 -0
- data/lib/mongoid/errors/inverse_not_found.rb +29 -0
- data/lib/mongoid/errors/mixed_relations.rb +32 -0
- data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
- data/lib/mongoid/errors/mongoid_error.rb +92 -0
- data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
- data/lib/mongoid/errors/no_default_session.rb +23 -0
- data/lib/mongoid/errors/no_environment.rb +19 -0
- data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
- data/lib/mongoid/errors/no_metadata.rb +21 -0
- data/lib/mongoid/errors/no_parent.rb +24 -0
- data/lib/mongoid/errors/no_session_config.rb +22 -0
- data/lib/mongoid/errors/no_session_database.rb +27 -0
- data/lib/mongoid/errors/no_session_hosts.rb +27 -0
- data/lib/mongoid/errors/no_sessions_config.rb +20 -0
- data/lib/mongoid/errors/readonly_attribute.rb +25 -0
- data/lib/mongoid/errors/scope_overwrite.rb +21 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
- data/lib/mongoid/errors/unknown_attribute.rb +25 -0
- data/lib/mongoid/errors/unsaved_document.rb +19 -0
- data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
- data/lib/mongoid/errors/validations.rb +29 -0
- data/lib/mongoid/evolvable.rb +19 -0
- data/lib/mongoid/extensions.rb +35 -0
- data/lib/mongoid/extensions/array.rb +180 -0
- data/lib/mongoid/extensions/big_decimal.rb +69 -0
- data/lib/mongoid/extensions/boolean.rb +21 -0
- data/lib/mongoid/extensions/date.rb +77 -0
- data/lib/mongoid/extensions/date_time.rb +73 -0
- data/lib/mongoid/extensions/false_class.rb +38 -0
- data/lib/mongoid/extensions/float.rb +56 -0
- data/lib/mongoid/extensions/hash.rb +209 -0
- data/lib/mongoid/extensions/integer.rb +67 -0
- data/lib/mongoid/extensions/module.rb +28 -0
- data/lib/mongoid/extensions/nil_class.rb +33 -0
- data/lib/mongoid/extensions/object.rb +274 -0
- data/lib/mongoid/extensions/object_id.rb +54 -0
- data/lib/mongoid/extensions/range.rb +79 -0
- data/lib/mongoid/extensions/regexp.rb +27 -0
- data/lib/mongoid/extensions/set.rb +55 -0
- data/lib/mongoid/extensions/string.rb +199 -0
- data/lib/mongoid/extensions/symbol.rb +54 -0
- data/lib/mongoid/extensions/time.rb +88 -0
- data/lib/mongoid/extensions/time_with_zone.rb +56 -0
- data/lib/mongoid/extensions/true_class.rb +38 -0
- data/lib/mongoid/factory.rb +46 -0
- data/lib/mongoid/fields.rb +542 -0
- data/lib/mongoid/fields/foreign_key.rb +174 -0
- data/lib/mongoid/fields/localized.rb +73 -0
- data/lib/mongoid/fields/standard.rb +273 -0
- data/lib/mongoid/fields/validators.rb +2 -0
- data/lib/mongoid/fields/validators/macro.rb +92 -0
- data/lib/mongoid/findable.rb +133 -0
- data/lib/mongoid/identity_map.rb +163 -0
- data/lib/mongoid/indexable.rb +147 -0
- data/lib/mongoid/indexable/specification.rb +115 -0
- data/lib/mongoid/indexable/validators/options.rb +103 -0
- data/lib/mongoid/inspectable.rb +59 -0
- data/lib/mongoid/interceptable.rb +265 -0
- data/lib/mongoid/loggable.rb +69 -0
- data/lib/mongoid/matchable.rb +152 -0
- data/lib/mongoid/matchable/all.rb +27 -0
- data/lib/mongoid/matchable/and.rb +30 -0
- data/lib/mongoid/matchable/default.rb +72 -0
- data/lib/mongoid/matchable/exists.rb +23 -0
- data/lib/mongoid/matchable/gt.rb +21 -0
- data/lib/mongoid/matchable/gte.rb +21 -0
- data/lib/mongoid/matchable/in.rb +24 -0
- data/lib/mongoid/matchable/lt.rb +21 -0
- data/lib/mongoid/matchable/lte.rb +21 -0
- data/lib/mongoid/matchable/ne.rb +21 -0
- data/lib/mongoid/matchable/nin.rb +21 -0
- data/lib/mongoid/matchable/or.rb +33 -0
- data/lib/mongoid/matchable/size.rb +21 -0
- data/lib/mongoid/persistable.rb +207 -0
- data/lib/mongoid/persistable/creatable.rb +189 -0
- data/lib/mongoid/persistable/deletable.rb +149 -0
- data/lib/mongoid/persistable/destroyable.rb +55 -0
- data/lib/mongoid/persistable/incrementable.rb +36 -0
- data/lib/mongoid/persistable/logical.rb +38 -0
- data/lib/mongoid/persistable/poppable.rb +39 -0
- data/lib/mongoid/persistable/pullable.rb +55 -0
- data/lib/mongoid/persistable/pushable.rb +62 -0
- data/lib/mongoid/persistable/renamable.rb +35 -0
- data/lib/mongoid/persistable/savable.rb +52 -0
- data/lib/mongoid/persistable/settable.rb +33 -0
- data/lib/mongoid/persistable/unsettable.rb +36 -0
- data/lib/mongoid/persistable/updatable.rb +151 -0
- data/lib/mongoid/persistable/upsertable.rb +55 -0
- data/lib/mongoid/positional.rb +71 -0
- data/lib/mongoid/railtie.rb +156 -0
- data/lib/mongoid/railties/database.rake +97 -0
- data/lib/mongoid/railties/document.rb +12 -0
- data/lib/mongoid/relations.rb +162 -0
- data/lib/mongoid/relations/accessors.rb +299 -0
- data/lib/mongoid/relations/auto_save.rb +106 -0
- data/lib/mongoid/relations/binding.rb +218 -0
- data/lib/mongoid/relations/bindings.rb +9 -0
- data/lib/mongoid/relations/bindings/embedded/in.rb +63 -0
- data/lib/mongoid/relations/bindings/embedded/many.rb +50 -0
- data/lib/mongoid/relations/bindings/embedded/one.rb +55 -0
- data/lib/mongoid/relations/bindings/referenced/in.rb +65 -0
- data/lib/mongoid/relations/bindings/referenced/many.rb +42 -0
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +67 -0
- data/lib/mongoid/relations/bindings/referenced/one.rb +44 -0
- data/lib/mongoid/relations/builder.rb +57 -0
- data/lib/mongoid/relations/builders.rb +104 -0
- data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
- data/lib/mongoid/relations/builders/embedded/many.rb +36 -0
- data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +174 -0
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +126 -0
- data/lib/mongoid/relations/builders/referenced/in.rb +26 -0
- data/lib/mongoid/relations/builders/referenced/many.rb +27 -0
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +40 -0
- data/lib/mongoid/relations/builders/referenced/one.rb +26 -0
- data/lib/mongoid/relations/cascading.rb +56 -0
- data/lib/mongoid/relations/cascading/delete.rb +44 -0
- data/lib/mongoid/relations/cascading/destroy.rb +43 -0
- data/lib/mongoid/relations/cascading/nullify.rb +35 -0
- data/lib/mongoid/relations/cascading/restrict.rb +39 -0
- data/lib/mongoid/relations/constraint.rb +49 -0
- data/lib/mongoid/relations/conversions.rb +34 -0
- data/lib/mongoid/relations/counter_cache.rb +105 -0
- data/lib/mongoid/relations/cyclic.rb +107 -0
- data/lib/mongoid/relations/embedded/batchable.rb +355 -0
- data/lib/mongoid/relations/embedded/in.rb +231 -0
- data/lib/mongoid/relations/embedded/many.rb +639 -0
- data/lib/mongoid/relations/embedded/one.rb +223 -0
- data/lib/mongoid/relations/macros.rb +356 -0
- data/lib/mongoid/relations/many.rb +208 -0
- data/lib/mongoid/relations/marshalable.rb +32 -0
- data/lib/mongoid/relations/metadata.rb +1174 -0
- data/lib/mongoid/relations/nested_builder.rb +74 -0
- data/lib/mongoid/relations/one.rb +48 -0
- data/lib/mongoid/relations/options.rb +48 -0
- data/lib/mongoid/relations/polymorphic.rb +39 -0
- data/lib/mongoid/relations/proxy.rb +270 -0
- data/lib/mongoid/relations/referenced/in.rb +297 -0
- data/lib/mongoid/relations/referenced/many.rb +787 -0
- data/lib/mongoid/relations/referenced/many_to_many.rb +486 -0
- data/lib/mongoid/relations/referenced/one.rb +290 -0
- data/lib/mongoid/relations/reflections.rb +62 -0
- data/lib/mongoid/relations/synchronization.rb +169 -0
- data/lib/mongoid/relations/targets.rb +2 -0
- data/lib/mongoid/relations/targets/enumerable.rb +473 -0
- data/lib/mongoid/relations/touchable.rb +94 -0
- data/lib/mongoid/reloadable.rb +95 -0
- data/lib/mongoid/scopable.rb +379 -0
- data/lib/mongoid/selectable.rb +59 -0
- data/lib/mongoid/serializable.rb +170 -0
- data/lib/mongoid/sessions.rb +330 -0
- data/lib/mongoid/sessions/factory.rb +129 -0
- data/lib/mongoid/sessions/mongo_uri.rb +93 -0
- data/lib/mongoid/sessions/options.rb +141 -0
- data/lib/mongoid/sessions/validators.rb +2 -0
- data/lib/mongoid/sessions/validators/storage.rb +49 -0
- data/lib/mongoid/shardable.rb +65 -0
- data/lib/mongoid/state.rb +97 -0
- data/lib/mongoid/threaded.rb +383 -0
- data/lib/mongoid/threaded/lifecycle.rb +164 -0
- data/lib/mongoid/timestamps.rb +15 -0
- data/lib/mongoid/timestamps/created.rb +30 -0
- data/lib/mongoid/timestamps/created/short.rb +19 -0
- data/lib/mongoid/timestamps/short.rb +10 -0
- data/lib/mongoid/timestamps/updated.rb +39 -0
- data/lib/mongoid/timestamps/updated/short.rb +19 -0
- data/lib/mongoid/traversable.rb +192 -0
- data/lib/mongoid/unit_of_work.rb +61 -0
- data/lib/mongoid/validatable.rb +180 -0
- data/lib/mongoid/validatable/associated.rb +48 -0
- data/lib/mongoid/validatable/format.rb +20 -0
- data/lib/mongoid/validatable/length.rb +20 -0
- data/lib/mongoid/validatable/localizable.rb +30 -0
- data/lib/mongoid/validatable/macros.rb +94 -0
- data/lib/mongoid/validatable/presence.rb +86 -0
- data/lib/mongoid/validatable/queryable.rb +30 -0
- data/lib/mongoid/validatable/uniqueness.rb +330 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/rack/mongoid.rb +2 -0
- data/lib/rack/mongoid/middleware/identity_map.rb +39 -0
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +76 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +25 -0
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +19 -0
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
- data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +4 -0
- data/lib/rails/generators/mongoid_generator.rb +65 -0
- data/lib/rails/mongoid.rb +180 -0
- data/lib/support/ruby_version.rb +26 -0
- data/spec/app/models/account.rb +28 -0
- data/spec/app/models/acolyte.rb +17 -0
- data/spec/app/models/actor.rb +18 -0
- data/spec/app/models/actress.rb +2 -0
- data/spec/app/models/address.rb +77 -0
- data/spec/app/models/address_component.rb +5 -0
- data/spec/app/models/address_number.rb +6 -0
- data/spec/app/models/agency.rb +5 -0
- data/spec/app/models/agent.rb +12 -0
- data/spec/app/models/album.rb +14 -0
- data/spec/app/models/alert.rb +5 -0
- data/spec/app/models/animal.rb +25 -0
- data/spec/app/models/answer.rb +4 -0
- data/spec/app/models/appointment.rb +7 -0
- data/spec/app/models/article.rb +10 -0
- data/spec/app/models/artist.rb +66 -0
- data/spec/app/models/artwork.rb +4 -0
- data/spec/app/models/audio.rb +5 -0
- data/spec/app/models/augmentation.rb +11 -0
- data/spec/app/models/author.rb +4 -0
- data/spec/app/models/band.rb +26 -0
- data/spec/app/models/bar.rb +10 -0
- data/spec/app/models/basic.rb +6 -0
- data/spec/app/models/bed.rb +1 -0
- data/spec/app/models/big_palette.rb +2 -0
- data/spec/app/models/birthday.rb +13 -0
- data/spec/app/models/book.rb +13 -0
- data/spec/app/models/breed.rb +4 -0
- data/spec/app/models/browser.rb +6 -0
- data/spec/app/models/building.rb +5 -0
- data/spec/app/models/building_address.rb +5 -0
- data/spec/app/models/bus.rb +7 -0
- data/spec/app/models/business.rb +5 -0
- data/spec/app/models/callback_recorder.rb +25 -0
- data/spec/app/models/callback_test.rb +9 -0
- data/spec/app/models/canvas.rb +25 -0
- data/spec/app/models/car.rb +1 -0
- data/spec/app/models/cat.rb +8 -0
- data/spec/app/models/category.rb +8 -0
- data/spec/app/models/child.rb +4 -0
- data/spec/app/models/child_doc.rb +22 -0
- data/spec/app/models/church.rb +4 -0
- data/spec/app/models/circle.rb +3 -0
- data/spec/app/models/circuit.rb +4 -0
- data/spec/app/models/circus.rb +7 -0
- data/spec/app/models/code.rb +5 -0
- data/spec/app/models/comment.rb +16 -0
- data/spec/app/models/contractor.rb +5 -0
- data/spec/app/models/cookie.rb +6 -0
- data/spec/app/models/country_code.rb +8 -0
- data/spec/app/models/definition.rb +7 -0
- data/spec/app/models/description.rb +11 -0
- data/spec/app/models/dictionary.rb +10 -0
- data/spec/app/models/division.rb +10 -0
- data/spec/app/models/doctor.rb +12 -0
- data/spec/app/models/dog.rb +7 -0
- data/spec/app/models/dokument.rb +5 -0
- data/spec/app/models/dragon.rb +4 -0
- data/spec/app/models/driver.rb +7 -0
- data/spec/app/models/drug.rb +6 -0
- data/spec/app/models/dungeon.rb +4 -0
- data/spec/app/models/email.rb +6 -0
- data/spec/app/models/employer.rb +5 -0
- data/spec/app/models/entry.rb +6 -0
- data/spec/app/models/eraser.rb +1 -0
- data/spec/app/models/event.rb +22 -0
- data/spec/app/models/exhibition.rb +4 -0
- data/spec/app/models/exhibitor.rb +5 -0
- data/spec/app/models/eye.rb +9 -0
- data/spec/app/models/eye_bowl.rb +9 -0
- data/spec/app/models/face.rb +8 -0
- data/spec/app/models/favorite.rb +6 -0
- data/spec/app/models/filesystem.rb +5 -0
- data/spec/app/models/fire_hydrant.rb +6 -0
- data/spec/app/models/firefox.rb +4 -0
- data/spec/app/models/fish.rb +7 -0
- data/spec/app/models/folder.rb +7 -0
- data/spec/app/models/folder_item.rb +9 -0
- data/spec/app/models/fruits.rb +28 -0
- data/spec/app/models/game.rb +19 -0
- data/spec/app/models/ghost.rb +7 -0
- data/spec/app/models/home.rb +4 -0
- data/spec/app/models/house.rb +6 -0
- data/spec/app/models/html_writer.rb +3 -0
- data/spec/app/models/image.rb +22 -0
- data/spec/app/models/implant.rb +16 -0
- data/spec/app/models/item.rb +8 -0
- data/spec/app/models/jar.rb +7 -0
- data/spec/app/models/label.rb +40 -0
- data/spec/app/models/language.rb +5 -0
- data/spec/app/models/lat_lng.rb +15 -0
- data/spec/app/models/league.rb +11 -0
- data/spec/app/models/learner.rb +2 -0
- data/spec/app/models/line_item.rb +6 -0
- data/spec/app/models/location.rb +8 -0
- data/spec/app/models/login.rb +8 -0
- data/spec/app/models/manufacturer.rb +7 -0
- data/spec/app/models/meat.rb +4 -0
- data/spec/app/models/membership.rb +4 -0
- data/spec/app/models/mixed_drink.rb +4 -0
- data/spec/app/models/movie.rb +13 -0
- data/spec/app/models/my_hash.rb +2 -0
- data/spec/app/models/name.rb +23 -0
- data/spec/app/models/node.rb +5 -0
- data/spec/app/models/note.rb +12 -0
- data/spec/app/models/ordered_post.rb +6 -0
- data/spec/app/models/ordered_preference.rb +6 -0
- data/spec/app/models/oscar.rb +15 -0
- data/spec/app/models/override.rb +16 -0
- data/spec/app/models/ownable.rb +6 -0
- data/spec/app/models/owner.rb +6 -0
- data/spec/app/models/pack.rb +3 -0
- data/spec/app/models/page.rb +5 -0
- data/spec/app/models/page_question.rb +4 -0
- data/spec/app/models/palette.rb +7 -0
- data/spec/app/models/parent.rb +5 -0
- data/spec/app/models/parent_doc.rb +6 -0
- data/spec/app/models/passport.rb +5 -0
- data/spec/app/models/patient.rb +9 -0
- data/spec/app/models/pdf_writer.rb +3 -0
- data/spec/app/models/pencil.rb +1 -0
- data/spec/app/models/person.rb +205 -0
- data/spec/app/models/pet.rb +23 -0
- data/spec/app/models/pet_owner.rb +6 -0
- data/spec/app/models/phone.rb +11 -0
- data/spec/app/models/pizza.rb +7 -0
- data/spec/app/models/player.rb +35 -0
- data/spec/app/models/post.rb +44 -0
- data/spec/app/models/powerup.rb +11 -0
- data/spec/app/models/preference.rb +9 -0
- data/spec/app/models/princess.rb +8 -0
- data/spec/app/models/product.rb +15 -0
- data/spec/app/models/profile.rb +5 -0
- data/spec/app/models/pronunciation.rb +5 -0
- data/spec/app/models/purchase.rb +4 -0
- data/spec/app/models/question.rb +8 -0
- data/spec/app/models/quiz.rb +7 -0
- data/spec/app/models/rating.rb +8 -0
- data/spec/app/models/record.rb +46 -0
- data/spec/app/models/registry.rb +4 -0
- data/spec/app/models/role.rb +7 -0
- data/spec/app/models/root_category.rb +4 -0
- data/spec/app/models/sandwich.rb +4 -0
- data/spec/app/models/scheduler.rb +7 -0
- data/spec/app/models/seo.rb +7 -0
- data/spec/app/models/series.rb +4 -0
- data/spec/app/models/server.rb +13 -0
- data/spec/app/models/service.rb +22 -0
- data/spec/app/models/shape.rb +12 -0
- data/spec/app/models/shelf.rb +5 -0
- data/spec/app/models/shipping_container.rb +5 -0
- data/spec/app/models/shipping_pack.rb +3 -0
- data/spec/app/models/shop.rb +6 -0
- data/spec/app/models/short_agent.rb +4 -0
- data/spec/app/models/short_quiz.rb +5 -0
- data/spec/app/models/slave.rb +6 -0
- data/spec/app/models/song.rb +8 -0
- data/spec/app/models/sound.rb +5 -0
- data/spec/app/models/square.rb +4 -0
- data/spec/app/models/strategy.rb +3 -0
- data/spec/app/models/sub_item.rb +3 -0
- data/spec/app/models/subscription.rb +4 -0
- data/spec/app/models/survey.rb +5 -0
- data/spec/app/models/symptom.rb +6 -0
- data/spec/app/models/tag.rb +8 -0
- data/spec/app/models/target.rb +5 -0
- data/spec/app/models/template.rb +5 -0
- data/spec/app/models/thing.rb +9 -0
- data/spec/app/models/title.rb +3 -0
- data/spec/app/models/tool.rb +8 -0
- data/spec/app/models/topping.rb +5 -0
- data/spec/app/models/track.rb +38 -0
- data/spec/app/models/translation.rb +5 -0
- data/spec/app/models/tree.rb +9 -0
- data/spec/app/models/truck.rb +3 -0
- data/spec/app/models/user.rb +21 -0
- data/spec/app/models/user_account.rb +10 -0
- data/spec/app/models/validation_callback.rb +10 -0
- data/spec/app/models/vehicle.rb +11 -0
- data/spec/app/models/version.rb +5 -0
- data/spec/app/models/vet_visit.rb +5 -0
- data/spec/app/models/video.rb +13 -0
- data/spec/app/models/weapon.rb +11 -0
- data/spec/app/models/wiki_page.rb +14 -0
- data/spec/app/models/word.rb +15 -0
- data/spec/app/models/word_origin.rb +11 -0
- data/spec/app/models/writer.rb +11 -0
- data/spec/config/mongoid.yml +38 -0
- data/spec/mongoid/atomic/modifiers_spec.rb +456 -0
- data/spec/mongoid/atomic/paths/embedded/many_spec.rb +118 -0
- data/spec/mongoid/atomic/paths/embedded/one_spec.rb +110 -0
- data/spec/mongoid/atomic/paths/root_spec.rb +48 -0
- data/spec/mongoid/atomic/paths_spec.rb +270 -0
- data/spec/mongoid/atomic_spec.rb +365 -0
- data/spec/mongoid/attributes/nested_spec.rb +4832 -0
- data/spec/mongoid/attributes/readonly_spec.rb +169 -0
- data/spec/mongoid/attributes_spec.rb +1412 -0
- data/spec/mongoid/changeable_spec.rb +1507 -0
- data/spec/mongoid/composable_spec.rb +24 -0
- data/spec/mongoid/config/environment_spec.rb +83 -0
- data/spec/mongoid/config/options_spec.rb +56 -0
- data/spec/mongoid/config_spec.rb +318 -0
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +293 -0
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +455 -0
- data/spec/mongoid/contextual/atomic_spec.rb +529 -0
- data/spec/mongoid/contextual/find_and_modify_spec.rb +220 -0
- data/spec/mongoid/contextual/geo_near_spec.rb +405 -0
- data/spec/mongoid/contextual/map_reduce_spec.rb +464 -0
- data/spec/mongoid/contextual/memory_spec.rb +1236 -0
- data/spec/mongoid/contextual/mongo_spec.rb +1843 -0
- data/spec/mongoid/contextual/text_search_spec.rb +207 -0
- data/spec/mongoid/copyable_spec.rb +393 -0
- data/spec/mongoid/criteria/findable_spec.rb +1189 -0
- data/spec/mongoid/criteria/inspectable_spec.rb +27 -0
- data/spec/mongoid/criteria/marshalable_spec.rb +28 -0
- data/spec/mongoid/criteria/modifiable_spec.rb +1063 -0
- data/spec/mongoid/criteria/scopable_spec.rb +391 -0
- data/spec/mongoid/criteria_spec.rb +3821 -0
- data/spec/mongoid/document_spec.rb +1205 -0
- data/spec/mongoid/equality_spec.rb +241 -0
- data/spec/mongoid/errors/ambiguous_relationship_spec.rb +29 -0
- data/spec/mongoid/errors/callback_spec.rb +29 -0
- data/spec/mongoid/errors/delete_restriction_spec.rb +29 -0
- data/spec/mongoid/errors/document_not_found_spec.rb +104 -0
- data/spec/mongoid/errors/eager_load_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_collection_spec.rb +36 -0
- data/spec/mongoid/errors/invalid_config_option_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_field_option_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_field_spec.rb +37 -0
- data/spec/mongoid/errors/invalid_find_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_includes_spec.rb +40 -0
- data/spec/mongoid/errors/invalid_index_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_options_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_path_spec.rb +23 -0
- data/spec/mongoid/errors/invalid_scope_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +17 -0
- data/spec/mongoid/errors/invalid_storage_options_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_time_spec.rb +29 -0
- data/spec/mongoid/errors/inverse_not_found_spec.rb +29 -0
- data/spec/mongoid/errors/mixed_relations_spec.rb +29 -0
- data/spec/mongoid/errors/mixed_session_configuration_spec.rb +29 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +48 -0
- data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +29 -0
- data/spec/mongoid/errors/no_environment_spec.rb +29 -0
- data/spec/mongoid/errors/no_map_reduce_output_spec.rb +29 -0
- data/spec/mongoid/errors/no_metadata_spec.rb +23 -0
- data/spec/mongoid/errors/no_parent_spec.rb +29 -0
- data/spec/mongoid/errors/no_session_config_spec.rb +29 -0
- data/spec/mongoid/errors/no_session_database_spec.rb +29 -0
- data/spec/mongoid/errors/no_session_hosts_spec.rb +29 -0
- data/spec/mongoid/errors/no_sessions_config_spec.rb +29 -0
- data/spec/mongoid/errors/readonly_attribute_spec.rb +29 -0
- data/spec/mongoid/errors/scope_overwrite_spec.rb +29 -0
- data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +29 -0
- data/spec/mongoid/errors/unknown_attribute_spec.rb +29 -0
- data/spec/mongoid/errors/unsaved_document_spec.rb +37 -0
- data/spec/mongoid/errors/unsupported_javascript_spec.rb +29 -0
- data/spec/mongoid/errors/validations_spec.rb +45 -0
- data/spec/mongoid/extensions/array_spec.rb +638 -0
- data/spec/mongoid/extensions/big_decimal_spec.rb +104 -0
- data/spec/mongoid/extensions/binary_spec.rb +60 -0
- data/spec/mongoid/extensions/boolean_spec.rb +135 -0
- data/spec/mongoid/extensions/date_spec.rb +235 -0
- data/spec/mongoid/extensions/date_time_spec.rb +155 -0
- data/spec/mongoid/extensions/false_class_spec.rb +42 -0
- data/spec/mongoid/extensions/float_spec.rb +133 -0
- data/spec/mongoid/extensions/hash_spec.rb +333 -0
- data/spec/mongoid/extensions/integer_spec.rb +136 -0
- data/spec/mongoid/extensions/module_spec.rb +42 -0
- data/spec/mongoid/extensions/nil_class_spec.rb +11 -0
- data/spec/mongoid/extensions/object_id_spec.rb +946 -0
- data/spec/mongoid/extensions/object_spec.rb +292 -0
- data/spec/mongoid/extensions/range_spec.rb +105 -0
- data/spec/mongoid/extensions/regexp_spec.rb +47 -0
- data/spec/mongoid/extensions/set_spec.rb +33 -0
- data/spec/mongoid/extensions/string_spec.rb +357 -0
- data/spec/mongoid/extensions/symbol_spec.rb +76 -0
- data/spec/mongoid/extensions/time_spec.rb +467 -0
- data/spec/mongoid/extensions/time_with_zone_spec.rb +405 -0
- data/spec/mongoid/extensions/true_class_spec.rb +42 -0
- data/spec/mongoid/extensions_spec.rb +15 -0
- data/spec/mongoid/factory_spec.rb +185 -0
- data/spec/mongoid/fields/foreign_key_spec.rb +694 -0
- data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +184 -0
- data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +201 -0
- data/spec/mongoid/fields/localized_spec.rb +386 -0
- data/spec/mongoid/fields/standard_spec.rb +166 -0
- data/spec/mongoid/fields_spec.rb +1229 -0
- data/spec/mongoid/findable_spec.rb +342 -0
- data/spec/mongoid/identity_map_spec.rb +564 -0
- data/spec/mongoid/indexable/specification_spec.rb +87 -0
- data/spec/mongoid/indexable_spec.rb +504 -0
- data/spec/mongoid/inspectable_spec.rb +49 -0
- data/spec/mongoid/interceptable_spec.rb +1564 -0
- data/spec/mongoid/loggable_spec.rb +21 -0
- data/spec/mongoid/matchable/all_spec.rb +31 -0
- data/spec/mongoid/matchable/and_spec.rb +162 -0
- data/spec/mongoid/matchable/default_spec.rb +130 -0
- data/spec/mongoid/matchable/exists_spec.rb +57 -0
- data/spec/mongoid/matchable/gt_spec.rb +75 -0
- data/spec/mongoid/matchable/gte_spec.rb +74 -0
- data/spec/mongoid/matchable/in_spec.rb +25 -0
- data/spec/mongoid/matchable/lt_spec.rb +74 -0
- data/spec/mongoid/matchable/lte_spec.rb +74 -0
- data/spec/mongoid/matchable/ne_spec.rb +25 -0
- data/spec/mongoid/matchable/nin_spec.rb +25 -0
- data/spec/mongoid/matchable/or_spec.rb +106 -0
- data/spec/mongoid/matchable/size_spec.rb +25 -0
- data/spec/mongoid/matchable_spec.rb +532 -0
- data/spec/mongoid/persistable/creatable_spec.rb +512 -0
- data/spec/mongoid/persistable/deletable_spec.rb +205 -0
- data/spec/mongoid/persistable/destroyable_spec.rb +148 -0
- data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
- data/spec/mongoid/persistable/logical_spec.rb +143 -0
- data/spec/mongoid/persistable/poppable_spec.rb +115 -0
- data/spec/mongoid/persistable/pullable_spec.rb +228 -0
- data/spec/mongoid/persistable/pushable_spec.rb +258 -0
- data/spec/mongoid/persistable/renamable_spec.rb +135 -0
- data/spec/mongoid/persistable/savable_spec.rb +432 -0
- data/spec/mongoid/persistable/settable_spec.rb +139 -0
- data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
- data/spec/mongoid/persistable/updatable_spec.rb +522 -0
- data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
- data/spec/mongoid/persistable_spec.rb +206 -0
- data/spec/mongoid/positional_spec.rb +227 -0
- data/spec/mongoid/railties/document_spec.rb +24 -0
- data/spec/mongoid/relations/accessors_spec.rb +736 -0
- data/spec/mongoid/relations/auto_save_spec.rb +261 -0
- data/spec/mongoid/relations/bindings/embedded/in_spec.rb +171 -0
- data/spec/mongoid/relations/bindings/embedded/many_spec.rb +54 -0
- data/spec/mongoid/relations/bindings/embedded/one_spec.rb +77 -0
- data/spec/mongoid/relations/bindings/referenced/in_spec.rb +241 -0
- data/spec/mongoid/relations/bindings/referenced/many_spec.rb +153 -0
- data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +178 -0
- data/spec/mongoid/relations/bindings/referenced/one_spec.rb +131 -0
- data/spec/mongoid/relations/builders/embedded/in_spec.rb +34 -0
- data/spec/mongoid/relations/builders/embedded/many_spec.rb +132 -0
- data/spec/mongoid/relations/builders/embedded/one_spec.rb +99 -0
- data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +234 -0
- data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +250 -0
- data/spec/mongoid/relations/builders/referenced/in_spec.rb +241 -0
- data/spec/mongoid/relations/builders/referenced/many_spec.rb +137 -0
- data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +178 -0
- data/spec/mongoid/relations/builders/referenced/one_spec.rb +124 -0
- data/spec/mongoid/relations/builders_spec.rb +226 -0
- data/spec/mongoid/relations/cascading/delete_spec.rb +101 -0
- data/spec/mongoid/relations/cascading/destroy_spec.rb +47 -0
- data/spec/mongoid/relations/cascading/nullify_spec.rb +32 -0
- data/spec/mongoid/relations/cascading/restrict_spec.rb +68 -0
- data/spec/mongoid/relations/cascading_spec.rb +355 -0
- data/spec/mongoid/relations/constraint_spec.rb +74 -0
- data/spec/mongoid/relations/conversions_spec.rb +126 -0
- data/spec/mongoid/relations/counter_cache_spec.rb +205 -0
- data/spec/mongoid/relations/cyclic_spec.rb +156 -0
- data/spec/mongoid/relations/embedded/dirty_spec.rb +65 -0
- data/spec/mongoid/relations/embedded/in_spec.rb +579 -0
- data/spec/mongoid/relations/embedded/many_spec.rb +3781 -0
- data/spec/mongoid/relations/embedded/one_spec.rb +1014 -0
- data/spec/mongoid/relations/macros_spec.rb +613 -0
- data/spec/mongoid/relations/metadata_spec.rb +1917 -0
- data/spec/mongoid/relations/options_spec.rb +35 -0
- data/spec/mongoid/relations/polymorphic_spec.rb +128 -0
- data/spec/mongoid/relations/proxy_spec.rb +48 -0
- data/spec/mongoid/relations/referenced/in_spec.rb +1435 -0
- data/spec/mongoid/relations/referenced/many_spec.rb +3546 -0
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +3556 -0
- data/spec/mongoid/relations/referenced/one_spec.rb +1289 -0
- data/spec/mongoid/relations/reflections_spec.rb +101 -0
- data/spec/mongoid/relations/synchronization_spec.rb +449 -0
- data/spec/mongoid/relations/targets/enumerable_spec.rb +1710 -0
- data/spec/mongoid/relations/touchable_spec.rb +296 -0
- data/spec/mongoid/relations_spec.rb +188 -0
- data/spec/mongoid/reloadable_spec.rb +305 -0
- data/spec/mongoid/scopable_spec.rb +926 -0
- data/spec/mongoid/selectable_spec.rb +134 -0
- data/spec/mongoid/serializable_spec.rb +862 -0
- data/spec/mongoid/sessions/factory_spec.rb +312 -0
- data/spec/mongoid/sessions/mongo_uri_spec.rb +103 -0
- data/spec/mongoid/sessions/options_spec.rb +71 -0
- data/spec/mongoid/sessions_spec.rb +1078 -0
- data/spec/mongoid/shardable_spec.rb +61 -0
- data/spec/mongoid/state_spec.rb +102 -0
- data/spec/mongoid/threaded_spec.rb +258 -0
- data/spec/mongoid/timestamps/created/short_spec.rb +51 -0
- data/spec/mongoid/timestamps/created_spec.rb +44 -0
- data/spec/mongoid/timestamps/updated/short_spec.rb +90 -0
- data/spec/mongoid/timestamps/updated_spec.rb +86 -0
- data/spec/mongoid/timestamps_spec.rb +112 -0
- data/spec/mongoid/traversable_spec.rb +244 -0
- data/spec/mongoid/unit_of_work_spec.rb +196 -0
- data/spec/mongoid/validatable/associated_spec.rb +183 -0
- data/spec/mongoid/validatable/format_spec.rb +83 -0
- data/spec/mongoid/validatable/length_spec.rb +119 -0
- data/spec/mongoid/validatable/numericality_spec.rb +30 -0
- data/spec/mongoid/validatable/presence_spec.rb +511 -0
- data/spec/mongoid/validatable/uniqueness_spec.rb +2305 -0
- data/spec/mongoid/validatable_spec.rb +309 -0
- data/spec/mongoid_spec.rb +74 -0
- data/spec/rack/mongoid/middleware/identity_map_spec.rb +72 -0
- data/spec/rails/mongoid_spec.rb +462 -0
- data/spec/spec_helper.rb +103 -0
- metadata +1159 -0
@@ -0,0 +1,440 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "mongoid/contextual/aggregable/memory"
|
3
|
+
|
4
|
+
module Mongoid
|
5
|
+
module Contextual
|
6
|
+
class Memory
|
7
|
+
include Enumerable
|
8
|
+
include Aggregable::Memory
|
9
|
+
include Eager
|
10
|
+
include Queryable
|
11
|
+
include Positional
|
12
|
+
|
13
|
+
# @attribute [r] root The root document.
|
14
|
+
# @attribute [r] path The atomic path.
|
15
|
+
# @attribute [r] selector The root document selector.
|
16
|
+
# @attribute [r] matching The in memory documents that match the selector.
|
17
|
+
attr_reader :documents, :path, :root, :selector
|
18
|
+
|
19
|
+
# Check if the context is equal to the other object.
|
20
|
+
#
|
21
|
+
# @example Check equality.
|
22
|
+
# context == []
|
23
|
+
#
|
24
|
+
# @param [ Array ] other The other array.
|
25
|
+
#
|
26
|
+
# @return [ true, false ] If the objects are equal.
|
27
|
+
#
|
28
|
+
# @since 3.0.0
|
29
|
+
def ==(other)
|
30
|
+
return false unless other.respond_to?(:entries)
|
31
|
+
entries == other.entries
|
32
|
+
end
|
33
|
+
|
34
|
+
# Delete all documents in the database that match the selector.
|
35
|
+
#
|
36
|
+
# @example Delete all the documents.
|
37
|
+
# context.delete
|
38
|
+
#
|
39
|
+
# @return [ nil ] Nil.
|
40
|
+
#
|
41
|
+
# @since 3.0.0
|
42
|
+
def delete
|
43
|
+
deleted = count
|
44
|
+
removed = map do |doc|
|
45
|
+
prepare_remove(doc)
|
46
|
+
doc.as_document
|
47
|
+
end
|
48
|
+
unless removed.empty?
|
49
|
+
collection.find(selector).update(
|
50
|
+
positionally(selector, "$pullAll" => { path => removed })
|
51
|
+
)
|
52
|
+
end
|
53
|
+
deleted
|
54
|
+
end
|
55
|
+
alias :delete_all :delete
|
56
|
+
|
57
|
+
# Destroy all documents in the database that match the selector.
|
58
|
+
#
|
59
|
+
# @example Destroy all the documents.
|
60
|
+
# context.destroy
|
61
|
+
#
|
62
|
+
# @return [ nil ] Nil.
|
63
|
+
#
|
64
|
+
# @since 3.0.0
|
65
|
+
def destroy
|
66
|
+
deleted = count
|
67
|
+
each do |doc|
|
68
|
+
documents.delete_one(doc)
|
69
|
+
doc.destroy
|
70
|
+
end
|
71
|
+
deleted
|
72
|
+
end
|
73
|
+
alias :destroy_all :destroy
|
74
|
+
|
75
|
+
# Get the distinct values in the db for the provided field.
|
76
|
+
#
|
77
|
+
# @example Get the distinct values.
|
78
|
+
# context.distinct(:name)
|
79
|
+
#
|
80
|
+
# @param [ String, Symbol ] field The name of the field.
|
81
|
+
#
|
82
|
+
# @return [ Array<Object> ] The distinct values for the field.
|
83
|
+
#
|
84
|
+
# @since 3.0.0
|
85
|
+
def distinct(field)
|
86
|
+
documents.map{ |doc| doc.send(field) }.uniq
|
87
|
+
end
|
88
|
+
|
89
|
+
# Iterate over the context. If provided a block, yield to a Mongoid
|
90
|
+
# document for each, otherwise return an enum.
|
91
|
+
#
|
92
|
+
# @example Iterate over the context.
|
93
|
+
# context.each do |doc|
|
94
|
+
# puts doc.name
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# @return [ Enumerator ] The enumerator.
|
98
|
+
#
|
99
|
+
# @since 3.0.0
|
100
|
+
def each
|
101
|
+
if block_given?
|
102
|
+
documents_for_iteration.each do |doc|
|
103
|
+
yield(doc)
|
104
|
+
end
|
105
|
+
# eager_loadable? ? docs : self
|
106
|
+
else
|
107
|
+
to_enum
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Do any documents exist for the context.
|
112
|
+
#
|
113
|
+
# @example Do any documents exist for the context.
|
114
|
+
# context.exists?
|
115
|
+
#
|
116
|
+
# @return [ true, false ] If the count is more than zero.
|
117
|
+
#
|
118
|
+
# @since 3.0.0
|
119
|
+
def exists?
|
120
|
+
count > 0
|
121
|
+
end
|
122
|
+
|
123
|
+
# Get the first document in the database for the criteria's selector.
|
124
|
+
#
|
125
|
+
# @example Get the first document.
|
126
|
+
# context.first
|
127
|
+
#
|
128
|
+
# @return [ Document ] The first document.
|
129
|
+
#
|
130
|
+
# @since 3.0.0
|
131
|
+
def first
|
132
|
+
doc = documents.first
|
133
|
+
eager_load_one(doc) if eager_loadable?(doc)
|
134
|
+
doc
|
135
|
+
end
|
136
|
+
alias :one :first
|
137
|
+
|
138
|
+
# Create the new in memory context.
|
139
|
+
#
|
140
|
+
# @example Create the new context.
|
141
|
+
# Memory.new(criteria)
|
142
|
+
#
|
143
|
+
# @param [ Criteria ] The criteria.
|
144
|
+
#
|
145
|
+
# @since 3.0.0
|
146
|
+
def initialize(criteria)
|
147
|
+
@criteria, @klass = criteria, criteria.klass
|
148
|
+
@documents = criteria.documents.select do |doc|
|
149
|
+
@root ||= doc._root
|
150
|
+
@collection ||= root.collection
|
151
|
+
doc.matches?(criteria.selector)
|
152
|
+
end
|
153
|
+
apply_sorting
|
154
|
+
apply_options
|
155
|
+
end
|
156
|
+
|
157
|
+
# Get the last document in the database for the criteria's selector.
|
158
|
+
#
|
159
|
+
# @example Get the last document.
|
160
|
+
# context.last
|
161
|
+
#
|
162
|
+
# @return [ Document ] The last document.
|
163
|
+
#
|
164
|
+
# @since 3.0.0
|
165
|
+
def last
|
166
|
+
doc = documents.last
|
167
|
+
eager_load_one(doc) if eager_loadable?(doc)
|
168
|
+
doc
|
169
|
+
end
|
170
|
+
|
171
|
+
# Get the length of matching documents in the context.
|
172
|
+
#
|
173
|
+
# @example Get the length of matching documents.
|
174
|
+
# context.length
|
175
|
+
#
|
176
|
+
# @return [ Integer ] The matching length.
|
177
|
+
#
|
178
|
+
# @since 3.0.0
|
179
|
+
def length
|
180
|
+
documents.length
|
181
|
+
end
|
182
|
+
alias :size :length
|
183
|
+
|
184
|
+
# Limits the number of documents that are returned.
|
185
|
+
#
|
186
|
+
# @example Limit the documents.
|
187
|
+
# context.limit(20)
|
188
|
+
#
|
189
|
+
# @param [ Integer ] value The number of documents to return.
|
190
|
+
#
|
191
|
+
# @return [ Mongo ] The context.
|
192
|
+
#
|
193
|
+
# @since 3.0.0
|
194
|
+
def limit(value)
|
195
|
+
self.limiting = value
|
196
|
+
self
|
197
|
+
end
|
198
|
+
|
199
|
+
# Skips the provided number of documents.
|
200
|
+
#
|
201
|
+
# @example Skip the documents.
|
202
|
+
# context.skip(20)
|
203
|
+
#
|
204
|
+
# @param [ Integer ] value The number of documents to skip.
|
205
|
+
#
|
206
|
+
# @return [ Mongo ] The context.
|
207
|
+
#
|
208
|
+
# @since 3.0.0
|
209
|
+
def skip(value)
|
210
|
+
self.skipping = value
|
211
|
+
self
|
212
|
+
end
|
213
|
+
|
214
|
+
# Sorts the documents by the provided spec.
|
215
|
+
#
|
216
|
+
# @example Sort the documents.
|
217
|
+
# context.sort(name: -1, title: 1)
|
218
|
+
#
|
219
|
+
# @param [ Hash ] values The sorting values as field/direction(1/-1)
|
220
|
+
# pairs.
|
221
|
+
#
|
222
|
+
# @return [ Mongo ] The context.
|
223
|
+
#
|
224
|
+
# @since 3.0.0
|
225
|
+
def sort(values)
|
226
|
+
in_place_sort(values) and self
|
227
|
+
end
|
228
|
+
|
229
|
+
# Update the first matching document atomically.
|
230
|
+
#
|
231
|
+
# @example Update the matching document.
|
232
|
+
# context.update(name: "Smiths")
|
233
|
+
#
|
234
|
+
# @param [ Hash ] attributes The new attributes for the document.
|
235
|
+
#
|
236
|
+
# @return [ nil, false ] False if no attributes were provided.
|
237
|
+
#
|
238
|
+
# @since 3.0.0
|
239
|
+
def update(attributes = nil)
|
240
|
+
update_documents(attributes, [ first ])
|
241
|
+
end
|
242
|
+
|
243
|
+
# Update all the matching documents atomically.
|
244
|
+
#
|
245
|
+
# @example Update all the matching documents.
|
246
|
+
# context.update_all(name: "Smiths")
|
247
|
+
#
|
248
|
+
# @param [ Hash ] attributes The new attributes for each document.
|
249
|
+
#
|
250
|
+
# @return [ nil, false ] False if no attributes were provided.
|
251
|
+
#
|
252
|
+
# @since 3.0.0
|
253
|
+
def update_all(attributes = nil)
|
254
|
+
update_documents(attributes, entries)
|
255
|
+
end
|
256
|
+
|
257
|
+
private
|
258
|
+
|
259
|
+
# Get the documents the context should iterate. This follows 3 rules:
|
260
|
+
#
|
261
|
+
# @api private
|
262
|
+
#
|
263
|
+
# @example Get the documents for iteration.
|
264
|
+
# context.documents_for_iteration
|
265
|
+
#
|
266
|
+
# @return [ Array<Document> ] The docs to iterate.
|
267
|
+
#
|
268
|
+
# @since 3.1.0
|
269
|
+
def documents_for_iteration
|
270
|
+
docs = documents[skipping || 0, limiting || documents.length] || []
|
271
|
+
if eager_loadable?
|
272
|
+
eager_load(docs)
|
273
|
+
end
|
274
|
+
docs
|
275
|
+
end
|
276
|
+
|
277
|
+
# Update the provided documents with the attributes.
|
278
|
+
#
|
279
|
+
# @api private
|
280
|
+
#
|
281
|
+
# @example Update the documents.
|
282
|
+
# context.update_documents({}, doc)
|
283
|
+
#
|
284
|
+
# @param [ Hash ] attributes The attributes.
|
285
|
+
# @param [ Array<Document> ] docs The docs to update.
|
286
|
+
#
|
287
|
+
# @since 3.0.4
|
288
|
+
def update_documents(attributes, docs)
|
289
|
+
return false if !attributes || docs.empty?
|
290
|
+
updates = { "$set" => {}}
|
291
|
+
docs.each do |doc|
|
292
|
+
@selector ||= root.atomic_selector
|
293
|
+
doc.write_attributes(attributes)
|
294
|
+
updates["$set"].merge!(doc.atomic_updates["$set"] || {})
|
295
|
+
doc.move_changes
|
296
|
+
end
|
297
|
+
collection.find(selector).update(updates)
|
298
|
+
end
|
299
|
+
|
300
|
+
# Get the limiting value.
|
301
|
+
#
|
302
|
+
# @api private
|
303
|
+
#
|
304
|
+
# @example Get the limiting value.
|
305
|
+
#
|
306
|
+
# @return [ Integer ] The limit.
|
307
|
+
#
|
308
|
+
# @since 3.0.0
|
309
|
+
def limiting
|
310
|
+
defined?(@limiting) ? @limiting : nil
|
311
|
+
end
|
312
|
+
|
313
|
+
# Set the limiting value.
|
314
|
+
#
|
315
|
+
# @api private
|
316
|
+
#
|
317
|
+
# @example Set the limiting value.
|
318
|
+
#
|
319
|
+
# @param [ Integer ] value The limit.
|
320
|
+
#
|
321
|
+
# @return [ Integer ] The limit.
|
322
|
+
#
|
323
|
+
# @since 3.0.0
|
324
|
+
def limiting=(value)
|
325
|
+
@limiting = value
|
326
|
+
end
|
327
|
+
|
328
|
+
# Get the skiping value.
|
329
|
+
#
|
330
|
+
# @api private
|
331
|
+
#
|
332
|
+
# @example Get the skiping value.
|
333
|
+
#
|
334
|
+
# @return [ Integer ] The skip.
|
335
|
+
#
|
336
|
+
# @since 3.0.0
|
337
|
+
def skipping
|
338
|
+
defined?(@skipping) ? @skipping : nil
|
339
|
+
end
|
340
|
+
|
341
|
+
# Set the skiping value.
|
342
|
+
#
|
343
|
+
# @api private
|
344
|
+
#
|
345
|
+
# @example Set the skiping value.
|
346
|
+
#
|
347
|
+
# @param [ Integer ] value The skip.
|
348
|
+
#
|
349
|
+
# @return [ Integer ] The skip.
|
350
|
+
#
|
351
|
+
# @since 3.0.0
|
352
|
+
def skipping=(value)
|
353
|
+
@skipping = value
|
354
|
+
end
|
355
|
+
|
356
|
+
# Apply criteria options.
|
357
|
+
#
|
358
|
+
# @api private
|
359
|
+
#
|
360
|
+
# @example Apply criteria options.
|
361
|
+
# context.apply_options
|
362
|
+
#
|
363
|
+
# @return [ Memory ] self.
|
364
|
+
#
|
365
|
+
# @since 3.0.0
|
366
|
+
def apply_options
|
367
|
+
skip(criteria.options[:skip]).limit(criteria.options[:limit])
|
368
|
+
end
|
369
|
+
|
370
|
+
# Map the sort symbols to the correct MongoDB values.
|
371
|
+
#
|
372
|
+
# @example Apply the sorting params.
|
373
|
+
# context.apply_sorting
|
374
|
+
#
|
375
|
+
# @since 3.0.0
|
376
|
+
def apply_sorting
|
377
|
+
if spec = criteria.options[:sort]
|
378
|
+
in_place_sort(spec)
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
# Compare two values, checking for nil.
|
383
|
+
#
|
384
|
+
# @api private
|
385
|
+
#
|
386
|
+
# @example Compare the two objects.
|
387
|
+
# context.compare(a, b)
|
388
|
+
#
|
389
|
+
# @param [ Object ] a The first object.
|
390
|
+
# @param [ Object ] b The first object.
|
391
|
+
#
|
392
|
+
# @return [ Integer ] The comparison value.
|
393
|
+
#
|
394
|
+
# @since 3.0.0
|
395
|
+
def compare(a, b)
|
396
|
+
case
|
397
|
+
when a.nil? then b.nil? ? 0 : 1
|
398
|
+
when b.nil? then -1
|
399
|
+
else a <=> b
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
# Sort the documents in place.
|
404
|
+
#
|
405
|
+
# @example Sort the documents.
|
406
|
+
# context.in_place_sort(name: 1)
|
407
|
+
#
|
408
|
+
# @param [ Hash ] values The field/direction sorting pairs.
|
409
|
+
#
|
410
|
+
# @since 3.0.0
|
411
|
+
def in_place_sort(values)
|
412
|
+
values.keys.reverse.each do |field|
|
413
|
+
documents.sort! do |a, b|
|
414
|
+
a_value, b_value = a[field], b[field]
|
415
|
+
value = compare(a_value.__sortable__, b_value.__sortable__)
|
416
|
+
values[field] < 0 ? value * -1 : value
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
# Prepare the document for batch removal.
|
422
|
+
#
|
423
|
+
# @api private
|
424
|
+
#
|
425
|
+
# @example Prepare for removal.
|
426
|
+
# context.prepare_remove(doc)
|
427
|
+
#
|
428
|
+
# @param [ Document ] doc The document.
|
429
|
+
#
|
430
|
+
# @since 3.0.0
|
431
|
+
def prepare_remove(doc)
|
432
|
+
@selector ||= root.atomic_selector
|
433
|
+
@path ||= doc.atomic_path
|
434
|
+
documents.delete_one(doc)
|
435
|
+
doc._parent.remove_child(doc)
|
436
|
+
doc.destroyed = true
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
@@ -0,0 +1,676 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "mongoid/contextual/atomic"
|
3
|
+
require "mongoid/contextual/aggregable/mongo"
|
4
|
+
require "mongoid/contextual/command"
|
5
|
+
require "mongoid/contextual/eager"
|
6
|
+
require "mongoid/contextual/find_and_modify"
|
7
|
+
require "mongoid/contextual/geo_near"
|
8
|
+
require "mongoid/contextual/map_reduce"
|
9
|
+
require "mongoid/contextual/text_search"
|
10
|
+
|
11
|
+
module Mongoid
|
12
|
+
module Contextual
|
13
|
+
class Mongo
|
14
|
+
include Enumerable
|
15
|
+
include Aggregable::Mongo
|
16
|
+
include Atomic
|
17
|
+
include Eager
|
18
|
+
include Queryable
|
19
|
+
|
20
|
+
# @attribute [r] query The Moped query.
|
21
|
+
attr_reader :query
|
22
|
+
|
23
|
+
# Is the context cached?
|
24
|
+
#
|
25
|
+
# @example Is the context cached?
|
26
|
+
# context.cached?
|
27
|
+
#
|
28
|
+
# @return [ true, false ] If the context is cached.
|
29
|
+
#
|
30
|
+
# @since 3.0.0
|
31
|
+
def cached?
|
32
|
+
!!@cache
|
33
|
+
end
|
34
|
+
|
35
|
+
# Get the number of documents matching the query.
|
36
|
+
#
|
37
|
+
# @example Get the number of matching documents.
|
38
|
+
# context.count
|
39
|
+
#
|
40
|
+
# @example Get the count of documents matching the provided.
|
41
|
+
# context.count(document)
|
42
|
+
#
|
43
|
+
# @example Get the count for where the provided block is true.
|
44
|
+
# context.count do |doc|
|
45
|
+
# doc.likes > 1
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# @param [ Document ] document A document to match or true if wanting
|
49
|
+
# skip and limit to be factored into the count.
|
50
|
+
#
|
51
|
+
# @return [ Integer ] The number of matches.
|
52
|
+
#
|
53
|
+
# @since 3.0.0
|
54
|
+
def count(document = false, &block)
|
55
|
+
return super(&block) if block_given?
|
56
|
+
if document.is_a?(Document)
|
57
|
+
return collection.find(criteria.and(_id: document.id).selector).count
|
58
|
+
end
|
59
|
+
return query.count(document) if document
|
60
|
+
try_cache(:count) { query.count }
|
61
|
+
end
|
62
|
+
|
63
|
+
# Delete all documents in the database that match the selector.
|
64
|
+
#
|
65
|
+
# @example Delete all the documents.
|
66
|
+
# context.delete
|
67
|
+
#
|
68
|
+
# @return [ nil ] Nil.
|
69
|
+
#
|
70
|
+
# @since 3.0.0
|
71
|
+
def delete
|
72
|
+
self.count.tap do
|
73
|
+
query.remove_all
|
74
|
+
end
|
75
|
+
end
|
76
|
+
alias :delete_all :delete
|
77
|
+
|
78
|
+
# Destroy all documents in the database that match the selector.
|
79
|
+
#
|
80
|
+
# @example Destroy all the documents.
|
81
|
+
# context.destroy
|
82
|
+
#
|
83
|
+
# @return [ nil ] Nil.
|
84
|
+
#
|
85
|
+
# @since 3.0.0
|
86
|
+
def destroy
|
87
|
+
destroyed = self.count
|
88
|
+
each do |doc|
|
89
|
+
doc.destroy
|
90
|
+
end
|
91
|
+
destroyed
|
92
|
+
end
|
93
|
+
alias :destroy_all :destroy
|
94
|
+
|
95
|
+
# Get the distinct values in the db for the provided field.
|
96
|
+
#
|
97
|
+
# @example Get the distinct values.
|
98
|
+
# context.distinct(:name)
|
99
|
+
#
|
100
|
+
# @param [ String, Symbol ] field The name of the field.
|
101
|
+
#
|
102
|
+
# @return [ Array<Object> ] The distinct values for the field.
|
103
|
+
#
|
104
|
+
# @since 3.0.0
|
105
|
+
def distinct(field)
|
106
|
+
query.distinct(klass.database_field_name(field))
|
107
|
+
end
|
108
|
+
|
109
|
+
# Iterate over the context. If provided a block, yield to a Mongoid
|
110
|
+
# document for each, otherwise return an enum.
|
111
|
+
#
|
112
|
+
# @example Iterate over the context.
|
113
|
+
# context.each do |doc|
|
114
|
+
# puts doc.name
|
115
|
+
# end
|
116
|
+
#
|
117
|
+
# @return [ Enumerator ] The enumerator.
|
118
|
+
#
|
119
|
+
# @since 3.0.0
|
120
|
+
def each(&block)
|
121
|
+
if block_given?
|
122
|
+
selecting do
|
123
|
+
documents_for_iteration.each do |doc|
|
124
|
+
yield_document(doc, &block)
|
125
|
+
end
|
126
|
+
@cache_loaded = true
|
127
|
+
eager_loadable? ? docs : self
|
128
|
+
end
|
129
|
+
else
|
130
|
+
to_enum
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Do any documents exist for the context.
|
135
|
+
#
|
136
|
+
# @example Do any documents exist for the context.
|
137
|
+
# context.exists?
|
138
|
+
#
|
139
|
+
# @note We don't use count here since Mongo does not use counted
|
140
|
+
# b-tree indexes, unless a count is already cached then that is
|
141
|
+
# used to determine the value.
|
142
|
+
#
|
143
|
+
# @return [ true, false ] If the count is more than zero.
|
144
|
+
#
|
145
|
+
# @since 3.0.0
|
146
|
+
def exists?
|
147
|
+
return !documents.empty? if cached? && cache_loaded?
|
148
|
+
return @count > 0 if instance_variable_defined?(:@count)
|
149
|
+
|
150
|
+
try_cache(:exists) do
|
151
|
+
!!(query.dup.select(_id: 1).limit(1).first)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Run an explain on the criteria.
|
156
|
+
#
|
157
|
+
# @example Explain the criteria.
|
158
|
+
# Band.where(name: "Depeche Mode").explain
|
159
|
+
#
|
160
|
+
# @return [ Hash ] The explain result.
|
161
|
+
#
|
162
|
+
# @since 3.0.0
|
163
|
+
def explain
|
164
|
+
query.explain
|
165
|
+
end
|
166
|
+
|
167
|
+
# Execute the find and modify command, used for MongoDB's
|
168
|
+
# $findAndModify.
|
169
|
+
#
|
170
|
+
# @example Execute the command.
|
171
|
+
# context.find_and_modify({ "$inc" => { likes: 1 }}, new: true)
|
172
|
+
#
|
173
|
+
# @param [ Hash ] update The updates.
|
174
|
+
# @param [ Hash ] options The command options.
|
175
|
+
#
|
176
|
+
# @option options [ true, false ] :new Return the updated document.
|
177
|
+
# @option options [ true, false ] :remove Delete the first document.
|
178
|
+
# @option options [ true, false ] :upsert Create the document if it doesn't exist.
|
179
|
+
#
|
180
|
+
# @return [ Document ] The result of the command.
|
181
|
+
#
|
182
|
+
# @since 3.0.0
|
183
|
+
def find_and_modify(update, options = {})
|
184
|
+
if doc = FindAndModify.new(collection, criteria, update, options).result
|
185
|
+
Factory.from_db(klass, doc)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# Get the first document in the database for the criteria's selector.
|
190
|
+
#
|
191
|
+
# @example Get the first document.
|
192
|
+
# context.first
|
193
|
+
#
|
194
|
+
# @return [ Document ] The first document.
|
195
|
+
#
|
196
|
+
# @since 3.0.0
|
197
|
+
def first
|
198
|
+
return documents.first if cached? && cache_loaded?
|
199
|
+
try_cache(:first) do
|
200
|
+
with_sorting do
|
201
|
+
with_eager_loading(query.first)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
alias :one :first
|
206
|
+
|
207
|
+
# Execute a $geoNear command against the database.
|
208
|
+
#
|
209
|
+
# @example Find documents close to 10, 10.
|
210
|
+
# context.geo_near([ 10, 10 ])
|
211
|
+
#
|
212
|
+
# @example Find with spherical distance.
|
213
|
+
# context.geo_near([ 10, 10 ]).spherical
|
214
|
+
#
|
215
|
+
# @example Find with a max distance.
|
216
|
+
# context.geo_near([ 10, 10 ]).max_distance(0.5)
|
217
|
+
#
|
218
|
+
# @example Provide a distance multiplier.
|
219
|
+
# context.geo_near([ 10, 10 ]).distance_multiplier(1133)
|
220
|
+
#
|
221
|
+
# @param [ Array<Float> ] coordinates The coordinates.
|
222
|
+
#
|
223
|
+
# @return [ GeoNear ] The GeoNear command.
|
224
|
+
#
|
225
|
+
# @since 3.1.0
|
226
|
+
def geo_near(coordinates)
|
227
|
+
GeoNear.new(collection, criteria, coordinates)
|
228
|
+
end
|
229
|
+
|
230
|
+
# Invoke the block for each element of Contextual. Create a new array
|
231
|
+
# containing the values returned by the block.
|
232
|
+
#
|
233
|
+
# If the symbol field name is passed instead of the block, additional
|
234
|
+
# optimizations would be used.
|
235
|
+
#
|
236
|
+
# @example Map by some field.
|
237
|
+
# context.map(:field1)
|
238
|
+
#
|
239
|
+
# @exmaple Map with block.
|
240
|
+
# context.map(&:field1)
|
241
|
+
#
|
242
|
+
# @param [ Symbol ] field The field name.
|
243
|
+
#
|
244
|
+
# @return [ Array ] The result of mapping.
|
245
|
+
def map(field = nil, &block)
|
246
|
+
if block_given?
|
247
|
+
super(&block)
|
248
|
+
else
|
249
|
+
field = field.to_sym
|
250
|
+
criteria.only(field).map(&field.to_proc)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
# Create the new Mongo context. This delegates operations to the
|
255
|
+
# underlying driver - in Mongoid's case Moped.
|
256
|
+
#
|
257
|
+
# @example Create the new context.
|
258
|
+
# Mongo.new(criteria)
|
259
|
+
#
|
260
|
+
# @param [ Criteria ] criteria The criteria.
|
261
|
+
#
|
262
|
+
# @since 3.0.0
|
263
|
+
def initialize(criteria)
|
264
|
+
@criteria, @klass, @cache = criteria, criteria.klass, criteria.options[:cache]
|
265
|
+
@collection = @klass.with(criteria.persistence_options || {}).collection
|
266
|
+
criteria.send(:merge_type_selection)
|
267
|
+
@query = collection.find(criteria.selector)
|
268
|
+
apply_options
|
269
|
+
end
|
270
|
+
|
271
|
+
delegate(:database_field_name, to: :@klass)
|
272
|
+
|
273
|
+
# Get the last document in the database for the criteria's selector.
|
274
|
+
#
|
275
|
+
# @example Get the last document.
|
276
|
+
# context.last
|
277
|
+
#
|
278
|
+
# @return [ Document ] The last document.
|
279
|
+
#
|
280
|
+
# @since 3.0.0
|
281
|
+
def last
|
282
|
+
try_cache(:last) do
|
283
|
+
with_inverse_sorting do
|
284
|
+
with_eager_loading(query.first)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
# Get's the number of documents matching the query selector.
|
290
|
+
#
|
291
|
+
# @example Get the length.
|
292
|
+
# context.length
|
293
|
+
#
|
294
|
+
# @return [ Integer ] The number of documents.
|
295
|
+
#
|
296
|
+
# @since 3.0.0
|
297
|
+
def length
|
298
|
+
@length ||= self.count
|
299
|
+
end
|
300
|
+
alias :size :length
|
301
|
+
|
302
|
+
# Limits the number of documents that are returned from the database.
|
303
|
+
#
|
304
|
+
# @example Limit the documents.
|
305
|
+
# context.limit(20)
|
306
|
+
#
|
307
|
+
# @param [ Integer ] value The number of documents to return.
|
308
|
+
#
|
309
|
+
# @return [ Mongo ] The context.
|
310
|
+
#
|
311
|
+
# @since 3.0.0
|
312
|
+
def limit(value)
|
313
|
+
query.limit(value) and self
|
314
|
+
end
|
315
|
+
|
316
|
+
# Initiate a map/reduce operation from the context.
|
317
|
+
#
|
318
|
+
# @example Initiate a map/reduce.
|
319
|
+
# context.map_reduce(map, reduce)
|
320
|
+
#
|
321
|
+
# @param [ String ] map The map js function.
|
322
|
+
# @param [ String ] reduce The reduce js function.
|
323
|
+
#
|
324
|
+
# @return [ MapReduce ] The map/reduce lazy wrapper.
|
325
|
+
#
|
326
|
+
# @since 3.0.0
|
327
|
+
def map_reduce(map, reduce)
|
328
|
+
MapReduce.new(collection, criteria, map, reduce)
|
329
|
+
end
|
330
|
+
|
331
|
+
# Pluck the single field values from the database. Will return duplicates
|
332
|
+
# if they exist and only works for top level fields.
|
333
|
+
#
|
334
|
+
# @example Pluck a field.
|
335
|
+
# context.pluck(:_id)
|
336
|
+
#
|
337
|
+
# @note This method will return the raw db values - it performs no custom
|
338
|
+
# serialization.
|
339
|
+
#
|
340
|
+
# @param [ String, Symbol, Array ] field Fields to pluck.
|
341
|
+
#
|
342
|
+
# @return [ Array<Object, Array> ] The plucked values.
|
343
|
+
#
|
344
|
+
# @since 3.1.0
|
345
|
+
def pluck(*fields)
|
346
|
+
normalized_select = fields.inject({}) do |hash, f|
|
347
|
+
hash[klass.database_field_name(f)] = 1
|
348
|
+
hash
|
349
|
+
end
|
350
|
+
|
351
|
+
query.dup.select(normalized_select).map do |doc|
|
352
|
+
if normalized_select.size == 1
|
353
|
+
doc[normalized_select.keys.first]
|
354
|
+
else
|
355
|
+
normalized_select.keys.map { |n| doc[n] }.compact
|
356
|
+
end
|
357
|
+
end.compact
|
358
|
+
end
|
359
|
+
|
360
|
+
# Skips the provided number of documents.
|
361
|
+
#
|
362
|
+
# @example Skip the documents.
|
363
|
+
# context.skip(20)
|
364
|
+
#
|
365
|
+
# @param [ Integer ] value The number of documents to skip.
|
366
|
+
#
|
367
|
+
# @return [ Mongo ] The context.
|
368
|
+
#
|
369
|
+
# @since 3.0.0
|
370
|
+
def skip(value)
|
371
|
+
query.skip(value) and self
|
372
|
+
end
|
373
|
+
|
374
|
+
# Sorts the documents by the provided spec.
|
375
|
+
#
|
376
|
+
# @example Sort the documents.
|
377
|
+
# context.sort(name: -1, title: 1)
|
378
|
+
#
|
379
|
+
# @param [ Hash ] values The sorting values as field/direction(1/-1)
|
380
|
+
# pairs.
|
381
|
+
#
|
382
|
+
# @return [ Mongo ] The context.
|
383
|
+
#
|
384
|
+
# @since 3.0.0
|
385
|
+
def sort(values = nil, &block)
|
386
|
+
if block_given?
|
387
|
+
super(&block)
|
388
|
+
else
|
389
|
+
# update the criteria
|
390
|
+
@criteria = criteria.order_by(values)
|
391
|
+
apply_option(:sort)
|
392
|
+
self
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
# Execute a text command against the database.
|
397
|
+
#
|
398
|
+
# @example Find documents with the text "phase"
|
399
|
+
# context.text_search("phase")
|
400
|
+
#
|
401
|
+
# @param [ String ] query The text search query.
|
402
|
+
#
|
403
|
+
# @return [ TextSearch ] The TextSearch command.
|
404
|
+
#
|
405
|
+
# @since 4.0.0
|
406
|
+
def text_search(query)
|
407
|
+
TextSearch.new(collection, criteria, query)
|
408
|
+
end
|
409
|
+
|
410
|
+
# Update the first matching document atomically.
|
411
|
+
#
|
412
|
+
# @example Update the first matching document.
|
413
|
+
# context.update({ "$set" => { name: "Smiths" }})
|
414
|
+
#
|
415
|
+
# @param [ Hash ] attributes The new attributes for the document.
|
416
|
+
#
|
417
|
+
# @return [ nil, false ] False if no attributes were provided.
|
418
|
+
#
|
419
|
+
# @since 3.0.0
|
420
|
+
def update(attributes = nil)
|
421
|
+
update_documents(attributes)
|
422
|
+
end
|
423
|
+
|
424
|
+
# Update all the matching documents atomically.
|
425
|
+
#
|
426
|
+
# @example Update all the matching documents.
|
427
|
+
# context.update({ "$set" => { name: "Smiths" }})
|
428
|
+
#
|
429
|
+
# @param [ Hash ] attributes The new attributes for each document.
|
430
|
+
#
|
431
|
+
# @return [ nil, false ] False if no attributes were provided.
|
432
|
+
#
|
433
|
+
# @since 3.0.0
|
434
|
+
def update_all(attributes = nil)
|
435
|
+
update_documents(attributes, :update_all)
|
436
|
+
end
|
437
|
+
|
438
|
+
private
|
439
|
+
|
440
|
+
# yield the block given or return the cached value
|
441
|
+
#
|
442
|
+
# @param [ String, Symbol ] key The instance variable name
|
443
|
+
#
|
444
|
+
# @return the result of the block
|
445
|
+
#
|
446
|
+
# @since 3.1.4
|
447
|
+
def try_cache(key, &block)
|
448
|
+
unless cached?
|
449
|
+
yield
|
450
|
+
else
|
451
|
+
unless ret = instance_variable_get("@#{key}")
|
452
|
+
instance_variable_set("@#{key}", ret = yield)
|
453
|
+
end
|
454
|
+
ret
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
# Update the documents for the provided method.
|
459
|
+
#
|
460
|
+
# @api private
|
461
|
+
#
|
462
|
+
# @example Update the documents.
|
463
|
+
# context.update_documents(attrs)
|
464
|
+
#
|
465
|
+
# @param [ Hash ] attributes The updates.
|
466
|
+
# @param [ Symbol ] method The method to use.
|
467
|
+
#
|
468
|
+
# @return [ true, false ] If the update succeeded.
|
469
|
+
#
|
470
|
+
# @since 3.0.4
|
471
|
+
def update_documents(attributes, method = :update)
|
472
|
+
return false unless attributes
|
473
|
+
attributes = Hash[attributes.map { |k, v| [klass.database_field_name(k.to_s), v] }]
|
474
|
+
query.send(method, attributes.__consolidate__(klass))
|
475
|
+
end
|
476
|
+
|
477
|
+
# Apply the field limitations.
|
478
|
+
#
|
479
|
+
# @api private
|
480
|
+
#
|
481
|
+
# @example Apply the field limitations.
|
482
|
+
# context.apply_fields
|
483
|
+
#
|
484
|
+
# @since 3.0.0
|
485
|
+
def apply_fields
|
486
|
+
if spec = criteria.options[:fields]
|
487
|
+
query.select(spec)
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
# Apply the options.
|
492
|
+
#
|
493
|
+
# @api private
|
494
|
+
#
|
495
|
+
# @example Apply all options.
|
496
|
+
# context.apply_options
|
497
|
+
#
|
498
|
+
# @since 3.1.0
|
499
|
+
def apply_options
|
500
|
+
apply_fields
|
501
|
+
[ :hint, :limit, :skip, :sort, :batch_size, :max_scan ].each do |name|
|
502
|
+
apply_option(name)
|
503
|
+
end
|
504
|
+
if criteria.options[:timeout] == false
|
505
|
+
query.no_timeout
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
# Apply an option.
|
510
|
+
#
|
511
|
+
# @api private
|
512
|
+
#
|
513
|
+
# @example Apply the skip option.
|
514
|
+
# context.apply_option(:skip)
|
515
|
+
#
|
516
|
+
# @since 3.1.0
|
517
|
+
def apply_option(name)
|
518
|
+
if spec = criteria.options[name]
|
519
|
+
query.send(name, spec)
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
523
|
+
# Apply an ascending id sort for use with #first queries, only if no
|
524
|
+
# other sorting is provided.
|
525
|
+
#
|
526
|
+
# @api private
|
527
|
+
#
|
528
|
+
# @example Apply the id sorting params to the given block
|
529
|
+
# context.with_sorting
|
530
|
+
#
|
531
|
+
# @since 3.0.0
|
532
|
+
def with_sorting
|
533
|
+
begin
|
534
|
+
unless criteria.options.has_key?(:sort)
|
535
|
+
query.sort(_id: 1)
|
536
|
+
end
|
537
|
+
yield
|
538
|
+
ensure
|
539
|
+
apply_option(:sort)
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
# Map the inverse sort symbols to the correct MongoDB values.
|
544
|
+
#
|
545
|
+
# @api private
|
546
|
+
#
|
547
|
+
# @example Apply the inverse sorting params to the given block
|
548
|
+
# context.with_inverse_sorting
|
549
|
+
#
|
550
|
+
# @since 3.0.0
|
551
|
+
def with_inverse_sorting
|
552
|
+
begin
|
553
|
+
if spec = criteria.options[:sort]
|
554
|
+
query.sort(Hash[spec.map{|k, v| [k, -1*v]}])
|
555
|
+
else
|
556
|
+
query.sort(_id: -1)
|
557
|
+
end
|
558
|
+
yield
|
559
|
+
ensure
|
560
|
+
apply_option(:sort)
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
# Is the cache able to be added to?
|
565
|
+
#
|
566
|
+
# @api private
|
567
|
+
#
|
568
|
+
# @example Is the context cacheable?
|
569
|
+
# context.cacheable?
|
570
|
+
#
|
571
|
+
# @return [ true, false ] If caching, and the cache isn't loaded.
|
572
|
+
#
|
573
|
+
# @since 3.0.0
|
574
|
+
def cacheable?
|
575
|
+
cached? && !cache_loaded?
|
576
|
+
end
|
577
|
+
|
578
|
+
# Is the cache fully loaded? Will be true if caching after one full
|
579
|
+
# iteration.
|
580
|
+
#
|
581
|
+
# @api private
|
582
|
+
#
|
583
|
+
# @example Is the cache loaded?
|
584
|
+
# context.cache_loaded?
|
585
|
+
#
|
586
|
+
# @return [ true, false ] If the cache is loaded.
|
587
|
+
#
|
588
|
+
# @since 3.0.0
|
589
|
+
def cache_loaded?
|
590
|
+
!!@cache_loaded
|
591
|
+
end
|
592
|
+
|
593
|
+
# Get the documents for cached queries.
|
594
|
+
#
|
595
|
+
# @api private
|
596
|
+
#
|
597
|
+
# @example Get the cached documents.
|
598
|
+
# context.documents
|
599
|
+
#
|
600
|
+
# @return [ Array<Document> ] The documents.
|
601
|
+
#
|
602
|
+
# @since 3.0.0
|
603
|
+
def documents
|
604
|
+
@documents ||= []
|
605
|
+
end
|
606
|
+
|
607
|
+
# Get the documents the context should iterate. This follows 3 rules:
|
608
|
+
#
|
609
|
+
# 1. If the query is cached, and we already have documents loaded, use
|
610
|
+
# them.
|
611
|
+
# 2. If we are eager loading, then eager load the documents and use
|
612
|
+
# those.
|
613
|
+
# 3. Use the query.
|
614
|
+
#
|
615
|
+
# @api private
|
616
|
+
#
|
617
|
+
# @example Get the documents for iteration.
|
618
|
+
# context.documents_for_iteration
|
619
|
+
#
|
620
|
+
# @return [ Array<Document>, Moped::Query ] The docs to iterate.
|
621
|
+
#
|
622
|
+
# @since 3.0.0
|
623
|
+
def documents_for_iteration
|
624
|
+
if cached? && !documents.empty?
|
625
|
+
documents
|
626
|
+
elsif eager_loadable?
|
627
|
+
docs = query.map{ |doc| Factory.from_db(klass, doc) }
|
628
|
+
eager_load(docs)
|
629
|
+
docs
|
630
|
+
else
|
631
|
+
query
|
632
|
+
end
|
633
|
+
end
|
634
|
+
|
635
|
+
# If we are limiting results, we need to set the field limitations on a
|
636
|
+
# thread local to avoid overriding the default values.
|
637
|
+
#
|
638
|
+
# @example Execute with selection.
|
639
|
+
# context.selecting do
|
640
|
+
# collection.find
|
641
|
+
# end
|
642
|
+
#
|
643
|
+
# @return [ Object ] The yielded value.
|
644
|
+
#
|
645
|
+
# @since 2.4.4
|
646
|
+
def selecting
|
647
|
+
begin
|
648
|
+
fields = criteria.options[:fields]
|
649
|
+
Threaded.set_selection(criteria.object_id, fields) unless fields.blank?
|
650
|
+
yield
|
651
|
+
ensure
|
652
|
+
Threaded.delete_selection(criteria.object_id)
|
653
|
+
end
|
654
|
+
end
|
655
|
+
|
656
|
+
# Yield to the document.
|
657
|
+
#
|
658
|
+
# @api private
|
659
|
+
#
|
660
|
+
# @example Yield the document.
|
661
|
+
# context.yield_document(doc) do |doc|
|
662
|
+
# ...
|
663
|
+
# end
|
664
|
+
#
|
665
|
+
# @param [ Document ] document The document to yield to.
|
666
|
+
#
|
667
|
+
# @since 3.0.0
|
668
|
+
def yield_document(document, &block)
|
669
|
+
doc = document.respond_to?(:_id) ?
|
670
|
+
document : Factory.from_db(klass, document, criteria.object_id)
|
671
|
+
yield(doc)
|
672
|
+
documents.push(doc) if cacheable?
|
673
|
+
end
|
674
|
+
end
|
675
|
+
end
|
676
|
+
end
|