dm-mongo-adapter 0.2.0.pre3 → 0.6.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.
- 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}
|