dm-mongo-adapter 0.2.0.pre3 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +27 -0
- data/README.rdoc +16 -35
- data/Rakefile +6 -16
- data/VERSION.yml +2 -2
- data/dm-mongo-adapter.gemspec +100 -121
- data/lib/mongo_adapter.rb +19 -62
- data/lib/mongo_adapter/adapter.rb +49 -36
- data/lib/mongo_adapter/conditions.rb +0 -5
- data/lib/mongo_adapter/migrations.rb +17 -23
- data/lib/mongo_adapter/model.rb +3 -74
- data/lib/mongo_adapter/modifier.rb +1 -1
- data/lib/mongo_adapter/property/array.rb +10 -0
- data/lib/mongo_adapter/property/db_ref.rb +17 -0
- data/lib/mongo_adapter/property/hash.rb +27 -0
- data/lib/mongo_adapter/property/object_id.rb +47 -0
- data/lib/mongo_adapter/query.rb +42 -45
- data/lib/mongo_adapter/rails/storage.rb +15 -0
- data/lib/mongo_adapter/resource.rb +0 -130
- data/lib/mongo_adapter/support/class.rb +11 -0
- data/lib/mongo_adapter/support/date.rb +11 -0
- data/lib/mongo_adapter/support/date_time.rb +12 -0
- data/lib/mongo_adapter/support/object.rb +9 -0
- data/spec/legacy/adapter_spec.rb +9 -6
- data/spec/legacy/associations_spec.rb +37 -29
- data/spec/legacy/property_spec.rb +4 -3
- data/spec/legacy/sti_spec.rb +1 -2
- data/spec/lib/cleanup_models.rb +0 -1
- data/spec/public/aggregates_spec.rb +171 -0
- data/spec/public/model_spec.rb +8 -22
- data/spec/public/modifier_spec.rb +109 -0
- data/spec/public/properties/db_ref_spec.rb +17 -0
- data/spec/public/properties/object_id_spec.rb +15 -0
- data/spec/public/resource_spec.rb +2 -383
- data/spec/public/shared/object_id_shared_spec.rb +16 -39
- data/spec/spec_helper.rb +0 -4
- metadata +87 -117
- data/.gitignore +0 -9
- data/lib/mongo_adapter/embedded_model.rb +0 -187
- data/lib/mongo_adapter/embedded_resource.rb +0 -134
- data/lib/mongo_adapter/embedments/one_to_many.rb +0 -144
- data/lib/mongo_adapter/embedments/one_to_one.rb +0 -57
- data/lib/mongo_adapter/embedments/relationship.rb +0 -258
- data/lib/mongo_adapter/model/embedment.rb +0 -215
- data/lib/mongo_adapter/types/date.rb +0 -24
- data/lib/mongo_adapter/types/date_time.rb +0 -28
- data/lib/mongo_adapter/types/db_ref.rb +0 -65
- data/lib/mongo_adapter/types/discriminator.rb +0 -32
- data/lib/mongo_adapter/types/object_id.rb +0 -72
- data/lib/mongo_adapter/types/objects.rb +0 -31
- data/spec/legacy/embedded_resource_spec.rb +0 -157
- data/spec/legacy/embedments_spec.rb +0 -177
- data/spec/legacy/modifier_spec.rb +0 -81
- data/spec/public/embedded_collection_spec.rb +0 -61
- data/spec/public/embedded_resource_spec.rb +0 -220
- data/spec/public/model/embedment_spec.rb +0 -186
- data/spec/public/shared/model_embedments_spec.rb +0 -338
- data/spec/public/types/df_ref_spec.rb +0 -6
- data/spec/public/types/discriminator_spec.rb +0 -118
- data/spec/public/types/embedded_array_spec.rb +0 -55
- data/spec/public/types/embedded_hash_spec.rb +0 -83
- data/spec/public/types/object_id_spec.rb +0 -6
- data/spec/semipublic/embedded_model_spec.rb +0 -43
- data/spec/semipublic/model/embedment_spec.rb +0 -42
- data/spec/semipublic/resource_spec.rb +0 -70
@@ -1,6 +1,9 @@
|
|
1
1
|
module DataMapper
|
2
2
|
module Mongo
|
3
3
|
class Adapter < DataMapper::Adapters::AbstractAdapter
|
4
|
+
include DataMapper::Mongo::Aggregates
|
5
|
+
include Migrations
|
6
|
+
|
4
7
|
class ConnectionError < StandardError; end
|
5
8
|
|
6
9
|
# Persists one or more new resources
|
@@ -37,7 +40,7 @@ module DataMapper
|
|
37
40
|
# @api semipublic
|
38
41
|
def read(query)
|
39
42
|
with_collection(query.model) do |collection|
|
40
|
-
Query.new(collection, query).read
|
43
|
+
load_retrieved_fields!(Query.new(collection, query).read, query.model)
|
41
44
|
end
|
42
45
|
end
|
43
46
|
|
@@ -117,7 +120,25 @@ module DataMapper
|
|
117
120
|
#
|
118
121
|
# @api private
|
119
122
|
def key(resource)
|
120
|
-
resource.model.key(name).map
|
123
|
+
DataMapper::Ext::Array.to_hash(resource.model.key(name).map do |key|
|
124
|
+
[ key.field, key.dump(resource.__send__(key.name)) ]
|
125
|
+
end)
|
126
|
+
end
|
127
|
+
|
128
|
+
# TODO: document
|
129
|
+
def load_retrieved_fields!(fields, model)
|
130
|
+
fields.each do |attributes|
|
131
|
+
if discriminator = model.properties.discriminator
|
132
|
+
attributes[discriminator.field] = Class.from_mongo(attributes[discriminator.field])
|
133
|
+
end
|
134
|
+
|
135
|
+
attributes.each do |key, value|
|
136
|
+
next if discriminator && key == discriminator
|
137
|
+
attributes[key] = load_field_value(value)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
fields
|
121
142
|
end
|
122
143
|
|
123
144
|
# Retrieves all of a records attributes and returns them as a Hash.
|
@@ -142,7 +163,9 @@ module DataMapper
|
|
142
163
|
attributes_from_properties_hash(record)
|
143
164
|
end
|
144
165
|
|
145
|
-
attributes.
|
166
|
+
attributes.delete('_id') unless attributes.nil?
|
167
|
+
|
168
|
+
attributes
|
146
169
|
end
|
147
170
|
|
148
171
|
# TODO: document
|
@@ -152,27 +175,7 @@ module DataMapper
|
|
152
175
|
model = record.model
|
153
176
|
|
154
177
|
model.properties.each do |property|
|
155
|
-
|
156
|
-
if model.public_method_defined?(name)
|
157
|
-
value = property.get(record)
|
158
|
-
|
159
|
-
attributes[property.field] = property.custom? ?
|
160
|
-
property.type.dump(value, property) : value
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
if model.respond_to?(:embedments)
|
165
|
-
model.embedments.each do |name, embedment|
|
166
|
-
if model.public_method_defined?(name)
|
167
|
-
value = record.__send__(name)
|
168
|
-
|
169
|
-
if embedment.kind_of?(Embedments::OneToMany::Relationship)
|
170
|
-
attributes[embedment.storage_name] = value.map{ |resource| attributes_as_fields(resource) }
|
171
|
-
else
|
172
|
-
attributes[name] = attributes_as_fields(value)
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
178
|
+
attributes[property.field] = dump_field_value(property.dump(property.get(record)))
|
176
179
|
end
|
177
180
|
|
178
181
|
attributes
|
@@ -183,17 +186,24 @@ module DataMapper
|
|
183
186
|
attributes = {}
|
184
187
|
|
185
188
|
record.each do |key, value|
|
186
|
-
|
187
|
-
when DataMapper::Property
|
188
|
-
attributes[key.field] = key.custom? ? key.type.dump(value, key) : value
|
189
|
-
when Embedments::Relationship
|
190
|
-
attributes[key.storage_name] = attributes_as_fields(value)
|
191
|
-
end
|
189
|
+
attributes[key.field] = dump_field_value(key.dump(value))
|
192
190
|
end
|
193
191
|
|
194
192
|
attributes
|
195
193
|
end
|
196
194
|
|
195
|
+
# TODO: document
|
196
|
+
def dump_field_value(value)
|
197
|
+
return nil if value.nil?
|
198
|
+
value.class.to_mongo(value)
|
199
|
+
end
|
200
|
+
|
201
|
+
# TODO: document
|
202
|
+
def load_field_value(value)
|
203
|
+
return nil if value.nil?
|
204
|
+
value.class.from_mongo(value)
|
205
|
+
end
|
206
|
+
|
197
207
|
# Runs the given block within the context of a Mongo collection.
|
198
208
|
#
|
199
209
|
# @param [Model] model
|
@@ -226,11 +236,14 @@ module DataMapper
|
|
226
236
|
unless defined?(@database)
|
227
237
|
@database = connection.db(@options[:database])
|
228
238
|
|
229
|
-
if @options[:username]
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
239
|
+
if @options[:username]
|
240
|
+
begin
|
241
|
+
@database.authenticate(@options[:username], @options[:password])
|
242
|
+
rescue ::Mongo::AuthenticationError
|
243
|
+
raise ConnectionError,
|
244
|
+
'MongoDB did not recognize the given username and/or ' \
|
245
|
+
'password; see the server logs for more information'
|
246
|
+
end
|
234
247
|
end
|
235
248
|
end
|
236
249
|
|
@@ -246,7 +259,7 @@ module DataMapper
|
|
246
259
|
#
|
247
260
|
# @api semipublic
|
248
261
|
def connection
|
249
|
-
@connection ||= ::Mongo::Connection.new(
|
262
|
+
@connection ||= ::Mongo::Connection.new(@options[:host], @options[:port], :slave_ok => true)
|
250
263
|
end
|
251
264
|
end # Adapter
|
252
265
|
end # Mongo
|
@@ -70,7 +70,6 @@ module DataMapper
|
|
70
70
|
# Comparisons not current supported are:
|
71
71
|
#
|
72
72
|
# * $nin with range
|
73
|
-
# * negated regexp comparison (see: http://jira.mongodb.org/browse/SERVER-251)
|
74
73
|
#
|
75
74
|
# @param [DataMapper::Query::Conditions::AbstractOperation, DataMapper::Query::Conditions::AbstractComparison] operand
|
76
75
|
# An operation to be made suitable for use with Mongo
|
@@ -82,10 +81,6 @@ module DataMapper
|
|
82
81
|
case operand
|
83
82
|
when OrOperation
|
84
83
|
true
|
85
|
-
when RegexpComparison
|
86
|
-
if operand.negated?
|
87
|
-
true
|
88
|
-
end
|
89
84
|
when InclusionComparison
|
90
85
|
if operand.negated?
|
91
86
|
true
|
@@ -1,26 +1,8 @@
|
|
1
|
-
|
2
|
-
module Migrations
|
3
|
-
module SingletonMethods
|
4
|
-
private
|
5
|
-
|
6
|
-
def repository_execute(method, repository_name)
|
7
|
-
DataMapper::Model.descendants.each do |model|
|
8
|
-
model.send(method, repository_name || model.default_repository_name) unless model == DataMapper::Mongo::EmbeddedResource
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
1
|
+
require 'dm-migrations/auto_migration'
|
13
2
|
|
3
|
+
module DataMapper
|
14
4
|
module Mongo
|
15
5
|
module Migrations
|
16
|
-
def self.included(base)
|
17
|
-
DataMapper.extend(DataMapper::Migrations::SingletonMethods)
|
18
|
-
|
19
|
-
[ :Repository, :Model ].each do |name|
|
20
|
-
DataMapper.const_get(name).send(:include, DataMapper::Migrations.const_get(name))
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
6
|
def storage_exists?(storage_name)
|
25
7
|
database.collections.map(&:name).include?(storage_name)
|
26
8
|
end
|
@@ -38,8 +20,20 @@ module DataMapper
|
|
38
20
|
database.drop_collection(model.storage_name)
|
39
21
|
end
|
40
22
|
|
41
|
-
|
23
|
+
module Model
|
24
|
+
def auto_migrate!(repository_name = self.repository_name)
|
25
|
+
adapter = repository(repository_name).adapter
|
26
|
+
|
27
|
+
return unless adapter.kind_of?(Mongo::Adapter)
|
28
|
+
|
29
|
+
adapter.destroy_model_storage(self)
|
30
|
+
adapter.create_model_storage(self)
|
31
|
+
end
|
32
|
+
|
33
|
+
def auto_upgrade!(repository_name = self.repository_name)
|
34
|
+
# noop
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
42
38
|
end
|
43
39
|
end
|
44
|
-
|
45
|
-
DataMapper::Mongo.send(:include, DataMapper::Mongo::Migrations)
|
data/lib/mongo_adapter/model.rb
CHANGED
@@ -1,85 +1,14 @@
|
|
1
1
|
module DataMapper
|
2
2
|
module Mongo
|
3
3
|
module Model
|
4
|
-
|
5
|
-
model.extend Embedment
|
6
|
-
end
|
7
|
-
|
8
|
-
# Defines a Property on the Resource
|
9
|
-
#
|
10
|
-
# Overrides the property method in dm-core so as to automatically map
|
11
|
-
# Array and Hash types to EmbeddedArray and EmbeddedHash respectively.
|
12
|
-
#
|
13
|
-
# @param [Symbol] name
|
14
|
-
# the name for which to call this property
|
15
|
-
# @param [Type] type
|
16
|
-
# the type to define this property ass
|
17
|
-
# @param [Hash(Symbol => String)] options
|
18
|
-
# a hash of available options
|
19
|
-
#
|
20
|
-
# @return [Property]
|
21
|
-
# the created Property
|
22
|
-
#
|
23
|
-
# @api public
|
24
|
-
def property(name, type, options = {})
|
25
|
-
if Array == type
|
26
|
-
type = DataMapper::Mongo::Types::EmbeddedArray
|
27
|
-
elsif Hash == type
|
28
|
-
type = DataMapper::Mongo::Types::EmbeddedHash
|
29
|
-
elsif DateTime == type
|
30
|
-
type = DataMapper::Mongo::Types::DateTime
|
31
|
-
elsif Date == type
|
32
|
-
type = DataMapper::Mongo::Types::Date
|
33
|
-
end
|
34
|
-
|
35
|
-
super(name, type, options)
|
36
|
-
end
|
37
|
-
|
38
|
-
# Loads an instance of this Model, taking into account IdentityMap
|
39
|
-
# lookup, inheritance columns(s) and Property typecasting. Also loads
|
40
|
-
# the embedments on the Resource.
|
41
|
-
#
|
42
|
-
# @param [Enumerable<Object>] records
|
43
|
-
# An Array of Resource or Hashes to load a Resource with
|
44
|
-
# @param [DataMapper::Query] query
|
45
|
-
# The query used to load the Resource
|
46
|
-
#
|
47
|
-
# @return [Resource]
|
48
|
-
# The loaded Resource instance
|
49
|
-
#
|
50
|
-
# @overrides DataMapper::Model#load
|
51
|
-
#
|
52
|
-
# @api semipublic
|
53
|
-
def load(records, query)
|
54
|
-
if discriminator = properties(query.repository.name).discriminator
|
55
|
-
records.each do |record|
|
56
|
-
discriminator_key = discriminator.name.to_s
|
57
|
-
discriminator_value = discriminator.type.load(record[discriminator_key], discriminator)
|
58
|
-
|
59
|
-
record[discriminator_key] = discriminator_value
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
resources = super
|
64
|
-
|
65
|
-
# Load embedded resources
|
66
|
-
resources.each_with_index do |resource, index|
|
67
|
-
resource.model.embedments.each do |name, relationship|
|
68
|
-
unless (targets = records[index][name.to_s]).blank?
|
69
|
-
relationship.set(resource, targets, true)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
resources
|
75
|
-
end
|
4
|
+
include Migrations::Model
|
76
5
|
|
77
6
|
private
|
78
7
|
|
79
8
|
# @api private
|
80
9
|
def const_missing(name)
|
81
|
-
if DataMapper::Mongo::
|
82
|
-
DataMapper::Mongo::
|
10
|
+
if DataMapper::Mongo::Property.const_defined?(name)
|
11
|
+
DataMapper::Mongo::Property.const_get(name)
|
83
12
|
else
|
84
13
|
super
|
85
14
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Mongo
|
3
|
+
class Property
|
4
|
+
# Database references are references from one document (object) to
|
5
|
+
# another within a database. A database reference is a standard embedded
|
6
|
+
# object: this is a MongoDB convention, not a special type.
|
7
|
+
#
|
8
|
+
# The DBRef is made available via your model as a String.
|
9
|
+
#
|
10
|
+
# @see http://www.mongodb.org/display/DOCS/DB+Ref
|
11
|
+
#
|
12
|
+
# @api public
|
13
|
+
class DBRef < DataMapper::Mongo::Property::ObjectId
|
14
|
+
end # DBRef
|
15
|
+
end # Property
|
16
|
+
end # Mongo
|
17
|
+
end # DataMapper
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Mongo
|
3
|
+
class Property
|
4
|
+
class Hash < DataMapper::Property::Object
|
5
|
+
include DataMapper::Property::PassThroughLoadDump
|
6
|
+
primitive ::Hash
|
7
|
+
|
8
|
+
# @api semipublic
|
9
|
+
def load(value)
|
10
|
+
typecast_to_primitive(value)
|
11
|
+
end
|
12
|
+
|
13
|
+
# @api semipublic
|
14
|
+
def typecast_to_primitive(value)
|
15
|
+
case value
|
16
|
+
when NilClass
|
17
|
+
nil
|
18
|
+
when ::Hash
|
19
|
+
DataMapper::Ext::Hash.to_mash(value).symbolize_keys
|
20
|
+
when ::Array
|
21
|
+
value.empty? ? {} : {value.first.to_sym => value.last}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end #Array
|
25
|
+
end # Property
|
26
|
+
end # Mongo
|
27
|
+
end # DataMapper
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Mongo
|
3
|
+
class Property
|
4
|
+
# Each object (document) stored in Mongo DB has an _id field as its
|
5
|
+
# first attribute. This is an object id. It must be unique for each
|
6
|
+
# member of a collection (this is enforced if the collection has an _id
|
7
|
+
# index, which is the case by default).
|
8
|
+
#
|
9
|
+
# The database will assign an _id if an object being inserted into a
|
10
|
+
# collection does not have one.
|
11
|
+
#
|
12
|
+
# The _id may be of any type as long as it is a unique value.
|
13
|
+
#
|
14
|
+
# @see http://www.mongodb.org/display/DOCS/Object+IDs
|
15
|
+
#
|
16
|
+
# @api public
|
17
|
+
class ObjectId < DataMapper::Property::Object
|
18
|
+
include DataMapper::Property::PassThroughLoadDump
|
19
|
+
|
20
|
+
primitive ::BSON::ObjectId
|
21
|
+
key true
|
22
|
+
field "_id"
|
23
|
+
required false
|
24
|
+
|
25
|
+
# Returns the ObjectId as a string
|
26
|
+
#
|
27
|
+
# @return [String]
|
28
|
+
#
|
29
|
+
# @api semipublic
|
30
|
+
def typecast_to_primitive(value)
|
31
|
+
case value
|
32
|
+
when ::String
|
33
|
+
::BSON::ObjectId.from_string(value)
|
34
|
+
else
|
35
|
+
raise ArgumentError.new('+value+ must String')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# @api semipublic
|
40
|
+
def valid?(value, negated = false)
|
41
|
+
value.nil? || primitive?(value)
|
42
|
+
end
|
43
|
+
|
44
|
+
end # ObjectId
|
45
|
+
end # Property
|
46
|
+
end # Mongo
|
47
|
+
end # DataMapper
|
data/lib/mongo_adapter/query.rb
CHANGED
@@ -3,7 +3,7 @@ module DataMapper
|
|
3
3
|
# This class is responsible for taking Query instances from DataMapper and
|
4
4
|
# formatting the query such that it can be performed by the Mongo library.
|
5
5
|
class Query
|
6
|
-
include
|
6
|
+
include DataMapper::Assertions
|
7
7
|
include DataMapper::Query::Conditions
|
8
8
|
|
9
9
|
# Creates a new Query instance
|
@@ -42,7 +42,7 @@ module DataMapper
|
|
42
42
|
|
43
43
|
# TODO: atm ruby driver doesn't support count with statements,
|
44
44
|
# that's why we use find and size here as a tmp workaround
|
45
|
-
if @statements.
|
45
|
+
if @statements.keys.empty?
|
46
46
|
[@collection.count]
|
47
47
|
else
|
48
48
|
[find.size]
|
@@ -68,7 +68,7 @@ module DataMapper
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
if operators.
|
71
|
+
if operators.empty?
|
72
72
|
initial = {}
|
73
73
|
reduce = JavaScript::Reduce.new.to_s
|
74
74
|
finalize = nil
|
@@ -81,9 +81,14 @@ module DataMapper
|
|
81
81
|
|
82
82
|
keys = keys - initial.keys
|
83
83
|
end
|
84
|
-
|
85
|
-
|
86
|
-
|
84
|
+
|
85
|
+
opts = {
|
86
|
+
:key => keys, :cond => @statements, :initial => initial,
|
87
|
+
:reduce => reduce, :finalize => finalize
|
88
|
+
}
|
89
|
+
|
90
|
+
@collection.group(opts).map do |records|
|
91
|
+
DataMapper::Ext::Hash.to_mash(records).symbolize_keys
|
87
92
|
end
|
88
93
|
end
|
89
94
|
|
@@ -93,10 +98,10 @@ module DataMapper
|
|
93
98
|
# @api private
|
94
99
|
def setup_conditions_and_options
|
95
100
|
@options = {}
|
96
|
-
|
101
|
+
|
97
102
|
@options[:limit] = @query.limit if @query.limit
|
98
103
|
@options[:skip] = @query.offset if @query.offset
|
99
|
-
@options[:sort] = sort_statement(@query.order) unless @query.order.
|
104
|
+
@options[:sort] = sort_statement(@query.order) unless @query.order.nil?
|
100
105
|
|
101
106
|
conditions_statement(@query.conditions)
|
102
107
|
end
|
@@ -144,16 +149,6 @@ module DataMapper
|
|
144
149
|
end
|
145
150
|
end
|
146
151
|
|
147
|
-
# TODO: document
|
148
|
-
# @api private
|
149
|
-
def comparison_statement_for_embedment(comparison, affirmative = true)
|
150
|
-
embedment = @query.model.embedments.values.detect { |e| e.target_model == comparison.subject.model }
|
151
|
-
|
152
|
-
field = "#{embedment.storage_name}.#{comparison.subject.field}"
|
153
|
-
|
154
|
-
update_statements(comparison, field, affirmative)
|
155
|
-
end
|
156
|
-
|
157
152
|
# Takes a Comparison condition and returns a Mongo-compatible hash
|
158
153
|
#
|
159
154
|
# @param [DataMapper::Query::Conditions::Comparison] comparison
|
@@ -170,39 +165,41 @@ module DataMapper
|
|
170
165
|
return conditions_statement(comparison.foreign_key_mapping, affirmative)
|
171
166
|
end
|
172
167
|
|
173
|
-
if comparison.subject.model && comparison.subject.model < EmbeddedResource
|
174
|
-
return comparison_statement_for_embedment(comparison, affirmative)
|
175
|
-
end
|
176
|
-
|
177
168
|
update_statements(comparison, comparison.subject.field, affirmative)
|
178
169
|
end
|
179
170
|
|
180
171
|
# TODO: document
|
181
172
|
# @api private
|
182
|
-
def
|
183
|
-
|
173
|
+
def
|
174
|
+
update_statements(comparison, field, affirmative = true)
|
175
|
+
value = if comparison.value.kind_of?(Array)
|
176
|
+
comparison.value.map { |value| value.class.to_mongo(value) }
|
177
|
+
else
|
178
|
+
comparison.value.class.to_mongo(comparison.value)
|
179
|
+
end
|
184
180
|
|
185
181
|
operator = if affirmative
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
182
|
+
case comparison
|
183
|
+
when EqualToComparison then value
|
184
|
+
when GreaterThanComparison then {'$gt' => value}
|
185
|
+
when LessThanComparison then {'$lt' => value}
|
186
|
+
when GreaterThanOrEqualToComparison then {'$gte' => value}
|
187
|
+
when LessThanOrEqualToComparison then {'$lte' => value}
|
188
|
+
when InclusionComparison then inclusion_comparison_operator(comparison, value)
|
189
|
+
when RegexpComparison then value
|
190
|
+
when LikeComparison then comparison.send(:expected)
|
191
|
+
else
|
192
|
+
raise NotImplementedError
|
193
|
+
end
|
194
|
+
else
|
195
|
+
case comparison
|
196
|
+
when EqualToComparison then {'$ne' => value}
|
197
|
+
when InclusionComparison then {'$nin' => value}
|
198
|
+
when RegexpComparison then {'$not' => value}
|
199
|
+
else
|
200
|
+
raise NotImplementedError
|
201
|
+
end
|
202
|
+
end
|
206
203
|
|
207
204
|
operator.is_a?(Hash) ?
|
208
205
|
(@statements[field.to_sym] ||= {}).merge!(operator) : @statements[field.to_sym] = operator
|
@@ -223,7 +220,7 @@ module DataMapper
|
|
223
220
|
{'$gte' => value.first, value.exclude_end? ? '$lt' : '$lte' => value.last}
|
224
221
|
elsif comparison.kind_of?(InclusionComparison) && value.size == 1
|
225
222
|
value.first
|
226
|
-
elsif comparison.subject.
|
223
|
+
elsif comparison.subject.kind_of?(DataMapper::Mongo::Property::Array)
|
227
224
|
value
|
228
225
|
else
|
229
226
|
{'$in' => value}
|