mongo 1.8.6 → 1.12.5
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/LICENSE +1 -1
- data/README.md +114 -282
- data/Rakefile +18 -4
- data/VERSION +1 -1
- data/bin/mongo_console +27 -5
- data/lib/mongo/bulk_write_collection_view.rb +387 -0
- data/lib/mongo/collection.rb +283 -222
- data/lib/mongo/collection_writer.rb +364 -0
- data/lib/mongo/{util → connection}/node.rb +58 -6
- data/lib/mongo/{util → connection}/pool.rb +61 -37
- data/lib/mongo/{util → connection}/pool_manager.rb +72 -22
- data/lib/mongo/{util → connection}/sharding_pool_manager.rb +13 -0
- data/lib/mongo/connection/socket/socket_util.rb +37 -0
- data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
- data/lib/mongo/connection/socket/tcp_socket.rb +87 -0
- data/lib/mongo/connection/socket/unix_socket.rb +39 -0
- data/lib/mongo/connection/socket.rb +18 -0
- data/lib/mongo/connection.rb +19 -0
- data/lib/mongo/cursor.rb +183 -57
- data/lib/mongo/db.rb +302 -138
- data/lib/mongo/exception.rb +145 -0
- data/lib/mongo/functional/authentication.rb +455 -0
- data/lib/mongo/{util → functional}/logging.rb +23 -7
- data/lib/mongo/functional/read_preference.rb +183 -0
- data/lib/mongo/functional/scram.rb +556 -0
- data/lib/mongo/functional/uri_parser.rb +409 -0
- data/lib/mongo/{util → functional}/write_concern.rb +21 -9
- data/lib/mongo/functional.rb +20 -0
- data/lib/mongo/gridfs/grid.rb +19 -8
- data/lib/mongo/gridfs/grid_ext.rb +14 -0
- data/lib/mongo/gridfs/grid_file_system.rb +17 -4
- data/lib/mongo/gridfs/grid_io.rb +21 -9
- data/lib/mongo/gridfs.rb +18 -0
- data/lib/mongo/legacy.rb +76 -7
- data/lib/mongo/mongo_client.rb +246 -206
- data/lib/mongo/mongo_replica_set_client.rb +65 -15
- data/lib/mongo/mongo_sharded_client.rb +18 -3
- data/lib/mongo/networking.rb +47 -18
- data/lib/mongo/{util → utils}/conversions.rb +18 -3
- data/lib/mongo/{util → utils}/core_ext.rb +15 -32
- data/lib/mongo/{util → utils}/server_version.rb +15 -0
- data/lib/mongo/{util → utils}/support.rb +22 -55
- data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
- data/lib/mongo/utils.rb +19 -0
- data/lib/mongo.rb +44 -26
- data/mongo.gemspec +2 -2
- data/test/functional/authentication_test.rb +31 -10
- data/test/functional/bulk_api_stress_test.rb +133 -0
- data/test/functional/bulk_write_collection_view_test.rb +1198 -0
- data/test/functional/client_test.rb +627 -0
- data/test/functional/collection_test.rb +1419 -654
- data/test/functional/collection_writer_test.rb +83 -0
- data/test/functional/conversions_test.rb +46 -2
- data/test/functional/cursor_fail_test.rb +17 -9
- data/test/functional/cursor_message_test.rb +28 -15
- data/test/functional/cursor_test.rb +300 -165
- data/test/functional/db_api_test.rb +294 -264
- data/test/functional/db_connection_test.rb +15 -3
- data/test/functional/db_test.rb +165 -99
- data/test/functional/grid_file_system_test.rb +124 -112
- data/test/functional/grid_io_test.rb +17 -3
- data/test/functional/grid_test.rb +16 -2
- data/test/functional/pool_test.rb +99 -10
- data/test/functional/safe_test.rb +18 -4
- data/test/functional/ssl_test.rb +29 -0
- data/test/functional/support_test.rb +14 -0
- data/test/functional/timeout_test.rb +27 -27
- data/test/functional/uri_test.rb +268 -22
- data/test/functional/write_concern_test.rb +19 -5
- data/test/helpers/general.rb +50 -0
- data/test/helpers/test_unit.rb +476 -0
- data/test/replica_set/authentication_test.rb +28 -11
- data/test/replica_set/basic_test.rb +79 -23
- data/test/replica_set/client_test.rb +253 -124
- data/test/replica_set/connection_test.rb +59 -37
- data/test/replica_set/count_test.rb +18 -2
- data/test/replica_set/cursor_test.rb +30 -8
- data/test/replica_set/insert_test.rb +109 -2
- data/test/replica_set/max_values_test.rb +85 -10
- data/test/replica_set/pinning_test.rb +66 -2
- data/test/replica_set/query_test.rb +17 -3
- data/test/replica_set/read_preference_test.rb +115 -96
- data/test/replica_set/refresh_test.rb +59 -9
- data/test/replica_set/replication_ack_test.rb +32 -11
- data/test/replica_set/ssl_test.rb +32 -0
- data/test/sharded_cluster/basic_test.rb +73 -25
- data/test/shared/authentication/basic_auth_shared.rb +260 -0
- data/test/shared/authentication/bulk_api_auth_shared.rb +249 -0
- data/test/shared/authentication/gssapi_shared.rb +176 -0
- data/test/shared/authentication/sasl_plain_shared.rb +96 -0
- data/test/shared/authentication/scram_shared.rb +92 -0
- data/test/shared/ssl_shared.rb +235 -0
- data/test/test_helper.rb +47 -196
- data/test/threading/basic_test.rb +42 -2
- data/test/tools/mongo_config.rb +175 -35
- data/test/tools/mongo_config_test.rb +15 -1
- data/test/unit/client_test.rb +186 -57
- data/test/unit/collection_test.rb +44 -54
- data/test/unit/connection_test.rb +160 -71
- data/test/unit/cursor_test.rb +37 -3
- data/test/unit/db_test.rb +38 -14
- data/test/unit/grid_test.rb +15 -1
- data/test/unit/mongo_sharded_client_test.rb +30 -14
- data/test/unit/node_test.rb +16 -1
- data/test/unit/pool_manager_test.rb +21 -4
- data/test/unit/read_pref_test.rb +386 -1
- data/test/unit/read_test.rb +27 -13
- data/test/unit/safe_test.rb +22 -8
- data/test/unit/sharding_pool_manager_test.rb +25 -4
- data/test/unit/write_concern_test.rb +23 -9
- data.tar.gz.sig +0 -0
- metadata +80 -54
- metadata.gz.sig +0 -0
- data/lib/mongo/exceptions.rb +0 -65
- data/lib/mongo/util/read_preference.rb +0 -112
- data/lib/mongo/util/socket_util.rb +0 -20
- data/lib/mongo/util/ssl_socket.rb +0 -51
- data/lib/mongo/util/tcp_socket.rb +0 -62
- data/lib/mongo/util/thread_local_variable_manager.rb +0 -11
- data/lib/mongo/util/unix_socket.rb +0 -23
- data/lib/mongo/util/uri_parser.rb +0 -337
- data/test/functional/connection_test.rb +0 -449
- data/test/functional/threading_test.rb +0 -95
- data/test/replica_set/complex_connect_test.rb +0 -64
- data/test/shared/authentication.rb +0 -66
- data/test/unit/pool_test.rb +0 -9
- data/test/unit/util_test.rb +0 -55
|
@@ -1,90 +1,500 @@
|
|
|
1
|
+
# Copyright (C) 2009-2013 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
|
+
|
|
1
15
|
require 'rbconfig'
|
|
2
16
|
require 'test_helper'
|
|
3
17
|
|
|
4
|
-
class
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
18
|
+
class CollectionTest < Test::Unit::TestCase
|
|
19
|
+
|
|
20
|
+
LIMITED_MAX_BSON_SIZE = 1024
|
|
21
|
+
LIMITED_BSON_SIZE_WITH_HEADROOM = LIMITED_MAX_BSON_SIZE + MongoClient::APPEND_HEADROOM
|
|
22
|
+
LIMITED_MAX_MESSAGE_SIZE = 3 * LIMITED_MAX_BSON_SIZE
|
|
23
|
+
LIMITED_TEST_HEADROOM = 50
|
|
24
|
+
LIMITED_VALID_VALUE_SIZE = LIMITED_MAX_BSON_SIZE - LIMITED_TEST_HEADROOM
|
|
25
|
+
LIMITED_INVALID_VALUE_SIZE = LIMITED_MAX_BSON_SIZE + Mongo::MongoClient::COMMAND_HEADROOM + 1
|
|
9
26
|
|
|
10
27
|
def setup
|
|
11
|
-
|
|
28
|
+
@client ||= standard_connection(:op_timeout => 10)
|
|
29
|
+
@db = @client.db(TEST_DB)
|
|
30
|
+
@test = @db.collection("test")
|
|
31
|
+
@version = @client.server_version
|
|
32
|
+
@test.remove
|
|
33
|
+
@ismaster = @client['admin'].command(:isMaster => 1)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
@@wv0 = Mongo::MongoClient::RELEASE_2_4_AND_BEFORE
|
|
37
|
+
@@wv2 = Mongo::MongoClient::BATCH_COMMANDS
|
|
38
|
+
@@a_h = Mongo::MongoClient::APPEND_HEADROOM
|
|
39
|
+
@@s_h = Mongo::MongoClient::SERIALIZE_HEADROOM
|
|
40
|
+
|
|
41
|
+
def max_size_exception_test(client)
|
|
42
|
+
base = [
|
|
43
|
+
#[@@wv0, client.max_bson_size, nil, /xyzzy/], # succeeds standalone, fails whole suite
|
|
44
|
+
]
|
|
45
|
+
base += max_size_exception_cruby_test(client) unless RUBY_PLATFORM == 'java'
|
|
46
|
+
#base += max_size_exception_jruby_test if RUBY_PLATFORM == 'java'
|
|
47
|
+
base += max_size_exception_commands_test(client) if @version >= '2.5.2'
|
|
48
|
+
base
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def max_size_exception_cruby_test(client)
|
|
52
|
+
[
|
|
53
|
+
[@@wv0, client.max_bson_size + 1, BSON::InvalidDocument, /Document.* too large/]
|
|
54
|
+
]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def max_size_exception_jruby_test(client)
|
|
58
|
+
[@@wv0, client.max_bson_size + 1, Mongo::OperationFailure, /object to insert too large/]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def max_size_exception_commands_test(client)
|
|
62
|
+
[
|
|
63
|
+
#[@@wv2, client.max_bson_size, nil, /xyzzy/], # succeeds standalone, fails whole suite
|
|
64
|
+
[@@wv2, client.max_bson_size + 1, Mongo::OperationFailure, /object to insert too large/],
|
|
65
|
+
[@@wv2, client.max_bson_size + @@s_h, Mongo::OperationFailure, /object to insert too large/],
|
|
66
|
+
[@@wv2, client.max_bson_size + @@a_h, BSON::InvalidDocument, /Document.* too large/]
|
|
67
|
+
]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def generate_sized_doc(size)
|
|
71
|
+
doc = {"_id" => BSON::ObjectId.new, "x" => "y"}
|
|
72
|
+
serialize_doc = BSON::BSON_CODER.serialize(doc, false, false, size)
|
|
73
|
+
doc = {"_id" => BSON::ObjectId.new, "x" => "y" * (1 + size - serialize_doc.size)}
|
|
74
|
+
assert_equal size, BSON::BSON_CODER.serialize(doc, false, false, size).size
|
|
75
|
+
doc
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def with_max_wire_version(client, wire_version) # does not support replica sets
|
|
79
|
+
if client.wire_version_feature?(wire_version)
|
|
80
|
+
client.class.class_eval(%Q{
|
|
81
|
+
alias :old_max_wire_version :max_wire_version
|
|
82
|
+
def max_wire_version
|
|
83
|
+
#{wire_version}
|
|
84
|
+
end
|
|
85
|
+
})
|
|
86
|
+
yield wire_version
|
|
87
|
+
client.class.class_eval(%Q{
|
|
88
|
+
alias :max_wire_version :old_max_wire_version
|
|
89
|
+
})
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def test_insert_batch_max_sizes
|
|
94
|
+
max_size_exception_test(@client).each do |wire_version, size, exc, regexp|
|
|
95
|
+
with_max_wire_version(@client, wire_version) do
|
|
96
|
+
@test.remove
|
|
97
|
+
doc = generate_sized_doc(size)
|
|
98
|
+
begin
|
|
99
|
+
@test.insert([doc.dup])
|
|
100
|
+
assert_equal nil, exc
|
|
101
|
+
rescue => e
|
|
102
|
+
assert_equal exc, e.class, "wire_version:#{wire_version}, size:#{size}, exc:#{exc} e:#{e.message.inspect} @version:#{@version}"
|
|
103
|
+
assert_match regexp, e.message
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_single_delete_write_command
|
|
110
|
+
return unless @version >= '2.5.4'
|
|
111
|
+
@test.drop
|
|
112
|
+
@test.insert([{ :a => 1 }, { :a => 1 }])
|
|
113
|
+
|
|
114
|
+
command = BSON::OrderedHash['delete', @test.name,
|
|
115
|
+
:deletes, [{ :q => { :a => 1 }, :limit => 1 }],
|
|
116
|
+
:writeConcern, { :w => 1 },
|
|
117
|
+
:ordered, false]
|
|
118
|
+
|
|
119
|
+
result = @db.command(command)
|
|
120
|
+
assert_equal 1, result['n']
|
|
121
|
+
assert_equal 1, result['ok']
|
|
122
|
+
assert_equal 1, @test.count
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_multi_ordered_delete_write_command
|
|
126
|
+
return unless @version >= '2.5.4'
|
|
127
|
+
@test.drop
|
|
128
|
+
@test.insert([{ :a => 1 }, { :a => 1 }])
|
|
129
|
+
|
|
130
|
+
command = BSON::OrderedHash['delete', @test.name,
|
|
131
|
+
:deletes, [{ :q => { :a => 1 }, :limit => 0 }],
|
|
132
|
+
:writeConcern, { :w => 1 },
|
|
133
|
+
:ordered, true]
|
|
134
|
+
|
|
135
|
+
result = @db.command(command)
|
|
136
|
+
assert_equal 2, result['n']
|
|
137
|
+
assert_equal 1, result['ok']
|
|
138
|
+
assert_equal 0, @test.count
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def test_multi_unordered_delete_write_command
|
|
142
|
+
return unless @version >= '2.5.4'
|
|
143
|
+
@test.drop
|
|
144
|
+
@test.insert([{ :a => 1 }, { :a => 1 }])
|
|
145
|
+
|
|
146
|
+
command = BSON::OrderedHash['delete', @test.name,
|
|
147
|
+
:deletes, [{ :q => { :a => 1 }, :limit => 0 }],
|
|
148
|
+
:writeConcern, { :w => 1 },
|
|
149
|
+
:ordered, false]
|
|
150
|
+
|
|
151
|
+
result = @db.command(command)
|
|
152
|
+
assert_equal 2, result['n']
|
|
153
|
+
assert_equal 1, result['ok']
|
|
154
|
+
assert_equal 0, @test.count
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def test_delete_write_command_with_no_concern
|
|
158
|
+
return unless @version >= '2.5.4'
|
|
159
|
+
@test.drop
|
|
160
|
+
@test.insert([{ :a => 1 }, { :a => 1 }])
|
|
161
|
+
|
|
162
|
+
command = BSON::OrderedHash['delete', @test.name,
|
|
163
|
+
:deletes, [{ :q => { :a => 1 }, :limit => 0 }],
|
|
164
|
+
:ordered, false]
|
|
165
|
+
|
|
166
|
+
result = @db.command(command)
|
|
167
|
+
assert_equal 2, result['n']
|
|
168
|
+
assert_equal 1, result['ok']
|
|
169
|
+
assert_equal 0, @test.count
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def test_delete_write_command_with_error
|
|
173
|
+
return unless @version >= '2.5.4'
|
|
174
|
+
@test.drop
|
|
175
|
+
@test.insert([{ :a => 1 }, { :a => 1 }])
|
|
176
|
+
|
|
177
|
+
command = BSON::OrderedHash['delete', @test.name,
|
|
178
|
+
:deletes, [{ :q => { '$set' => { :a => 1 }}, :limit => 0 }],
|
|
179
|
+
:writeConcern, { :w => 1 },
|
|
180
|
+
:ordered, false]
|
|
181
|
+
|
|
182
|
+
assert_raise Mongo::OperationFailure do
|
|
183
|
+
@db.command(command)
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def test_single_insert_write_command
|
|
188
|
+
return unless @version >= '2.5.4'
|
|
189
|
+
@test.drop
|
|
190
|
+
|
|
191
|
+
command = BSON::OrderedHash['insert', @test.name,
|
|
192
|
+
:documents, [{ :a => 1 }],
|
|
193
|
+
:writeConcern, { :w => 1 },
|
|
194
|
+
:ordered, false]
|
|
195
|
+
|
|
196
|
+
result = @db.command(command)
|
|
197
|
+
assert_equal 1, result['ok']
|
|
198
|
+
assert_equal 1, @test.count
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def test_multi_ordered_insert_write_command
|
|
202
|
+
return unless @version >= '2.5.4'
|
|
203
|
+
@test.drop
|
|
204
|
+
|
|
205
|
+
command = BSON::OrderedHash['insert', @test.name,
|
|
206
|
+
:documents, [{ :a => 1 }, { :a => 2 }],
|
|
207
|
+
:writeConcern, { :w => 1 },
|
|
208
|
+
:ordered, true]
|
|
209
|
+
|
|
210
|
+
result = @db.command(command)
|
|
211
|
+
assert_equal 1, result['ok']
|
|
212
|
+
assert_equal 2, @test.count
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def test_multi_unordered_insert_write_command
|
|
216
|
+
return unless @version >= '2.5.4'
|
|
217
|
+
@test.drop
|
|
218
|
+
|
|
219
|
+
command = BSON::OrderedHash['insert', @test.name,
|
|
220
|
+
:documents, [{ :a => 1 }, { :a => 2 }],
|
|
221
|
+
:writeConcern, { :w => 1 },
|
|
222
|
+
:ordered, false]
|
|
223
|
+
|
|
224
|
+
result = @db.command(command)
|
|
225
|
+
assert_equal 1, result['ok']
|
|
226
|
+
assert_equal 2, @test.count
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def test_insert_write_command_with_no_concern
|
|
230
|
+
return unless @version >= '2.5.4'
|
|
231
|
+
@test.drop
|
|
232
|
+
|
|
233
|
+
command = BSON::OrderedHash['insert', @test.name,
|
|
234
|
+
:documents, [{ :a => 1 }, { :a => 2 }],
|
|
235
|
+
:ordered, false]
|
|
236
|
+
|
|
237
|
+
result = @db.command(command)
|
|
238
|
+
assert_equal 1, result['ok']
|
|
239
|
+
assert_equal 2, @test.count
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def test_insert_write_command_with_error
|
|
243
|
+
return unless @version >= '2.5.4'
|
|
244
|
+
@test.drop
|
|
245
|
+
@test.ensure_index([[:a, 1]], { :unique => true })
|
|
246
|
+
|
|
247
|
+
command = BSON::OrderedHash['insert', @test.name,
|
|
248
|
+
:documents, [{ :a => 1 }, { :a => 1 }],
|
|
249
|
+
:writeConcern, { :w => 1 },
|
|
250
|
+
:ordered, false]
|
|
251
|
+
|
|
252
|
+
assert_raise Mongo::OperationFailure do
|
|
253
|
+
@db.command(command)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def test_single_update_write_command
|
|
258
|
+
return unless @version >= '2.5.4'
|
|
259
|
+
@test.drop
|
|
260
|
+
@test.insert([{ :a => 1 }, { :a => 2 }])
|
|
261
|
+
|
|
262
|
+
command = BSON::OrderedHash['update', @test.name,
|
|
263
|
+
:updates, [{ :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}}],
|
|
264
|
+
:writeConcern, { :w => 1 }]
|
|
265
|
+
|
|
266
|
+
result = @db.command(command)
|
|
267
|
+
assert_equal 1, result['ok']
|
|
268
|
+
assert_equal 1, result['n']
|
|
269
|
+
assert_equal 2, @test.find({ :a => 2 }).count
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def test_multi_ordered_update_write_command
|
|
273
|
+
return unless @version >= '2.5.4'
|
|
274
|
+
@test.drop
|
|
275
|
+
@test.insert([{ :a => 1 }, { :a => 3 }])
|
|
276
|
+
|
|
277
|
+
command = BSON::OrderedHash['update', @test.name,
|
|
278
|
+
:updates, [
|
|
279
|
+
{ :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}},
|
|
280
|
+
{ :q => { :a => 3 }, :u => { '$set' => { :a => 4 }}}
|
|
281
|
+
],
|
|
282
|
+
:writeConcern, { :w => 1 },
|
|
283
|
+
:ordered, true]
|
|
284
|
+
|
|
285
|
+
result = @db.command(command)
|
|
286
|
+
assert_equal 1, result['ok']
|
|
287
|
+
assert_equal 2, result['n']
|
|
288
|
+
assert_equal 1, @test.find({ :a => 2 }).count
|
|
289
|
+
assert_equal 1, @test.find({ :a => 4 }).count
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def test_multi_unordered_update_write_command
|
|
293
|
+
return unless @version >= '2.5.4'
|
|
294
|
+
@test.drop
|
|
295
|
+
@test.insert([{ :a => 1 }, { :a => 3 }])
|
|
296
|
+
|
|
297
|
+
command = BSON::OrderedHash['update', @test.name,
|
|
298
|
+
:updates, [
|
|
299
|
+
{ :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}},
|
|
300
|
+
{ :q => { :a => 3 }, :u => { '$set' => { :a => 4 }}}
|
|
301
|
+
],
|
|
302
|
+
:writeConcern, { :w => 1 },
|
|
303
|
+
:ordered, false]
|
|
304
|
+
|
|
305
|
+
result = @db.command(command)
|
|
306
|
+
assert_equal 1, result['ok']
|
|
307
|
+
assert_equal 2, result['n']
|
|
308
|
+
assert_equal 1, @test.find({ :a => 2 }).count
|
|
309
|
+
assert_equal 1, @test.find({ :a => 4 }).count
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def test_update_write_command_with_no_concern
|
|
313
|
+
return unless @version >= '2.5.4'
|
|
314
|
+
@test.drop
|
|
315
|
+
@test.insert([{ :a => 1 }, { :a => 3 }])
|
|
316
|
+
|
|
317
|
+
command = BSON::OrderedHash['update', @test.name,
|
|
318
|
+
:updates, [
|
|
319
|
+
{ :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}},
|
|
320
|
+
{ :q => { :a => 3 }, :u => { '$set' => { :a => 4 }}}
|
|
321
|
+
],
|
|
322
|
+
:ordered, false]
|
|
323
|
+
|
|
324
|
+
result = @db.command(command)
|
|
325
|
+
assert_equal 1, result['ok']
|
|
326
|
+
assert_equal 2, result['n']
|
|
327
|
+
assert_equal 1, @test.find({ :a => 2 }).count
|
|
328
|
+
assert_equal 1, @test.find({ :a => 4 }).count
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def test_update_write_command_with_error
|
|
332
|
+
return unless @version >= '2.5.4'
|
|
333
|
+
@test.drop
|
|
334
|
+
@test.ensure_index([[:a, 1]], { :unique => true })
|
|
335
|
+
@test.insert([{ :a => 1 }, { :a => 2 }])
|
|
336
|
+
|
|
337
|
+
command = BSON::OrderedHash['update', @test.name,
|
|
338
|
+
:updates, [
|
|
339
|
+
{ :q => { :a => 2 }, :u => { '$set' => { :a => 1 }}}
|
|
340
|
+
],
|
|
341
|
+
:ordered, false]
|
|
342
|
+
|
|
343
|
+
assert_raise Mongo::OperationFailure do
|
|
344
|
+
@db.command(command)
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
def test_error_code
|
|
349
|
+
coll = @db['test-error-code']
|
|
350
|
+
coll.ensure_index(BSON::OrderedHash[:x, Mongo::ASCENDING], { :unique => true })
|
|
351
|
+
coll.save(:x => 2)
|
|
352
|
+
begin
|
|
353
|
+
coll.save(:x => 2)
|
|
354
|
+
rescue => ex
|
|
355
|
+
assert_not_nil ex.error_code
|
|
356
|
+
end
|
|
357
|
+
coll.drop
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def test_aggregation_cursor
|
|
361
|
+
return unless @version >= '2.5.1'
|
|
362
|
+
[10, 1000].each do |size|
|
|
363
|
+
@test.drop
|
|
364
|
+
size.times {|i| @test.insert({ :_id => i }) }
|
|
365
|
+
expected_sum = size.times.reduce(:+)
|
|
366
|
+
|
|
367
|
+
cursor = @test.aggregate(
|
|
368
|
+
[{ :$project => {:_id => '$_id'}} ],
|
|
369
|
+
:cursor => {}
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
assert_equal Mongo::Cursor, cursor.class
|
|
373
|
+
|
|
374
|
+
cursor_sum = cursor.reduce(0) do |sum, doc|
|
|
375
|
+
sum += doc['_id']
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
assert_equal expected_sum, cursor_sum
|
|
379
|
+
end
|
|
380
|
+
@test.drop
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
def test_aggregation_array
|
|
384
|
+
return unless @version >= '2.5.1'
|
|
385
|
+
@test.drop
|
|
386
|
+
100.times {|i| @test.insert({ :_id => i }) }
|
|
387
|
+
agg = @test.aggregate([{ :$project => {:_id => '$_id'}} ])
|
|
388
|
+
|
|
389
|
+
assert agg.kind_of?(Array)
|
|
390
|
+
|
|
391
|
+
@test.drop
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
def test_aggregation_cursor_invalid_ops
|
|
395
|
+
return unless @version >= '2.5.1'
|
|
396
|
+
cursor = @test.aggregate([], :cursor => {})
|
|
397
|
+
assert_raise(Mongo::InvalidOperation) { cursor.rewind! }
|
|
398
|
+
assert_raise(Mongo::InvalidOperation) { cursor.explain }
|
|
399
|
+
assert_raise(Mongo::InvalidOperation) { cursor.count }
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
def test_aggregation_invalid_read_pref
|
|
403
|
+
assert_raise Mongo::MongoArgumentError do
|
|
404
|
+
@test.aggregate([], :read => :invalid_read_pref)
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
def test_aggregation_supports_explain
|
|
409
|
+
return unless @version >= '2.5.3'
|
|
410
|
+
@db.expects(:command).with do |selector, opts|
|
|
411
|
+
opts[:explain] == true
|
|
412
|
+
end.returns({ 'ok' => 1 })
|
|
413
|
+
@test.aggregate([], :explain => true)
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
def test_aggregation_explain_returns_raw_result
|
|
417
|
+
return unless @version >= '2.5.3'
|
|
418
|
+
response = @test.aggregate([], :explain => true)
|
|
419
|
+
assert response['stages']
|
|
12
420
|
end
|
|
13
421
|
|
|
14
422
|
def test_capped_method
|
|
15
|
-
|
|
16
|
-
assert
|
|
17
|
-
|
|
423
|
+
@db.create_collection('normal')
|
|
424
|
+
assert !@db['normal'].capped?
|
|
425
|
+
@db.drop_collection('normal')
|
|
18
426
|
|
|
19
|
-
|
|
20
|
-
assert
|
|
21
|
-
|
|
427
|
+
@db.create_collection('c', :capped => true, :size => 100_000)
|
|
428
|
+
assert @db['c'].capped?
|
|
429
|
+
@db.drop_collection('c')
|
|
22
430
|
end
|
|
23
431
|
|
|
24
432
|
def test_optional_pk_factory
|
|
25
|
-
@coll_default_pk =
|
|
433
|
+
@coll_default_pk = @db.collection('stuff')
|
|
26
434
|
assert_equal BSON::ObjectId, @coll_default_pk.pk_factory
|
|
27
|
-
@coll_default_pk =
|
|
435
|
+
@coll_default_pk = @db.create_collection('more-stuff')
|
|
28
436
|
assert_equal BSON::ObjectId, @coll_default_pk.pk_factory
|
|
29
437
|
|
|
30
438
|
# Create a db with a pk_factory.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
439
|
+
client = MongoClient.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
|
|
440
|
+
ENV['MONGO_RUBY_DRIVER_PORT'] || MongoClient::DEFAULT_PORT)
|
|
441
|
+
client[TEST_DB].authenticate(TEST_USER, TEST_USER_PWD)
|
|
442
|
+
db = client.db(TEST_DB, :pk => Object.new)
|
|
35
443
|
|
|
36
|
-
|
|
37
|
-
assert
|
|
444
|
+
coll = db.collection('coll-with-pk')
|
|
445
|
+
assert coll.pk_factory.is_a?(Object)
|
|
446
|
+
|
|
447
|
+
coll = db.create_collection('created_coll_with_pk')
|
|
448
|
+
assert coll.pk_factory.is_a?(Object)
|
|
38
449
|
end
|
|
39
450
|
|
|
40
|
-
class
|
|
451
|
+
class PKTest
|
|
41
452
|
def self.create_pk
|
|
42
453
|
end
|
|
43
454
|
end
|
|
44
455
|
|
|
45
456
|
def test_pk_factory_on_collection
|
|
46
457
|
silently do
|
|
47
|
-
@coll = Collection.new('foo',
|
|
48
|
-
assert_equal
|
|
458
|
+
@coll = Collection.new('foo', @db, PKTest)
|
|
459
|
+
assert_equal PKTest, @coll.pk_factory
|
|
49
460
|
end
|
|
50
461
|
|
|
51
|
-
|
|
52
|
-
@coll2
|
|
53
|
-
assert_equal TestPK, @coll2.pk_factory
|
|
462
|
+
@coll2 = Collection.new('foo', @db, :pk => PKTest)
|
|
463
|
+
assert_equal PKTest, @coll2.pk_factory
|
|
54
464
|
end
|
|
55
465
|
|
|
56
466
|
def test_valid_names
|
|
57
467
|
assert_raise Mongo::InvalidNSName do
|
|
58
|
-
|
|
468
|
+
@db["te$t"]
|
|
59
469
|
end
|
|
60
470
|
|
|
61
471
|
assert_raise Mongo::InvalidNSName do
|
|
62
|
-
|
|
472
|
+
@db['$main']
|
|
63
473
|
end
|
|
64
474
|
|
|
65
|
-
assert
|
|
66
|
-
assert
|
|
475
|
+
assert @db['$cmd']
|
|
476
|
+
assert @db['oplog.$main']
|
|
67
477
|
end
|
|
68
478
|
|
|
69
479
|
def test_collection
|
|
70
|
-
assert_kind_of Collection,
|
|
71
|
-
assert_equal
|
|
72
|
-
assert_equal
|
|
480
|
+
assert_kind_of Collection, @db["test"]
|
|
481
|
+
assert_equal @db["test"].name(), @db.collection("test").name()
|
|
482
|
+
assert_equal @db["test"].name(), @db[:test].name()
|
|
73
483
|
|
|
74
|
-
assert_kind_of Collection,
|
|
75
|
-
assert_equal
|
|
76
|
-
assert_equal
|
|
484
|
+
assert_kind_of Collection, @db["test"]["foo"]
|
|
485
|
+
assert_equal @db["test"]["foo"].name(), @db.collection("test.foo").name()
|
|
486
|
+
assert_equal @db["test"]["foo"].name(), @db["test.foo"].name()
|
|
77
487
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
assert_equal 5,
|
|
488
|
+
@db["test"]["foo"].remove
|
|
489
|
+
@db["test"]["foo"].insert("x" => 5)
|
|
490
|
+
assert_equal 5, @db.collection("test.foo").find_one()["x"]
|
|
81
491
|
end
|
|
82
492
|
|
|
83
493
|
def test_rename_collection
|
|
84
|
-
|
|
85
|
-
|
|
494
|
+
@db.drop_collection('foo1')
|
|
495
|
+
@db.drop_collection('bar1')
|
|
86
496
|
|
|
87
|
-
@col =
|
|
497
|
+
@col = @db.create_collection('foo1')
|
|
88
498
|
assert_equal 'foo1', @col.name
|
|
89
499
|
|
|
90
500
|
@col.rename('bar1')
|
|
@@ -92,65 +502,69 @@ class TestCollection < Test::Unit::TestCase
|
|
|
92
502
|
end
|
|
93
503
|
|
|
94
504
|
def test_nil_id
|
|
95
|
-
assert_equal 5,
|
|
96
|
-
assert_equal 5,
|
|
97
|
-
assert_equal nil,
|
|
98
|
-
assert_equal "baz",
|
|
505
|
+
assert_equal 5, @test.insert({"_id" => 5, "foo" => "bar"})
|
|
506
|
+
assert_equal 5, @test.save({"_id" => 5, "foo" => "baz"})
|
|
507
|
+
assert_equal nil, @test.find_one("foo" => "bar")
|
|
508
|
+
assert_equal "baz", @test.find_one(:_id => 5)["foo"]
|
|
99
509
|
assert_raise OperationFailure do
|
|
100
|
-
|
|
510
|
+
@test.insert({"_id" => 5, "foo" => "bar"})
|
|
101
511
|
end
|
|
102
512
|
|
|
103
|
-
assert_equal nil,
|
|
104
|
-
assert_equal nil,
|
|
105
|
-
assert_equal nil,
|
|
106
|
-
assert_equal "baz",
|
|
513
|
+
assert_equal nil, @test.insert({"_id" => nil, "foo" => "bar"})
|
|
514
|
+
assert_equal nil, @test.save({"_id" => nil, "foo" => "baz"})
|
|
515
|
+
assert_equal nil, @test.find_one("foo" => "bar")
|
|
516
|
+
assert_equal "baz", @test.find_one(:_id => nil)["foo"]
|
|
107
517
|
assert_raise OperationFailure do
|
|
108
|
-
|
|
518
|
+
@test.insert({"_id" => nil, "foo" => "bar"})
|
|
109
519
|
end
|
|
110
520
|
assert_raise OperationFailure do
|
|
111
|
-
|
|
521
|
+
@test.insert({:_id => nil, "foo" => "bar"})
|
|
112
522
|
end
|
|
113
523
|
end
|
|
114
524
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
525
|
+
def setup_for_distinct
|
|
526
|
+
return unless @version > "1.1"
|
|
527
|
+
@test.remove
|
|
528
|
+
@test.insert([{:a => 0, :b => {:c => "a"}},
|
|
529
|
+
{:a => 1, :b => {:c => "b"}},
|
|
530
|
+
{:a => 1, :b => {:c => "c"}},
|
|
531
|
+
{:a => 2, :b => {:c => "a"}},
|
|
532
|
+
{:a => 3},
|
|
533
|
+
{:a => 3}])
|
|
534
|
+
end
|
|
125
535
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
536
|
+
def test_distinct_queries
|
|
537
|
+
return unless @version > "1.1"
|
|
538
|
+
setup_for_distinct
|
|
539
|
+
assert_equal [0, 1, 2, 3], @test.distinct(:a).sort
|
|
540
|
+
assert_equal ["a", "b", "c"], @test.distinct("b.c").sort
|
|
541
|
+
end
|
|
131
542
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
543
|
+
def test_filter_collection_with_query
|
|
544
|
+
return unless @version >= "1.2"
|
|
545
|
+
setup_for_distinct
|
|
546
|
+
assert_equal [2, 3], @test.distinct(:a, {:a => {"$gt" => 1}}).sort
|
|
547
|
+
end
|
|
137
548
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
end
|
|
549
|
+
def test_filter_nested_objects
|
|
550
|
+
return unless @version >= "1.2"
|
|
551
|
+
setup_for_distinct
|
|
552
|
+
assert_equal ["a", "b"], @test.distinct("b.c", {"b.c" => {"$ne" => "c"}}).sort
|
|
143
553
|
end
|
|
144
554
|
|
|
145
555
|
def test_safe_insert
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
556
|
+
@test.create_index("hello", :unique => true)
|
|
557
|
+
begin
|
|
558
|
+
a = {"hello" => "world"}
|
|
559
|
+
@test.insert(a)
|
|
560
|
+
@test.insert(a, :w => 0)
|
|
561
|
+
assert(@db.get_last_error['err'].include?("11000"))
|
|
151
562
|
|
|
152
|
-
|
|
153
|
-
|
|
563
|
+
assert_raise OperationFailure do
|
|
564
|
+
@test.insert(a)
|
|
565
|
+
end
|
|
566
|
+
ensure
|
|
567
|
+
@test.drop_indexes
|
|
154
568
|
end
|
|
155
569
|
end
|
|
156
570
|
|
|
@@ -159,38 +573,41 @@ class TestCollection < Test::Unit::TestCase
|
|
|
159
573
|
docs << {:foo => 1}
|
|
160
574
|
docs << {:foo => 2}
|
|
161
575
|
docs << {:foo => 3}
|
|
162
|
-
response =
|
|
576
|
+
response = @test.insert(docs)
|
|
163
577
|
assert_equal 3, response.length
|
|
164
578
|
assert response.all? {|id| id.is_a?(BSON::ObjectId)}
|
|
165
|
-
assert_equal 3,
|
|
579
|
+
assert_equal 3, @test.count
|
|
166
580
|
end
|
|
167
581
|
|
|
168
582
|
def test_bulk_insert_with_continue_on_error
|
|
169
|
-
if
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
583
|
+
if @version >= "2.0"
|
|
584
|
+
@test.create_index([["foo", 1]], :unique => true)
|
|
585
|
+
begin
|
|
586
|
+
docs = []
|
|
587
|
+
docs << {:foo => 1}
|
|
588
|
+
docs << {:foo => 1}
|
|
589
|
+
docs << {:foo => 2}
|
|
590
|
+
docs << {:foo => 3}
|
|
591
|
+
assert_raise OperationFailure do
|
|
592
|
+
@test.insert(docs)
|
|
593
|
+
end
|
|
594
|
+
assert_equal 1, @test.count
|
|
595
|
+
@test.remove
|
|
596
|
+
|
|
597
|
+
docs = []
|
|
598
|
+
docs << {:foo => 1}
|
|
599
|
+
docs << {:foo => 1}
|
|
600
|
+
docs << {:foo => 2}
|
|
601
|
+
docs << {:foo => 3}
|
|
602
|
+
assert_raise OperationFailure do
|
|
603
|
+
@test.insert(docs, :continue_on_error => true)
|
|
604
|
+
end
|
|
605
|
+
assert_equal 3, @test.count
|
|
191
606
|
|
|
192
|
-
|
|
193
|
-
|
|
607
|
+
@test.remove
|
|
608
|
+
ensure
|
|
609
|
+
@test.drop_index("foo_1")
|
|
610
|
+
end
|
|
194
611
|
end
|
|
195
612
|
end
|
|
196
613
|
|
|
@@ -198,8 +615,8 @@ class TestCollection < Test::Unit::TestCase
|
|
|
198
615
|
docs = []
|
|
199
616
|
docs << {:foo => 1}
|
|
200
617
|
docs << {:bar => 1}
|
|
201
|
-
doc_ids, error_docs =
|
|
202
|
-
assert_equal 2,
|
|
618
|
+
doc_ids, error_docs = @test.insert(docs, :collect_on_error => true)
|
|
619
|
+
assert_equal 2, @test.count
|
|
203
620
|
assert_equal 2, doc_ids.count
|
|
204
621
|
assert_equal error_docs, []
|
|
205
622
|
end
|
|
@@ -213,12 +630,12 @@ class TestCollection < Test::Unit::TestCase
|
|
|
213
630
|
invalid_docs << {'invalid.key' => 1}
|
|
214
631
|
docs += invalid_docs
|
|
215
632
|
assert_raise BSON::InvalidKeyName do
|
|
216
|
-
|
|
633
|
+
@test.insert(docs, :collect_on_error => false)
|
|
217
634
|
end
|
|
218
|
-
assert_equal
|
|
635
|
+
assert_equal 2, @test.count
|
|
219
636
|
|
|
220
|
-
doc_ids, error_docs =
|
|
221
|
-
assert_equal 2,
|
|
637
|
+
doc_ids, error_docs = @test.insert(docs, :collect_on_error => true)
|
|
638
|
+
assert_equal 2, @test.count
|
|
222
639
|
assert_equal 2, doc_ids.count
|
|
223
640
|
assert_equal error_docs, invalid_docs
|
|
224
641
|
end
|
|
@@ -234,230 +651,334 @@ class TestCollection < Test::Unit::TestCase
|
|
|
234
651
|
docs += invalid_docs
|
|
235
652
|
|
|
236
653
|
assert_raise BSON::InvalidStringEncoding do
|
|
237
|
-
|
|
654
|
+
@test.insert(docs, :collect_on_error => false)
|
|
238
655
|
end
|
|
239
|
-
assert_equal
|
|
656
|
+
assert_equal 2, @test.count
|
|
240
657
|
|
|
241
|
-
doc_ids, error_docs =
|
|
242
|
-
assert_equal 2,
|
|
658
|
+
doc_ids, error_docs = @test.insert(docs, :collect_on_error => true)
|
|
659
|
+
assert_equal 2, @test.count
|
|
243
660
|
assert_equal 2, doc_ids.count
|
|
244
661
|
assert_equal error_docs, invalid_docs
|
|
245
662
|
end
|
|
246
663
|
|
|
664
|
+
def test_insert_one_error_doc_with_collect_on_error
|
|
665
|
+
invalid_doc = {'$invalid-key' => 1}
|
|
666
|
+
invalid_docs = [invalid_doc]
|
|
667
|
+
doc_ids, error_docs = @test.insert(invalid_docs, :collect_on_error => true)
|
|
668
|
+
assert_equal [], doc_ids
|
|
669
|
+
assert_equal [invalid_doc], error_docs
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
def test_insert_empty_docs_raises_exception
|
|
673
|
+
assert_raise OperationFailure do
|
|
674
|
+
@test.insert([])
|
|
675
|
+
end
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
def test_insert_empty_docs_with_collect_on_error_raises_exception
|
|
679
|
+
assert_raise OperationFailure do
|
|
680
|
+
@test.insert([], :collect_on_error => true)
|
|
681
|
+
end
|
|
682
|
+
end
|
|
683
|
+
|
|
247
684
|
def limited_collection
|
|
248
685
|
conn = standard_connection(:connect => false)
|
|
686
|
+
is_master = @ismaster.merge('maxBsonObjectSize' => LIMITED_MAX_BSON_SIZE,
|
|
687
|
+
'maxMessageSizeBytes' => LIMITED_MAX_BSON_SIZE)
|
|
249
688
|
admin_db = Object.new
|
|
250
|
-
admin_db.expects(:command).returns(
|
|
251
|
-
|
|
252
|
-
'ismaster' => 1,
|
|
253
|
-
'maxBsonObjectSize' => 1024,
|
|
254
|
-
'maxMessageSizeBytes' => 3 * 1024
|
|
255
|
-
})
|
|
256
|
-
conn.expects(:[]).with('admin').returns(admin_db)
|
|
689
|
+
admin_db.expects(:command).returns(is_master)
|
|
690
|
+
conn.expects(:[]).with(TEST_DB).returns(admin_db)
|
|
257
691
|
conn.connect
|
|
258
|
-
return conn.db(
|
|
692
|
+
return conn.db(TEST_DB)["test"]
|
|
259
693
|
end
|
|
260
694
|
|
|
261
|
-
def
|
|
695
|
+
def test_non_operation_failure_halts_insertion_with_continue_on_error
|
|
696
|
+
coll = limited_collection
|
|
697
|
+
if @client.wire_version_feature?(MongoClient::BATCH_COMMANDS)
|
|
698
|
+
coll.db.stubs(:command).raises(OperationTimeout).times(1)
|
|
699
|
+
else
|
|
700
|
+
coll.db.connection.stubs(:send_message_with_gle).raises(OperationTimeout).times(1)
|
|
701
|
+
end
|
|
262
702
|
docs = []
|
|
263
|
-
|
|
264
|
-
docs << {'foo' => 'a' *
|
|
703
|
+
10.times do
|
|
704
|
+
docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
|
|
705
|
+
end
|
|
706
|
+
assert_raise OperationTimeout do
|
|
707
|
+
coll.insert(docs, :continue_on_error => true)
|
|
265
708
|
end
|
|
266
|
-
assert_equal limited_collection.insert(docs).length, 3
|
|
267
709
|
end
|
|
268
710
|
|
|
269
|
-
def
|
|
270
|
-
|
|
271
|
-
|
|
711
|
+
def test_chunking_batch_insert
|
|
712
|
+
docs = []
|
|
713
|
+
10.times do
|
|
714
|
+
docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
|
|
715
|
+
end
|
|
716
|
+
limited_collection.insert(docs)
|
|
717
|
+
assert_equal 10, limited_collection.count
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
def test_chunking_batch_insert_without_collect_on_error
|
|
721
|
+
docs = []
|
|
722
|
+
4.times do
|
|
723
|
+
docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
|
|
724
|
+
end
|
|
725
|
+
invalid_docs = []
|
|
726
|
+
invalid_docs << {'$invalid-key' => 1} # non utf8 encoding
|
|
727
|
+
docs += invalid_docs
|
|
728
|
+
4.times do
|
|
729
|
+
docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
|
|
730
|
+
end
|
|
731
|
+
assert_raise BSON::InvalidKeyName do
|
|
732
|
+
limited_collection.insert(docs, :collect_on_error => false)
|
|
733
|
+
end
|
|
734
|
+
end
|
|
735
|
+
|
|
736
|
+
def test_chunking_batch_insert_with_collect_on_error
|
|
737
|
+
# Broken for current JRuby
|
|
738
|
+
if RUBY_PLATFORM == 'java' then return end
|
|
739
|
+
docs = []
|
|
740
|
+
4.times do
|
|
741
|
+
docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
|
|
742
|
+
end
|
|
743
|
+
invalid_docs = []
|
|
744
|
+
invalid_docs << {'$invalid-key' => 1} # non utf8 encoding
|
|
745
|
+
docs += invalid_docs
|
|
746
|
+
4.times do
|
|
747
|
+
docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
|
|
748
|
+
end
|
|
749
|
+
doc_ids, error_docs = limited_collection.insert(docs, :collect_on_error => true)
|
|
750
|
+
assert_equal 8, doc_ids.count
|
|
751
|
+
assert_equal doc_ids.count, limited_collection.count
|
|
752
|
+
assert_equal error_docs, invalid_docs
|
|
753
|
+
end
|
|
754
|
+
|
|
755
|
+
def test_chunking_batch_insert_with_continue_on_error
|
|
756
|
+
coll = limited_collection
|
|
757
|
+
docs = []
|
|
758
|
+
4.times do
|
|
759
|
+
docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
|
|
760
|
+
end
|
|
761
|
+
docs << {'_id' => 'b', 'foo' => 'a'}
|
|
762
|
+
docs << {'_id' => 'b', 'foo' => 'c'}
|
|
763
|
+
4.times do
|
|
764
|
+
docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
|
|
765
|
+
end
|
|
766
|
+
assert_raise OperationFailure do
|
|
767
|
+
coll.insert(docs, :continue_on_error => true)
|
|
272
768
|
end
|
|
769
|
+
assert coll.count >= 6, "write commands need headroom for doc wrapping overhead - count:#{coll.count}"
|
|
273
770
|
end
|
|
274
771
|
|
|
275
|
-
def
|
|
772
|
+
def test_chunking_batch_insert_without_continue_on_error
|
|
276
773
|
docs = []
|
|
277
774
|
4.times do
|
|
278
|
-
docs << {'foo' => 'a' *
|
|
775
|
+
docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
|
|
776
|
+
end
|
|
777
|
+
docs << {'_id' => 'b', 'foo' => 'a'}
|
|
778
|
+
docs << {'_id' => 'b', 'foo' => 'c'}
|
|
779
|
+
4.times do
|
|
780
|
+
docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
|
|
781
|
+
end
|
|
782
|
+
assert_raise OperationFailure do
|
|
783
|
+
limited_collection.insert(docs, :continue_on_error => false)
|
|
784
|
+
end
|
|
785
|
+
assert_equal 5, limited_collection.count
|
|
786
|
+
end
|
|
787
|
+
|
|
788
|
+
def test_maximum_insert_size
|
|
789
|
+
docs = []
|
|
790
|
+
3.times do
|
|
791
|
+
docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
|
|
279
792
|
end
|
|
793
|
+
assert_equal limited_collection.insert(docs).length, 3
|
|
794
|
+
end
|
|
280
795
|
|
|
281
|
-
|
|
282
|
-
|
|
796
|
+
def test_maximum_document_size
|
|
797
|
+
assert_raise InvalidDocument do
|
|
798
|
+
limited_collection.insert({'foo' => 'a' * LIMITED_BSON_SIZE_WITH_HEADROOM})
|
|
283
799
|
end
|
|
284
800
|
end
|
|
285
801
|
|
|
286
802
|
def test_maximum_save_size
|
|
287
|
-
assert limited_collection.save({'foo' => 'a' *
|
|
803
|
+
assert limited_collection.save({'foo' => 'a' * LIMITED_VALID_VALUE_SIZE})
|
|
288
804
|
assert_raise InvalidDocument do
|
|
289
|
-
limited_collection.save({'foo' => 'a' *
|
|
805
|
+
limited_collection.save({'foo' => 'a' * LIMITED_BSON_SIZE_WITH_HEADROOM})
|
|
290
806
|
end
|
|
291
807
|
end
|
|
292
808
|
|
|
293
809
|
def test_maximum_remove_size
|
|
294
|
-
assert limited_collection.remove({'foo' => 'a' *
|
|
810
|
+
assert limited_collection.remove({'foo' => 'a' * LIMITED_VALID_VALUE_SIZE})
|
|
295
811
|
assert_raise InvalidDocument do
|
|
296
|
-
limited_collection.remove({'foo' => 'a' *
|
|
812
|
+
limited_collection.remove({'foo' => 'a' * LIMITED_BSON_SIZE_WITH_HEADROOM})
|
|
297
813
|
end
|
|
298
814
|
end
|
|
299
815
|
|
|
300
816
|
def test_maximum_update_size
|
|
301
817
|
assert_raise InvalidDocument do
|
|
302
818
|
limited_collection.update(
|
|
303
|
-
{'foo' => 'a' *
|
|
304
|
-
{'foo' => 'a' *
|
|
819
|
+
{'foo' => 'a' * LIMITED_BSON_SIZE_WITH_HEADROOM},
|
|
820
|
+
{'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
|
|
305
821
|
)
|
|
306
822
|
end
|
|
307
823
|
|
|
308
824
|
assert_raise InvalidDocument do
|
|
309
825
|
limited_collection.update(
|
|
310
|
-
{'foo' => 'a' *
|
|
311
|
-
{'foo' => 'a' *
|
|
826
|
+
{'foo' => 'a' * LIMITED_BSON_SIZE_WITH_HEADROOM},
|
|
827
|
+
{'foo' => 'a' * LIMITED_MAX_BSON_SIZE}
|
|
312
828
|
)
|
|
313
829
|
end
|
|
314
830
|
|
|
315
831
|
assert_raise InvalidDocument do
|
|
316
832
|
limited_collection.update(
|
|
317
|
-
{'foo' => 'a' *
|
|
318
|
-
{'foo' => 'a' *
|
|
833
|
+
{'foo' => 'a' * LIMITED_BSON_SIZE_WITH_HEADROOM},
|
|
834
|
+
{'foo' => 'a' * LIMITED_BSON_SIZE_WITH_HEADROOM}
|
|
319
835
|
)
|
|
320
836
|
end
|
|
321
837
|
|
|
322
838
|
assert limited_collection.update(
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
839
|
+
{'foo' => 'a' * (LIMITED_VALID_VALUE_SIZE/2)},
|
|
840
|
+
{'foo' => 'a' * (LIMITED_VALID_VALUE_SIZE/2)}
|
|
841
|
+
)
|
|
326
842
|
end
|
|
327
843
|
|
|
328
844
|
def test_maximum_query_size
|
|
329
|
-
assert limited_collection.find({'foo' => 'a' *
|
|
845
|
+
assert limited_collection.find({'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}).to_a
|
|
330
846
|
assert limited_collection.find(
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
847
|
+
{'foo' => 'a' * LIMITED_VALID_VALUE_SIZE},
|
|
848
|
+
{:fields => {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}}
|
|
849
|
+
).to_a
|
|
334
850
|
|
|
335
851
|
assert_raise InvalidDocument do
|
|
336
|
-
limited_collection.find({'foo' => 'a' *
|
|
852
|
+
limited_collection.find({'foo' => 'a' * LIMITED_INVALID_VALUE_SIZE}).to_a
|
|
337
853
|
end
|
|
338
854
|
|
|
339
855
|
assert_raise InvalidDocument do
|
|
340
856
|
limited_collection.find(
|
|
341
|
-
{'foo' => 'a' *
|
|
342
|
-
{:fields => {'foo' => 'a' *
|
|
857
|
+
{'foo' => 'a' * LIMITED_VALID_VALUE_SIZE},
|
|
858
|
+
{:fields => {'foo' => 'a' * LIMITED_MAX_BSON_SIZE}}
|
|
343
859
|
).to_a
|
|
344
860
|
end
|
|
345
861
|
end
|
|
346
862
|
|
|
347
|
-
#if
|
|
863
|
+
#if @version >= "1.5.1"
|
|
348
864
|
# def test_safe_mode_with_advanced_safe_with_invalid_options
|
|
349
865
|
# assert_raise_error ArgumentError, "Unknown key(s): wtime" do
|
|
350
|
-
#
|
|
866
|
+
# @test.insert({:foo => 1}, :w => 2, :wtime => 1, :fsync => true)
|
|
351
867
|
# end
|
|
352
868
|
# assert_raise_error ArgumentError, "Unknown key(s): wtime" do
|
|
353
|
-
#
|
|
869
|
+
# @test.update({:foo => 1}, {:foo => 2}, :w => 2, :wtime => 1, :fsync => true)
|
|
354
870
|
# end
|
|
355
871
|
#
|
|
356
872
|
# assert_raise_error ArgumentError, "Unknown key(s): wtime" do
|
|
357
|
-
#
|
|
873
|
+
# @test.remove({:foo => 2}, :w => 2, :wtime => 1, :fsync => true)
|
|
358
874
|
# end
|
|
359
875
|
# end
|
|
360
876
|
#end
|
|
361
877
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
878
|
+
def test_safe_mode_with_journal_commit_option
|
|
879
|
+
with_default_journaling(@client) do
|
|
880
|
+
@test.insert({:foo => 1}, :j => true)
|
|
881
|
+
@test.update({:foo => 1}, {:foo => 2}, :j => true)
|
|
882
|
+
@test.remove({:foo => 2}, :j => true)
|
|
883
|
+
end
|
|
884
|
+
end
|
|
885
|
+
|
|
886
|
+
def test_jnote_raises_exception
|
|
887
|
+
return unless @version < "2.5.3"
|
|
888
|
+
with_no_journaling(@client) do
|
|
889
|
+
ex = assert_raise Mongo::WriteConcernError do
|
|
890
|
+
@test.insert({:foo => 1}, :j => true)
|
|
891
|
+
end
|
|
892
|
+
result = ex.result
|
|
893
|
+
assert_true result.has_key?("jnote")
|
|
367
894
|
end
|
|
368
895
|
end
|
|
369
896
|
|
|
897
|
+
def test_wnote_raises_exception_with_err_not_nil
|
|
898
|
+
return unless @version < "2.5.3"
|
|
899
|
+
ex = assert_raise Mongo::WriteConcernError do
|
|
900
|
+
@test.insert({:foo => 1}, :w => 2)
|
|
901
|
+
end
|
|
902
|
+
result = ex.result
|
|
903
|
+
assert_not_nil result["err"]
|
|
904
|
+
assert_true result.has_key?("wnote")
|
|
905
|
+
end
|
|
906
|
+
|
|
370
907
|
def test_update
|
|
371
|
-
id1 =
|
|
372
|
-
|
|
373
|
-
assert_equal 1,
|
|
374
|
-
assert_equal 6,
|
|
908
|
+
id1 = @test.save("x" => 5)
|
|
909
|
+
@test.update({}, {"$inc" => {"x" => 1}})
|
|
910
|
+
assert_equal 1, @test.count()
|
|
911
|
+
assert_equal 6, @test.find_one(:_id => id1)["x"]
|
|
375
912
|
|
|
376
|
-
id2 =
|
|
377
|
-
|
|
378
|
-
assert_equal 7,
|
|
379
|
-
assert_equal 1,
|
|
913
|
+
id2 = @test.save("x" => 1)
|
|
914
|
+
@test.update({"x" => 6}, {"$inc" => {"x" => 1}})
|
|
915
|
+
assert_equal 7, @test.find_one(:_id => id1)["x"]
|
|
916
|
+
assert_equal 1, @test.find_one(:_id => id2)["x"]
|
|
380
917
|
end
|
|
381
918
|
|
|
382
919
|
def test_update_check_keys
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
920
|
+
return unless @version < "2.5.3"
|
|
921
|
+
@test.save("x" => 1)
|
|
922
|
+
@test.update({"x" => 1}, {"$set" => {"a.b" => 2}})
|
|
923
|
+
assert_equal 2, @test.find_one("x" => 1)["a"]["b"]
|
|
386
924
|
|
|
387
925
|
assert_raise_error BSON::InvalidKeyName do
|
|
388
|
-
|
|
926
|
+
@test.update({"x" => 1}, {"a.b" => 3})
|
|
389
927
|
end
|
|
390
928
|
end
|
|
391
929
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
930
|
+
def test_multi_update
|
|
931
|
+
return unless @version >= "1.1.3"
|
|
932
|
+
@test.save("num" => 10)
|
|
933
|
+
@test.save("num" => 10)
|
|
934
|
+
@test.save("num" => 10)
|
|
935
|
+
assert_equal 3, @test.count
|
|
398
936
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
end
|
|
937
|
+
@test.update({"num" => 10}, {"$set" => {"num" => 100}}, :multi => true)
|
|
938
|
+
@test.find.each do |doc|
|
|
939
|
+
assert_equal 100, doc["num"]
|
|
403
940
|
end
|
|
404
941
|
end
|
|
405
942
|
|
|
406
943
|
def test_upsert
|
|
407
|
-
|
|
408
|
-
|
|
944
|
+
@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
|
|
945
|
+
@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
|
|
409
946
|
|
|
410
|
-
assert_equal 1,
|
|
411
|
-
assert_equal 2,
|
|
947
|
+
assert_equal 1, @test.count()
|
|
948
|
+
assert_equal 2, @test.find_one()["count"]
|
|
412
949
|
end
|
|
413
950
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
@@test.update({}, {"$inc" => {"x" => 1}})
|
|
420
|
-
assert @@db.error?
|
|
421
|
-
|
|
422
|
-
# Can't change an index.
|
|
423
|
-
assert_raise OperationFailure do
|
|
424
|
-
@@test.update({}, {"$inc" => {"x" => 1}})
|
|
425
|
-
end
|
|
426
|
-
@@test.drop
|
|
427
|
-
end
|
|
428
|
-
else
|
|
429
|
-
def test_safe_update
|
|
430
|
-
@@test.create_index("x", :unique => true)
|
|
431
|
-
@@test.insert("x" => 5)
|
|
432
|
-
@@test.insert("x" => 10)
|
|
951
|
+
def test_safe_update
|
|
952
|
+
@test.create_index("x", :unique => true)
|
|
953
|
+
@test.insert("x" => 5)
|
|
954
|
+
@test.insert("x" => 10)
|
|
433
955
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
956
|
+
# Can update an indexed collection.
|
|
957
|
+
@test.update({}, {"$inc" => {"x" => 1}})
|
|
958
|
+
assert !@db.error?
|
|
437
959
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
end
|
|
442
|
-
@@test.drop
|
|
960
|
+
# Can't duplicate an index.
|
|
961
|
+
assert_raise OperationFailure do
|
|
962
|
+
@test.update({}, {"x" => 10})
|
|
443
963
|
end
|
|
964
|
+
@test.drop
|
|
444
965
|
end
|
|
445
966
|
|
|
446
967
|
def test_safe_save
|
|
447
|
-
|
|
968
|
+
@test.create_index("hello", :unique => true)
|
|
448
969
|
|
|
449
|
-
|
|
450
|
-
|
|
970
|
+
@test.save("hello" => "world")
|
|
971
|
+
@test.save({"hello" => "world"}, :w => 0)
|
|
451
972
|
|
|
452
973
|
assert_raise OperationFailure do
|
|
453
|
-
|
|
974
|
+
@test.save({"hello" => "world"})
|
|
454
975
|
end
|
|
455
|
-
|
|
976
|
+
@test.drop
|
|
456
977
|
end
|
|
457
978
|
|
|
458
979
|
def test_mocked_safe_remove
|
|
459
980
|
@client = standard_connection
|
|
460
|
-
@db = @client[
|
|
981
|
+
@db = @client[TEST_DB]
|
|
461
982
|
@test = @db['test-safe-remove']
|
|
462
983
|
@test.save({:a => 20})
|
|
463
984
|
@client.stubs(:receive).returns([[{'ok' => 0, 'err' => 'failed'}], 1, 0])
|
|
@@ -470,7 +991,7 @@ class TestCollection < Test::Unit::TestCase
|
|
|
470
991
|
|
|
471
992
|
def test_safe_remove
|
|
472
993
|
@client = standard_connection
|
|
473
|
-
@db = @client[
|
|
994
|
+
@db = @client[TEST_DB]
|
|
474
995
|
@test = @db['test-safe-remove']
|
|
475
996
|
@test.remove
|
|
476
997
|
@test.save({:a => 50})
|
|
@@ -479,115 +1000,216 @@ class TestCollection < Test::Unit::TestCase
|
|
|
479
1000
|
end
|
|
480
1001
|
|
|
481
1002
|
def test_remove_return_value
|
|
482
|
-
assert_equal true,
|
|
1003
|
+
assert_equal true, @test.remove({}, :w => 0)
|
|
1004
|
+
end
|
|
1005
|
+
|
|
1006
|
+
def test_remove_with_limit
|
|
1007
|
+
@test.insert([{:n => 1},{:n => 2},{:n => 3}])
|
|
1008
|
+
@test.remove({}, :limit => 1)
|
|
1009
|
+
assert_equal 2, @test.count
|
|
1010
|
+
@test.remove({}, :limit => 0)
|
|
1011
|
+
assert_equal 0, @test.count
|
|
483
1012
|
end
|
|
484
1013
|
|
|
485
1014
|
def test_count
|
|
486
|
-
|
|
1015
|
+
@test.drop
|
|
487
1016
|
|
|
488
|
-
assert_equal 0,
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
assert_equal 2,
|
|
1017
|
+
assert_equal 0, @test.count
|
|
1018
|
+
@test.save(:x => 1)
|
|
1019
|
+
@test.save(:x => 2)
|
|
1020
|
+
assert_equal 2, @test.count
|
|
492
1021
|
|
|
493
|
-
assert_equal 1,
|
|
494
|
-
assert_equal 1,
|
|
495
|
-
assert_equal 0,
|
|
1022
|
+
assert_equal 1, @test.count(:query => {:x => 1})
|
|
1023
|
+
assert_equal 1, @test.count(:limit => 1)
|
|
1024
|
+
assert_equal 0, @test.count(:skip => 2)
|
|
1025
|
+
end
|
|
1026
|
+
|
|
1027
|
+
def test_count_with_hint
|
|
1028
|
+
@test.drop
|
|
1029
|
+
@test.save(:i => 1)
|
|
1030
|
+
@test.save(:i => 2)
|
|
1031
|
+
assert_equal 2, @test.count
|
|
1032
|
+
|
|
1033
|
+
@test.ensure_index(BSON::OrderedHash[:i, Mongo::ASCENDING])
|
|
1034
|
+
|
|
1035
|
+
# Check that a named_hint can be specified
|
|
1036
|
+
assert_equal 1, @test.count(:query => { :i => 1 }, :named_hint => '_id_')
|
|
1037
|
+
assert_equal 2, @test.count(:query => { }, :named_hint => '_id_')
|
|
1038
|
+
|
|
1039
|
+
# Verify that the hint is being sent to the server by providing a bad hint
|
|
1040
|
+
if @version > '2.6'
|
|
1041
|
+
assert_raise Mongo::OperationFailure do
|
|
1042
|
+
@test.count(:query => { :i => 1 }, :hint => 'bad_hint')
|
|
1043
|
+
end
|
|
1044
|
+
else
|
|
1045
|
+
assert_equal 1, @test.count(:query => { :i => 1 }, :hint => 'bad_hint')
|
|
1046
|
+
end
|
|
1047
|
+
|
|
1048
|
+
# Verify that the named_hint is being sent to the server by providing a bad hint
|
|
1049
|
+
if @version > '2.6'
|
|
1050
|
+
assert_raise Mongo::OperationFailure do
|
|
1051
|
+
@test.count(:query => { :i => 1 }, :named_hint => 'bad_hint')
|
|
1052
|
+
end
|
|
1053
|
+
else
|
|
1054
|
+
assert_equal 1, @test.count(:query => { :i => 1 }, :named_hint => 'bad_hint')
|
|
1055
|
+
end
|
|
1056
|
+
|
|
1057
|
+
@test.ensure_index(BSON::OrderedHash[:x, Mongo::ASCENDING], :sparse => true)
|
|
1058
|
+
|
|
1059
|
+
# The sparse index won't have any entries.
|
|
1060
|
+
# Check that count returns 0 when using the hint.
|
|
1061
|
+
expected = @version > '2.6' ? 0 : 1
|
|
1062
|
+
assert_equal expected, @test.count(:query => { :i => 1 }, :hint => { 'x' => 1 })
|
|
1063
|
+
assert_equal expected, @test.count(:query => { :i => 1 }, :hint => 'x')
|
|
1064
|
+
assert_equal expected, @test.count(:query => { :i => 1 }, :named_hint => 'x_1')
|
|
1065
|
+
|
|
1066
|
+
# Verify that the hint / named hint set on the collection is used.
|
|
1067
|
+
@test.hint = { 'x' => 1 }
|
|
1068
|
+
assert_equal expected, @test.count(:query => { :i => 1 })
|
|
1069
|
+
|
|
1070
|
+
@test.hint = 'x'
|
|
1071
|
+
assert_equal expected, @test.count(:query => { :i => 1 })
|
|
1072
|
+
|
|
1073
|
+
# The driver should allow x_1, but the code sets named_hint to @hint without
|
|
1074
|
+
# normalizing.
|
|
1075
|
+
@test.named_hint = 'x'
|
|
1076
|
+
assert_equal expected, @test.count(:query => { :i => 1 })
|
|
1077
|
+
|
|
1078
|
+
assert_equal 2, @test.count(:query => { }, :hint => 'x')
|
|
1079
|
+
assert_equal 2, @test.count(:query => { }, :named_hint => 'x_1')
|
|
496
1080
|
end
|
|
497
1081
|
|
|
498
1082
|
# Note: #size is just an alias for #count.
|
|
499
1083
|
def test_size
|
|
500
|
-
|
|
1084
|
+
@test.drop
|
|
501
1085
|
|
|
502
|
-
assert_equal 0,
|
|
503
|
-
assert_equal
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
assert_equal
|
|
1086
|
+
assert_equal 0, @test.count
|
|
1087
|
+
assert_equal @test.size, @test.count
|
|
1088
|
+
@test.save("x" => 1)
|
|
1089
|
+
@test.save("x" => 2)
|
|
1090
|
+
assert_equal @test.size, @test.count
|
|
507
1091
|
end
|
|
508
1092
|
|
|
509
1093
|
def test_no_timeout_option
|
|
510
|
-
|
|
1094
|
+
@test.drop
|
|
511
1095
|
|
|
512
1096
|
assert_raise ArgumentError, "Timeout can be set to false only when #find is invoked with a block." do
|
|
513
|
-
|
|
1097
|
+
@test.find({}, :timeout => false)
|
|
514
1098
|
end
|
|
515
1099
|
|
|
516
|
-
|
|
1100
|
+
@test.find({}, :timeout => false) do |cursor|
|
|
517
1101
|
assert_equal 0, cursor.count
|
|
518
1102
|
end
|
|
519
1103
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
1104
|
+
@test.save("x" => 1)
|
|
1105
|
+
@test.save("x" => 2)
|
|
1106
|
+
@test.find({}, :timeout => false) do |cursor|
|
|
523
1107
|
assert_equal 2, cursor.count
|
|
524
1108
|
end
|
|
525
1109
|
end
|
|
526
1110
|
|
|
527
|
-
def
|
|
528
|
-
cursor =
|
|
1111
|
+
def test_default_timeout
|
|
1112
|
+
cursor = @test.find
|
|
529
1113
|
assert_equal true, cursor.timeout
|
|
530
1114
|
end
|
|
531
1115
|
|
|
532
1116
|
def test_fields_as_hash
|
|
533
|
-
|
|
1117
|
+
@test.save(:a => 1, :b => 1, :c => 1)
|
|
534
1118
|
|
|
535
|
-
doc =
|
|
1119
|
+
doc = @test.find_one({:a => 1}, :fields => {:b => 0})
|
|
536
1120
|
assert_nil doc['b']
|
|
537
1121
|
assert doc['a']
|
|
538
1122
|
assert doc['c']
|
|
539
1123
|
|
|
540
|
-
doc =
|
|
1124
|
+
doc = @test.find_one({:a => 1}, :fields => {:a => 1, :b => 1})
|
|
541
1125
|
assert_nil doc['c']
|
|
542
1126
|
assert doc['a']
|
|
543
1127
|
assert doc['b']
|
|
544
1128
|
|
|
545
1129
|
|
|
546
1130
|
assert_raise Mongo::OperationFailure do
|
|
547
|
-
|
|
1131
|
+
@test.find_one({:a => 1}, :fields => {:a => 1, :b => 0})
|
|
548
1132
|
end
|
|
549
1133
|
end
|
|
550
1134
|
|
|
551
|
-
if @@version >= "1.5.1"
|
|
552
|
-
def test_fields_with_slice
|
|
553
|
-
@@test.save({:foo => [1, 2, 3, 4, 5, 6], :test => 'slice'})
|
|
554
1135
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
1136
|
+
def test_meta_field_projection
|
|
1137
|
+
return unless @version >= '2.5.5'
|
|
1138
|
+
@test.save({ :t => 'spam eggs and spam'})
|
|
1139
|
+
@test.save({ :t => 'spam'})
|
|
1140
|
+
@test.save({ :t => 'egg sausage and bacon'})
|
|
1141
|
+
|
|
1142
|
+
@test.ensure_index([[:t, 'text']])
|
|
1143
|
+
assert @test.find_one({ :$text => { :$search => 'spam' }},
|
|
1144
|
+
{ :fields => [:t, { :score => { :$meta => 'textScore' } }] })
|
|
1145
|
+
end
|
|
1146
|
+
|
|
1147
|
+
def test_sort_by_meta
|
|
1148
|
+
return unless @version >= '2.5.5'
|
|
1149
|
+
@test.save({ :t => 'spam eggs and spam'})
|
|
1150
|
+
@test.save({ :t => 'spam'})
|
|
1151
|
+
@test.save({ :t => 'egg sausage and bacon'})
|
|
1152
|
+
|
|
1153
|
+
@test.ensure_index([[:t, 'text']])
|
|
1154
|
+
assert @test.find({ :$text => { :$search => 'spam' }}).sort([:score, { '$meta' => 'textScore' }])
|
|
1155
|
+
assert @test.find({ :$text => { :$search => 'spam' }}).sort(:score => { '$meta' =>'textScore' })
|
|
1156
|
+
end
|
|
1157
|
+
|
|
1158
|
+
def test_fields_with_slice
|
|
1159
|
+
return unless @version >= "1.5.1"
|
|
1160
|
+
@test.save({:foo => [1, 2, 3, 4, 5, 6], :test => 'slice'})
|
|
1161
|
+
|
|
1162
|
+
doc = @test.find_one({:test => 'slice'}, :fields => {'foo' => {'$slice' => [0, 3]}})
|
|
1163
|
+
assert_equal [1, 2, 3], doc['foo']
|
|
1164
|
+
@test.remove
|
|
559
1165
|
end
|
|
560
1166
|
|
|
561
1167
|
def test_find_one
|
|
562
|
-
id =
|
|
1168
|
+
id = @test.save("hello" => "world", "foo" => "bar")
|
|
563
1169
|
|
|
564
|
-
assert_equal "world",
|
|
565
|
-
assert_equal
|
|
566
|
-
assert_equal
|
|
567
|
-
assert_equal
|
|
568
|
-
assert_equal
|
|
569
|
-
assert_equal
|
|
1170
|
+
assert_equal "world", @test.find_one()["hello"]
|
|
1171
|
+
assert_equal @test.find_one(id), @test.find_one()
|
|
1172
|
+
assert_equal @test.find_one(nil), @test.find_one()
|
|
1173
|
+
assert_equal @test.find_one({}), @test.find_one()
|
|
1174
|
+
assert_equal @test.find_one("hello" => "world"), @test.find_one()
|
|
1175
|
+
assert_equal @test.find_one(BSON::OrderedHash["hello", "world"]), @test.find_one()
|
|
570
1176
|
|
|
571
|
-
assert
|
|
572
|
-
assert
|
|
573
|
-
assert_equal ["_id"],
|
|
1177
|
+
assert @test.find_one(nil, :fields => ["hello"]).include?("hello")
|
|
1178
|
+
assert !@test.find_one(nil, :fields => ["foo"]).include?("hello")
|
|
1179
|
+
assert_equal ["_id"], @test.find_one(nil, :fields => []).keys()
|
|
574
1180
|
|
|
575
|
-
assert_equal nil,
|
|
576
|
-
assert_equal nil,
|
|
577
|
-
assert_equal nil,
|
|
1181
|
+
assert_equal nil, @test.find_one("hello" => "foo")
|
|
1182
|
+
assert_equal nil, @test.find_one(BSON::OrderedHash["hello", "foo"])
|
|
1183
|
+
assert_equal nil, @test.find_one(ObjectId.new)
|
|
578
1184
|
|
|
579
1185
|
assert_raise TypeError do
|
|
580
|
-
|
|
1186
|
+
@test.find_one(6)
|
|
1187
|
+
end
|
|
1188
|
+
end
|
|
1189
|
+
|
|
1190
|
+
def test_find_one_with_max_time_ms
|
|
1191
|
+
with_forced_timeout(@client) do
|
|
1192
|
+
assert_raise ExecutionTimeout do
|
|
1193
|
+
@test.find_one({}, { :max_time_ms => 100 })
|
|
1194
|
+
end
|
|
581
1195
|
end
|
|
582
1196
|
end
|
|
583
1197
|
|
|
1198
|
+
def test_find_one_with_compile_regex_option
|
|
1199
|
+
regex = /.*/
|
|
1200
|
+
@test.insert('r' => /.*/)
|
|
1201
|
+
assert_kind_of Regexp, @test.find_one({})['r']
|
|
1202
|
+
assert_kind_of Regexp, @test.find_one({}, :compile_regex => true)['r']
|
|
1203
|
+
assert_equal BSON::Regex, @test.find_one({}, :compile_regex => false)['r'].class
|
|
1204
|
+
end
|
|
1205
|
+
|
|
584
1206
|
def test_insert_adds_id
|
|
585
1207
|
doc = {"hello" => "world"}
|
|
586
|
-
|
|
1208
|
+
@test.insert(doc)
|
|
587
1209
|
assert(doc.include?(:_id))
|
|
588
1210
|
|
|
589
1211
|
docs = [{"hello" => "world"}, {"hello" => "world"}]
|
|
590
|
-
|
|
1212
|
+
@test.insert(docs)
|
|
591
1213
|
docs.each do |d|
|
|
592
1214
|
assert(d.include?(:_id))
|
|
593
1215
|
end
|
|
@@ -595,23 +1217,23 @@ class TestCollection < Test::Unit::TestCase
|
|
|
595
1217
|
|
|
596
1218
|
def test_save_adds_id
|
|
597
1219
|
doc = {"hello" => "world"}
|
|
598
|
-
|
|
1220
|
+
@test.save(doc)
|
|
599
1221
|
assert(doc.include?(:_id))
|
|
600
1222
|
end
|
|
601
1223
|
|
|
602
1224
|
def test_optional_find_block
|
|
603
1225
|
10.times do |i|
|
|
604
|
-
|
|
1226
|
+
@test.save("i" => i)
|
|
605
1227
|
end
|
|
606
1228
|
|
|
607
1229
|
x = nil
|
|
608
|
-
|
|
1230
|
+
@test.find("i" => 2) { |cursor|
|
|
609
1231
|
x = cursor.count()
|
|
610
1232
|
}
|
|
611
1233
|
assert_equal 1, x
|
|
612
1234
|
|
|
613
1235
|
i = 0
|
|
614
|
-
|
|
1236
|
+
@test.find({}, :skip => 5) do |cursor|
|
|
615
1237
|
cursor.each do |doc|
|
|
616
1238
|
i = i + 1
|
|
617
1239
|
end
|
|
@@ -619,7 +1241,7 @@ class TestCollection < Test::Unit::TestCase
|
|
|
619
1241
|
assert_equal 5, i
|
|
620
1242
|
|
|
621
1243
|
c = nil
|
|
622
|
-
|
|
1244
|
+
@test.find() do |cursor|
|
|
623
1245
|
c = cursor
|
|
624
1246
|
end
|
|
625
1247
|
assert c.closed?
|
|
@@ -627,290 +1249,414 @@ class TestCollection < Test::Unit::TestCase
|
|
|
627
1249
|
|
|
628
1250
|
def setup_aggregate_data
|
|
629
1251
|
# save some data
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
{ "author" => "barbara" , "text" => "this is interesting" },
|
|
653
|
-
{ "author" => "jenny", "text" => "i like to play pinball", "votes" => 10 }
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
end
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
end
|
|
1252
|
+
@test.save( {
|
|
1253
|
+
"_id" => 1,
|
|
1254
|
+
"title" => "this is my title",
|
|
1255
|
+
"author" => "bob",
|
|
1256
|
+
"posted" => Time.utc(2000),
|
|
1257
|
+
"pageViews" => 5 ,
|
|
1258
|
+
"tags" => [ "fun" , "good" , "fun" ],
|
|
1259
|
+
"comments" => [
|
|
1260
|
+
{ "author" => "joe", "text" => "this is cool" },
|
|
1261
|
+
{ "author" => "sam", "text" => "this is bad" }
|
|
1262
|
+
],
|
|
1263
|
+
"other" => { "foo" => 5 }
|
|
1264
|
+
} )
|
|
1265
|
+
|
|
1266
|
+
@test.save( {
|
|
1267
|
+
"_id" => 2,
|
|
1268
|
+
"title" => "this is your title",
|
|
1269
|
+
"author" => "dave",
|
|
1270
|
+
"posted" => Time.utc(2001),
|
|
1271
|
+
"pageViews" => 7,
|
|
1272
|
+
"tags" => [ "fun" , "nasty" ],
|
|
1273
|
+
"comments" => [
|
|
1274
|
+
{ "author" => "barbara" , "text" => "this is interesting" },
|
|
1275
|
+
{ "author" => "jenny", "text" => "i like to play pinball", "votes" => 10 }
|
|
1276
|
+
],
|
|
1277
|
+
"other" => { "bar" => 14 }
|
|
1278
|
+
})
|
|
1279
|
+
|
|
1280
|
+
@test.save( {
|
|
1281
|
+
"_id" => 3,
|
|
1282
|
+
"title" => "this is some other title",
|
|
1283
|
+
"author" => "jane",
|
|
1284
|
+
"posted" => Time.utc(2002),
|
|
1285
|
+
"pageViews" => 6 ,
|
|
1286
|
+
"tags" => [ "nasty", "filthy" ],
|
|
1287
|
+
"comments" => [
|
|
1288
|
+
{ "author" => "will" , "text" => "i don't like the color" } ,
|
|
1289
|
+
{ "author" => "jenny" , "text" => "can i get that in green?" }
|
|
1290
|
+
],
|
|
1291
|
+
"other" => { "bar" => 14 }
|
|
1292
|
+
})
|
|
1293
|
+
|
|
1294
|
+
end
|
|
1295
|
+
|
|
1296
|
+
def test_reponds_to_aggregate
|
|
1297
|
+
return unless @version > '2.1.1'
|
|
1298
|
+
assert_respond_to @test, :aggregate
|
|
1299
|
+
end
|
|
1300
|
+
|
|
1301
|
+
def test_aggregate_requires_arguments
|
|
1302
|
+
return unless @version > '2.1.1'
|
|
1303
|
+
assert_raise MongoArgumentError do
|
|
1304
|
+
@test.aggregate()
|
|
1305
|
+
end
|
|
1306
|
+
end
|
|
1307
|
+
|
|
1308
|
+
def test_aggregate_requires_valid_arguments
|
|
1309
|
+
return unless @version > '2.1.1'
|
|
1310
|
+
assert_raise MongoArgumentError do
|
|
1311
|
+
@test.aggregate({})
|
|
1312
|
+
end
|
|
1313
|
+
end
|
|
1314
|
+
|
|
1315
|
+
def test_aggregate_pipeline_operator_format
|
|
1316
|
+
return unless @version > '2.1.1'
|
|
1317
|
+
assert_raise Mongo::OperationFailure do
|
|
1318
|
+
@test.aggregate([{"$project" => "_id"}])
|
|
1319
|
+
end
|
|
1320
|
+
end
|
|
1321
|
+
|
|
1322
|
+
def test_aggregate_pipeline_operators_using_strings
|
|
1323
|
+
return unless @version > '2.1.1'
|
|
1324
|
+
setup_aggregate_data
|
|
1325
|
+
desired_results = [ {"_id"=>1, "pageViews"=>5, "tags"=>["fun", "good", "fun"]},
|
|
1326
|
+
{"_id"=>2, "pageViews"=>7, "tags"=>["fun", "nasty"]},
|
|
1327
|
+
{"_id"=>3, "pageViews"=>6, "tags"=>["nasty", "filthy"]} ]
|
|
1328
|
+
results = @test.aggregate([{"$project" => {"tags" => 1, "pageViews" => 1}}])
|
|
1329
|
+
assert_equal desired_results, results
|
|
1330
|
+
end
|
|
1331
|
+
|
|
1332
|
+
def test_aggregate_pipeline_operators_using_symbols
|
|
1333
|
+
return unless @version > '2.1.1'
|
|
1334
|
+
setup_aggregate_data
|
|
1335
|
+
desired_results = [ {"_id"=>1, "pageViews"=>5, "tags"=>["fun", "good", "fun"]},
|
|
1336
|
+
{"_id"=>2, "pageViews"=>7, "tags"=>["fun", "nasty"]},
|
|
1337
|
+
{"_id"=>3, "pageViews"=>6, "tags"=>["nasty", "filthy"]} ]
|
|
1338
|
+
results = @test.aggregate([{"$project" => {:tags => 1, :pageViews => 1}}])
|
|
1339
|
+
assert_equal desired_results, results
|
|
1340
|
+
end
|
|
1341
|
+
|
|
1342
|
+
def test_aggregate_command_using_sym
|
|
1343
|
+
return unless @version > '2.1.1'
|
|
1344
|
+
cmd = BSON::OrderedHash[:aggregate, @test.name, :pipeline, [{'$match' => {:_id => true}}]]
|
|
1345
|
+
assert @db.command(cmd)
|
|
1346
|
+
end
|
|
1347
|
+
|
|
1348
|
+
def test_aggregate_pipeline_multiple_operators
|
|
1349
|
+
return unless @version > '2.1.1'
|
|
1350
|
+
setup_aggregate_data
|
|
1351
|
+
results = @test.aggregate([{"$project" => {"tags" => 1, "pageViews" => 1}}, {"$match" => {"pageViews" => 7}}])
|
|
1352
|
+
assert_equal 1, results.length
|
|
1353
|
+
end
|
|
1354
|
+
|
|
1355
|
+
def test_aggregate_pipeline_unwind
|
|
1356
|
+
return unless @version > '2.1.1'
|
|
1357
|
+
setup_aggregate_data
|
|
1358
|
+
desired_results = [ {"_id"=>1, "title"=>"this is my title", "author"=>"bob", "posted"=>Time.utc(2000),
|
|
1359
|
+
"pageViews"=>5, "tags"=>"fun", "comments"=>[{"author"=>"joe", "text"=>"this is cool"},
|
|
1360
|
+
{"author"=>"sam", "text"=>"this is bad"}], "other"=>{"foo"=>5 } },
|
|
1361
|
+
{"_id"=>1, "title"=>"this is my title", "author"=>"bob", "posted"=>Time.utc(2000),
|
|
1362
|
+
"pageViews"=>5, "tags"=>"good", "comments"=>[{"author"=>"joe", "text"=>"this is cool"},
|
|
1363
|
+
{"author"=>"sam", "text"=>"this is bad"}], "other"=>{"foo"=>5 } },
|
|
1364
|
+
{"_id"=>1, "title"=>"this is my title", "author"=>"bob", "posted"=>Time.utc(2000),
|
|
1365
|
+
"pageViews"=>5, "tags"=>"fun", "comments"=>[{"author"=>"joe", "text"=>"this is cool"},
|
|
1366
|
+
{"author"=>"sam", "text"=>"this is bad"}], "other"=>{"foo"=>5 } },
|
|
1367
|
+
{"_id"=>2, "title"=>"this is your title", "author"=>"dave", "posted"=>Time.utc(2001),
|
|
1368
|
+
"pageViews"=>7, "tags"=>"fun", "comments"=>[{"author"=>"barbara", "text"=>"this is interesting"},
|
|
1369
|
+
{"author"=>"jenny", "text"=>"i like to play pinball", "votes"=>10 }], "other"=>{"bar"=>14 } },
|
|
1370
|
+
{"_id"=>2, "title"=>"this is your title", "author"=>"dave", "posted"=>Time.utc(2001),
|
|
1371
|
+
"pageViews"=>7, "tags"=>"nasty", "comments"=>[{"author"=>"barbara", "text"=>"this is interesting"},
|
|
1372
|
+
{"author"=>"jenny", "text"=>"i like to play pinball", "votes"=>10 }], "other"=>{"bar"=>14 } },
|
|
1373
|
+
{"_id"=>3, "title"=>"this is some other title", "author"=>"jane", "posted"=>Time.utc(2002),
|
|
1374
|
+
"pageViews"=>6, "tags"=>"nasty", "comments"=>[{"author"=>"will", "text"=>"i don't like the color"},
|
|
1375
|
+
{"author"=>"jenny", "text"=>"can i get that in green?"}], "other"=>{"bar"=>14 } },
|
|
1376
|
+
{"_id"=>3, "title"=>"this is some other title", "author"=>"jane", "posted"=>Time.utc(2002),
|
|
1377
|
+
"pageViews"=>6, "tags"=>"filthy", "comments"=>[{"author"=>"will", "text"=>"i don't like the color"},
|
|
1378
|
+
{"author"=>"jenny", "text"=>"can i get that in green?"}], "other"=>{"bar"=>14 } }
|
|
1379
|
+
]
|
|
1380
|
+
results = @test.aggregate([{"$unwind"=> "$tags"}])
|
|
1381
|
+
assert_equal desired_results, results
|
|
1382
|
+
end
|
|
1383
|
+
|
|
1384
|
+
def test_aggregate_with_compile_regex_option
|
|
1385
|
+
return unless @version > '2.1.1'
|
|
1386
|
+
# see SERVER-6470
|
|
1387
|
+
return unless @version >= '2.3.2'
|
|
1388
|
+
@test.insert({ 'r' => /.*/ })
|
|
1389
|
+
result1 = @test.aggregate([])
|
|
1390
|
+
assert_kind_of Regexp, result1.first['r']
|
|
1391
|
+
|
|
1392
|
+
result2 = @test.aggregate([], :compile_regex => false)
|
|
1393
|
+
assert_kind_of BSON::Regex, result2.first['r']
|
|
1394
|
+
|
|
1395
|
+
return unless @version >= '2.5.1'
|
|
1396
|
+
result = @test.aggregate([], :compile_regex => false, :cursor => {})
|
|
1397
|
+
assert_kind_of BSON::Regex, result.first['r']
|
|
1398
|
+
end
|
|
1399
|
+
|
|
1400
|
+
def test_out_aggregate
|
|
1401
|
+
return unless @version >= "2.5.2"
|
|
1402
|
+
out_collection = 'test_out'
|
|
1403
|
+
@db.drop_collection(out_collection)
|
|
1404
|
+
setup_aggregate_data
|
|
1405
|
+
docs = @test.find.to_a
|
|
1406
|
+
pipeline = [{:$out => out_collection}]
|
|
1407
|
+
@test.aggregate(pipeline)
|
|
1408
|
+
assert_equal docs, @db.collection(out_collection).find.to_a
|
|
1409
|
+
end
|
|
1410
|
+
|
|
1411
|
+
def test_out_aggregate_nonprimary_sym_warns
|
|
1412
|
+
return unless @version >= "2.5.2"
|
|
1413
|
+
ReadPreference::expects(:warn).with(regexp_matches(/rerouted to primary/))
|
|
1414
|
+
pipeline = [{:$out => 'test_out'}]
|
|
1415
|
+
@test.aggregate(pipeline, :read => :secondary)
|
|
1416
|
+
end
|
|
1417
|
+
|
|
1418
|
+
def test_out_aggregate_nonprimary_string_warns
|
|
1419
|
+
return unless @version >= "2.5.2"
|
|
1420
|
+
ReadPreference::expects(:warn).with(regexp_matches(/rerouted to primary/))
|
|
1421
|
+
pipeline = [{'$out' => 'test_out'}]
|
|
1422
|
+
@test.aggregate(pipeline, :read => :secondary)
|
|
1423
|
+
end
|
|
1424
|
+
|
|
1425
|
+
def test_out_aggregate_string_returns_raw_response
|
|
1426
|
+
return unless @version >= "2.5.2"
|
|
1427
|
+
pipeline = [{'$out' => 'test_out'}]
|
|
1428
|
+
response = @test.aggregate(pipeline)
|
|
1429
|
+
assert response.respond_to?(:keys)
|
|
1430
|
+
end
|
|
1431
|
+
|
|
1432
|
+
def test_out_aggregate_sym_returns_raw_response
|
|
1433
|
+
return unless @version >= "2.5.2"
|
|
1434
|
+
pipeline = [{:$out => 'test_out'}]
|
|
1435
|
+
response = @test.aggregate(pipeline)
|
|
1436
|
+
assert response.respond_to?(:keys)
|
|
1437
|
+
end
|
|
1438
|
+
|
|
1439
|
+
def test_map_reduce
|
|
1440
|
+
return unless @version > "1.1.1"
|
|
1441
|
+
@test << { "user_id" => 1 }
|
|
1442
|
+
@test << { "user_id" => 2 }
|
|
1443
|
+
|
|
1444
|
+
m = "function() { emit(this.user_id, 1); }"
|
|
1445
|
+
r = "function(k,vals) { return 1; }"
|
|
1446
|
+
res = @test.map_reduce(m, r, :out => 'foo')
|
|
1447
|
+
assert res.find_one({"_id" => 1})
|
|
1448
|
+
assert res.find_one({"_id" => 2})
|
|
1449
|
+
end
|
|
1450
|
+
|
|
1451
|
+
def test_map_reduce_with_code_objects
|
|
1452
|
+
return unless @version > "1.1.1"
|
|
1453
|
+
@test << { "user_id" => 1 }
|
|
1454
|
+
@test << { "user_id" => 2 }
|
|
1455
|
+
|
|
1456
|
+
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
1457
|
+
r = Code.new("function(k,vals) { return 1; }")
|
|
1458
|
+
res = @test.map_reduce(m, r, :out => 'foo')
|
|
1459
|
+
assert res.find_one({"_id" => 1})
|
|
1460
|
+
assert res.find_one({"_id" => 2})
|
|
1461
|
+
end
|
|
1462
|
+
|
|
1463
|
+
def test_map_reduce_with_options
|
|
1464
|
+
return unless @version > "1.1.1"
|
|
1465
|
+
@test.remove
|
|
1466
|
+
@test << { "user_id" => 1 }
|
|
1467
|
+
@test << { "user_id" => 2 }
|
|
1468
|
+
@test << { "user_id" => 3 }
|
|
1469
|
+
|
|
1470
|
+
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
1471
|
+
r = Code.new("function(k,vals) { return 1; }")
|
|
1472
|
+
res = @test.map_reduce(m, r, :query => {"user_id" => {"$gt" => 1}}, :out => 'foo')
|
|
1473
|
+
assert_equal 2, res.count
|
|
1474
|
+
assert res.find_one({"_id" => 2})
|
|
1475
|
+
assert res.find_one({"_id" => 3})
|
|
1476
|
+
end
|
|
1477
|
+
|
|
1478
|
+
def test_map_reduce_with_raw_response
|
|
1479
|
+
return unless @version > "1.1.1"
|
|
1480
|
+
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
1481
|
+
r = Code.new("function(k,vals) { return 1; }")
|
|
1482
|
+
res = @test.map_reduce(m, r, :raw => true, :out => 'foo')
|
|
1483
|
+
assert res["result"]
|
|
1484
|
+
assert res["counts"]
|
|
1485
|
+
assert res["timeMillis"]
|
|
1486
|
+
end
|
|
1487
|
+
|
|
1488
|
+
def test_map_reduce_with_output_collection
|
|
1489
|
+
return unless @version > "1.1.1"
|
|
1490
|
+
output_collection = "test-map-coll"
|
|
1491
|
+
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
1492
|
+
r = Code.new("function(k,vals) { return 1; }")
|
|
1493
|
+
res = @test.map_reduce(m, r, :raw => true, :out => output_collection)
|
|
1494
|
+
assert_equal output_collection, res["result"]
|
|
1495
|
+
assert res["counts"]
|
|
1496
|
+
assert res["timeMillis"]
|
|
1497
|
+
end
|
|
1498
|
+
|
|
1499
|
+
def test_map_reduce_nonprimary_output_collection_reroutes
|
|
1500
|
+
return unless @version > "1.1.1"
|
|
1501
|
+
output_collection = "test-map-coll"
|
|
1502
|
+
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
1503
|
+
r = Code.new("function(k,vals) { return 1; }")
|
|
1504
|
+
Mongo::ReadPreference.expects(:warn).with(regexp_matches(/rerouted to primary/))
|
|
1505
|
+
res = @test.map_reduce(m, r, :raw => true, :out => output_collection, :read => :secondary)
|
|
1506
|
+
end
|
|
1507
|
+
|
|
1508
|
+
def test_map_reduce_with_collection_merge
|
|
1509
|
+
return unless @version >= "1.8.0"
|
|
1510
|
+
@test << {:user_id => 1}
|
|
1511
|
+
@test << {:user_id => 2}
|
|
1512
|
+
output_collection = "test-map-coll"
|
|
1513
|
+
m = Code.new("function() { emit(this.user_id, {count: 1}); }")
|
|
1514
|
+
r = Code.new("function(k,vals) { var sum = 0;" +
|
|
1515
|
+
" vals.forEach(function(v) { sum += v.count;} ); return {count: sum}; }")
|
|
1516
|
+
res = @test.map_reduce(m, r, :out => output_collection)
|
|
684
1517
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
end
|
|
1518
|
+
@test.remove
|
|
1519
|
+
@test << {:user_id => 3}
|
|
1520
|
+
res = @test.map_reduce(m, r, :out => {:merge => output_collection})
|
|
1521
|
+
assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 1}
|
|
690
1522
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
1523
|
+
@test.remove
|
|
1524
|
+
@test << {:user_id => 3}
|
|
1525
|
+
res = @test.map_reduce(m, r, :out => {:reduce => output_collection})
|
|
1526
|
+
assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 2}
|
|
1527
|
+
|
|
1528
|
+
assert_raise ArgumentError do
|
|
1529
|
+
@test.map_reduce(m, r, :out => {:inline => 1})
|
|
1530
|
+
end
|
|
1531
|
+
|
|
1532
|
+
@test.map_reduce(m, r, :raw => true, :out => {:inline => 1})
|
|
1533
|
+
assert res["results"]
|
|
1534
|
+
end
|
|
1535
|
+
|
|
1536
|
+
def test_map_reduce_with_collection_output_to_other_db
|
|
1537
|
+
return unless @version > "1.1.1"
|
|
1538
|
+
@test << {:user_id => 1}
|
|
1539
|
+
@test << {:user_id => 2}
|
|
1540
|
+
|
|
1541
|
+
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
1542
|
+
r = Code.new("function(k,vals) { return 1; }")
|
|
1543
|
+
oh = BSON::OrderedHash.new
|
|
1544
|
+
oh[:replace] = 'foo'
|
|
1545
|
+
oh[:db] = TEST_DB
|
|
1546
|
+
res = @test.map_reduce(m, r, :out => (oh))
|
|
1547
|
+
assert res["result"]
|
|
1548
|
+
assert res["counts"]
|
|
1549
|
+
assert res["timeMillis"]
|
|
1550
|
+
assert res.find.to_a.any? {|doc| doc["_id"] == 2 && doc["value"] == 1}
|
|
1551
|
+
end
|
|
1552
|
+
|
|
1553
|
+
def test_aggregation_allow_disk_use
|
|
1554
|
+
return unless @version >= '2.5.5'
|
|
1555
|
+
@db.expects(:command).with do |selector, opts|
|
|
1556
|
+
opts[:allowDiskUse] == true
|
|
1557
|
+
end.returns({ 'ok' => 1 })
|
|
1558
|
+
@test.aggregate([], :allowDiskUse => true)
|
|
1559
|
+
end
|
|
1560
|
+
|
|
1561
|
+
def test_parallel_scan
|
|
1562
|
+
return unless @version >= '2.5.5'
|
|
1563
|
+
8000.times { |i| @test.insert({ :_id => i }) }
|
|
1564
|
+
|
|
1565
|
+
lock = Mutex.new
|
|
1566
|
+
doc_ids = Set.new
|
|
1567
|
+
threads = []
|
|
1568
|
+
cursors = @test.parallel_scan(3)
|
|
1569
|
+
cursors.each_with_index do |cursor, i|
|
|
1570
|
+
threads << Thread.new do
|
|
1571
|
+
docs = cursor.to_a
|
|
1572
|
+
lock.synchronize do
|
|
1573
|
+
docs.each do |doc|
|
|
1574
|
+
doc_ids << doc['_id']
|
|
1575
|
+
end
|
|
1576
|
+
end
|
|
694
1577
|
end
|
|
695
1578
|
end
|
|
1579
|
+
threads.each(&:join)
|
|
1580
|
+
assert_equal 8000, doc_ids.count
|
|
1581
|
+
end
|
|
696
1582
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
results = @@test.aggregate([{"$project" => {"tags" => 1, "pageViews" => 1}}])
|
|
703
|
-
assert_equal desired_results, results
|
|
704
|
-
end
|
|
705
|
-
|
|
706
|
-
def test_aggregate_pipeline_operators_using_symbols
|
|
707
|
-
setup_aggregate_data
|
|
708
|
-
desired_results = [ {"_id"=>1, "pageViews"=>5, "tags"=>["fun", "good", "fun"]},
|
|
709
|
-
{"_id"=>2, "pageViews"=>7, "tags"=>["fun", "nasty"]},
|
|
710
|
-
{"_id"=>3, "pageViews"=>6, "tags"=>["nasty", "filthy"]} ]
|
|
711
|
-
results = @@test.aggregate([{"$project" => {:tags => 1, :pageViews => 1}}])
|
|
712
|
-
assert_equal desired_results, results
|
|
713
|
-
end
|
|
714
|
-
|
|
715
|
-
def test_aggregate_pipeline_multiple_operators
|
|
716
|
-
setup_aggregate_data
|
|
717
|
-
results = @@test.aggregate([{"$project" => {"tags" => 1, "pageViews" => 1}}, {"$match" => {"pageViews" => 7}}])
|
|
718
|
-
assert_equal 1, results.length
|
|
719
|
-
end
|
|
720
|
-
|
|
721
|
-
def test_aggregate_pipeline_unwind
|
|
722
|
-
setup_aggregate_data
|
|
723
|
-
desired_results = [ {"_id"=>1, "title"=>"this is my title", "author"=>"bob", "posted"=>Time.utc(2000),
|
|
724
|
-
"pageViews"=>5, "tags"=>"fun", "comments"=>[{"author"=>"joe", "text"=>"this is cool"},
|
|
725
|
-
{"author"=>"sam", "text"=>"this is bad"}], "other"=>{"foo"=>5 } },
|
|
726
|
-
{"_id"=>1, "title"=>"this is my title", "author"=>"bob", "posted"=>Time.utc(2000),
|
|
727
|
-
"pageViews"=>5, "tags"=>"good", "comments"=>[{"author"=>"joe", "text"=>"this is cool"},
|
|
728
|
-
{"author"=>"sam", "text"=>"this is bad"}], "other"=>{"foo"=>5 } },
|
|
729
|
-
{"_id"=>1, "title"=>"this is my title", "author"=>"bob", "posted"=>Time.utc(2000),
|
|
730
|
-
"pageViews"=>5, "tags"=>"fun", "comments"=>[{"author"=>"joe", "text"=>"this is cool"},
|
|
731
|
-
{"author"=>"sam", "text"=>"this is bad"}], "other"=>{"foo"=>5 } },
|
|
732
|
-
{"_id"=>2, "title"=>"this is your title", "author"=>"dave", "posted"=>Time.utc(2001),
|
|
733
|
-
"pageViews"=>7, "tags"=>"fun", "comments"=>[{"author"=>"barbara", "text"=>"this is interesting"},
|
|
734
|
-
{"author"=>"jenny", "text"=>"i like to play pinball", "votes"=>10 }], "other"=>{"bar"=>14 } },
|
|
735
|
-
{"_id"=>2, "title"=>"this is your title", "author"=>"dave", "posted"=>Time.utc(2001),
|
|
736
|
-
"pageViews"=>7, "tags"=>"nasty", "comments"=>[{"author"=>"barbara", "text"=>"this is interesting"},
|
|
737
|
-
{"author"=>"jenny", "text"=>"i like to play pinball", "votes"=>10 }], "other"=>{"bar"=>14 } },
|
|
738
|
-
{"_id"=>3, "title"=>"this is some other title", "author"=>"jane", "posted"=>Time.utc(2002),
|
|
739
|
-
"pageViews"=>6, "tags"=>"nasty", "comments"=>[{"author"=>"will", "text"=>"i don't like the color"},
|
|
740
|
-
{"author"=>"jenny", "text"=>"can i get that in green?"}], "other"=>{"bar"=>14 } },
|
|
741
|
-
{"_id"=>3, "title"=>"this is some other title", "author"=>"jane", "posted"=>Time.utc(2002),
|
|
742
|
-
"pageViews"=>6, "tags"=>"filthy", "comments"=>[{"author"=>"will", "text"=>"i don't like the color"},
|
|
743
|
-
{"author"=>"jenny", "text"=>"can i get that in green?"}], "other"=>{"bar"=>14 } }
|
|
744
|
-
]
|
|
745
|
-
results = @@test.aggregate([{"$unwind"=> "$tags"}])
|
|
746
|
-
assert_equal desired_results, results
|
|
747
|
-
end
|
|
748
|
-
end
|
|
749
|
-
|
|
750
|
-
if @@version > "1.1.1"
|
|
751
|
-
def test_map_reduce
|
|
752
|
-
@@test << { "user_id" => 1 }
|
|
753
|
-
@@test << { "user_id" => 2 }
|
|
754
|
-
|
|
755
|
-
m = "function() { emit(this.user_id, 1); }"
|
|
756
|
-
r = "function(k,vals) { return 1; }"
|
|
757
|
-
res = @@test.map_reduce(m, r, :out => 'foo');
|
|
758
|
-
assert res.find_one({"_id" => 1})
|
|
759
|
-
assert res.find_one({"_id" => 2})
|
|
760
|
-
end
|
|
761
|
-
|
|
762
|
-
def test_map_reduce_with_code_objects
|
|
763
|
-
@@test << { "user_id" => 1 }
|
|
764
|
-
@@test << { "user_id" => 2 }
|
|
765
|
-
|
|
766
|
-
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
767
|
-
r = Code.new("function(k,vals) { return 1; }")
|
|
768
|
-
res = @@test.map_reduce(m, r, :out => 'foo');
|
|
769
|
-
assert res.find_one({"_id" => 1})
|
|
770
|
-
assert res.find_one({"_id" => 2})
|
|
771
|
-
end
|
|
772
|
-
|
|
773
|
-
def test_map_reduce_with_options
|
|
774
|
-
@@test.remove
|
|
775
|
-
@@test << { "user_id" => 1 }
|
|
776
|
-
@@test << { "user_id" => 2 }
|
|
777
|
-
@@test << { "user_id" => 3 }
|
|
778
|
-
|
|
779
|
-
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
780
|
-
r = Code.new("function(k,vals) { return 1; }")
|
|
781
|
-
res = @@test.map_reduce(m, r, :query => {"user_id" => {"$gt" => 1}}, :out => 'foo');
|
|
782
|
-
assert_equal 2, res.count
|
|
783
|
-
assert res.find_one({"_id" => 2})
|
|
784
|
-
assert res.find_one({"_id" => 3})
|
|
785
|
-
end
|
|
786
|
-
|
|
787
|
-
def test_map_reduce_with_raw_response
|
|
788
|
-
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
789
|
-
r = Code.new("function(k,vals) { return 1; }")
|
|
790
|
-
res = @@test.map_reduce(m, r, :raw => true, :out => 'foo')
|
|
791
|
-
assert res["result"]
|
|
792
|
-
assert res["counts"]
|
|
793
|
-
assert res["timeMillis"]
|
|
794
|
-
end
|
|
795
|
-
|
|
796
|
-
def test_map_reduce_with_output_collection
|
|
797
|
-
output_collection = "test-map-coll"
|
|
798
|
-
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
799
|
-
r = Code.new("function(k,vals) { return 1; }")
|
|
800
|
-
res = @@test.map_reduce(m, r, :raw => true, :out => output_collection)
|
|
801
|
-
assert_equal output_collection, res["result"]
|
|
802
|
-
assert res["counts"]
|
|
803
|
-
assert res["timeMillis"]
|
|
804
|
-
end
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
if @@version >= "1.8.0"
|
|
808
|
-
def test_map_reduce_with_collection_merge
|
|
809
|
-
@@test << {:user_id => 1}
|
|
810
|
-
@@test << {:user_id => 2}
|
|
811
|
-
output_collection = "test-map-coll"
|
|
812
|
-
m = Code.new("function() { emit(this.user_id, {count: 1}); }")
|
|
813
|
-
r = Code.new("function(k,vals) { var sum = 0;" +
|
|
814
|
-
" vals.forEach(function(v) { sum += v.count;} ); return {count: sum}; }")
|
|
815
|
-
res = @@test.map_reduce(m, r, :out => output_collection)
|
|
816
|
-
|
|
817
|
-
@@test.remove
|
|
818
|
-
@@test << {:user_id => 3}
|
|
819
|
-
res = @@test.map_reduce(m, r, :out => {:merge => output_collection})
|
|
820
|
-
assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 1}
|
|
821
|
-
|
|
822
|
-
@@test.remove
|
|
823
|
-
@@test << {:user_id => 3}
|
|
824
|
-
res = @@test.map_reduce(m, r, :out => {:reduce => output_collection})
|
|
825
|
-
assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 2}
|
|
826
|
-
|
|
827
|
-
assert_raise ArgumentError do
|
|
828
|
-
@@test.map_reduce(m, r, :out => {:inline => 1})
|
|
829
|
-
end
|
|
1583
|
+
def test_find_and_modify
|
|
1584
|
+
return unless @version > "1.3.0"
|
|
1585
|
+
@test << { :a => 1, :processed => false }
|
|
1586
|
+
@test << { :a => 2, :processed => false }
|
|
1587
|
+
@test << { :a => 3, :processed => false }
|
|
830
1588
|
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
1589
|
+
@test.find_and_modify(:query => {},
|
|
1590
|
+
:sort => [['a', -1]],
|
|
1591
|
+
:update => {"$set" => {:processed => true}})
|
|
834
1592
|
|
|
835
|
-
|
|
836
|
-
@@test << {:user_id => 1}
|
|
837
|
-
@@test << {:user_id => 2}
|
|
838
|
-
|
|
839
|
-
m = Code.new("function() { emit(this.user_id, 1); }")
|
|
840
|
-
r = Code.new("function(k,vals) { return 1; }")
|
|
841
|
-
oh = BSON::OrderedHash.new
|
|
842
|
-
oh[:replace] = 'foo'
|
|
843
|
-
oh[:db] = MONGO_TEST_DB
|
|
844
|
-
res = @@test.map_reduce(m, r, :out => (oh))
|
|
845
|
-
assert res["result"]
|
|
846
|
-
assert res["counts"]
|
|
847
|
-
assert res["timeMillis"]
|
|
848
|
-
assert res.find.to_a.any? {|doc| doc["_id"] == 2 && doc["value"] == 1}
|
|
849
|
-
end
|
|
850
|
-
end
|
|
1593
|
+
assert @test.find_one({:a => 3})['processed']
|
|
851
1594
|
end
|
|
852
1595
|
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
@@test << { :a => 3, :processed => false }
|
|
858
|
-
|
|
859
|
-
@@test.find_and_modify(:query => {}, :sort => [['a', -1]], :update => {"$set" => {:processed => true}})
|
|
1596
|
+
def test_find_and_modify_with_invalid_options
|
|
1597
|
+
@test << { :a => 1, :processed => false }
|
|
1598
|
+
@test << { :a => 2, :processed => false }
|
|
1599
|
+
@test << { :a => 3, :processed => false }
|
|
860
1600
|
|
|
861
|
-
|
|
1601
|
+
assert_raise Mongo::OperationFailure do
|
|
1602
|
+
@test.find_and_modify(:blimey => {})
|
|
862
1603
|
end
|
|
1604
|
+
end
|
|
863
1605
|
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
1606
|
+
def test_find_and_modify_with_full_response
|
|
1607
|
+
@test << { :a => 1, :processed => false }
|
|
1608
|
+
@test << { :a => 2, :processed => false }
|
|
1609
|
+
@test << { :a => 3, :processed => false }
|
|
868
1610
|
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
1611
|
+
doc = @test.find_and_modify(:query => {},
|
|
1612
|
+
:sort => [['a', -1]],
|
|
1613
|
+
:update => {"$set" => {:processed => true}},
|
|
1614
|
+
:full_response => true,
|
|
1615
|
+
:new => true)
|
|
1616
|
+
|
|
1617
|
+
assert doc['value']['processed']
|
|
1618
|
+
assert ['ok', 'value', 'lastErrorObject'].all? { |key| doc.key?(key) }
|
|
873
1619
|
end
|
|
874
1620
|
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
1621
|
+
def test_coll_stats
|
|
1622
|
+
return unless @version >= "1.3.5"
|
|
1623
|
+
@test << {:n => 1}
|
|
1624
|
+
@test.create_index("n")
|
|
879
1625
|
|
|
880
|
-
|
|
881
|
-
|
|
1626
|
+
assert_equal "#{TEST_DB}.test", @test.stats['ns']
|
|
1627
|
+
@test.drop
|
|
882
1628
|
end
|
|
883
1629
|
|
|
884
1630
|
def test_saving_dates_pre_epoch
|
|
885
1631
|
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ then return true end
|
|
886
1632
|
begin
|
|
887
|
-
|
|
888
|
-
assert_in_delta Time.utc(1600),
|
|
1633
|
+
@test.save({'date' => Time.utc(1600)})
|
|
1634
|
+
assert_in_delta Time.utc(1600), @test.find_one()["date"], 2
|
|
889
1635
|
rescue ArgumentError
|
|
890
1636
|
# See note in test_date_before_epoch (BSONTest)
|
|
891
1637
|
end
|
|
892
1638
|
end
|
|
893
1639
|
|
|
894
1640
|
def test_save_symbol_find_string
|
|
895
|
-
|
|
1641
|
+
@test.save(:foo => :mike)
|
|
896
1642
|
|
|
897
|
-
assert_equal :mike,
|
|
898
|
-
assert_equal :mike,
|
|
1643
|
+
assert_equal :mike, @test.find_one(:foo => :mike)["foo"]
|
|
1644
|
+
assert_equal :mike, @test.find_one("foo" => :mike)["foo"]
|
|
899
1645
|
|
|
900
1646
|
# TODO enable these tests conditionally based on server version (if >1.0)
|
|
901
|
-
# assert_equal :mike,
|
|
902
|
-
# assert_equal :mike,
|
|
1647
|
+
# assert_equal :mike, @test.find_one(:foo => "mike")["foo"]
|
|
1648
|
+
# assert_equal :mike, @test.find_one("foo" => "mike")["foo"]
|
|
903
1649
|
end
|
|
904
1650
|
|
|
905
1651
|
def test_batch_size
|
|
906
1652
|
n_docs = 6
|
|
907
1653
|
batch_size = n_docs/2
|
|
908
1654
|
n_docs.times do |i|
|
|
909
|
-
|
|
1655
|
+
@test.save(:foo => i)
|
|
910
1656
|
end
|
|
911
1657
|
|
|
912
1658
|
doc_count = 0
|
|
913
|
-
cursor =
|
|
1659
|
+
cursor = @test.find({}, :batch_size => batch_size)
|
|
914
1660
|
cursor.next
|
|
915
1661
|
assert_equal batch_size, cursor.instance_variable_get(:@returned)
|
|
916
1662
|
doc_count += batch_size
|
|
@@ -924,10 +1670,10 @@ class TestCollection < Test::Unit::TestCase
|
|
|
924
1670
|
n_docs = 6
|
|
925
1671
|
batch_size = n_docs/2
|
|
926
1672
|
n_docs.times do |i|
|
|
927
|
-
|
|
1673
|
+
@test.insert(:foo => i)
|
|
928
1674
|
end
|
|
929
1675
|
|
|
930
|
-
cursor =
|
|
1676
|
+
cursor = @test.find({}, :batch_size => batch_size, :limit => 2)
|
|
931
1677
|
cursor.next
|
|
932
1678
|
assert_equal 2, cursor.instance_variable_get(:@returned)
|
|
933
1679
|
end
|
|
@@ -936,11 +1682,11 @@ class TestCollection < Test::Unit::TestCase
|
|
|
936
1682
|
n_docs = 6
|
|
937
1683
|
batch_size = n_docs/2
|
|
938
1684
|
n_docs.times do |i|
|
|
939
|
-
|
|
1685
|
+
@test.insert(:foo => i)
|
|
940
1686
|
end
|
|
941
1687
|
|
|
942
1688
|
doc_count = 0
|
|
943
|
-
cursor =
|
|
1689
|
+
cursor = @test.find({}, :batch_size => batch_size, :limit => n_docs + 5)
|
|
944
1690
|
cursor.next
|
|
945
1691
|
assert_equal batch_size, cursor.instance_variable_get(:@returned)
|
|
946
1692
|
doc_count += batch_size
|
|
@@ -948,44 +1694,44 @@ class TestCollection < Test::Unit::TestCase
|
|
|
948
1694
|
assert_equal doc_count + batch_size, cursor.instance_variable_get(:@returned)
|
|
949
1695
|
doc_count += batch_size
|
|
950
1696
|
assert_equal n_docs, doc_count
|
|
951
|
-
end
|
|
1697
|
+
end
|
|
952
1698
|
|
|
953
1699
|
def test_batch_size_with_negative_limit
|
|
954
1700
|
n_docs = 6
|
|
955
1701
|
batch_size = n_docs/2
|
|
956
1702
|
n_docs.times do |i|
|
|
957
|
-
|
|
1703
|
+
@test.insert(:foo => i)
|
|
958
1704
|
end
|
|
959
1705
|
|
|
960
|
-
cursor =
|
|
1706
|
+
cursor = @test.find({}, :batch_size => batch_size, :limit => -7)
|
|
961
1707
|
cursor.next
|
|
962
1708
|
assert_equal n_docs, cursor.instance_variable_get(:@returned)
|
|
963
1709
|
end
|
|
964
1710
|
|
|
965
1711
|
def test_limit_and_skip
|
|
966
1712
|
10.times do |i|
|
|
967
|
-
|
|
1713
|
+
@test.save(:foo => i)
|
|
968
1714
|
end
|
|
969
1715
|
|
|
970
|
-
assert_equal 5,
|
|
971
|
-
assert_equal nil,
|
|
1716
|
+
assert_equal 5, @test.find({}, :skip => 5).next_document()["foo"]
|
|
1717
|
+
assert_equal nil, @test.find({}, :skip => 10).next_document()
|
|
972
1718
|
|
|
973
|
-
assert_equal 5,
|
|
1719
|
+
assert_equal 5, @test.find({}, :limit => 5).to_a.length
|
|
974
1720
|
|
|
975
|
-
assert_equal 3,
|
|
976
|
-
assert_equal 5,
|
|
1721
|
+
assert_equal 3, @test.find({}, :skip => 3, :limit => 5).next_document()["foo"]
|
|
1722
|
+
assert_equal 5, @test.find({}, :skip => 3, :limit => 5).to_a.length
|
|
977
1723
|
end
|
|
978
1724
|
|
|
979
1725
|
def test_large_limit
|
|
980
1726
|
2000.times do |i|
|
|
981
|
-
|
|
1727
|
+
@test.insert("x" => i, "y" => "mongomongo" * 1000)
|
|
982
1728
|
end
|
|
983
1729
|
|
|
984
|
-
assert_equal 2000,
|
|
1730
|
+
assert_equal 2000, @test.count
|
|
985
1731
|
|
|
986
1732
|
i = 0
|
|
987
1733
|
y = 0
|
|
988
|
-
|
|
1734
|
+
@test.find({}, :limit => 1900).each do |doc|
|
|
989
1735
|
i += 1
|
|
990
1736
|
y += doc["x"]
|
|
991
1737
|
end
|
|
@@ -995,13 +1741,13 @@ end
|
|
|
995
1741
|
end
|
|
996
1742
|
|
|
997
1743
|
def test_small_limit
|
|
998
|
-
|
|
999
|
-
|
|
1744
|
+
@test.insert("x" => "hello world")
|
|
1745
|
+
@test.insert("x" => "goodbye world")
|
|
1000
1746
|
|
|
1001
|
-
assert_equal 2,
|
|
1747
|
+
assert_equal 2, @test.count
|
|
1002
1748
|
|
|
1003
1749
|
x = 0
|
|
1004
|
-
|
|
1750
|
+
@test.find({}, :limit => 1).each do |doc|
|
|
1005
1751
|
x += 1
|
|
1006
1752
|
assert_equal "hello world", doc["x"]
|
|
1007
1753
|
end
|
|
@@ -1012,55 +1758,56 @@ end
|
|
|
1012
1758
|
def test_find_with_transformer
|
|
1013
1759
|
klass = Struct.new(:id, :a)
|
|
1014
1760
|
transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
|
|
1015
|
-
cursor =
|
|
1761
|
+
cursor = @test.find({}, :transformer => transformer)
|
|
1016
1762
|
assert_equal(transformer, cursor.transformer)
|
|
1017
1763
|
end
|
|
1018
1764
|
|
|
1019
1765
|
def test_find_one_with_transformer
|
|
1020
1766
|
klass = Struct.new(:id, :a)
|
|
1021
1767
|
transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
|
|
1022
|
-
id =
|
|
1023
|
-
doc =
|
|
1768
|
+
id = @test.insert('a' => 1)
|
|
1769
|
+
doc = @test.find_one(id, :transformer => transformer)
|
|
1024
1770
|
assert_instance_of(klass, doc)
|
|
1025
1771
|
end
|
|
1026
1772
|
|
|
1027
1773
|
def test_ensure_index
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
assert_equal 1,
|
|
1774
|
+
@test.drop_indexes
|
|
1775
|
+
@test.insert("x" => "hello world")
|
|
1776
|
+
assert_equal 1, @test.index_information.keys.count #default index
|
|
1031
1777
|
|
|
1032
|
-
|
|
1033
|
-
assert_equal 2,
|
|
1034
|
-
assert
|
|
1778
|
+
@test.ensure_index([["x", Mongo::DESCENDING]], {})
|
|
1779
|
+
assert_equal 2, @test.index_information.keys.count
|
|
1780
|
+
assert @test.index_information.keys.include?("x_-1")
|
|
1035
1781
|
|
|
1036
|
-
|
|
1037
|
-
assert
|
|
1782
|
+
@test.ensure_index([["x", Mongo::ASCENDING]])
|
|
1783
|
+
assert @test.index_information.keys.include?("x_1")
|
|
1038
1784
|
|
|
1039
|
-
|
|
1040
|
-
assert
|
|
1785
|
+
@test.ensure_index([["type", 1], ["date", -1]])
|
|
1786
|
+
assert @test.index_information.keys.include?("type_1_date_-1")
|
|
1041
1787
|
|
|
1042
|
-
|
|
1043
|
-
assert_equal 3,
|
|
1044
|
-
|
|
1045
|
-
assert_equal 2,
|
|
1788
|
+
@test.drop_index("x_1")
|
|
1789
|
+
assert_equal 3, @test.index_information.keys.count
|
|
1790
|
+
@test.drop_index("x_-1")
|
|
1791
|
+
assert_equal 2, @test.index_information.keys.count
|
|
1046
1792
|
|
|
1047
|
-
|
|
1048
|
-
assert_equal 3,
|
|
1049
|
-
assert
|
|
1793
|
+
@test.ensure_index([["x", Mongo::DESCENDING]], {})
|
|
1794
|
+
assert_equal 3, @test.index_information.keys.count
|
|
1795
|
+
assert @test.index_information.keys.include?("x_-1")
|
|
1050
1796
|
|
|
1051
1797
|
# Make sure that drop_index expires cache properly
|
|
1052
|
-
|
|
1053
|
-
assert
|
|
1054
|
-
|
|
1055
|
-
assert
|
|
1056
|
-
|
|
1057
|
-
assert
|
|
1058
|
-
|
|
1798
|
+
@test.ensure_index([['a', 1]])
|
|
1799
|
+
assert @test.index_information.keys.include?("a_1")
|
|
1800
|
+
@test.drop_index("a_1")
|
|
1801
|
+
assert !@test.index_information.keys.include?("a_1")
|
|
1802
|
+
@test.ensure_index([['a', 1]])
|
|
1803
|
+
assert @test.index_information.keys.include?("a_1")
|
|
1804
|
+
@test.drop_index("a_1")
|
|
1805
|
+
@test.drop_indexes
|
|
1059
1806
|
end
|
|
1060
1807
|
|
|
1061
1808
|
def test_ensure_index_timeout
|
|
1062
|
-
|
|
1063
|
-
coll =
|
|
1809
|
+
@db.cache_time = 1
|
|
1810
|
+
coll = @db['ensure_test']
|
|
1064
1811
|
coll.expects(:generate_indexes).twice
|
|
1065
1812
|
coll.ensure_index([['a', 1]])
|
|
1066
1813
|
|
|
@@ -1070,100 +1817,108 @@ end
|
|
|
1070
1817
|
coll.ensure_index([['a', 1]])
|
|
1071
1818
|
coll.ensure_index([['a', 1]])
|
|
1072
1819
|
|
|
1073
|
-
sleep(
|
|
1820
|
+
sleep(1)
|
|
1074
1821
|
# This won't be, so generate_indexes will be called twice
|
|
1075
1822
|
coll.ensure_index([['a', 1]])
|
|
1823
|
+
coll.drop
|
|
1076
1824
|
end
|
|
1077
1825
|
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1826
|
+
def test_show_disk_loc
|
|
1827
|
+
return unless @version > '2.0.0'
|
|
1828
|
+
@test.save({:a => 1})
|
|
1829
|
+
@test.save({:a => 2})
|
|
1830
|
+
assert @test.find({:a => 1}, :show_disk_loc => true).show_disk_loc
|
|
1831
|
+
doc = @test.find({:a => 1}, :show_disk_loc => true).next
|
|
1832
|
+
assert (doc['$diskLoc'] || doc['$recordId'])
|
|
1833
|
+
@test.remove
|
|
1834
|
+
end
|
|
1086
1835
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1836
|
+
def test_max_scan
|
|
1837
|
+
return unless @version > '2.0.0'
|
|
1838
|
+
@test.drop
|
|
1839
|
+
n = 100
|
|
1840
|
+
n.times do |i|
|
|
1841
|
+
@test.save({:_id => i, :x => i % 10})
|
|
1842
|
+
end
|
|
1843
|
+
assert_equal(n, @test.find.to_a.size)
|
|
1844
|
+
assert_equal(50, @test.find({}, :max_scan => 50).to_a.size)
|
|
1845
|
+
assert_equal(10, @test.find({:x => 2}).to_a.size)
|
|
1846
|
+
assert_equal(5, @test.find({:x => 2}, :max_scan => 50).to_a.size)
|
|
1847
|
+
@test.ensure_index([[:x, 1]])
|
|
1848
|
+
assert_equal(10, @test.find({:x => 2}, :max_scan => n).to_a.size)
|
|
1849
|
+
@test.drop
|
|
1095
1850
|
end
|
|
1096
1851
|
|
|
1097
1852
|
context "Grouping" do
|
|
1098
1853
|
setup do
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1854
|
+
@test.remove
|
|
1855
|
+
@test.save("a" => 1)
|
|
1856
|
+
@test.save("b" => 1)
|
|
1102
1857
|
@initial = {"count" => 0}
|
|
1103
1858
|
@reduce_function = "function (obj, prev) { prev.count += inc_value; }"
|
|
1104
1859
|
end
|
|
1105
1860
|
|
|
1106
1861
|
should "fail if missing required options" do
|
|
1107
1862
|
assert_raise MongoArgumentError do
|
|
1108
|
-
|
|
1863
|
+
@test.group(:initial => {})
|
|
1109
1864
|
end
|
|
1110
1865
|
|
|
1111
1866
|
assert_raise MongoArgumentError do
|
|
1112
|
-
|
|
1867
|
+
@test.group(:reduce => "foo")
|
|
1113
1868
|
end
|
|
1114
1869
|
end
|
|
1115
1870
|
|
|
1116
1871
|
should "group results using eval form" do
|
|
1117
|
-
assert_equal 1,
|
|
1118
|
-
assert_equal 2,
|
|
1119
|
-
assert_equal 4,
|
|
1872
|
+
assert_equal 1, @test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 0.5}))[0]["count"]
|
|
1873
|
+
assert_equal 2, @test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 1}))[0]["count"]
|
|
1874
|
+
assert_equal 4, @test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 2}))[0]["count"]
|
|
1120
1875
|
end
|
|
1121
1876
|
|
|
1122
1877
|
should "finalize grouped results" do
|
|
1123
1878
|
@finalize = "function(doc) {doc.f = doc.count + 200; }"
|
|
1124
|
-
assert_equal 202,
|
|
1879
|
+
assert_equal 202, @test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 1}), :finalize => @finalize)[0]["f"]
|
|
1125
1880
|
end
|
|
1126
1881
|
end
|
|
1127
1882
|
|
|
1128
1883
|
context "Grouping with key" do
|
|
1129
1884
|
setup do
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1885
|
+
@test.remove
|
|
1886
|
+
@test.save("a" => 1, "pop" => 100)
|
|
1887
|
+
@test.save("a" => 1, "pop" => 100)
|
|
1888
|
+
@test.save("a" => 2, "pop" => 100)
|
|
1889
|
+
@test.save("a" => 2, "pop" => 100)
|
|
1135
1890
|
@initial = {"count" => 0, "foo" => 1}
|
|
1136
1891
|
@reduce_function = "function (obj, prev) { prev.count += obj.pop; }"
|
|
1137
1892
|
end
|
|
1138
1893
|
|
|
1139
1894
|
should "group" do
|
|
1140
|
-
result =
|
|
1895
|
+
result = @test.group(:key => :a, :initial => @initial, :reduce => @reduce_function)
|
|
1141
1896
|
assert result.all? { |r| r['count'] == 200 }
|
|
1142
1897
|
end
|
|
1143
1898
|
end
|
|
1144
1899
|
|
|
1145
1900
|
context "Grouping with a key function" do
|
|
1146
|
-
setup do
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1901
|
+
setup do
|
|
1902
|
+
@test.remove
|
|
1903
|
+
@test.save("a" => 1)
|
|
1904
|
+
@test.save("a" => 2)
|
|
1905
|
+
@test.save("a" => 3)
|
|
1906
|
+
@test.save("a" => 4)
|
|
1907
|
+
@test.save("a" => 5)
|
|
1153
1908
|
@initial = {"count" => 0}
|
|
1154
1909
|
@keyf = "function (doc) { if(doc.a % 2 == 0) { return {even: true}; } else {return {odd: true}} };"
|
|
1155
1910
|
@reduce = "function (obj, prev) { prev.count += 1; }"
|
|
1156
1911
|
end
|
|
1157
1912
|
|
|
1158
1913
|
should "group results" do
|
|
1159
|
-
results =
|
|
1914
|
+
results = @test.group(:keyf => @keyf, :initial => @initial, :reduce => @reduce).sort {|a, b| a['count'] <=> b['count']}
|
|
1160
1915
|
assert results[0]['even'] && results[0]['count'] == 2.0
|
|
1161
1916
|
assert results[1]['odd'] && results[1]['count'] == 3.0
|
|
1162
1917
|
end
|
|
1163
1918
|
|
|
1164
1919
|
should "group filtered results" do
|
|
1165
|
-
results =
|
|
1166
|
-
|
|
1920
|
+
results = @test.group(:keyf => @keyf, :cond => {:a => {'$ne' => 2}},
|
|
1921
|
+
:initial => @initial, :reduce => @reduce).sort {|a, b| a['count'] <=> b['count']}
|
|
1167
1922
|
assert results[0]['even'] && results[0]['count'] == 1.0
|
|
1168
1923
|
assert results[1]['odd'] && results[1]['count'] == 3.0
|
|
1169
1924
|
end
|
|
@@ -1171,7 +1926,7 @@ end
|
|
|
1171
1926
|
|
|
1172
1927
|
context "A collection with two records" do
|
|
1173
1928
|
setup do
|
|
1174
|
-
@collection =
|
|
1929
|
+
@collection = @db.collection('test-collection')
|
|
1175
1930
|
@collection.remove
|
|
1176
1931
|
@collection.insert({:name => "Jones"})
|
|
1177
1932
|
@collection.insert({:name => "Smith"})
|
|
@@ -1199,8 +1954,8 @@ end
|
|
|
1199
1954
|
|
|
1200
1955
|
context "Drop index " do
|
|
1201
1956
|
setup do
|
|
1202
|
-
|
|
1203
|
-
@collection =
|
|
1957
|
+
@db.drop_collection('test-collection')
|
|
1958
|
+
@collection = @db.collection('test-collection')
|
|
1204
1959
|
end
|
|
1205
1960
|
|
|
1206
1961
|
should "drop an index" do
|
|
@@ -1234,10 +1989,10 @@ end
|
|
|
1234
1989
|
|
|
1235
1990
|
context "Creating indexes " do
|
|
1236
1991
|
setup do
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
@collection =
|
|
1240
|
-
@geo =
|
|
1992
|
+
@db.drop_collection('geo')
|
|
1993
|
+
@db.drop_collection('test-collection')
|
|
1994
|
+
@collection = @db.collection('test-collection')
|
|
1995
|
+
@geo = @db.collection('geo')
|
|
1241
1996
|
end
|
|
1242
1997
|
|
|
1243
1998
|
should "create index using symbols" do
|
|
@@ -1272,6 +2027,7 @@ end
|
|
|
1272
2027
|
should "create a geoHaystack index" do
|
|
1273
2028
|
@geo.save({ "_id" => 100, "pos" => { "long" => 126.9, "lat" => 35.2 }, "type" => "restaurant"})
|
|
1274
2029
|
@geo.create_index([['pos', Mongo::GEOHAYSTACK], ['type', Mongo::ASCENDING]], :bucket_size => 1)
|
|
2030
|
+
assert @geo.index_information['pos_geoHaystack_type_1']
|
|
1275
2031
|
end
|
|
1276
2032
|
|
|
1277
2033
|
should "create a geo 2dsphere index" do
|
|
@@ -1286,31 +2042,37 @@ end
|
|
|
1286
2042
|
end
|
|
1287
2043
|
|
|
1288
2044
|
should "drop duplicates" do
|
|
1289
|
-
@
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
2045
|
+
if @version < '2.7'
|
|
2046
|
+
@collection.insert({:a => 1})
|
|
2047
|
+
@collection.insert({:a => 1})
|
|
2048
|
+
assert_equal 2, @collection.find({:a => 1}).count
|
|
2049
|
+
@collection.create_index([['a', Mongo::ASCENDING]], :unique => true, :dropDups => true)
|
|
2050
|
+
assert_equal 1, @collection.find({:a => 1}).count
|
|
2051
|
+
end
|
|
1294
2052
|
end
|
|
1295
2053
|
|
|
1296
2054
|
should "drop duplicates with ruby-like drop_dups key" do
|
|
1297
|
-
@
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
2055
|
+
if @version < '2.7'
|
|
2056
|
+
@collection.insert({:a => 1})
|
|
2057
|
+
@collection.insert({:a => 1})
|
|
2058
|
+
assert_equal 2, @collection.find({:a => 1}).count
|
|
2059
|
+
@collection.create_index([['a', Mongo::ASCENDING]], :unique => true, :drop_dups => true)
|
|
2060
|
+
assert_equal 1, @collection.find({:a => 1}).count
|
|
2061
|
+
end
|
|
1302
2062
|
end
|
|
1303
2063
|
|
|
1304
2064
|
should "drop duplicates with ensure_index and drop_dups key" do
|
|
1305
|
-
@
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
2065
|
+
if @version < '2.7'
|
|
2066
|
+
@collection.insert({:a => 1})
|
|
2067
|
+
@collection.insert({:a => 1})
|
|
2068
|
+
assert_equal 2, @collection.find({:a => 1}).count
|
|
2069
|
+
@collection.ensure_index([['a', Mongo::ASCENDING]], :unique => true, :drop_dups => true)
|
|
2070
|
+
assert_equal 1, @collection.find({:a => 1}).count
|
|
2071
|
+
end
|
|
1310
2072
|
end
|
|
1311
2073
|
|
|
1312
2074
|
should "create an index in the background" do
|
|
1313
|
-
if
|
|
2075
|
+
if @version > '1.3.1'
|
|
1314
2076
|
@collection.create_index([['b', Mongo::ASCENDING]], :background => true)
|
|
1315
2077
|
assert @collection.index_information['b_1']['background'] == true
|
|
1316
2078
|
else
|
|
@@ -1333,27 +2095,30 @@ end
|
|
|
1333
2095
|
should "raise an error if index name is greater than 128" do
|
|
1334
2096
|
assert_raise Mongo::OperationFailure do
|
|
1335
2097
|
@collection.create_index([['a' * 25, 1], ['b' * 25, 1],
|
|
1336
|
-
|
|
2098
|
+
['c' * 25, 1], ['d' * 25, 1], ['e' * 25, 1]])
|
|
1337
2099
|
end
|
|
1338
2100
|
end
|
|
1339
2101
|
|
|
1340
2102
|
should "allow for an alternate name to be specified" do
|
|
1341
2103
|
@collection.create_index([['a' * 25, 1], ['b' * 25, 1],
|
|
1342
|
-
|
|
2104
|
+
['c' * 25, 1], ['d' * 25, 1], ['e' * 25, 1]], :name => 'foo_index')
|
|
1343
2105
|
assert @collection.index_information['foo_index']
|
|
1344
2106
|
end
|
|
1345
2107
|
|
|
1346
2108
|
should "generate indexes in the proper order" do
|
|
1347
|
-
|
|
1348
|
-
|
|
2109
|
+
key = BSON::OrderedHash['b', 1, 'a', 1]
|
|
2110
|
+
if @version < '2.5.5'
|
|
2111
|
+
@collection.expects(:send_write) do |type, selector, documents, check_keys, opts, collection_name|
|
|
2112
|
+
assert_equal key, selector[:key]
|
|
2113
|
+
end
|
|
2114
|
+
else
|
|
2115
|
+
@collection.db.expects(:command) do |selector|
|
|
2116
|
+
assert_equal key, selector[:indexes].first[:key]
|
|
2117
|
+
end
|
|
1349
2118
|
end
|
|
1350
2119
|
@collection.create_index([['b', 1], ['a', 1]])
|
|
1351
2120
|
end
|
|
1352
2121
|
|
|
1353
|
-
should "allow multiple calls to create_index" do
|
|
1354
|
-
|
|
1355
|
-
end
|
|
1356
|
-
|
|
1357
2122
|
should "allow creation of multiple indexes" do
|
|
1358
2123
|
assert @collection.create_index([['a', 1]])
|
|
1359
2124
|
assert @collection.create_index([['a', 1]])
|
|
@@ -1372,8 +2137,8 @@ end
|
|
|
1372
2137
|
|
|
1373
2138
|
context "Capped collections" do
|
|
1374
2139
|
setup do
|
|
1375
|
-
|
|
1376
|
-
@capped =
|
|
2140
|
+
@db.drop_collection('log')
|
|
2141
|
+
@capped = @db.create_collection('log', :capped => true, :size => LIMITED_MAX_BSON_SIZE)
|
|
1377
2142
|
|
|
1378
2143
|
10.times { |n| @capped.insert({:n => n}) }
|
|
1379
2144
|
end
|
|
@@ -1389,7 +2154,7 @@ end
|
|
|
1389
2154
|
end
|
|
1390
2155
|
|
|
1391
2156
|
should "fail tailable cursor on a non-capped collection" do
|
|
1392
|
-
col =
|
|
2157
|
+
col = @db['regular-collection']
|
|
1393
2158
|
col.insert({:a => 1000})
|
|
1394
2159
|
tail = Cursor.new(col, :tailable => true, :order => [['$natural', 1]])
|
|
1395
2160
|
assert_raise OperationFailure do
|