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,3 +1,17 @@
|
|
|
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 'test_helper'
|
|
2
16
|
require 'logger'
|
|
3
17
|
|
|
@@ -5,15 +19,14 @@ class CursorTest < Test::Unit::TestCase
|
|
|
5
19
|
include Mongo
|
|
6
20
|
include Mongo::Constants
|
|
7
21
|
|
|
8
|
-
@@connection = standard_connection
|
|
9
|
-
@@db = @@connection.db(MONGO_TEST_DB)
|
|
10
|
-
@@coll = @@db.collection('test')
|
|
11
|
-
@@version = @@connection.server_version
|
|
12
|
-
|
|
13
22
|
def setup
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
23
|
+
@connection = standard_connection
|
|
24
|
+
@db = @connection.db(TEST_DB)
|
|
25
|
+
@coll = @db.collection('test')
|
|
26
|
+
@version = @connection.server_version
|
|
27
|
+
@coll.remove
|
|
28
|
+
@coll.insert('a' => 1) # collection not created until it's used
|
|
29
|
+
@coll_full_name = "#{TEST_DB}.test"
|
|
17
30
|
end
|
|
18
31
|
|
|
19
32
|
def test_alive
|
|
@@ -22,18 +35,18 @@ class CursorTest < Test::Unit::TestCase
|
|
|
22
35
|
batch << {:a => n}
|
|
23
36
|
end
|
|
24
37
|
|
|
25
|
-
|
|
26
|
-
cursor =
|
|
38
|
+
@coll.insert(batch)
|
|
39
|
+
cursor = @coll.find
|
|
27
40
|
assert !cursor.alive?
|
|
28
41
|
cursor.next
|
|
29
42
|
assert cursor.alive?
|
|
30
43
|
cursor.close
|
|
31
44
|
assert !cursor.alive?
|
|
32
|
-
|
|
45
|
+
@coll.remove
|
|
33
46
|
end
|
|
34
47
|
|
|
35
48
|
def test_add_and_remove_options
|
|
36
|
-
c =
|
|
49
|
+
c = @coll.find
|
|
37
50
|
assert_equal 0, c.options & OP_QUERY_EXHAUST
|
|
38
51
|
c.add_option(OP_QUERY_EXHAUST)
|
|
39
52
|
assert_equal OP_QUERY_EXHAUST, c.options & OP_QUERY_EXHAUST
|
|
@@ -51,19 +64,19 @@ class CursorTest < Test::Unit::TestCase
|
|
|
51
64
|
end
|
|
52
65
|
|
|
53
66
|
def test_exhaust
|
|
54
|
-
if
|
|
55
|
-
|
|
67
|
+
if @version >= "2.0"
|
|
68
|
+
@coll.remove
|
|
56
69
|
data = "1" * 10_000
|
|
57
70
|
5000.times do |n|
|
|
58
|
-
|
|
71
|
+
@coll.insert({:n => n, :data => data})
|
|
59
72
|
end
|
|
60
73
|
|
|
61
|
-
c = Cursor.new(
|
|
74
|
+
c = Cursor.new(@coll)
|
|
62
75
|
c.add_option(OP_QUERY_EXHAUST)
|
|
63
|
-
assert_equal
|
|
76
|
+
assert_equal @coll.count, c.to_a.size
|
|
64
77
|
assert c.closed?
|
|
65
78
|
|
|
66
|
-
c = Cursor.new(
|
|
79
|
+
c = Cursor.new(@coll)
|
|
67
80
|
c.add_option(OP_QUERY_EXHAUST)
|
|
68
81
|
4999.times do
|
|
69
82
|
c.next
|
|
@@ -73,116 +86,185 @@ class CursorTest < Test::Unit::TestCase
|
|
|
73
86
|
assert !c.has_next?
|
|
74
87
|
assert c.closed?
|
|
75
88
|
|
|
76
|
-
|
|
89
|
+
@coll.remove
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def test_compile_regex_get_more
|
|
94
|
+
return unless defined?(BSON::BSON_RUBY) && BSON::BSON_CODER == BSON::BSON_RUBY
|
|
95
|
+
@coll.remove
|
|
96
|
+
n_docs = 3
|
|
97
|
+
n_docs.times { |n| @coll.insert({ 'n' => /.*/ }) }
|
|
98
|
+
cursor = @coll.find({}, :batch_size => (n_docs-1), :compile_regex => false)
|
|
99
|
+
cursor.expects(:send_get_more)
|
|
100
|
+
cursor.to_a.each do |doc|
|
|
101
|
+
assert_kind_of BSON::Regex, doc['n']
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def test_max_time_ms_error
|
|
106
|
+
cursor = @coll.find
|
|
107
|
+
cursor.stubs(:send_initial_query).returns(true)
|
|
108
|
+
|
|
109
|
+
cursor.instance_variable_set(:@cache, [{
|
|
110
|
+
'$err' => 'operation exceeded time limit',
|
|
111
|
+
'code' => 50
|
|
112
|
+
}])
|
|
113
|
+
|
|
114
|
+
assert_raise ExecutionTimeout do
|
|
115
|
+
cursor.to_a
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def test_max_time_ms
|
|
120
|
+
with_forced_timeout(@connection) do
|
|
121
|
+
assert_raise ExecutionTimeout do
|
|
122
|
+
cursor = @coll.find.max_time_ms(100)
|
|
123
|
+
cursor.to_a
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def test_exhaust_after_limit_error
|
|
129
|
+
c = Cursor.new(@coll, :limit => 17)
|
|
130
|
+
assert_raise MongoArgumentError do
|
|
131
|
+
c.add_option(OP_QUERY_EXHAUST)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
assert_raise MongoArgumentError do
|
|
135
|
+
c.add_option(OP_QUERY_EXHAUST + OP_QUERY_SLAVE_OK)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_limit_after_exhaust_error
|
|
140
|
+
c = Cursor.new(@coll)
|
|
141
|
+
c.add_option(OP_QUERY_EXHAUST)
|
|
142
|
+
assert_raise MongoArgumentError do
|
|
143
|
+
c.limit(17)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def test_exhaust_with_mongos
|
|
148
|
+
@connection.expects(:mongos?).returns(:true)
|
|
149
|
+
c = Cursor.new(@coll)
|
|
150
|
+
|
|
151
|
+
assert_raise MongoArgumentError do
|
|
152
|
+
c.add_option(OP_QUERY_EXHAUST)
|
|
77
153
|
end
|
|
78
154
|
end
|
|
79
155
|
|
|
80
156
|
def test_inspect
|
|
81
157
|
selector = {:a => 1}
|
|
82
|
-
cursor =
|
|
83
|
-
assert_equal "<Mongo::Cursor:0x#{cursor.object_id.to_s(16)} namespace='#{
|
|
84
|
-
|
|
158
|
+
cursor = @coll.find(selector)
|
|
159
|
+
assert_equal "<Mongo::Cursor:0x#{cursor.object_id.to_s(16)} namespace='#{@db.name}.#{@coll.name}' " +
|
|
160
|
+
"@selector=#{selector.inspect} @cursor_id=#{cursor.cursor_id}>", cursor.inspect
|
|
85
161
|
end
|
|
86
162
|
|
|
87
163
|
def test_explain
|
|
88
|
-
cursor =
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
164
|
+
cursor = @coll.find('a' => 1)
|
|
165
|
+
explanation = cursor.explain
|
|
166
|
+
if @version < '2.7'
|
|
167
|
+
assert_not_nil explanation['cursor']
|
|
168
|
+
assert_kind_of Numeric, explanation['n']
|
|
169
|
+
assert_kind_of Numeric, explanation['millis']
|
|
170
|
+
assert_kind_of Numeric, explanation['nscanned']
|
|
171
|
+
else
|
|
172
|
+
cursor = @coll.find('a' => 1)
|
|
173
|
+
assert_not_nil explanation
|
|
174
|
+
assert explanation.keys.include?('executionStats')
|
|
175
|
+
end
|
|
94
176
|
end
|
|
95
177
|
|
|
96
178
|
def test_each_with_no_block
|
|
97
|
-
assert_kind_of(Enumerator,
|
|
179
|
+
assert_kind_of(Enumerator, @coll.find().each) if defined? Enumerator
|
|
98
180
|
end
|
|
99
181
|
|
|
100
182
|
def test_count
|
|
101
|
-
|
|
183
|
+
@coll.remove
|
|
102
184
|
|
|
103
|
-
assert_equal 0,
|
|
185
|
+
assert_equal 0, @coll.find().count()
|
|
104
186
|
|
|
105
187
|
10.times do |i|
|
|
106
|
-
|
|
188
|
+
@coll.save("x" => i)
|
|
107
189
|
end
|
|
108
190
|
|
|
109
|
-
assert_equal 10,
|
|
110
|
-
assert_kind_of Integer,
|
|
111
|
-
assert_equal 10,
|
|
112
|
-
assert_equal 10,
|
|
191
|
+
assert_equal 10, @coll.find().count()
|
|
192
|
+
assert_kind_of Integer, @coll.find().count()
|
|
193
|
+
assert_equal 10, @coll.find({}, :limit => 5).count()
|
|
194
|
+
assert_equal 10, @coll.find({}, :skip => 5).count()
|
|
113
195
|
|
|
114
|
-
assert_equal 5,
|
|
115
|
-
assert_equal 5,
|
|
116
|
-
assert_equal 2,
|
|
196
|
+
assert_equal 5, @coll.find({}, :limit => 5).count(true)
|
|
197
|
+
assert_equal 5, @coll.find({}, :skip => 5).count(true)
|
|
198
|
+
assert_equal 2, @coll.find({}, :skip => 5, :limit => 2).count(true)
|
|
117
199
|
|
|
118
|
-
assert_equal 1,
|
|
119
|
-
assert_equal 5,
|
|
200
|
+
assert_equal 1, @coll.find({"x" => 1}).count()
|
|
201
|
+
assert_equal 5, @coll.find({"x" => {"$lt" => 5}}).count()
|
|
120
202
|
|
|
121
|
-
a =
|
|
203
|
+
a = @coll.find()
|
|
122
204
|
b = a.count()
|
|
123
205
|
a.each do |doc|
|
|
124
206
|
break
|
|
125
207
|
end
|
|
126
208
|
assert_equal b, a.count()
|
|
127
209
|
|
|
128
|
-
assert_equal 0,
|
|
210
|
+
assert_equal 0, @db['acollectionthatdoesn'].count()
|
|
129
211
|
end
|
|
130
212
|
|
|
131
213
|
def test_sort
|
|
132
|
-
|
|
133
|
-
5.times{|x|
|
|
214
|
+
@coll.remove
|
|
215
|
+
5.times{|x| @coll.insert({"age" => x}) }
|
|
134
216
|
|
|
135
|
-
assert_kind_of Cursor,
|
|
217
|
+
assert_kind_of Cursor, @coll.find().sort(:age, 1)
|
|
136
218
|
|
|
137
|
-
assert_equal 0,
|
|
138
|
-
assert_equal 4,
|
|
139
|
-
assert_equal 0,
|
|
219
|
+
assert_equal 0, @coll.find().sort(:age, 1).next_document["age"]
|
|
220
|
+
assert_equal 4, @coll.find().sort(:age, -1).next_document["age"]
|
|
221
|
+
assert_equal 0, @coll.find().sort([["age", :asc]]).next_document["age"]
|
|
140
222
|
|
|
141
|
-
assert_kind_of Cursor,
|
|
223
|
+
assert_kind_of Cursor, @coll.find().sort([[:age, -1], [:b, 1]])
|
|
142
224
|
|
|
143
|
-
assert_equal 4,
|
|
144
|
-
assert_equal 0,
|
|
225
|
+
assert_equal 4, @coll.find().sort(:age, 1).sort(:age, -1).next_document["age"]
|
|
226
|
+
assert_equal 0, @coll.find().sort(:age, -1).sort(:age, 1).next_document["age"]
|
|
145
227
|
|
|
146
|
-
assert_equal 4,
|
|
147
|
-
assert_equal 0,
|
|
228
|
+
assert_equal 4, @coll.find().sort([:age, :asc]).sort(:age, -1).next_document["age"]
|
|
229
|
+
assert_equal 0, @coll.find().sort([:age, :desc]).sort(:age, 1).next_document["age"]
|
|
148
230
|
|
|
149
|
-
cursor =
|
|
231
|
+
cursor = @coll.find()
|
|
150
232
|
cursor.next_document
|
|
151
233
|
assert_raise InvalidOperation do
|
|
152
234
|
cursor.sort(["age"])
|
|
153
235
|
end
|
|
154
236
|
|
|
155
237
|
assert_raise InvalidSortValueError do
|
|
156
|
-
|
|
238
|
+
@coll.find().sort(:age, 25).next_document
|
|
157
239
|
end
|
|
158
240
|
|
|
159
241
|
assert_raise InvalidSortValueError do
|
|
160
|
-
|
|
242
|
+
@coll.find().sort(25).next_document
|
|
161
243
|
end
|
|
162
244
|
end
|
|
163
245
|
|
|
164
246
|
def test_sort_date
|
|
165
|
-
|
|
166
|
-
5.times{|x|
|
|
247
|
+
@coll.remove
|
|
248
|
+
5.times{|x| @coll.insert({"created_at" => Time.utc(2000 + x)}) }
|
|
167
249
|
|
|
168
|
-
assert_equal 2000,
|
|
169
|
-
assert_equal 2004,
|
|
250
|
+
assert_equal 2000, @coll.find().sort(:created_at, :asc).next_document["created_at"].year
|
|
251
|
+
assert_equal 2004, @coll.find().sort(:created_at, :desc).next_document["created_at"].year
|
|
170
252
|
|
|
171
|
-
assert_equal 2000,
|
|
172
|
-
assert_equal 2004,
|
|
253
|
+
assert_equal 2000, @coll.find().sort([:created_at, :asc]).next_document["created_at"].year
|
|
254
|
+
assert_equal 2004, @coll.find().sort([:created_at, :desc]).next_document["created_at"].year
|
|
173
255
|
|
|
174
|
-
assert_equal 2000,
|
|
175
|
-
assert_equal 2004,
|
|
256
|
+
assert_equal 2000, @coll.find().sort([[:created_at, :asc]]).next_document["created_at"].year
|
|
257
|
+
assert_equal 2004, @coll.find().sort([[:created_at, :desc]]).next_document["created_at"].year
|
|
176
258
|
end
|
|
177
259
|
|
|
178
260
|
def test_sort_min_max_keys
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
261
|
+
@coll.remove
|
|
262
|
+
@coll.insert({"n" => 1000000})
|
|
263
|
+
@coll.insert({"n" => -1000000})
|
|
264
|
+
@coll.insert({"n" => MaxKey.new})
|
|
265
|
+
@coll.insert({"n" => MinKey.new})
|
|
184
266
|
|
|
185
|
-
results =
|
|
267
|
+
results = @coll.find.sort([:n, :asc]).to_a
|
|
186
268
|
|
|
187
269
|
assert_equal MinKey.new, results[0]['n']
|
|
188
270
|
assert_equal(-1000000, results[1]['n'])
|
|
@@ -191,73 +273,73 @@ class CursorTest < Test::Unit::TestCase
|
|
|
191
273
|
end
|
|
192
274
|
|
|
193
275
|
def test_id_range_queries
|
|
194
|
-
|
|
276
|
+
@coll.remove
|
|
195
277
|
|
|
196
278
|
t1 = Time.now
|
|
197
279
|
t1_id = ObjectId.from_time(t1)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
sleep(
|
|
280
|
+
@coll.save({:t => 't1'})
|
|
281
|
+
@coll.save({:t => 't1'})
|
|
282
|
+
@coll.save({:t => 't1'})
|
|
283
|
+
sleep(1)
|
|
202
284
|
t2 = Time.now
|
|
203
285
|
t2_id = ObjectId.from_time(t2)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
286
|
+
@coll.save({:t => 't2'})
|
|
287
|
+
@coll.save({:t => 't2'})
|
|
288
|
+
@coll.save({:t => 't2'})
|
|
207
289
|
|
|
208
|
-
assert_equal 3,
|
|
209
|
-
|
|
290
|
+
assert_equal 3, @coll.find({'_id' => {'$gt' => t1_id, '$lt' => t2_id}}).count
|
|
291
|
+
@coll.find({'_id' => {'$gt' => t2_id}}).each do |doc|
|
|
210
292
|
assert_equal 't2', doc['t']
|
|
211
293
|
end
|
|
212
294
|
end
|
|
213
295
|
|
|
214
296
|
def test_limit
|
|
215
|
-
|
|
297
|
+
@coll.remove
|
|
216
298
|
|
|
217
299
|
10.times do |i|
|
|
218
|
-
|
|
300
|
+
@coll.save("x" => i)
|
|
219
301
|
end
|
|
220
|
-
assert_equal 10,
|
|
302
|
+
assert_equal 10, @coll.find().count()
|
|
221
303
|
|
|
222
|
-
results =
|
|
304
|
+
results = @coll.find().limit(5).to_a
|
|
223
305
|
assert_equal 5, results.length
|
|
224
306
|
end
|
|
225
307
|
|
|
226
308
|
def test_timeout_options
|
|
227
|
-
cursor = Cursor.new(
|
|
309
|
+
cursor = Cursor.new(@coll)
|
|
228
310
|
assert_equal true, cursor.timeout
|
|
229
311
|
|
|
230
|
-
cursor =
|
|
312
|
+
cursor = @coll.find
|
|
231
313
|
assert_equal true, cursor.timeout
|
|
232
314
|
|
|
233
|
-
cursor =
|
|
315
|
+
cursor = @coll.find({}, :timeout => nil)
|
|
234
316
|
assert_equal true, cursor.timeout
|
|
235
317
|
|
|
236
|
-
cursor = Cursor.new(
|
|
318
|
+
cursor = Cursor.new(@coll, :timeout => false)
|
|
237
319
|
assert_equal false, cursor.timeout
|
|
238
320
|
|
|
239
|
-
|
|
321
|
+
@coll.find({}, :timeout => false) do |c|
|
|
240
322
|
assert_equal false, c.timeout
|
|
241
323
|
end
|
|
242
324
|
end
|
|
243
325
|
|
|
244
326
|
def test_timeout
|
|
245
|
-
opts = Cursor.new(
|
|
327
|
+
opts = Cursor.new(@coll).options
|
|
246
328
|
assert_equal 0, opts & Mongo::Constants::OP_QUERY_NO_CURSOR_TIMEOUT
|
|
247
329
|
|
|
248
|
-
opts = Cursor.new(
|
|
330
|
+
opts = Cursor.new(@coll, :timeout => false).options
|
|
249
331
|
assert_equal Mongo::Constants::OP_QUERY_NO_CURSOR_TIMEOUT,
|
|
250
|
-
|
|
332
|
+
opts & Mongo::Constants::OP_QUERY_NO_CURSOR_TIMEOUT
|
|
251
333
|
end
|
|
252
334
|
|
|
253
335
|
def test_limit_exceptions
|
|
254
|
-
cursor =
|
|
336
|
+
cursor = @coll.find()
|
|
255
337
|
cursor.next_document
|
|
256
338
|
assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
|
|
257
339
|
cursor.limit(1)
|
|
258
340
|
end
|
|
259
341
|
|
|
260
|
-
cursor =
|
|
342
|
+
cursor = @coll.find()
|
|
261
343
|
cursor.close
|
|
262
344
|
assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
|
|
263
345
|
cursor.limit(1)
|
|
@@ -265,15 +347,15 @@ class CursorTest < Test::Unit::TestCase
|
|
|
265
347
|
end
|
|
266
348
|
|
|
267
349
|
def test_skip
|
|
268
|
-
|
|
350
|
+
@coll.remove
|
|
269
351
|
|
|
270
352
|
10.times do |i|
|
|
271
|
-
|
|
353
|
+
@coll.save("x" => i)
|
|
272
354
|
end
|
|
273
|
-
assert_equal 10,
|
|
355
|
+
assert_equal 10, @coll.find().count()
|
|
274
356
|
|
|
275
|
-
all_results =
|
|
276
|
-
skip_results =
|
|
357
|
+
all_results = @coll.find().to_a
|
|
358
|
+
skip_results = @coll.find().skip(2).to_a
|
|
277
359
|
assert_equal 10, all_results.length
|
|
278
360
|
assert_equal 8, skip_results.length
|
|
279
361
|
|
|
@@ -281,13 +363,13 @@ class CursorTest < Test::Unit::TestCase
|
|
|
281
363
|
end
|
|
282
364
|
|
|
283
365
|
def test_skip_exceptions
|
|
284
|
-
cursor =
|
|
366
|
+
cursor = @coll.find()
|
|
285
367
|
cursor.next_document
|
|
286
368
|
assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
|
|
287
369
|
cursor.skip(1)
|
|
288
370
|
end
|
|
289
371
|
|
|
290
|
-
cursor =
|
|
372
|
+
cursor = @coll.find()
|
|
291
373
|
cursor.close
|
|
292
374
|
assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
|
|
293
375
|
cursor.skip(1)
|
|
@@ -295,20 +377,20 @@ class CursorTest < Test::Unit::TestCase
|
|
|
295
377
|
end
|
|
296
378
|
|
|
297
379
|
def test_limit_skip_chaining
|
|
298
|
-
|
|
380
|
+
@coll.remove
|
|
299
381
|
10.times do |i|
|
|
300
|
-
|
|
382
|
+
@coll.save("x" => i)
|
|
301
383
|
end
|
|
302
384
|
|
|
303
|
-
all_results =
|
|
304
|
-
limited_skip_results =
|
|
385
|
+
all_results = @coll.find().to_a
|
|
386
|
+
limited_skip_results = @coll.find().limit(5).skip(3).to_a
|
|
305
387
|
|
|
306
388
|
assert_equal all_results.slice(3...8), limited_skip_results
|
|
307
389
|
end
|
|
308
390
|
|
|
309
391
|
def test_close_no_query_sent
|
|
310
392
|
begin
|
|
311
|
-
cursor =
|
|
393
|
+
cursor = @coll.find('a' => 1)
|
|
312
394
|
cursor.close
|
|
313
395
|
assert cursor.closed?
|
|
314
396
|
rescue => ex
|
|
@@ -317,33 +399,33 @@ class CursorTest < Test::Unit::TestCase
|
|
|
317
399
|
end
|
|
318
400
|
|
|
319
401
|
def test_refill_via_get_more
|
|
320
|
-
assert_equal 1,
|
|
402
|
+
assert_equal 1, @coll.count
|
|
321
403
|
1000.times { |i|
|
|
322
|
-
assert_equal 1 + i,
|
|
323
|
-
|
|
404
|
+
assert_equal 1 + i, @coll.count
|
|
405
|
+
@coll.insert('a' => i)
|
|
324
406
|
}
|
|
325
407
|
|
|
326
|
-
assert_equal 1001,
|
|
408
|
+
assert_equal 1001, @coll.count
|
|
327
409
|
count = 0
|
|
328
|
-
|
|
410
|
+
@coll.find.each { |obj|
|
|
329
411
|
count += obj['a']
|
|
330
412
|
}
|
|
331
|
-
assert_equal 1001,
|
|
413
|
+
assert_equal 1001, @coll.count
|
|
332
414
|
|
|
333
415
|
# do the same thing again for debugging
|
|
334
|
-
assert_equal 1001,
|
|
416
|
+
assert_equal 1001, @coll.count
|
|
335
417
|
count2 = 0
|
|
336
|
-
|
|
418
|
+
@coll.find.each { |obj|
|
|
337
419
|
count2 += obj['a']
|
|
338
420
|
}
|
|
339
|
-
assert_equal 1001,
|
|
421
|
+
assert_equal 1001, @coll.count
|
|
340
422
|
|
|
341
423
|
assert_equal count, count2
|
|
342
424
|
assert_equal 499501, count
|
|
343
425
|
end
|
|
344
426
|
|
|
345
427
|
def test_refill_via_get_more_alt_coll
|
|
346
|
-
coll =
|
|
428
|
+
coll = @db.collection('test-alt-coll')
|
|
347
429
|
coll.remove
|
|
348
430
|
coll.insert('a' => 1) # collection not created until it's used
|
|
349
431
|
assert_equal 1, coll.count
|
|
@@ -374,7 +456,7 @@ class CursorTest < Test::Unit::TestCase
|
|
|
374
456
|
|
|
375
457
|
def test_close_after_query_sent
|
|
376
458
|
begin
|
|
377
|
-
cursor =
|
|
459
|
+
cursor = @coll.find('a' => 1)
|
|
378
460
|
cursor.next_document
|
|
379
461
|
cursor.close
|
|
380
462
|
assert cursor.closed?
|
|
@@ -384,82 +466,127 @@ class CursorTest < Test::Unit::TestCase
|
|
|
384
466
|
end
|
|
385
467
|
|
|
386
468
|
def test_kill_cursors
|
|
387
|
-
|
|
469
|
+
@coll.drop
|
|
388
470
|
|
|
389
|
-
client_cursors =
|
|
471
|
+
client_cursors = cursor_count(@db)
|
|
390
472
|
|
|
391
473
|
10000.times do |i|
|
|
392
|
-
|
|
474
|
+
@coll.insert("i" => i)
|
|
393
475
|
end
|
|
394
476
|
|
|
395
|
-
assert_equal(client_cursors,
|
|
396
|
-
@@db.command("cursorInfo" => 1)["clientCursors_size"])
|
|
477
|
+
assert_equal(client_cursors, cursor_count(@db))
|
|
397
478
|
|
|
398
479
|
10.times do |i|
|
|
399
|
-
|
|
480
|
+
@coll.find_one()
|
|
400
481
|
end
|
|
401
482
|
|
|
402
|
-
assert_equal(client_cursors,
|
|
403
|
-
@@db.command("cursorInfo" => 1)["clientCursors_size"])
|
|
483
|
+
assert_equal(client_cursors, cursor_count(@db))
|
|
404
484
|
|
|
405
485
|
10.times do |i|
|
|
406
|
-
a =
|
|
486
|
+
a = @coll.find()
|
|
407
487
|
a.next_document
|
|
408
488
|
a.close()
|
|
409
489
|
end
|
|
410
490
|
|
|
411
|
-
assert_equal(client_cursors,
|
|
412
|
-
@@db.command("cursorInfo" => 1)["clientCursors_size"])
|
|
491
|
+
assert_equal(client_cursors, cursor_count(@db))
|
|
413
492
|
|
|
414
|
-
a =
|
|
493
|
+
a = @coll.find()
|
|
415
494
|
a.next_document
|
|
416
495
|
|
|
417
|
-
assert_not_equal(client_cursors,
|
|
418
|
-
@@db.command("cursorInfo" => 1)["clientCursors_size"])
|
|
496
|
+
assert_not_equal(client_cursors, cursor_count(@db))
|
|
419
497
|
|
|
420
498
|
a.close()
|
|
421
499
|
|
|
422
|
-
assert_equal(client_cursors,
|
|
423
|
-
@@db.command("cursorInfo" => 1)["clientCursors_size"])
|
|
500
|
+
assert_equal(client_cursors, cursor_count(@db))
|
|
424
501
|
|
|
425
|
-
a =
|
|
502
|
+
a = @coll.find({}, :limit => 10).next_document
|
|
426
503
|
|
|
427
|
-
assert_equal(client_cursors,
|
|
428
|
-
@@db.command("cursorInfo" => 1)["clientCursors_size"])
|
|
504
|
+
assert_equal(client_cursors, cursor_count(@db))
|
|
429
505
|
|
|
430
|
-
|
|
506
|
+
@coll.find() do |cursor|
|
|
431
507
|
cursor.next_document
|
|
432
508
|
end
|
|
433
509
|
|
|
434
|
-
assert_equal(client_cursors,
|
|
435
|
-
@@db.command("cursorInfo" => 1)["clientCursors_size"])
|
|
510
|
+
assert_equal(client_cursors, cursor_count(@db))
|
|
436
511
|
|
|
437
|
-
|
|
512
|
+
@coll.find() { |cursor|
|
|
438
513
|
cursor.next_document
|
|
439
514
|
}
|
|
440
515
|
|
|
441
|
-
assert_equal(client_cursors,
|
|
442
|
-
@@db.command("cursorInfo" => 1)["clientCursors_size"])
|
|
516
|
+
assert_equal(client_cursors, cursor_count(@db))
|
|
443
517
|
end
|
|
444
518
|
|
|
445
519
|
def test_count_with_fields
|
|
446
|
-
|
|
447
|
-
|
|
520
|
+
@coll.remove
|
|
521
|
+
@coll.save("x" => 1)
|
|
522
|
+
|
|
523
|
+
if @version < "1.1.3"
|
|
524
|
+
assert_equal(0, @coll.find({}, :fields => ["a"]).count())
|
|
525
|
+
else
|
|
526
|
+
assert_equal(1, @coll.find({}, :fields => ["a"]).count())
|
|
527
|
+
end
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
def test_count_with_hint
|
|
531
|
+
@coll.drop
|
|
532
|
+
@coll.save(:i => 1)
|
|
533
|
+
@coll.save(:i => 2)
|
|
534
|
+
assert_equal 2, @coll.find.count
|
|
535
|
+
|
|
536
|
+
@coll.ensure_index(BSON::OrderedHash[:i, Mongo::ASCENDING])
|
|
537
|
+
|
|
538
|
+
# Check that a named_hint can be specified
|
|
539
|
+
assert_equal 1, @coll.find({ :i => 1 }, :named_hint => '_id_').count
|
|
540
|
+
assert_equal 2, @coll.find({ }, :named_hint => '_id_').count
|
|
541
|
+
|
|
542
|
+
# Verify that the hint is being sent to the server by providing a bad hint
|
|
543
|
+
if @version > '2.6'
|
|
544
|
+
assert_raise Mongo::OperationFailure do
|
|
545
|
+
@coll.find({ :i => 1 }, :hint => 'bad_hint').count
|
|
546
|
+
end
|
|
547
|
+
else
|
|
548
|
+
assert_equal 1, @coll.find({ :i => 1 }, :hint => 'bad_hint').count
|
|
549
|
+
end
|
|
448
550
|
|
|
449
|
-
|
|
450
|
-
|
|
551
|
+
# Verify that the named_hint is being sent to the server by providing a bad hint
|
|
552
|
+
if @version > '2.6'
|
|
553
|
+
assert_raise Mongo::OperationFailure do
|
|
554
|
+
@coll.find({ :i => 1 }, :named_hint => 'bad_hint').count
|
|
555
|
+
end
|
|
451
556
|
else
|
|
452
|
-
assert_equal
|
|
557
|
+
assert_equal 1, @coll.find({ :i => 1 }, :named_hint => 'bad_hint').count
|
|
453
558
|
end
|
|
559
|
+
|
|
560
|
+
@coll.ensure_index(BSON::OrderedHash[:x, Mongo::ASCENDING], :sparse => true)
|
|
561
|
+
|
|
562
|
+
# The sparse index won't have any entries.
|
|
563
|
+
# Check that count returns 0 when using the hint.
|
|
564
|
+
expected = @version > '2.6' ? 0 : 1
|
|
565
|
+
assert_equal expected, @coll.find({ :i => 1 }, :hint => { 'x' => 1 }).count
|
|
566
|
+
assert_equal expected, @coll.find({ :i => 1 }, :hint => 'x').count
|
|
567
|
+
assert_equal expected, @coll.find({ :i => 1 }, :named_hint => 'x_1').count
|
|
568
|
+
|
|
569
|
+
# Verify that the hint / named hint set on the collection is used.
|
|
570
|
+
@coll.hint = { 'x' => 1 }
|
|
571
|
+
assert_equal expected, @coll.find(:i => 1).count
|
|
572
|
+
|
|
573
|
+
@coll.hint = 'x'
|
|
574
|
+
assert_equal expected, @coll.find(:i => 1).count
|
|
575
|
+
|
|
576
|
+
@coll.named_hint = 'x_1'
|
|
577
|
+
assert_equal expected, @coll.find(:i => 1).count
|
|
578
|
+
|
|
579
|
+
assert_equal 2, @coll.find({ }, :hint => 'x').count
|
|
580
|
+
assert_equal 2, @coll.find({ }, :named_hint => 'x_1').count
|
|
454
581
|
end
|
|
455
582
|
|
|
456
583
|
def test_has_next
|
|
457
|
-
|
|
584
|
+
@coll.remove
|
|
458
585
|
200.times do |n|
|
|
459
|
-
|
|
586
|
+
@coll.save("x" => n)
|
|
460
587
|
end
|
|
461
588
|
|
|
462
|
-
cursor =
|
|
589
|
+
cursor = @coll.find
|
|
463
590
|
n = 0
|
|
464
591
|
while cursor.has_next?
|
|
465
592
|
assert cursor.next
|
|
@@ -471,12 +598,12 @@ class CursorTest < Test::Unit::TestCase
|
|
|
471
598
|
end
|
|
472
599
|
|
|
473
600
|
def test_cursor_invalid
|
|
474
|
-
|
|
601
|
+
@coll.remove
|
|
475
602
|
10000.times do |n|
|
|
476
|
-
|
|
603
|
+
@coll.insert({:a => n})
|
|
477
604
|
end
|
|
478
605
|
|
|
479
|
-
cursor =
|
|
606
|
+
cursor = @coll.find({})
|
|
480
607
|
|
|
481
608
|
assert_raise_error Mongo::OperationFailure, "CURSOR_NOT_FOUND" do
|
|
482
609
|
9999.times do
|
|
@@ -487,26 +614,26 @@ class CursorTest < Test::Unit::TestCase
|
|
|
487
614
|
end
|
|
488
615
|
|
|
489
616
|
def test_enumberables
|
|
490
|
-
|
|
617
|
+
@coll.remove
|
|
491
618
|
100.times do |n|
|
|
492
|
-
|
|
619
|
+
@coll.insert({:a => n})
|
|
493
620
|
end
|
|
494
621
|
|
|
495
|
-
assert_equal 100,
|
|
496
|
-
assert_equal 100,
|
|
622
|
+
assert_equal 100, @coll.find.to_a.length
|
|
623
|
+
assert_equal 100, @coll.find.to_set.length
|
|
497
624
|
|
|
498
|
-
cursor =
|
|
625
|
+
cursor = @coll.find
|
|
499
626
|
50.times { |n| cursor.next_document }
|
|
500
627
|
assert_equal 50, cursor.to_a.length
|
|
501
628
|
end
|
|
502
629
|
|
|
503
630
|
def test_rewind
|
|
504
|
-
|
|
631
|
+
@coll.remove
|
|
505
632
|
100.times do |n|
|
|
506
|
-
|
|
633
|
+
@coll.insert({:a => n})
|
|
507
634
|
end
|
|
508
635
|
|
|
509
|
-
cursor =
|
|
636
|
+
cursor = @coll.find
|
|
510
637
|
cursor.to_a
|
|
511
638
|
assert_equal [], cursor.map {|doc| doc }
|
|
512
639
|
|
|
@@ -521,14 +648,14 @@ class CursorTest < Test::Unit::TestCase
|
|
|
521
648
|
|
|
522
649
|
def test_transformer
|
|
523
650
|
transformer = Proc.new { |doc| doc }
|
|
524
|
-
cursor = Cursor.new(
|
|
651
|
+
cursor = Cursor.new(@coll, :transformer => transformer)
|
|
525
652
|
assert_equal(transformer, cursor.transformer)
|
|
526
653
|
end
|
|
527
654
|
|
|
528
655
|
def test_instance_transformation_with_next
|
|
529
656
|
klass = Struct.new(:id, :a)
|
|
530
657
|
transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
|
|
531
|
-
cursor = Cursor.new(
|
|
658
|
+
cursor = Cursor.new(@coll, :transformer => transformer)
|
|
532
659
|
instance = cursor.next
|
|
533
660
|
|
|
534
661
|
assert_instance_of(klass, instance)
|
|
@@ -539,10 +666,18 @@ class CursorTest < Test::Unit::TestCase
|
|
|
539
666
|
def test_instance_transformation_with_each
|
|
540
667
|
klass = Struct.new(:id, :a)
|
|
541
668
|
transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
|
|
542
|
-
cursor = Cursor.new(
|
|
669
|
+
cursor = Cursor.new(@coll, :transformer => transformer)
|
|
543
670
|
|
|
544
671
|
cursor.each do |instance|
|
|
545
672
|
assert_instance_of(klass, instance)
|
|
546
673
|
end
|
|
547
674
|
end
|
|
675
|
+
|
|
676
|
+
def cursor_count(db)
|
|
677
|
+
if @version > '2.6.0'
|
|
678
|
+
db.command("serverStatus" => 1)["metrics"]["cursor"]["open"]["total"]
|
|
679
|
+
else
|
|
680
|
+
db.command("cursorInfo" => 1)["clientCursors_size"]
|
|
681
|
+
end
|
|
682
|
+
end
|
|
548
683
|
end
|