mongoid-braxton 2.0.2
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.
- data/LICENSE +20 -0
- data/README.rdoc +50 -0
- data/Rakefile +51 -0
- data/lib/config/locales/bg.yml +41 -0
- data/lib/config/locales/de.yml +41 -0
- data/lib/config/locales/en.yml +45 -0
- data/lib/config/locales/es.yml +41 -0
- data/lib/config/locales/fr.yml +42 -0
- data/lib/config/locales/hu.yml +44 -0
- data/lib/config/locales/id.yml +46 -0
- data/lib/config/locales/it.yml +39 -0
- data/lib/config/locales/ja.yml +40 -0
- data/lib/config/locales/kr.yml +65 -0
- data/lib/config/locales/nl.yml +39 -0
- data/lib/config/locales/pl.yml +39 -0
- data/lib/config/locales/pt-BR.yml +40 -0
- data/lib/config/locales/pt.yml +40 -0
- data/lib/config/locales/ro.yml +46 -0
- data/lib/config/locales/ru.yml +41 -0
- data/lib/config/locales/sv.yml +40 -0
- data/lib/config/locales/vi.yml +45 -0
- data/lib/config/locales/zh-CN.yml +33 -0
- data/lib/mongoid.rb +140 -0
- data/lib/mongoid/atomicity.rb +111 -0
- data/lib/mongoid/attributes.rb +185 -0
- data/lib/mongoid/attributes/processing.rb +145 -0
- data/lib/mongoid/callbacks.rb +23 -0
- data/lib/mongoid/collection.rb +137 -0
- data/lib/mongoid/collections.rb +71 -0
- data/lib/mongoid/collections/master.rb +37 -0
- data/lib/mongoid/collections/operations.rb +42 -0
- data/lib/mongoid/collections/retry.rb +39 -0
- data/lib/mongoid/components.rb +45 -0
- data/lib/mongoid/config.rb +349 -0
- data/lib/mongoid/config/database.rb +167 -0
- data/lib/mongoid/config/replset_database.rb +78 -0
- data/lib/mongoid/contexts.rb +19 -0
- data/lib/mongoid/contexts/enumerable.rb +275 -0
- data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
- data/lib/mongoid/contexts/mongo.rb +345 -0
- data/lib/mongoid/copyable.rb +46 -0
- data/lib/mongoid/criteria.rb +357 -0
- data/lib/mongoid/criterion/builder.rb +34 -0
- data/lib/mongoid/criterion/complex.rb +34 -0
- data/lib/mongoid/criterion/creational.rb +34 -0
- data/lib/mongoid/criterion/exclusion.rb +108 -0
- data/lib/mongoid/criterion/inclusion.rb +198 -0
- data/lib/mongoid/criterion/inspection.rb +22 -0
- data/lib/mongoid/criterion/optional.rb +193 -0
- data/lib/mongoid/criterion/selector.rb +143 -0
- data/lib/mongoid/criterion/unconvertable.rb +20 -0
- data/lib/mongoid/cursor.rb +86 -0
- data/lib/mongoid/default_scope.rb +36 -0
- data/lib/mongoid/dirty.rb +253 -0
- data/lib/mongoid/document.rb +284 -0
- data/lib/mongoid/errors.rb +13 -0
- data/lib/mongoid/errors/document_not_found.rb +29 -0
- data/lib/mongoid/errors/invalid_collection.rb +19 -0
- data/lib/mongoid/errors/invalid_database.rb +20 -0
- data/lib/mongoid/errors/invalid_field.rb +19 -0
- data/lib/mongoid/errors/invalid_options.rb +16 -0
- data/lib/mongoid/errors/invalid_type.rb +26 -0
- data/lib/mongoid/errors/mixed_relations.rb +37 -0
- data/lib/mongoid/errors/mongoid_error.rb +27 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +21 -0
- data/lib/mongoid/errors/unsaved_document.rb +23 -0
- data/lib/mongoid/errors/unsupported_version.rb +21 -0
- data/lib/mongoid/errors/validations.rb +24 -0
- data/lib/mongoid/extensions.rb +123 -0
- data/lib/mongoid/extensions/array/conversions.rb +23 -0
- data/lib/mongoid/extensions/array/parentization.rb +13 -0
- data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
- data/lib/mongoid/extensions/binary/conversions.rb +17 -0
- data/lib/mongoid/extensions/boolean/conversions.rb +27 -0
- data/lib/mongoid/extensions/date/conversions.rb +25 -0
- data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
- data/lib/mongoid/extensions/false_class/equality.rb +13 -0
- data/lib/mongoid/extensions/float/conversions.rb +20 -0
- data/lib/mongoid/extensions/hash/conversions.rb +19 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +22 -0
- data/lib/mongoid/extensions/hash/scoping.rb +12 -0
- data/lib/mongoid/extensions/integer/conversions.rb +20 -0
- data/lib/mongoid/extensions/nil/collectionization.rb +12 -0
- data/lib/mongoid/extensions/object/checks.rb +32 -0
- data/lib/mongoid/extensions/object/conversions.rb +25 -0
- data/lib/mongoid/extensions/object/reflections.rb +17 -0
- data/lib/mongoid/extensions/object/yoda.rb +27 -0
- data/lib/mongoid/extensions/object_id/conversions.rb +96 -0
- data/lib/mongoid/extensions/proc/scoping.rb +12 -0
- data/lib/mongoid/extensions/range/conversions.rb +25 -0
- data/lib/mongoid/extensions/set/conversions.rb +20 -0
- data/lib/mongoid/extensions/string/conversions.rb +34 -0
- data/lib/mongoid/extensions/string/inflections.rb +97 -0
- data/lib/mongoid/extensions/symbol/conversions.rb +21 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
- data/lib/mongoid/extensions/time_conversions.rb +38 -0
- data/lib/mongoid/extensions/true_class/equality.rb +13 -0
- data/lib/mongoid/extras.rb +42 -0
- data/lib/mongoid/factory.rb +37 -0
- data/lib/mongoid/field.rb +162 -0
- data/lib/mongoid/fields.rb +183 -0
- data/lib/mongoid/finders.rb +127 -0
- data/lib/mongoid/hierarchy.rb +85 -0
- data/lib/mongoid/identity.rb +92 -0
- data/lib/mongoid/indexes.rb +38 -0
- data/lib/mongoid/inspection.rb +54 -0
- data/lib/mongoid/javascript.rb +21 -0
- data/lib/mongoid/javascript/functions.yml +37 -0
- data/lib/mongoid/json.rb +16 -0
- data/lib/mongoid/keys.rb +131 -0
- data/lib/mongoid/logger.rb +18 -0
- data/lib/mongoid/matchers.rb +32 -0
- data/lib/mongoid/matchers/all.rb +11 -0
- data/lib/mongoid/matchers/default.rb +70 -0
- data/lib/mongoid/matchers/exists.rb +13 -0
- data/lib/mongoid/matchers/gt.rb +11 -0
- data/lib/mongoid/matchers/gte.rb +11 -0
- data/lib/mongoid/matchers/in.rb +11 -0
- data/lib/mongoid/matchers/lt.rb +11 -0
- data/lib/mongoid/matchers/lte.rb +11 -0
- data/lib/mongoid/matchers/ne.rb +11 -0
- data/lib/mongoid/matchers/nin.rb +11 -0
- data/lib/mongoid/matchers/or.rb +30 -0
- data/lib/mongoid/matchers/size.rb +11 -0
- data/lib/mongoid/matchers/strategies.rb +63 -0
- data/lib/mongoid/multi_database.rb +11 -0
- data/lib/mongoid/multi_parameter_attributes.rb +82 -0
- data/lib/mongoid/named_scope.rb +137 -0
- data/lib/mongoid/nested_attributes.rb +51 -0
- data/lib/mongoid/observer.rb +67 -0
- data/lib/mongoid/paranoia.rb +103 -0
- data/lib/mongoid/paths.rb +61 -0
- data/lib/mongoid/persistence.rb +240 -0
- data/lib/mongoid/persistence/atomic.rb +88 -0
- data/lib/mongoid/persistence/atomic/add_to_set.rb +32 -0
- data/lib/mongoid/persistence/atomic/inc.rb +28 -0
- data/lib/mongoid/persistence/atomic/operation.rb +44 -0
- data/lib/mongoid/persistence/atomic/pull_all.rb +33 -0
- data/lib/mongoid/persistence/atomic/push.rb +28 -0
- data/lib/mongoid/persistence/command.rb +71 -0
- data/lib/mongoid/persistence/insert.rb +53 -0
- data/lib/mongoid/persistence/insert_embedded.rb +43 -0
- data/lib/mongoid/persistence/remove.rb +44 -0
- data/lib/mongoid/persistence/remove_all.rb +40 -0
- data/lib/mongoid/persistence/remove_embedded.rb +48 -0
- data/lib/mongoid/persistence/update.rb +77 -0
- data/lib/mongoid/railtie.rb +139 -0
- data/lib/mongoid/railties/database.rake +171 -0
- data/lib/mongoid/railties/document.rb +12 -0
- data/lib/mongoid/relations.rb +107 -0
- data/lib/mongoid/relations/accessors.rb +175 -0
- data/lib/mongoid/relations/auto_save.rb +34 -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 +82 -0
- data/lib/mongoid/relations/bindings/embedded/many.rb +98 -0
- data/lib/mongoid/relations/bindings/embedded/one.rb +66 -0
- data/lib/mongoid/relations/bindings/referenced/in.rb +74 -0
- data/lib/mongoid/relations/bindings/referenced/many.rb +96 -0
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +103 -0
- data/lib/mongoid/relations/bindings/referenced/one.rb +66 -0
- data/lib/mongoid/relations/builder.rb +42 -0
- data/lib/mongoid/relations/builders.rb +79 -0
- data/lib/mongoid/relations/builders/embedded/in.rb +25 -0
- data/lib/mongoid/relations/builders/embedded/many.rb +32 -0
- data/lib/mongoid/relations/builders/embedded/one.rb +26 -0
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +126 -0
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
- data/lib/mongoid/relations/builders/referenced/in.rb +29 -0
- data/lib/mongoid/relations/builders/referenced/many.rb +47 -0
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
- data/lib/mongoid/relations/builders/referenced/one.rb +27 -0
- data/lib/mongoid/relations/cascading.rb +55 -0
- data/lib/mongoid/relations/cascading/delete.rb +19 -0
- data/lib/mongoid/relations/cascading/destroy.rb +19 -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/cyclic.rb +103 -0
- data/lib/mongoid/relations/embedded/atomic.rb +86 -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 +173 -0
- data/lib/mongoid/relations/embedded/many.rb +499 -0
- data/lib/mongoid/relations/embedded/one.rb +170 -0
- data/lib/mongoid/relations/macros.rb +310 -0
- data/lib/mongoid/relations/many.rb +215 -0
- data/lib/mongoid/relations/metadata.rb +539 -0
- data/lib/mongoid/relations/nested_builder.rb +68 -0
- data/lib/mongoid/relations/one.rb +47 -0
- data/lib/mongoid/relations/polymorphic.rb +54 -0
- data/lib/mongoid/relations/proxy.rb +143 -0
- data/lib/mongoid/relations/referenced/batch.rb +71 -0
- data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
- data/lib/mongoid/relations/referenced/in.rb +216 -0
- data/lib/mongoid/relations/referenced/many.rb +516 -0
- data/lib/mongoid/relations/referenced/many_to_many.rb +396 -0
- data/lib/mongoid/relations/referenced/one.rb +222 -0
- data/lib/mongoid/relations/reflections.rb +45 -0
- data/lib/mongoid/safe.rb +23 -0
- data/lib/mongoid/safety.rb +207 -0
- data/lib/mongoid/scope.rb +31 -0
- data/lib/mongoid/serialization.rb +99 -0
- data/lib/mongoid/sharding.rb +51 -0
- data/lib/mongoid/state.rb +67 -0
- data/lib/mongoid/timestamps.rb +14 -0
- data/lib/mongoid/timestamps/created.rb +31 -0
- data/lib/mongoid/timestamps/updated.rb +33 -0
- data/lib/mongoid/validations.rb +124 -0
- data/lib/mongoid/validations/associated.rb +44 -0
- data/lib/mongoid/validations/referenced.rb +58 -0
- data/lib/mongoid/validations/uniqueness.rb +85 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/mongoid/versioning.rb +113 -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 +19 -0
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
- data/lib/rails/generators/mongoid/observer/templates/observer.rb +4 -0
- data/lib/rails/generators/mongoid_generator.rb +70 -0
- data/lib/rails/mongoid.rb +58 -0
- metadata +406 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Criterion #:nodoc:
|
|
4
|
+
|
|
5
|
+
# This module defines criteria behavior for creating documents in the
|
|
6
|
+
# database for specified conditions.
|
|
7
|
+
module Creational
|
|
8
|
+
|
|
9
|
+
# Create a document in the database given the selector and return it.
|
|
10
|
+
# Complex criteria, such as $in and $or operations will get ignored.
|
|
11
|
+
#
|
|
12
|
+
# @example Create the document.
|
|
13
|
+
# Person.where(:title => "Sir").create
|
|
14
|
+
#
|
|
15
|
+
# @example Create with selectors getting ignored.
|
|
16
|
+
# Person.where(:age.gt => 5).create
|
|
17
|
+
#
|
|
18
|
+
# @return [ Document ] A newly created document.
|
|
19
|
+
#
|
|
20
|
+
# @since 2.0.0.rc.1
|
|
21
|
+
def create(attrs = {})
|
|
22
|
+
klass.create(
|
|
23
|
+
selector.inject(attrs) do |hash, (key, value)|
|
|
24
|
+
hash.tap do |attrs|
|
|
25
|
+
unless key.to_s =~ /\$/ || value.is_a?(Hash)
|
|
26
|
+
attrs[key] = value
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Criterion #:nodoc:
|
|
4
|
+
|
|
5
|
+
# This module contains criteria behaviour for exclusion of values.
|
|
6
|
+
module Exclusion
|
|
7
|
+
|
|
8
|
+
# Adds a criterion to the +Criteria+ that specifies values that are not
|
|
9
|
+
# allowed to match any document in the database. The MongoDB
|
|
10
|
+
# conditional operator that will be used is "$ne".
|
|
11
|
+
#
|
|
12
|
+
# @example Match documents without these values.
|
|
13
|
+
# criteria.excludes(:field => "value1")
|
|
14
|
+
# criteria.excludes(:field1 => "value1", :field2 => "value1")
|
|
15
|
+
#
|
|
16
|
+
# @param [ Hash ] attributes: A +Hash+ where the key is the field
|
|
17
|
+
# name and the value is a value that must not be equal to the
|
|
18
|
+
# corresponding field value in the database.
|
|
19
|
+
#
|
|
20
|
+
# @return [ Criteria ] A newly cloned copy.
|
|
21
|
+
def excludes(attributes = {})
|
|
22
|
+
mongo_id = attributes.delete(:id)
|
|
23
|
+
attributes = attributes.merge(:_id => mongo_id) if mongo_id
|
|
24
|
+
update_selector(attributes, "$ne")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Used when wanting to set the fields options directly using a hash
|
|
28
|
+
# instead of going through only or without.
|
|
29
|
+
#
|
|
30
|
+
# @example Set the limited fields.
|
|
31
|
+
# criteria.fields(:field => 1)
|
|
32
|
+
#
|
|
33
|
+
# @param [ Hash ] attributes The field options.
|
|
34
|
+
#
|
|
35
|
+
# @return [ Criteria ] A newly cloned copy.
|
|
36
|
+
#
|
|
37
|
+
# @since 2.0.2
|
|
38
|
+
def fields(attributes = nil)
|
|
39
|
+
clone.tap { |crit| crit.options[:fields] = attributes || {} }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Adds a criterion to the +Criteria+ that specifies values where none
|
|
43
|
+
# should match in order to return results. This is similar to an SQL
|
|
44
|
+
# "NOT IN" clause. The MongoDB conditional operator that will be
|
|
45
|
+
# used is "$nin".
|
|
46
|
+
#
|
|
47
|
+
# @example Match documents with values not in the provided.
|
|
48
|
+
# criteria.not_in(:field => ["value1", "value2"])
|
|
49
|
+
# criteria.not_in(:field1 => ["value1", "value2"], :field2 => ["value1"])
|
|
50
|
+
#
|
|
51
|
+
# @param [ Hash ] attributes A +Hash+ where the key is the field name
|
|
52
|
+
# and the value is an +Array+ of values that none can match.
|
|
53
|
+
#
|
|
54
|
+
# @return [ Criteria ] A newly cloned copy.
|
|
55
|
+
def not_in(attributes)
|
|
56
|
+
update_selector(attributes, "$nin")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Adds a criterion to the +Criteria+ that specifies the fields that will
|
|
60
|
+
# get returned from the Document. Used mainly for list views that do not
|
|
61
|
+
# require all fields to be present. This is similar to SQL "SELECT" values.
|
|
62
|
+
#
|
|
63
|
+
# @example Limit the fields to only the specified.
|
|
64
|
+
# criteria.only(:field1, :field2, :field3)
|
|
65
|
+
#
|
|
66
|
+
# @note #only and #without cannot be used together.
|
|
67
|
+
#
|
|
68
|
+
# @param [ Array<Symbol> ] args A list of field names to limit to.
|
|
69
|
+
#
|
|
70
|
+
# @return [ Criteria ] A newly cloned copy.
|
|
71
|
+
def only(*args)
|
|
72
|
+
clone.tap do |crit|
|
|
73
|
+
if args.any?
|
|
74
|
+
crit.options[:fields] = {:_type => 1}
|
|
75
|
+
crit.field_list = args.flatten
|
|
76
|
+
crit.field_list.each do |f|
|
|
77
|
+
crit.options[:fields][f] = 1
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Adds a criterion to the +Criteria+ that specifies the fields that will
|
|
84
|
+
# not get returned by the document.
|
|
85
|
+
#
|
|
86
|
+
# @example Filter out specific fields.
|
|
87
|
+
# criteria.without(:field2, :field2)
|
|
88
|
+
#
|
|
89
|
+
# @note #only and #without cannot be used together.
|
|
90
|
+
#
|
|
91
|
+
# @param [ Array<Symbol> args A list of fields to exclude.
|
|
92
|
+
#
|
|
93
|
+
# @return [ Criteria ] A newly cloned copy.
|
|
94
|
+
#
|
|
95
|
+
# @since 2.0.0
|
|
96
|
+
def without(*args)
|
|
97
|
+
clone.tap do |crit|
|
|
98
|
+
if args.any?
|
|
99
|
+
crit.options[:fields] = {}
|
|
100
|
+
args.flatten.each do |f|
|
|
101
|
+
crit.options[:fields][f] = 0
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Criterion #:nodoc:
|
|
4
|
+
module Inclusion
|
|
5
|
+
|
|
6
|
+
# Adds a criterion to the +Criteria+ that specifies values that must all
|
|
7
|
+
# be matched in order to return results. Similar to an "in" clause but the
|
|
8
|
+
# underlying conditional logic is an "AND" and not an "OR". The MongoDB
|
|
9
|
+
# conditional operator that will be used is "$all".
|
|
10
|
+
#
|
|
11
|
+
# @example Adding the criterion.
|
|
12
|
+
# criteria.all(:field => ["value1", "value2"])
|
|
13
|
+
# criteria.all(:field1 => ["value1", "value2"], :field2 => ["value1"])
|
|
14
|
+
#
|
|
15
|
+
# @param [ Hash ] attributes Name/value pairs that all must match.
|
|
16
|
+
#
|
|
17
|
+
# @return [ Criteria ] A new criteria with the added selector.
|
|
18
|
+
def all(attributes = {})
|
|
19
|
+
update_selector(attributes, "$all")
|
|
20
|
+
end
|
|
21
|
+
alias :all_in :all
|
|
22
|
+
|
|
23
|
+
# Adds a criterion to the +Criteria+ that specifies values where any can
|
|
24
|
+
# be matched in order to return results. This is similar to an SQL "IN"
|
|
25
|
+
# clause. The MongoDB conditional operator that will be used is "$in".
|
|
26
|
+
# Any previously matching "$in" arrays will be unioned with new
|
|
27
|
+
# arguments.
|
|
28
|
+
#
|
|
29
|
+
# @example Adding the criterion.
|
|
30
|
+
# criteria.in(:field => ["value1"]).also_in(:field => ["value2"])
|
|
31
|
+
#
|
|
32
|
+
# @param [ Hash ] attributes Name/value pairs any can match.
|
|
33
|
+
#
|
|
34
|
+
# @return [ Criteria ] A new criteria with the added selector.
|
|
35
|
+
def also_in(attributes = {})
|
|
36
|
+
update_selector(attributes, "$in")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Adds a criterion to the +Criteria+ that specifies values that must
|
|
40
|
+
# be matched in order to return results. This is similar to a SQL "WHERE"
|
|
41
|
+
# clause. This is the actual selector that will be provided to MongoDB,
|
|
42
|
+
# similar to the Javascript object that is used when performing a find()
|
|
43
|
+
# in the MongoDB console.
|
|
44
|
+
#
|
|
45
|
+
# @example Adding the criterion.
|
|
46
|
+
# criteria.and(:field1 => "value1", :field2 => 15)
|
|
47
|
+
#
|
|
48
|
+
# @param [ Hash ] selectior Name/value pairs that all must match.
|
|
49
|
+
#
|
|
50
|
+
# @return [ Criteria ] A new criteria with the added selector.
|
|
51
|
+
def and(selector = nil)
|
|
52
|
+
where(selector)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Adds a criterion to the +Criteria+ that specifies a set of expressions
|
|
56
|
+
# to match if any of them return true. This is a $or query in MongoDB and
|
|
57
|
+
# is similar to a SQL OR. This is named #any_of and aliased "or" for
|
|
58
|
+
# readability.
|
|
59
|
+
#
|
|
60
|
+
# @example Adding the criterion.
|
|
61
|
+
# criteria.any_of({ :field1 => "value" }, { :field2 => "value2" })
|
|
62
|
+
#
|
|
63
|
+
# @param [ Array<Hash> ] args A list of name/value pairs any can match.
|
|
64
|
+
#
|
|
65
|
+
# @return [ Criteria ] A new criteria with the added selector.
|
|
66
|
+
def any_of(*args)
|
|
67
|
+
clone.tap do |crit|
|
|
68
|
+
criterion = @selector["$or"] || []
|
|
69
|
+
converted = BSON::ObjectId.convert(klass, args.flatten)
|
|
70
|
+
expanded = converted.collect(&:expand_complex_criteria)
|
|
71
|
+
crit.selector["$or"] = criterion.concat(expanded)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
alias :or :any_of
|
|
75
|
+
|
|
76
|
+
# Find the matchind document in the criteria, either based on id or
|
|
77
|
+
# conditions.
|
|
78
|
+
#
|
|
79
|
+
# @todo Durran: DRY up duplicated code in a few places.
|
|
80
|
+
#
|
|
81
|
+
# @example Find by an id.
|
|
82
|
+
# criteria.find(BSON::ObjectId.new)
|
|
83
|
+
#
|
|
84
|
+
# @example Find by multiple ids.
|
|
85
|
+
# criteria.find([ BSON::ObjectId.new, BSON::ObjectId.new ])
|
|
86
|
+
#
|
|
87
|
+
# @example Conditionally find all matching documents.
|
|
88
|
+
# criteria.find(:all, :conditions => { :title => "Sir" })
|
|
89
|
+
#
|
|
90
|
+
# @example Conditionally find the first document.
|
|
91
|
+
# criteria.find(:first, :conditions => { :title => "Sir" })
|
|
92
|
+
#
|
|
93
|
+
# @example Conditionally find the last document.
|
|
94
|
+
# criteria.find(:last, :conditions => { :title => "Sir" })
|
|
95
|
+
#
|
|
96
|
+
# @param [ Symbol, BSON::ObjectId, Array<BSON::ObjectId> ] arg The
|
|
97
|
+
# argument to search with.
|
|
98
|
+
# @param [ Hash ] options The options to search with.
|
|
99
|
+
#
|
|
100
|
+
# @return [ Document, Criteria ] The matching document(s).
|
|
101
|
+
def find(*args)
|
|
102
|
+
type, crit = search(*args)
|
|
103
|
+
case type
|
|
104
|
+
when :first then crit.one
|
|
105
|
+
when :last then crit.last
|
|
106
|
+
when :ids then execute_or_raise(args, crit)
|
|
107
|
+
else
|
|
108
|
+
crit
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Adds a criterion to the +Criteria+ that specifies values where any can
|
|
113
|
+
# be matched in order to return results. This is similar to an SQL "IN"
|
|
114
|
+
# clause. The MongoDB conditional operator that will be used is "$in".
|
|
115
|
+
#
|
|
116
|
+
# @example Adding the criterion.
|
|
117
|
+
# criteria.in(:field => ["value1", "value2"])
|
|
118
|
+
# criteria.in(:field1 => ["value1", "value2"], :field2 => ["value1"])
|
|
119
|
+
#
|
|
120
|
+
# @param [ Hash ] attributes Name/value pairs any can match.
|
|
121
|
+
#
|
|
122
|
+
# @return [ Criteria ] A new criteria with the added selector.
|
|
123
|
+
def in(attributes = {})
|
|
124
|
+
update_selector(attributes, "$in", :&)
|
|
125
|
+
end
|
|
126
|
+
alias :any_in :in
|
|
127
|
+
|
|
128
|
+
# Adds a criterion to the +Criteria+ that specifies values to do
|
|
129
|
+
# geospacial searches by. The field must be indexed with the "2d" option.
|
|
130
|
+
#
|
|
131
|
+
# @example Adding the criterion.
|
|
132
|
+
# criteria.near(:field1 => [30, -44])
|
|
133
|
+
#
|
|
134
|
+
# @param [ Hash ] attributes The fields with lat/long values.
|
|
135
|
+
#
|
|
136
|
+
# @return [ Criteria ] A new criteria with the added selector.
|
|
137
|
+
def near(attributes = {})
|
|
138
|
+
update_selector(attributes, "$near")
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Adds a criterion to the +Criteria+ that specifies values that must
|
|
142
|
+
# be matched in order to return results. This is similar to a SQL "WHERE"
|
|
143
|
+
# clause. This is the actual selector that will be provided to MongoDB,
|
|
144
|
+
# similar to the Javascript object that is used when performing a find()
|
|
145
|
+
# in the MongoDB console.
|
|
146
|
+
#
|
|
147
|
+
# @example Adding the criterion.
|
|
148
|
+
# criteria.where(:field1 => "value1", :field2 => 15)
|
|
149
|
+
#
|
|
150
|
+
# @param [ Hash ] selector Name/value pairs where all must match.
|
|
151
|
+
#
|
|
152
|
+
# @return [ Criteria ] A new criteria with the added selector.
|
|
153
|
+
def where(selector = nil)
|
|
154
|
+
clone.tap do |crit|
|
|
155
|
+
selector = case selector
|
|
156
|
+
when String then {"$where" => selector}
|
|
157
|
+
else
|
|
158
|
+
BSON::ObjectId.convert(klass, selector || {}, false).expand_complex_criteria
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
selector.each_pair do |key, value|
|
|
162
|
+
if crit.selector.has_key?(key) && crit.selector[key].respond_to?(:merge!)
|
|
163
|
+
crit.selector[key] =
|
|
164
|
+
crit.selector[key].merge!(value) do |key, old, new|
|
|
165
|
+
key == '$in' ? old & new : new
|
|
166
|
+
end
|
|
167
|
+
else
|
|
168
|
+
crit.selector[key] = value
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
private
|
|
175
|
+
|
|
176
|
+
# Execute the criteria or raise an error if no documents found.
|
|
177
|
+
#
|
|
178
|
+
# @example Execute or raise
|
|
179
|
+
# criteria.execute_or_raise(id, criteria)
|
|
180
|
+
#
|
|
181
|
+
# @param [ Object ] args The arguments passed.
|
|
182
|
+
# @param [ Criteria ] criteria The criteria to execute.
|
|
183
|
+
#
|
|
184
|
+
# @raise [ Errors::DocumentNotFound ] If nothing returned.
|
|
185
|
+
#
|
|
186
|
+
# @return [ Document, Array<Document> ] The document(s).
|
|
187
|
+
#
|
|
188
|
+
# @since 2.0.0
|
|
189
|
+
def execute_or_raise(args, criteria)
|
|
190
|
+
(args[0].is_a?(Array) ? criteria.entries : criteria.one).tap do |result|
|
|
191
|
+
if Mongoid.raise_not_found_error && !args.flatten.blank?
|
|
192
|
+
raise Errors::DocumentNotFound.new(klass, args) if result._vacant?
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
@@ -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,193 @@
|
|
|
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:
|
|
10
|
+
#
|
|
11
|
+
# <tt>criteria.ascending(:title, :dob)</tt>
|
|
12
|
+
def ascending(*fields)
|
|
13
|
+
clone.tap do |crit|
|
|
14
|
+
crit.options[:sort] = [] unless options[:sort] || fields.first.nil?
|
|
15
|
+
fields.flatten.each { |field| crit.options[:sort] << [ field, :asc ] }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
alias :asc :ascending
|
|
19
|
+
|
|
20
|
+
# Tells the criteria that the cursor that gets returned needs to be
|
|
21
|
+
# cached. This is so multiple iterations don't hit the database multiple
|
|
22
|
+
# times, however this is not advisable when working with large data sets
|
|
23
|
+
# as the entire results will get stored in memory.
|
|
24
|
+
#
|
|
25
|
+
# Example:
|
|
26
|
+
#
|
|
27
|
+
# <tt>criteria.cache</tt>
|
|
28
|
+
def cache
|
|
29
|
+
clone.tap { |crit| crit.options.merge!(:cache => true) }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Will return true if the cache option has been set.
|
|
33
|
+
#
|
|
34
|
+
# Example:
|
|
35
|
+
#
|
|
36
|
+
# <tt>criteria.cached?</tt>
|
|
37
|
+
def cached?
|
|
38
|
+
options[:cache] == true
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Adds fields to be sorted in descending order. Will add them in the order
|
|
42
|
+
# they were passed into the method.
|
|
43
|
+
#
|
|
44
|
+
# Example:
|
|
45
|
+
#
|
|
46
|
+
# <tt>criteria.descending(:title, :dob)</tt>
|
|
47
|
+
def descending(*fields)
|
|
48
|
+
clone.tap do |crit|
|
|
49
|
+
crit.options[:sort] = [] unless options[:sort] || fields.first.nil?
|
|
50
|
+
fields.flatten.each { |field| crit.options[:sort] << [ field, :desc ] }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
alias :desc :descending
|
|
54
|
+
|
|
55
|
+
# Adds a criterion to the +Criteria+ that specifies additional options
|
|
56
|
+
# to be passed to the Ruby driver, in the exact format for the driver.
|
|
57
|
+
#
|
|
58
|
+
# Options:
|
|
59
|
+
#
|
|
60
|
+
# extras: A +Hash+ that gets set to the driver options.
|
|
61
|
+
#
|
|
62
|
+
# Example:
|
|
63
|
+
#
|
|
64
|
+
# <tt>criteria.extras(:limit => 20, :skip => 40)</tt>
|
|
65
|
+
#
|
|
66
|
+
# Returns: <tt>self</tt>
|
|
67
|
+
def extras(extras)
|
|
68
|
+
clone.tap do |crit|
|
|
69
|
+
crit.options.merge!(extras)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Adds a criterion to the +Criteria+ that specifies an id that must be matched.
|
|
74
|
+
#
|
|
75
|
+
# Options:
|
|
76
|
+
#
|
|
77
|
+
# object_id: A single id or an array of ids in +String+ or <tt>BSON::ObjectId</tt> format
|
|
78
|
+
#
|
|
79
|
+
# Example:
|
|
80
|
+
#
|
|
81
|
+
# <tt>criteria.for_ids("4ab2bc4b8ad548971900005c")</tt>
|
|
82
|
+
# <tt>criteria.for_ids(["4ab2bc4b8ad548971900005c", "4c454e7ebf4b98032d000001"])</tt>
|
|
83
|
+
#
|
|
84
|
+
# Returns: <tt>self</tt>
|
|
85
|
+
def for_ids(*ids)
|
|
86
|
+
ids.flatten!
|
|
87
|
+
if ids.size > 1
|
|
88
|
+
any_in(
|
|
89
|
+
:_id => ::BSON::ObjectId.convert(klass, ids)
|
|
90
|
+
)
|
|
91
|
+
else
|
|
92
|
+
clone.tap do |crit|
|
|
93
|
+
crit.selector[:_id] =
|
|
94
|
+
::BSON::ObjectId.convert(klass, ids.first)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Adds a criterion to the +Criteria+ that specifies the maximum number of
|
|
100
|
+
# results to return. This is mostly used in conjunction with <tt>skip()</tt>
|
|
101
|
+
# to handle paginated results.
|
|
102
|
+
#
|
|
103
|
+
# Options:
|
|
104
|
+
#
|
|
105
|
+
# value: An +Integer+ specifying the max number of results. Defaults to 20.
|
|
106
|
+
#
|
|
107
|
+
# Example:
|
|
108
|
+
#
|
|
109
|
+
# <tt>criteria.limit(100)</tt>
|
|
110
|
+
#
|
|
111
|
+
# Returns: <tt>self</tt>
|
|
112
|
+
def limit(value = 20)
|
|
113
|
+
clone.tap { |crit| crit.options[:limit] = value }
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Returns the offset option. If a per_page option is in the list then it
|
|
117
|
+
# will replace it with a skip parameter and return the same value. Defaults
|
|
118
|
+
# to 20 if nothing was provided.
|
|
119
|
+
def offset(*args)
|
|
120
|
+
args.size > 0 ? skip(args.first) : options[:skip]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Adds a criterion to the +Criteria+ that specifies the sort order of
|
|
124
|
+
# the returned documents in the database. Similar to a SQL "ORDER BY".
|
|
125
|
+
#
|
|
126
|
+
# Options:
|
|
127
|
+
#
|
|
128
|
+
# params: An +Array+ of [field, direction] sorting pairs.
|
|
129
|
+
#
|
|
130
|
+
# Example:
|
|
131
|
+
#
|
|
132
|
+
# <tt>criteria.order_by([[:field1, :asc], [:field2, :desc]])</tt>
|
|
133
|
+
#
|
|
134
|
+
# Returns: <tt>self</tt>
|
|
135
|
+
def order_by(*args)
|
|
136
|
+
clone.tap do |crit|
|
|
137
|
+
crit.options[:sort] = [] unless options[:sort] || args.first.nil?
|
|
138
|
+
arguments = args.first
|
|
139
|
+
case arguments
|
|
140
|
+
when Hash
|
|
141
|
+
arguments.each do |field, direction|
|
|
142
|
+
crit.options[:sort] << [ field, direction ]
|
|
143
|
+
end
|
|
144
|
+
when Array
|
|
145
|
+
crit.options[:sort].concat(arguments)
|
|
146
|
+
when Complex
|
|
147
|
+
args.flatten.each do |complex|
|
|
148
|
+
crit.options[:sort] << [ complex.key, complex.operator.to_sym ]
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
alias :order :order_by
|
|
154
|
+
|
|
155
|
+
# Adds a criterion to the +Criteria+ that specifies how many results to skip
|
|
156
|
+
# when returning Documents. This is mostly used in conjunction with
|
|
157
|
+
# <tt>limit()</tt> to handle paginated results, and is similar to the
|
|
158
|
+
# traditional "offset" parameter.
|
|
159
|
+
#
|
|
160
|
+
# Options:
|
|
161
|
+
#
|
|
162
|
+
# value: An +Integer+ specifying the number of results to skip. Defaults to 0.
|
|
163
|
+
#
|
|
164
|
+
# Example:
|
|
165
|
+
#
|
|
166
|
+
# <tt>criteria.skip(20)</tt>
|
|
167
|
+
#
|
|
168
|
+
# Returns: <tt>self</tt>
|
|
169
|
+
def skip(value = 0)
|
|
170
|
+
clone.tap { |crit| crit.options[:skip] = value }
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Adds a criterion to the +Criteria+ that specifies a type or an Array of
|
|
174
|
+
# type that must be matched.
|
|
175
|
+
#
|
|
176
|
+
# Options:
|
|
177
|
+
#
|
|
178
|
+
# types : An +Array+ of types of a +String+ representing the Type of you search
|
|
179
|
+
#
|
|
180
|
+
# Example:
|
|
181
|
+
#
|
|
182
|
+
# <tt>criteria.type('Browser')</tt>
|
|
183
|
+
# <tt>criteria.type(['Firefox', 'Browser'])</tt>
|
|
184
|
+
#
|
|
185
|
+
# Returns: <tt>self</tt>
|
|
186
|
+
def type(types)
|
|
187
|
+
types = [types] unless types.is_a?(Array)
|
|
188
|
+
any_in(:_type => types)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|