mongoid-multi-db 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +615 -0
- data/LICENSE +20 -0
- data/README.md +62 -0
- data/Rakefile +49 -0
- data/lib/config/locales/bg.yml +54 -0
- data/lib/config/locales/de.yml +54 -0
- data/lib/config/locales/en-GB.yml +55 -0
- data/lib/config/locales/en.yml +55 -0
- data/lib/config/locales/es.yml +52 -0
- data/lib/config/locales/fr.yml +55 -0
- data/lib/config/locales/hi.yml +46 -0
- data/lib/config/locales/hu.yml +57 -0
- data/lib/config/locales/id.yml +55 -0
- data/lib/config/locales/it.yml +52 -0
- data/lib/config/locales/ja.yml +50 -0
- data/lib/config/locales/kr.yml +47 -0
- data/lib/config/locales/nl.yml +52 -0
- data/lib/config/locales/pl.yml +52 -0
- data/lib/config/locales/pt-BR.yml +53 -0
- data/lib/config/locales/pt.yml +53 -0
- data/lib/config/locales/ro.yml +59 -0
- data/lib/config/locales/ru.yml +54 -0
- data/lib/config/locales/sv.yml +53 -0
- data/lib/config/locales/vi.yml +55 -0
- data/lib/config/locales/zh-CN.yml +46 -0
- data/lib/mongoid.rb +148 -0
- data/lib/mongoid/atomic.rb +230 -0
- data/lib/mongoid/atomic/modifiers.rb +243 -0
- data/lib/mongoid/atomic/paths.rb +3 -0
- data/lib/mongoid/atomic/paths/embedded.rb +43 -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 +40 -0
- data/lib/mongoid/attributes.rb +234 -0
- data/lib/mongoid/attributes/processing.rb +146 -0
- data/lib/mongoid/callbacks.rb +135 -0
- data/lib/mongoid/collection.rb +153 -0
- data/lib/mongoid/collection_proxy.rb +59 -0
- data/lib/mongoid/collections.rb +120 -0
- data/lib/mongoid/collections/master.rb +45 -0
- data/lib/mongoid/collections/operations.rb +44 -0
- data/lib/mongoid/collections/retry.rb +46 -0
- data/lib/mongoid/components.rb +96 -0
- data/lib/mongoid/config.rb +347 -0
- data/lib/mongoid/config/database.rb +186 -0
- data/lib/mongoid/config/replset_database.rb +82 -0
- data/lib/mongoid/connection_proxy.rb +30 -0
- data/lib/mongoid/contexts.rb +25 -0
- data/lib/mongoid/contexts/enumerable.rb +288 -0
- data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
- data/lib/mongoid/contexts/mongo.rb +409 -0
- data/lib/mongoid/copyable.rb +48 -0
- data/lib/mongoid/criteria.rb +418 -0
- data/lib/mongoid/criterion/builder.rb +34 -0
- data/lib/mongoid/criterion/complex.rb +84 -0
- data/lib/mongoid/criterion/creational.rb +34 -0
- data/lib/mongoid/criterion/exclusion.rb +108 -0
- data/lib/mongoid/criterion/inclusion.rb +305 -0
- data/lib/mongoid/criterion/inspection.rb +22 -0
- data/lib/mongoid/criterion/optional.rb +232 -0
- data/lib/mongoid/criterion/selector.rb +153 -0
- data/lib/mongoid/cursor.rb +86 -0
- data/lib/mongoid/database_proxy.rb +97 -0
- data/lib/mongoid/default_scope.rb +36 -0
- data/lib/mongoid/dirty.rb +110 -0
- data/lib/mongoid/document.rb +280 -0
- data/lib/mongoid/errors.rb +17 -0
- data/lib/mongoid/errors/callback.rb +26 -0
- data/lib/mongoid/errors/document_not_found.rb +28 -0
- data/lib/mongoid/errors/eager_load.rb +25 -0
- data/lib/mongoid/errors/invalid_collection.rb +18 -0
- data/lib/mongoid/errors/invalid_database.rb +19 -0
- data/lib/mongoid/errors/invalid_field.rb +18 -0
- data/lib/mongoid/errors/invalid_find.rb +19 -0
- data/lib/mongoid/errors/invalid_options.rb +28 -0
- data/lib/mongoid/errors/invalid_time.rb +25 -0
- data/lib/mongoid/errors/invalid_type.rb +25 -0
- data/lib/mongoid/errors/mixed_relations.rb +37 -0
- data/lib/mongoid/errors/mongoid_error.rb +26 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
- data/lib/mongoid/errors/unsaved_document.rb +23 -0
- data/lib/mongoid/errors/unsupported_version.rb +20 -0
- data/lib/mongoid/errors/validations.rb +23 -0
- data/lib/mongoid/extensions.rb +82 -0
- data/lib/mongoid/extensions/array/deletion.rb +29 -0
- data/lib/mongoid/extensions/false_class/equality.rb +26 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +45 -0
- data/lib/mongoid/extensions/hash/scoping.rb +25 -0
- data/lib/mongoid/extensions/integer/checks.rb +23 -0
- data/lib/mongoid/extensions/nil/collectionization.rb +23 -0
- data/lib/mongoid/extensions/object/checks.rb +29 -0
- data/lib/mongoid/extensions/object/reflections.rb +48 -0
- data/lib/mongoid/extensions/object/substitutable.rb +15 -0
- data/lib/mongoid/extensions/object/yoda.rb +44 -0
- data/lib/mongoid/extensions/object_id/conversions.rb +60 -0
- data/lib/mongoid/extensions/proc/scoping.rb +25 -0
- data/lib/mongoid/extensions/string/checks.rb +36 -0
- data/lib/mongoid/extensions/string/conversions.rb +22 -0
- data/lib/mongoid/extensions/string/inflections.rb +118 -0
- data/lib/mongoid/extensions/symbol/checks.rb +23 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +66 -0
- data/lib/mongoid/extensions/true_class/equality.rb +26 -0
- data/lib/mongoid/extras.rb +31 -0
- data/lib/mongoid/factory.rb +46 -0
- data/lib/mongoid/fields.rb +332 -0
- data/lib/mongoid/fields/mappings.rb +41 -0
- data/lib/mongoid/fields/serializable.rb +201 -0
- data/lib/mongoid/fields/serializable/array.rb +49 -0
- data/lib/mongoid/fields/serializable/big_decimal.rb +42 -0
- data/lib/mongoid/fields/serializable/bignum.rb +10 -0
- data/lib/mongoid/fields/serializable/binary.rb +11 -0
- data/lib/mongoid/fields/serializable/boolean.rb +43 -0
- data/lib/mongoid/fields/serializable/date.rb +51 -0
- data/lib/mongoid/fields/serializable/date_time.rb +28 -0
- data/lib/mongoid/fields/serializable/fixnum.rb +10 -0
- data/lib/mongoid/fields/serializable/float.rb +32 -0
- data/lib/mongoid/fields/serializable/foreign_keys/array.rb +42 -0
- data/lib/mongoid/fields/serializable/foreign_keys/object.rb +47 -0
- data/lib/mongoid/fields/serializable/hash.rb +11 -0
- data/lib/mongoid/fields/serializable/integer.rb +44 -0
- data/lib/mongoid/fields/serializable/localized.rb +41 -0
- data/lib/mongoid/fields/serializable/nil_class.rb +38 -0
- data/lib/mongoid/fields/serializable/object.rb +11 -0
- data/lib/mongoid/fields/serializable/object_id.rb +31 -0
- data/lib/mongoid/fields/serializable/range.rb +42 -0
- data/lib/mongoid/fields/serializable/set.rb +42 -0
- data/lib/mongoid/fields/serializable/string.rb +27 -0
- data/lib/mongoid/fields/serializable/symbol.rb +27 -0
- data/lib/mongoid/fields/serializable/time.rb +23 -0
- data/lib/mongoid/fields/serializable/time_with_zone.rb +23 -0
- data/lib/mongoid/fields/serializable/timekeeping.rb +106 -0
- data/lib/mongoid/finders.rb +152 -0
- data/lib/mongoid/hierarchy.rb +120 -0
- data/lib/mongoid/identity.rb +92 -0
- data/lib/mongoid/identity_map.rb +119 -0
- data/lib/mongoid/indexes.rb +54 -0
- data/lib/mongoid/inspection.rb +54 -0
- data/lib/mongoid/javascript.rb +20 -0
- data/lib/mongoid/javascript/functions.yml +63 -0
- data/lib/mongoid/json.rb +16 -0
- data/lib/mongoid/keys.rb +144 -0
- data/lib/mongoid/logger.rb +39 -0
- data/lib/mongoid/matchers.rb +32 -0
- data/lib/mongoid/matchers/all.rb +21 -0
- data/lib/mongoid/matchers/and.rb +30 -0
- data/lib/mongoid/matchers/default.rb +70 -0
- data/lib/mongoid/matchers/exists.rb +23 -0
- data/lib/mongoid/matchers/gt.rb +21 -0
- data/lib/mongoid/matchers/gte.rb +21 -0
- data/lib/mongoid/matchers/in.rb +21 -0
- data/lib/mongoid/matchers/lt.rb +21 -0
- data/lib/mongoid/matchers/lte.rb +21 -0
- data/lib/mongoid/matchers/ne.rb +21 -0
- data/lib/mongoid/matchers/nin.rb +21 -0
- data/lib/mongoid/matchers/or.rb +33 -0
- data/lib/mongoid/matchers/size.rb +21 -0
- data/lib/mongoid/matchers/strategies.rb +93 -0
- data/lib/mongoid/multi_database.rb +31 -0
- data/lib/mongoid/multi_parameter_attributes.rb +106 -0
- data/lib/mongoid/named_scope.rb +146 -0
- data/lib/mongoid/nested_attributes.rb +54 -0
- data/lib/mongoid/observer.rb +170 -0
- data/lib/mongoid/paranoia.rb +158 -0
- data/lib/mongoid/persistence.rb +264 -0
- data/lib/mongoid/persistence/atomic.rb +223 -0
- data/lib/mongoid/persistence/atomic/add_to_set.rb +35 -0
- data/lib/mongoid/persistence/atomic/bit.rb +37 -0
- data/lib/mongoid/persistence/atomic/inc.rb +31 -0
- data/lib/mongoid/persistence/atomic/operation.rb +85 -0
- data/lib/mongoid/persistence/atomic/pop.rb +34 -0
- data/lib/mongoid/persistence/atomic/pull.rb +34 -0
- data/lib/mongoid/persistence/atomic/pull_all.rb +34 -0
- data/lib/mongoid/persistence/atomic/push.rb +31 -0
- data/lib/mongoid/persistence/atomic/push_all.rb +31 -0
- data/lib/mongoid/persistence/atomic/rename.rb +31 -0
- data/lib/mongoid/persistence/atomic/sets.rb +30 -0
- data/lib/mongoid/persistence/atomic/unset.rb +28 -0
- data/lib/mongoid/persistence/deletion.rb +32 -0
- data/lib/mongoid/persistence/insertion.rb +41 -0
- data/lib/mongoid/persistence/modification.rb +37 -0
- data/lib/mongoid/persistence/operations.rb +211 -0
- data/lib/mongoid/persistence/operations/embedded/insert.rb +42 -0
- data/lib/mongoid/persistence/operations/embedded/remove.rb +40 -0
- data/lib/mongoid/persistence/operations/insert.rb +34 -0
- data/lib/mongoid/persistence/operations/remove.rb +33 -0
- data/lib/mongoid/persistence/operations/update.rb +64 -0
- data/lib/mongoid/railtie.rb +126 -0
- data/lib/mongoid/railties/database.rake +182 -0
- data/lib/mongoid/railties/document.rb +12 -0
- data/lib/mongoid/relations.rb +144 -0
- data/lib/mongoid/relations/accessors.rb +138 -0
- data/lib/mongoid/relations/auto_save.rb +38 -0
- data/lib/mongoid/relations/binding.rb +26 -0
- data/lib/mongoid/relations/bindings.rb +9 -0
- data/lib/mongoid/relations/bindings/embedded/in.rb +69 -0
- data/lib/mongoid/relations/bindings/embedded/many.rb +93 -0
- data/lib/mongoid/relations/bindings/embedded/one.rb +61 -0
- data/lib/mongoid/relations/bindings/referenced/in.rb +76 -0
- data/lib/mongoid/relations/bindings/referenced/many.rb +54 -0
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +51 -0
- data/lib/mongoid/relations/bindings/referenced/one.rb +58 -0
- data/lib/mongoid/relations/builder.rb +57 -0
- data/lib/mongoid/relations/builders.rb +83 -0
- data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
- data/lib/mongoid/relations/builders/embedded/many.rb +40 -0
- data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +110 -0
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -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 +38 -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 +19 -0
- data/lib/mongoid/relations/cascading/destroy.rb +26 -0
- data/lib/mongoid/relations/cascading/nullify.rb +18 -0
- data/lib/mongoid/relations/cascading/strategy.rb +26 -0
- data/lib/mongoid/relations/constraint.rb +42 -0
- data/lib/mongoid/relations/conversions.rb +35 -0
- data/lib/mongoid/relations/cyclic.rb +103 -0
- data/lib/mongoid/relations/embedded/atomic.rb +89 -0
- data/lib/mongoid/relations/embedded/atomic/operation.rb +63 -0
- data/lib/mongoid/relations/embedded/atomic/pull.rb +65 -0
- data/lib/mongoid/relations/embedded/atomic/push_all.rb +59 -0
- data/lib/mongoid/relations/embedded/atomic/set.rb +61 -0
- data/lib/mongoid/relations/embedded/atomic/unset.rb +41 -0
- data/lib/mongoid/relations/embedded/in.rb +220 -0
- data/lib/mongoid/relations/embedded/many.rb +560 -0
- data/lib/mongoid/relations/embedded/one.rb +206 -0
- data/lib/mongoid/relations/embedded/sort.rb +31 -0
- data/lib/mongoid/relations/macros.rb +310 -0
- data/lib/mongoid/relations/many.rb +135 -0
- data/lib/mongoid/relations/metadata.rb +919 -0
- data/lib/mongoid/relations/nested_builder.rb +75 -0
- data/lib/mongoid/relations/one.rb +36 -0
- data/lib/mongoid/relations/options.rb +47 -0
- data/lib/mongoid/relations/polymorphic.rb +40 -0
- data/lib/mongoid/relations/proxy.rb +145 -0
- data/lib/mongoid/relations/referenced/batch.rb +72 -0
- data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
- data/lib/mongoid/relations/referenced/in.rb +262 -0
- data/lib/mongoid/relations/referenced/many.rb +623 -0
- data/lib/mongoid/relations/referenced/many_to_many.rb +396 -0
- data/lib/mongoid/relations/referenced/one.rb +272 -0
- data/lib/mongoid/relations/reflections.rb +62 -0
- data/lib/mongoid/relations/synchronization.rb +153 -0
- data/lib/mongoid/relations/targets.rb +2 -0
- data/lib/mongoid/relations/targets/enumerable.rb +372 -0
- data/lib/mongoid/reloading.rb +91 -0
- data/lib/mongoid/safety.rb +105 -0
- data/lib/mongoid/scope.rb +31 -0
- data/lib/mongoid/serialization.rb +134 -0
- data/lib/mongoid/sharding.rb +61 -0
- data/lib/mongoid/state.rb +97 -0
- data/lib/mongoid/threaded.rb +530 -0
- data/lib/mongoid/threaded/lifecycle.rb +192 -0
- data/lib/mongoid/timestamps.rb +15 -0
- data/lib/mongoid/timestamps/created.rb +24 -0
- data/lib/mongoid/timestamps/timeless.rb +50 -0
- data/lib/mongoid/timestamps/updated.rb +26 -0
- data/lib/mongoid/validations.rb +140 -0
- data/lib/mongoid/validations/associated.rb +46 -0
- data/lib/mongoid/validations/uniqueness.rb +145 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/mongoid/versioning.rb +185 -0
- data/lib/rack/mongoid.rb +2 -0
- data/lib/rack/mongoid/middleware/identity_map.rb +38 -0
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +20 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +24 -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 +70 -0
- data/lib/rails/mongoid.rb +91 -0
- metadata +465 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Criterion #:nodoc:
|
4
|
+
module Inspection #:nodoc:
|
5
|
+
|
6
|
+
# Get a pretty string representation of the criteria, including the
|
7
|
+
# selector, options, matching count and documents for inspection.
|
8
|
+
#
|
9
|
+
# @example Inspect the criteria.
|
10
|
+
# criteria.inspect
|
11
|
+
#
|
12
|
+
# @return [ String ] The inspection string.
|
13
|
+
def inspect
|
14
|
+
"#<Mongoid::Criteria\n" <<
|
15
|
+
" selector: #{selector.inspect},\n" <<
|
16
|
+
" options: #{options.inspect},\n" <<
|
17
|
+
" class: #{klass},\n" <<
|
18
|
+
" embedded: #{embedded}>\n"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Criterion #:nodoc:
|
4
|
+
module Optional
|
5
|
+
|
6
|
+
# Adds fields to be sorted in ascending order. Will add them in the order
|
7
|
+
# they were passed into the method.
|
8
|
+
#
|
9
|
+
# @example Sort in ascending order.
|
10
|
+
# criteria.ascending(:title, :dob)
|
11
|
+
# criteria.asc(:title, :dob)
|
12
|
+
#
|
13
|
+
# @param [ Array<Symbol> ] fields The fields to sort on.
|
14
|
+
#
|
15
|
+
# @return [ Criteria ] The cloned criteria.
|
16
|
+
def ascending(*fields)
|
17
|
+
clone.tap do |crit|
|
18
|
+
crit.options[:sort] = [] unless options[:sort] || fields.first.nil?
|
19
|
+
fields.flatten.each { |field| merge_options(crit.options[:sort], [ field, :asc ]) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
alias :asc :ascending
|
23
|
+
|
24
|
+
# Tells the criteria that the cursor that gets returned needs to be
|
25
|
+
# cached. This is so multiple iterations don't hit the database multiple
|
26
|
+
# times, however this is not advisable when working with large data sets
|
27
|
+
# as the entire results will get stored in memory.
|
28
|
+
#
|
29
|
+
# @example Flag the criteria as cached.
|
30
|
+
# criteria.cache
|
31
|
+
#
|
32
|
+
# @return [ Criteria ] The cloned criteria.
|
33
|
+
def cache
|
34
|
+
clone.tap { |crit| crit.options.merge!(:cache => true) }
|
35
|
+
end
|
36
|
+
|
37
|
+
# Will return true if the cache option has been set.
|
38
|
+
#
|
39
|
+
# @example Is the criteria cached?
|
40
|
+
# criteria.cached?
|
41
|
+
#
|
42
|
+
# @return [ true, false ] If the criteria is flagged as cached.
|
43
|
+
def cached?
|
44
|
+
options[:cache] == true
|
45
|
+
end
|
46
|
+
|
47
|
+
# Adds fields to be sorted in descending order. Will add them in the order
|
48
|
+
# they were passed into the method.
|
49
|
+
#
|
50
|
+
# @example Sort the criteria in descending order.
|
51
|
+
# criteria.descending(:title, :dob)
|
52
|
+
# criteria.desc(:title, :dob)
|
53
|
+
#
|
54
|
+
# @param [ Array<Symbol> ] fields The fields to sort on.
|
55
|
+
#
|
56
|
+
# @return [ Criteria ] The cloned criteria.
|
57
|
+
def descending(*fields)
|
58
|
+
clone.tap do |crit|
|
59
|
+
crit.options[:sort] = [] unless options[:sort] || fields.first.nil?
|
60
|
+
fields.flatten.each { |field| merge_options(crit.options[:sort], [ field, :desc ]) }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
alias :desc :descending
|
64
|
+
|
65
|
+
# Adds a criterion to the +Criteria+ that specifies additional options
|
66
|
+
# to be passed to the Ruby driver, in the exact format for the driver.
|
67
|
+
#
|
68
|
+
# @example Add extra params to the criteria.
|
69
|
+
# criteria.extras(:limit => 20, :skip => 40)
|
70
|
+
#
|
71
|
+
# @param [ Hash ] extras The extra driver options.
|
72
|
+
#
|
73
|
+
# @return [ Criteria ] The cloned criteria.
|
74
|
+
def extras(extras)
|
75
|
+
clone.tap do |crit|
|
76
|
+
crit.options.merge!(extras)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Adds a criterion to the +Criteria+ that specifies an id that must be matched.
|
81
|
+
#
|
82
|
+
# @example Add a single id criteria.
|
83
|
+
# criteria.for_ids("4ab2bc4b8ad548971900005c")
|
84
|
+
#
|
85
|
+
# @example Add multiple id criteria.
|
86
|
+
# criteria.for_ids(["4ab2bc4b8ad548971900005c", "4c454e7ebf4b98032d000001"])
|
87
|
+
#
|
88
|
+
# @param [ Array ] ids: A single id or an array of ids.
|
89
|
+
#
|
90
|
+
# @return [ Criteria ] The cloned criteria.
|
91
|
+
def for_ids(*ids)
|
92
|
+
ids.flatten!
|
93
|
+
if ids.size > 1
|
94
|
+
where(:_id.in => ::BSON::ObjectId.convert(klass, ids))
|
95
|
+
else
|
96
|
+
where(:_id => ids.first)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Adds a criterion to the +Criteria+ that specifies the maximum number of
|
101
|
+
# results to return. This is mostly used in conjunction with skip()
|
102
|
+
# to handle paginated results.
|
103
|
+
#
|
104
|
+
# @example Limit the result set size.
|
105
|
+
# criteria.limit(100)
|
106
|
+
#
|
107
|
+
# @param [ Integer ] value The max number of results.
|
108
|
+
#
|
109
|
+
# @return [ Criteria ] The cloned criteria.
|
110
|
+
def limit(value = 20)
|
111
|
+
clone.tap { |crit| crit.options[:limit] = value }
|
112
|
+
end
|
113
|
+
|
114
|
+
# Returns the offset option. If a per_page option is in the list then it
|
115
|
+
# will replace it with a skip parameter and return the same value. Defaults
|
116
|
+
# to 20 if nothing was provided.
|
117
|
+
#
|
118
|
+
# @example Get the offset.
|
119
|
+
# criteria.offset(10)
|
120
|
+
#
|
121
|
+
# @return [ Integer ] The number of documents to skip.
|
122
|
+
def offset(*args)
|
123
|
+
args.size > 0 ? skip(args.first) : options[:skip]
|
124
|
+
end
|
125
|
+
|
126
|
+
# Adds a criterion to the +Criteria+ that specifies the sort order of
|
127
|
+
# the returned documents in the database. Similar to a SQL "ORDER BY".
|
128
|
+
#
|
129
|
+
# @example Order by specific fields.
|
130
|
+
# criteria.order_by([[:field1, :asc], [:field2, :desc]])
|
131
|
+
#
|
132
|
+
# @param [ Array ] params: An +Array+ of [field, direction] sorting pairs.
|
133
|
+
#
|
134
|
+
# @return [ Criteria ] The cloned criteria.
|
135
|
+
def order_by(*args)
|
136
|
+
clone.tap do |crit|
|
137
|
+
arguments = args.size == 1 ? args.first : args
|
138
|
+
crit.options[:sort] = [] unless options[:sort] || args.first.nil?
|
139
|
+
if arguments.is_a?(Array)
|
140
|
+
#[:name, :asc]
|
141
|
+
if arguments.size == 2 && (arguments.first.is_a?(Symbol) || arguments.first.is_a?(String))
|
142
|
+
build_order_options(arguments, crit)
|
143
|
+
else
|
144
|
+
arguments.each { |argument| build_order_options(argument, crit) }
|
145
|
+
end
|
146
|
+
else
|
147
|
+
build_order_options(arguments, crit)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
alias :order :order_by
|
152
|
+
|
153
|
+
# Adds a criterion to the +Criteria+ that specifies how many results to skip
|
154
|
+
# when returning Documents. This is mostly used in conjunction with
|
155
|
+
# limit() to handle paginated results, and is similar to the
|
156
|
+
# traditional "offset" parameter.
|
157
|
+
#
|
158
|
+
# @example Skip a specified number of documents.
|
159
|
+
# criteria.skip(20)
|
160
|
+
#
|
161
|
+
# @param [ Integer ] value The number of results to skip.
|
162
|
+
#
|
163
|
+
# @return [ Criteria ] The cloned criteria.
|
164
|
+
def skip(value = 0)
|
165
|
+
clone.tap { |crit| crit.options[:skip] = value }
|
166
|
+
end
|
167
|
+
|
168
|
+
# Adds a criterion to the +Criteria+ that specifies a type or an Array of
|
169
|
+
# types that must be matched.
|
170
|
+
#
|
171
|
+
# @example Match only specific models.
|
172
|
+
# criteria.type('Browser')
|
173
|
+
# criteria.type(['Firefox', 'Browser'])
|
174
|
+
#
|
175
|
+
# @param [ Array<String> ] types The types to match against.
|
176
|
+
#
|
177
|
+
# @return [ Criteria ] The cloned criteria.
|
178
|
+
def type(types)
|
179
|
+
types = [types] unless types.is_a?(Array)
|
180
|
+
any_in(:_type => types)
|
181
|
+
end
|
182
|
+
|
183
|
+
private
|
184
|
+
|
185
|
+
# Build ordering options from given arguments on given criteria
|
186
|
+
#
|
187
|
+
# @example build order options
|
188
|
+
# criteria.build_order_options(:name.asc, criteria)
|
189
|
+
#
|
190
|
+
#
|
191
|
+
# @param [ <Hash>, <Array>, <Complex> ] argument to build criteria from
|
192
|
+
# @param [ Criterion ] criterion to change
|
193
|
+
def build_order_options(arguments, crit)
|
194
|
+
case arguments
|
195
|
+
when Hash
|
196
|
+
if arguments.size > 1
|
197
|
+
raise ArgumentError, "Please don't use hash to define multiple orders " +
|
198
|
+
"due to the fact that hash doesn't have order this may cause unpredictable results"
|
199
|
+
end
|
200
|
+
arguments.each_pair do |field, direction|
|
201
|
+
merge_options(crit.options[:sort], [ field, direction ])
|
202
|
+
end
|
203
|
+
when Array
|
204
|
+
merge_options(crit.options[:sort],arguments)
|
205
|
+
when Complex
|
206
|
+
merge_options(crit.options[:sort], [ arguments.key, arguments.operator.to_sym ])
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# Merge options for order_by criterion
|
211
|
+
# Allow only one order direction for same field
|
212
|
+
#
|
213
|
+
# @example Merge ordering options
|
214
|
+
# criteria.merge_options([[:title, :asc], [:created_at, :asc]], [:title, :desc])
|
215
|
+
#
|
216
|
+
#
|
217
|
+
# @param [ Array<Array> ] Existing options
|
218
|
+
# @param [ Array ] New option for merge.
|
219
|
+
#
|
220
|
+
# @since 2.1.0
|
221
|
+
def merge_options(options, new_option)
|
222
|
+
old_option = options.assoc(new_option.first)
|
223
|
+
|
224
|
+
if old_option
|
225
|
+
options[options.index(old_option)] = new_option.flatten
|
226
|
+
else
|
227
|
+
options << new_option.flatten
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Criterion #:nodoc:
|
4
|
+
|
5
|
+
# The selector is a hash-like object that has special behaviour for merging
|
6
|
+
# mongoid criteria selectors.
|
7
|
+
class Selector < Hash
|
8
|
+
|
9
|
+
attr_reader :fields, :klass
|
10
|
+
|
11
|
+
# Create the new selector.
|
12
|
+
#
|
13
|
+
# @example Create the selector.
|
14
|
+
# Selector.new(Person)
|
15
|
+
#
|
16
|
+
# @param [ Class ] klass The class the selector is for.
|
17
|
+
#
|
18
|
+
# @since 1.0.0
|
19
|
+
def initialize(klass)
|
20
|
+
@fields, @klass = klass.fields.except("_id", "_type"), klass
|
21
|
+
end
|
22
|
+
|
23
|
+
# Set the value for the supplied key, attempting to typecast the value.
|
24
|
+
#
|
25
|
+
# @example Set the value for the key.
|
26
|
+
# selector["$ne"] = { :name => "Zorg" }
|
27
|
+
#
|
28
|
+
# @param [ String, Symbol ] key The hash key.
|
29
|
+
# @param [ Object ] value The value to set.
|
30
|
+
#
|
31
|
+
# @since 2.0.0
|
32
|
+
def []=(key, value)
|
33
|
+
key = "#{key}.#{::I18n.locale}" if klass.fields[key.to_s].try(:localized?)
|
34
|
+
super(key, try_to_typecast(key, value))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Merge the selector with another hash.
|
38
|
+
#
|
39
|
+
# @example Merge the objects.
|
40
|
+
# selector.merge!({ :key => "value" })
|
41
|
+
#
|
42
|
+
# @param [ Hash, Selector ] other The object to merge with.
|
43
|
+
#
|
44
|
+
# @return [ Selector ] The merged selector.
|
45
|
+
#
|
46
|
+
# @since 1.0.0
|
47
|
+
def merge!(other)
|
48
|
+
tap do |selector|
|
49
|
+
other.each_pair do |key, value|
|
50
|
+
selector[key] = value
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
alias :update :merge!
|
55
|
+
|
56
|
+
if RUBY_VERSION < '1.9'
|
57
|
+
|
58
|
+
# Generate pretty inspection for old ruby versions.
|
59
|
+
#
|
60
|
+
# @example Inspect the selector.
|
61
|
+
# selector.inspect
|
62
|
+
#
|
63
|
+
# @return [ String ] The inspected selector.
|
64
|
+
def inspect
|
65
|
+
ret = self.keys.inject([]) do |ret, key|
|
66
|
+
ret << "#{key.inspect}=>#{self[key].inspect}"
|
67
|
+
end
|
68
|
+
"{#{ret.sort.join(', ')}}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# If the key is defined as a field, then attempt to typecast it.
|
75
|
+
#
|
76
|
+
# @example Try to cast.
|
77
|
+
# selector.try_to_typecast(:id, 1)
|
78
|
+
#
|
79
|
+
# @param [ String, Symbol ] key The field name.
|
80
|
+
# @param [ Object ] value The value.
|
81
|
+
#
|
82
|
+
# @return [ Object ] The typecasted value.
|
83
|
+
#
|
84
|
+
# @since 1.0.0
|
85
|
+
def try_to_typecast(key, value)
|
86
|
+
access = key.to_s
|
87
|
+
return value unless fields.has_key?(access)
|
88
|
+
field = fields[access]
|
89
|
+
typecast_value_for(field, value)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Get the typecast value for the defined field.
|
93
|
+
#
|
94
|
+
# @example Get the typecast value.
|
95
|
+
# selector.typecast_value_for(:name, "Corbin")
|
96
|
+
#
|
97
|
+
# @param [ Field ] field The defined field.
|
98
|
+
# @param [ Object ] value The value to cast.
|
99
|
+
#
|
100
|
+
# @return [ Object ] The cast value.
|
101
|
+
#
|
102
|
+
# @since 1.0.0
|
103
|
+
def typecast_value_for(field, value)
|
104
|
+
return field.serialize(value) if field.type === value
|
105
|
+
case value
|
106
|
+
when Hash
|
107
|
+
value = value.dup
|
108
|
+
value.each_pair do |k, v|
|
109
|
+
value[k] = typecast_hash_value(field, k, v)
|
110
|
+
end
|
111
|
+
when Array
|
112
|
+
value.map { |v| typecast_value_for(field, v) }
|
113
|
+
when Regexp
|
114
|
+
value
|
115
|
+
when Range
|
116
|
+
{
|
117
|
+
"$gte" => typecast_value_for(field, value.first),
|
118
|
+
"$lte" => typecast_value_for(field, value.last)
|
119
|
+
}
|
120
|
+
else
|
121
|
+
if field.type == Array
|
122
|
+
Serialization.mongoize(value, value.class)
|
123
|
+
else
|
124
|
+
field.serialize(value)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Typecast the value for booleans and integers in hashes.
|
130
|
+
#
|
131
|
+
# @example Typecast the hash values.
|
132
|
+
# selector.typecast_hash_value(field, "$exists", "true")
|
133
|
+
#
|
134
|
+
# @param [ Field ] field The defined field.
|
135
|
+
# @param [ String ] key The modifier key.
|
136
|
+
# @param [ Object ] value The value to cast.
|
137
|
+
#
|
138
|
+
# @return [ Object ] The cast value.
|
139
|
+
#
|
140
|
+
# @since 1.0.0
|
141
|
+
def typecast_hash_value(field, key, value)
|
142
|
+
case key
|
143
|
+
when "$exists"
|
144
|
+
Serialization.mongoize(value, Boolean)
|
145
|
+
when "$size"
|
146
|
+
Serialization.mongoize(value, Integer)
|
147
|
+
else
|
148
|
+
typecast_value_for(field, value)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc
|
3
|
+
|
4
|
+
# Mongoid wrapper of the Ruby Driver cursor.
|
5
|
+
class Cursor
|
6
|
+
include Mongoid::Collections::Retry
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
# Operations on the Mongo::Cursor object that will not get overriden by the
|
10
|
+
# Mongoid::Cursor are defined here.
|
11
|
+
OPERATIONS = [
|
12
|
+
:close,
|
13
|
+
:closed?,
|
14
|
+
:count,
|
15
|
+
:explain,
|
16
|
+
:fields,
|
17
|
+
:full_collection_name,
|
18
|
+
:hint,
|
19
|
+
:limit,
|
20
|
+
:order,
|
21
|
+
:query_options_hash,
|
22
|
+
:query_opts,
|
23
|
+
:selector,
|
24
|
+
:skip,
|
25
|
+
:snapshot,
|
26
|
+
:sort,
|
27
|
+
:timeout
|
28
|
+
]
|
29
|
+
|
30
|
+
attr_reader :collection, :cursor, :klass
|
31
|
+
|
32
|
+
# The operations above will all delegate to the proxied Mongo::Cursor.
|
33
|
+
OPERATIONS.each do |name|
|
34
|
+
class_eval <<-EOS, __FILE__, __LINE__
|
35
|
+
def #{name}(*args)
|
36
|
+
retry_on_connection_failure do
|
37
|
+
cursor.#{name}(*args)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
EOS
|
41
|
+
end
|
42
|
+
|
43
|
+
# Iterate over each document in the cursor and yield to it.
|
44
|
+
#
|
45
|
+
# @example Iterate over the cursor.
|
46
|
+
# cursor.each { |doc| p doc.title }
|
47
|
+
def each
|
48
|
+
cursor.each do |document|
|
49
|
+
yield Mongoid::Factory.from_db(klass, document)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Create the new +Mongoid::Cursor+.
|
54
|
+
#
|
55
|
+
# @example Instantiate the cursor.
|
56
|
+
# Mongoid::Cursor.new(Person, cursor)
|
57
|
+
#
|
58
|
+
# @param [ Class ] klass The class associated with the cursor.
|
59
|
+
# @param [ Collection ] collection The Mongoid::Collection instance.
|
60
|
+
# @param [ Mongo::Cursor ] cursor The Mongo::Cursor to be proxied.
|
61
|
+
def initialize(klass, collection, cursor)
|
62
|
+
@klass, @collection, @cursor = klass, collection, cursor
|
63
|
+
end
|
64
|
+
|
65
|
+
# Return the next document in the cursor. Will instantiate a new Mongoid
|
66
|
+
# document with the attributes.
|
67
|
+
#
|
68
|
+
# @example Get the next document.
|
69
|
+
# cursor.next_document
|
70
|
+
#
|
71
|
+
# @return [ Document ] The next document in the cursor.
|
72
|
+
def next_document
|
73
|
+
Mongoid::Factory.from_db(klass, cursor.next_document)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns an array of all the documents in the cursor.
|
77
|
+
#
|
78
|
+
# @example Get the cursor as an array.
|
79
|
+
# cursor.to_a
|
80
|
+
#
|
81
|
+
# @return [ Array<Document> ] An array of documents.
|
82
|
+
def to_a
|
83
|
+
cursor.to_a.collect { |attrs| Mongoid::Factory.from_db(klass, attrs) }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|