mongo 2.0.0.rc → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -1
- data/README.md +1 -4
- data/lib/mongo/client.rb +1 -1
- data/lib/mongo/collection.rb +1 -1
- data/lib/mongo/collection/view.rb +1 -1
- data/lib/mongo/collection/view/writable.rb +26 -10
- data/lib/mongo/database.rb +1 -1
- data/lib/mongo/grid/file.rb +12 -0
- data/lib/mongo/grid/file/chunk.rb +1 -1
- data/lib/mongo/grid/file/metadata.rb +13 -0
- data/lib/mongo/operation/aggregate.rb +1 -1
- data/lib/mongo/operation/write.rb +1 -5
- data/lib/mongo/operation/write/bulk.rb +17 -0
- data/lib/mongo/operation/write/{bulk_delete.rb → bulk/bulk_delete.rb} +1 -1
- data/lib/mongo/operation/{bulk_delete → write/bulk/bulk_delete}/result.rb +3 -0
- data/lib/mongo/operation/write/{bulk_insert.rb → bulk/bulk_insert.rb} +1 -1
- data/lib/mongo/operation/{bulk_insert → write/bulk/bulk_insert}/result.rb +3 -0
- data/lib/mongo/operation/write/{bulk_mergable.rb → bulk/bulk_mergable.rb} +0 -0
- data/lib/mongo/operation/write/{bulk_update.rb → bulk/bulk_update.rb} +1 -1
- data/lib/mongo/operation/{bulk_update → write/bulk/bulk_update}/result.rb +8 -1
- data/lib/mongo/operation/write/{legacy_bulk_mergable.rb → bulk/legacy_bulk_mergable.rb} +0 -0
- data/lib/mongo/operation/write/delete.rb +2 -0
- data/lib/mongo/operation/write/delete/result.rb +40 -0
- data/lib/mongo/operation/write/insert.rb +2 -0
- data/lib/mongo/operation/write/insert/result.rb +32 -0
- data/lib/mongo/operation/write/update.rb +9 -4
- data/lib/mongo/operation/write/update/result.rb +160 -0
- data/lib/mongo/server/connectable.rb +11 -0
- data/lib/mongo/server/connection.rb +1 -0
- data/lib/mongo/server/connection_pool.rb +1 -1
- data/lib/mongo/server/connection_pool/queue.rb +1 -1
- data/lib/mongo/server/monitor.rb +16 -0
- data/lib/mongo/server/monitor/connection.rb +1 -0
- data/lib/mongo/socket/ssl.rb +30 -8
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo/write_concern/acknowledged.rb +1 -1
- data/lib/mongo/write_concern/unacknowledged.rb +1 -1
- data/spec/certificates/ca.pem +17 -0
- data/spec/certificates/client.pem +101 -0
- data/spec/certificates/crl.pem +10 -0
- data/spec/certificates/crl_client_revoked.pem +12 -0
- data/spec/certificates/password_protected.pem +51 -0
- data/spec/certificates/server.pem +34 -0
- data/spec/mongo/collection/view/writable_spec.rb +175 -0
- data/spec/mongo/crud_spec.rb +42 -0
- data/spec/mongo/grid/file/metadata_spec.rb +23 -0
- data/spec/mongo/grid/file_spec.rb +34 -0
- data/spec/mongo/operation/write/delete_spec.rb +8 -0
- data/spec/mongo/operation/write/insert_spec.rb +21 -8
- data/spec/mongo/operation/write/update_spec.rb +52 -1
- data/spec/mongo/server/connection_spec.rb +33 -10
- data/spec/mongo/server/monitor_spec.rb +14 -0
- data/spec/spec_helper.rb +2 -17
- data/spec/support/crud.rb +203 -0
- data/spec/support/crud/read.rb +144 -0
- data/spec/support/crud/write.rb +214 -0
- data/spec/support/crud_tests/read/aggregate.yml +43 -0
- data/spec/support/crud_tests/read/count.yml +37 -0
- data/spec/support/crud_tests/read/distinct.yml +33 -0
- data/spec/support/crud_tests/read/find.yml +50 -0
- data/spec/support/crud_tests/write/deleteMany.yml +36 -0
- data/spec/support/crud_tests/write/deleteOne.yml +49 -0
- data/spec/support/crud_tests/write/findOneAndDelete.yml +54 -0
- data/spec/support/crud_tests/write/findOneAndReplace.yml +153 -0
- data/spec/support/crud_tests/write/findOneAndUpdate.yml +161 -0
- data/spec/support/crud_tests/write/insertMany.yml +24 -0
- data/spec/support/crud_tests/write/insertOne.yml +19 -0
- data/spec/support/crud_tests/write/replaceOne.yml +96 -0
- data/spec/support/crud_tests/write/updateMany.yml +83 -0
- data/spec/support/crud_tests/write/updateOne.yml +80 -0
- metadata +64 -20
- metadata.gz.sig +0 -0
- data/spec/mongo_orchestration_spec.rb +0 -70
- data/spec/support/mongo_orchestration.rb +0 -61
- data/spec/support/mongo_orchestration/requestable.rb +0 -109
- data/spec/support/mongo_orchestration/standalone.rb +0 -57
@@ -0,0 +1,214 @@
|
|
1
|
+
# Copyright (C) 2014-2015 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Mongo
|
16
|
+
module CRUD
|
17
|
+
module Operation
|
18
|
+
|
19
|
+
# Defines common behaviour for running CRUD write operation tests on a
|
20
|
+
# collection.
|
21
|
+
#
|
22
|
+
# @since 2.0.0
|
23
|
+
class Write
|
24
|
+
|
25
|
+
# Map of CRUD operation names to method names.
|
26
|
+
#
|
27
|
+
# @since 2.0.0
|
28
|
+
OPERATIONS = { 'deleteMany' => :delete_many,
|
29
|
+
'deleteOne' => :delete_one,
|
30
|
+
'insertMany' => :insert_many,
|
31
|
+
'insertOne' => :insert_one,
|
32
|
+
'replaceOne' => :replace_one,
|
33
|
+
'updateMany' => :update_many,
|
34
|
+
'updateOne' => :update_one,
|
35
|
+
'findOneAndDelete' => :find_one_and_delete,
|
36
|
+
'findOneAndReplace' => :find_one_and_replace,
|
37
|
+
'findOneAndUpdate' => :find_one_and_update
|
38
|
+
}
|
39
|
+
|
40
|
+
# Map of operation options to method names.
|
41
|
+
#
|
42
|
+
# @since 2.0.0
|
43
|
+
ARGUMENT_MAP = {
|
44
|
+
:sort => 'sort',
|
45
|
+
:projection => 'projection'
|
46
|
+
}
|
47
|
+
|
48
|
+
# Operations that need a check if results on < 2.6 will match.
|
49
|
+
#
|
50
|
+
# @since 2.0.0
|
51
|
+
REQUIRES_2_6 = ['findOneAndReplace',
|
52
|
+
'updateMany',
|
53
|
+
'updateOne',
|
54
|
+
'replaceOne']
|
55
|
+
|
56
|
+
# The operation name.
|
57
|
+
#
|
58
|
+
# @return [ String ] name The operation name.
|
59
|
+
#
|
60
|
+
# @since 2.0.0
|
61
|
+
attr_reader :name
|
62
|
+
|
63
|
+
def initialize(spec)
|
64
|
+
@spec = spec
|
65
|
+
@name = spec['name']
|
66
|
+
end
|
67
|
+
|
68
|
+
# Whether the operation is expected to have restuls.
|
69
|
+
#
|
70
|
+
# @example Whether the operation is expected to have results.
|
71
|
+
# operation.has_results?
|
72
|
+
#
|
73
|
+
# @return [ true ] If the operation is expected to have results.
|
74
|
+
#
|
75
|
+
# @since 2.0.0
|
76
|
+
def has_results?
|
77
|
+
true
|
78
|
+
end
|
79
|
+
|
80
|
+
# Execute the operation.
|
81
|
+
#
|
82
|
+
# @example Execute the operation.
|
83
|
+
# operation.execute
|
84
|
+
#
|
85
|
+
# @param [ Collection ] collection The collection to execute
|
86
|
+
# the operation on.
|
87
|
+
#
|
88
|
+
# @return [ Result, Array<Hash> ] The result of executing the operation.
|
89
|
+
#
|
90
|
+
# @since 2.0.0
|
91
|
+
def execute(collection)
|
92
|
+
send(OPERATIONS[name], collection)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Whether this operation requires >= 2.6 to be tested.
|
96
|
+
#
|
97
|
+
# @example Determine whether this operation requires >= 2.6.
|
98
|
+
# operation.requires_2_6?(collection)
|
99
|
+
#
|
100
|
+
# @param [ Collection ] collection The collection the operation
|
101
|
+
# should be executed on.
|
102
|
+
#
|
103
|
+
# @return [ true, false ] Whether this operation requires 2.6
|
104
|
+
# to be tested.
|
105
|
+
#
|
106
|
+
# @since 2.0.0
|
107
|
+
def requires_2_6?(collection)
|
108
|
+
REQUIRES_2_6.include?(name) && upsert
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def delete_many(collection)
|
114
|
+
result = collection.find(filter).delete_many
|
115
|
+
{ 'deletedCount' => result.deleted_count }
|
116
|
+
end
|
117
|
+
|
118
|
+
def delete_one(collection)
|
119
|
+
result = collection.find(filter).delete_one
|
120
|
+
{ 'deletedCount' => result.deleted_count }
|
121
|
+
end
|
122
|
+
|
123
|
+
def insert_many(collection)
|
124
|
+
collection.insert_many(documents)
|
125
|
+
# returning inserted_ids is optional
|
126
|
+
{ 'insertedIds' => documents.collect { |d| d['_id'] } }
|
127
|
+
end
|
128
|
+
|
129
|
+
def insert_one(collection)
|
130
|
+
result = collection.insert_one(document)
|
131
|
+
# returning inserted_id is optional
|
132
|
+
{ 'insertedId' => document['_id'] }
|
133
|
+
end
|
134
|
+
|
135
|
+
def update_return_doc(result)
|
136
|
+
return_doc = { 'upsertedId' => result.upserted_id } if upsert
|
137
|
+
(return_doc || {}).merge!({ 'matchedCount' => result.matched_count,
|
138
|
+
'modifiedCount' => result.modified_count })
|
139
|
+
end
|
140
|
+
|
141
|
+
def replace_one(collection)
|
142
|
+
result = collection.find(filter).replace_one(replacement, upsert: upsert)
|
143
|
+
update_return_doc(result)
|
144
|
+
end
|
145
|
+
|
146
|
+
def update_many(collection)
|
147
|
+
result = collection.find(filter).update_many(update, upsert: upsert)
|
148
|
+
update_return_doc(result)
|
149
|
+
end
|
150
|
+
|
151
|
+
def update_one(collection)
|
152
|
+
result = collection.find(filter).update_one(update, upsert: upsert)
|
153
|
+
update_return_doc(result)
|
154
|
+
end
|
155
|
+
|
156
|
+
def find_one_and_delete(collection)
|
157
|
+
view = collection.find(filter)
|
158
|
+
ARGUMENT_MAP.each do |key, value|
|
159
|
+
view = view.send(key, arguments[value]) if arguments[value]
|
160
|
+
end
|
161
|
+
view.find_one_and_delete
|
162
|
+
end
|
163
|
+
|
164
|
+
def find_one_and_replace(collection)
|
165
|
+
view = collection.find(filter)
|
166
|
+
ARGUMENT_MAP.each do |key, value|
|
167
|
+
view = view.send(key, arguments[value]) if arguments[value]
|
168
|
+
end
|
169
|
+
view.find_one_and_replace(replacement, upsert: upsert, return_document: return_document)
|
170
|
+
end
|
171
|
+
|
172
|
+
def find_one_and_update(collection)
|
173
|
+
view = collection.find(filter)
|
174
|
+
ARGUMENT_MAP.each do |key, value|
|
175
|
+
view = view.send(key, arguments[value]) if arguments[value]
|
176
|
+
end
|
177
|
+
view.find_one_and_update(update, upsert: upsert, return_document: return_document)
|
178
|
+
end
|
179
|
+
|
180
|
+
def replacement
|
181
|
+
arguments['replacement']
|
182
|
+
end
|
183
|
+
|
184
|
+
def documents
|
185
|
+
arguments['documents']
|
186
|
+
end
|
187
|
+
|
188
|
+
def document
|
189
|
+
arguments['document']
|
190
|
+
end
|
191
|
+
|
192
|
+
def filter
|
193
|
+
arguments['filter']
|
194
|
+
end
|
195
|
+
|
196
|
+
def upsert
|
197
|
+
arguments['upsert']
|
198
|
+
end
|
199
|
+
|
200
|
+
def return_document
|
201
|
+
:after if arguments['returnDocument']
|
202
|
+
end
|
203
|
+
|
204
|
+
def update
|
205
|
+
arguments['update']
|
206
|
+
end
|
207
|
+
|
208
|
+
def arguments
|
209
|
+
@spec['arguments']
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
data:
|
2
|
+
- {_id: 1, x: 11}
|
3
|
+
- {_id: 2, x: 22}
|
4
|
+
- {_id: 3, x: 33}
|
5
|
+
|
6
|
+
tests:
|
7
|
+
-
|
8
|
+
description: "Aggregate with multiple stages"
|
9
|
+
operation:
|
10
|
+
name: aggregate
|
11
|
+
arguments:
|
12
|
+
pipeline:
|
13
|
+
- $sort: {x: 1}
|
14
|
+
- $match:
|
15
|
+
_id: {$gt: 1}
|
16
|
+
batchSize: 2
|
17
|
+
|
18
|
+
outcome:
|
19
|
+
result:
|
20
|
+
- {_id: 2, x: 22}
|
21
|
+
- {_id: 3, x: 33}
|
22
|
+
-
|
23
|
+
description: "Aggregate with $out"
|
24
|
+
operation:
|
25
|
+
name: aggregate
|
26
|
+
arguments:
|
27
|
+
pipeline:
|
28
|
+
- $sort: {x: 1}
|
29
|
+
- $match:
|
30
|
+
_id: {$gt: 1}
|
31
|
+
- $out: "other_test_collection"
|
32
|
+
batchSize: 2
|
33
|
+
|
34
|
+
outcome:
|
35
|
+
result:
|
36
|
+
- {_id: 2, x: 22}
|
37
|
+
- {_id: 3, x: 33}
|
38
|
+
collection:
|
39
|
+
name: "other_test_collection"
|
40
|
+
data:
|
41
|
+
- {_id: 2, x: 22}
|
42
|
+
- {_id: 3, x: 33}
|
43
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
data:
|
2
|
+
- {_id: 1, x: 11}
|
3
|
+
- {_id: 2, x: 22}
|
4
|
+
- {_id: 3, x: 33}
|
5
|
+
|
6
|
+
tests:
|
7
|
+
-
|
8
|
+
description: "Count without a filter"
|
9
|
+
operation:
|
10
|
+
name: count
|
11
|
+
arguments:
|
12
|
+
filter: { }
|
13
|
+
|
14
|
+
outcome:
|
15
|
+
result: 3
|
16
|
+
-
|
17
|
+
description: "Count with a filter"
|
18
|
+
operation:
|
19
|
+
name: count
|
20
|
+
arguments:
|
21
|
+
filter:
|
22
|
+
_id: {$gt: 1}
|
23
|
+
|
24
|
+
outcome:
|
25
|
+
result: 2
|
26
|
+
-
|
27
|
+
description: "Count with skip and limit"
|
28
|
+
operation:
|
29
|
+
name: count
|
30
|
+
arguments:
|
31
|
+
filter: {}
|
32
|
+
skip: 1
|
33
|
+
limit: 3
|
34
|
+
|
35
|
+
outcome:
|
36
|
+
result: 2
|
37
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
data:
|
2
|
+
- {_id: 1, x: 11}
|
3
|
+
- {_id: 2, x: 22}
|
4
|
+
- {_id: 3, x: 33}
|
5
|
+
|
6
|
+
tests:
|
7
|
+
-
|
8
|
+
description: "Distinct without a filter"
|
9
|
+
operation:
|
10
|
+
name: distinct
|
11
|
+
arguments:
|
12
|
+
fieldName: "x"
|
13
|
+
filter: {}
|
14
|
+
|
15
|
+
outcome:
|
16
|
+
result:
|
17
|
+
- 11
|
18
|
+
- 22
|
19
|
+
- 33
|
20
|
+
-
|
21
|
+
description: "Distinct with a filter"
|
22
|
+
operation:
|
23
|
+
name: distinct
|
24
|
+
arguments:
|
25
|
+
fieldName: "x"
|
26
|
+
filter:
|
27
|
+
_id: {$gt: 1}
|
28
|
+
|
29
|
+
outcome:
|
30
|
+
result:
|
31
|
+
- 22
|
32
|
+
- 33
|
33
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
data:
|
2
|
+
- {_id: 1, x: 11}
|
3
|
+
- {_id: 2, x: 22}
|
4
|
+
- {_id: 3, x: 33}
|
5
|
+
- {_id: 4, x: 44}
|
6
|
+
- {_id: 5, x: 55}
|
7
|
+
|
8
|
+
tests:
|
9
|
+
-
|
10
|
+
description: "Find with filter"
|
11
|
+
operation:
|
12
|
+
name: "find"
|
13
|
+
arguments:
|
14
|
+
filter: {_id: 1}
|
15
|
+
|
16
|
+
outcome:
|
17
|
+
result:
|
18
|
+
- {_id: 1, x: 11}
|
19
|
+
|
20
|
+
-
|
21
|
+
description: "Find with filter, sort, skip, and limit"
|
22
|
+
operation:
|
23
|
+
name: "find"
|
24
|
+
arguments:
|
25
|
+
filter:
|
26
|
+
_id: {$gt: 2}
|
27
|
+
sort: {_id: 1}
|
28
|
+
skip: 2
|
29
|
+
limit: 2
|
30
|
+
|
31
|
+
outcome:
|
32
|
+
result:
|
33
|
+
- {_id: 5, x: 55}
|
34
|
+
-
|
35
|
+
description: "Find with limit, sort, and batchsize"
|
36
|
+
operation:
|
37
|
+
name: "find"
|
38
|
+
arguments:
|
39
|
+
filter: {}
|
40
|
+
sort: {_id: 1}
|
41
|
+
limit: 4
|
42
|
+
batchSize: 2
|
43
|
+
|
44
|
+
outcome:
|
45
|
+
result:
|
46
|
+
- {_id: 1, x: 11}
|
47
|
+
- {_id: 2, x: 22}
|
48
|
+
- {_id: 3, x: 33}
|
49
|
+
- {_id: 4, x: 44}
|
50
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
data:
|
2
|
+
- {_id: 1, x: 11}
|
3
|
+
- {_id: 2, x: 22}
|
4
|
+
- {_id: 3, x: 33}
|
5
|
+
|
6
|
+
tests:
|
7
|
+
-
|
8
|
+
description: "DeleteMany when many documents match"
|
9
|
+
operation:
|
10
|
+
name: "deleteMany"
|
11
|
+
arguments:
|
12
|
+
filter:
|
13
|
+
_id: {$gt: 1}
|
14
|
+
|
15
|
+
outcome:
|
16
|
+
result:
|
17
|
+
deletedCount: 2
|
18
|
+
collection:
|
19
|
+
data:
|
20
|
+
- {_id: 1, x: 11}
|
21
|
+
-
|
22
|
+
description: "DeleteMany when no document matches"
|
23
|
+
operation:
|
24
|
+
name: "deleteMany"
|
25
|
+
arguments:
|
26
|
+
filter: {_id: 4}
|
27
|
+
|
28
|
+
outcome:
|
29
|
+
result:
|
30
|
+
deletedCount: 0
|
31
|
+
collection:
|
32
|
+
data:
|
33
|
+
- {_id: 1, x: 11}
|
34
|
+
- {_id: 2, x: 22}
|
35
|
+
- {_id: 3, x: 33}
|
36
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
data:
|
2
|
+
- {_id: 1, x: 11}
|
3
|
+
- {_id: 2, x: 22}
|
4
|
+
- {_id: 3, x: 33}
|
5
|
+
|
6
|
+
tests:
|
7
|
+
-
|
8
|
+
description: "DeleteOne when many documents match"
|
9
|
+
operation:
|
10
|
+
name: "deleteOne"
|
11
|
+
arguments:
|
12
|
+
filter:
|
13
|
+
_id: {$gt: 1}
|
14
|
+
|
15
|
+
outcome:
|
16
|
+
result:
|
17
|
+
deletedCount: 1
|
18
|
+
# can't verify collection because we don't have a way
|
19
|
+
# of knowing which document gets deleted.
|
20
|
+
-
|
21
|
+
description: "DeleteOne when one document matches"
|
22
|
+
operation:
|
23
|
+
name: "deleteOne"
|
24
|
+
arguments:
|
25
|
+
filter: {_id: 2}
|
26
|
+
|
27
|
+
outcome:
|
28
|
+
result:
|
29
|
+
deletedCount: 1
|
30
|
+
collection:
|
31
|
+
data:
|
32
|
+
- {_id: 1, x: 11}
|
33
|
+
- {_id: 3, x: 33}
|
34
|
+
-
|
35
|
+
description: "DeleteOne when no documents match"
|
36
|
+
operation:
|
37
|
+
name: "deleteOne"
|
38
|
+
arguments:
|
39
|
+
filter: {_id: 4}
|
40
|
+
|
41
|
+
outcome:
|
42
|
+
result:
|
43
|
+
deletedCount: 0
|
44
|
+
collection:
|
45
|
+
data:
|
46
|
+
- {_id: 1, x: 11}
|
47
|
+
- {_id: 2, x: 22}
|
48
|
+
- {_id: 3, x: 33}
|
49
|
+
|