mongo 1.1.5 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +15 -15
- data/Rakefile +38 -17
- data/docs/FAQ.md +4 -0
- data/docs/HISTORY.md +59 -0
- data/docs/RELEASES.md +33 -0
- data/docs/REPLICA_SETS.md +13 -16
- data/lib/mongo/collection.rb +157 -69
- data/lib/mongo/connection.rb +189 -65
- data/lib/mongo/cursor.rb +43 -29
- data/lib/mongo/db.rb +63 -43
- data/lib/mongo/exceptions.rb +4 -1
- data/lib/mongo/gridfs/grid.rb +1 -1
- data/lib/mongo/gridfs/grid_ext.rb +1 -1
- data/lib/mongo/gridfs/grid_file_system.rb +1 -1
- data/lib/mongo/gridfs/grid_io.rb +89 -8
- data/lib/mongo/gridfs/grid_io_fix.rb +1 -1
- data/lib/mongo/repl_set_connection.rb +72 -20
- data/lib/mongo/test.rb +20 -0
- data/lib/mongo/util/conversions.rb +1 -1
- data/lib/mongo/util/core_ext.rb +11 -1
- data/lib/mongo/util/pool.rb +67 -15
- data/lib/mongo/util/server_version.rb +1 -1
- data/lib/mongo/util/support.rb +1 -1
- data/lib/mongo/util/uri_parser.rb +127 -13
- data/lib/mongo.rb +38 -2
- data/test/async/collection_test.rb +224 -0
- data/test/async/connection_test.rb +24 -0
- data/test/async/cursor_test.rb +162 -0
- data/test/async/worker_pool_test.rb +99 -0
- data/test/auxillary/fork_test.rb +30 -0
- data/test/auxillary/repl_set_auth_test.rb +58 -0
- data/test/auxillary/threaded_authentication_test.rb +101 -0
- data/test/bson/bson_test.rb +140 -28
- data/test/bson/byte_buffer_test.rb +18 -0
- data/test/bson/object_id_test.rb +14 -1
- data/test/bson/ordered_hash_test.rb +7 -0
- data/test/bson/timestamp_test.rb +24 -0
- data/test/collection_test.rb +104 -15
- data/test/connection_test.rb +78 -2
- data/test/conversions_test.rb +10 -11
- data/test/cursor_fail_test.rb +1 -1
- data/test/cursor_message_test.rb +1 -1
- data/test/cursor_test.rb +33 -4
- data/test/db_api_test.rb +30 -52
- data/test/db_test.rb +3 -3
- data/test/grid_file_system_test.rb +0 -1
- data/test/grid_io_test.rb +72 -1
- data/test/grid_test.rb +16 -16
- data/test/load/resque/load.rb +21 -0
- data/test/load/resque/processor.rb +26 -0
- data/test/load/thin/load.rb +24 -0
- data/test/load/unicorn/load.rb +23 -0
- data/test/load/unicorn/unicorn.rb +29 -0
- data/test/replica_sets/connect_test.rb +11 -1
- data/test/replica_sets/connection_string_test.rb +32 -0
- data/test/replica_sets/query_secondaries.rb +16 -0
- data/test/replica_sets/query_test.rb +10 -0
- data/test/replica_sets/replication_ack_test.rb +2 -0
- data/test/replica_sets/rs_test_helper.rb +9 -11
- data/test/support/hash_with_indifferent_access.rb +0 -13
- data/test/support_test.rb +0 -1
- data/test/test_helper.rb +27 -8
- data/test/tools/auth_repl_set_manager.rb +14 -0
- data/test/tools/load.rb +58 -0
- data/test/tools/repl_set_manager.rb +34 -9
- data/test/tools/sharding_manager.rb +202 -0
- data/test/tools/test.rb +3 -12
- data/test/unit/collection_test.rb +20 -24
- data/test/unit/connection_test.rb +4 -18
- data/test/unit/cursor_test.rb +16 -6
- data/test/unit/db_test.rb +10 -11
- data/test/unit/repl_set_connection_test.rb +0 -23
- data/test/unit/safe_test.rb +3 -3
- data/test/uri_test.rb +91 -0
- metadata +49 -12
- data/docs/1.0_UPGRADE.md +0 -21
data/lib/mongo/db.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
|
|
3
3
|
# --
|
|
4
|
-
# Copyright (C) 2008-
|
|
4
|
+
# Copyright (C) 2008-2011 10gen Inc.
|
|
5
5
|
#
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
# you may not use this file except in compliance with the License.
|
|
@@ -56,33 +56,33 @@ module Mongo
|
|
|
56
56
|
|
|
57
57
|
# Instances of DB are normally obtained by calling Mongo#db.
|
|
58
58
|
#
|
|
59
|
-
# @param [String]
|
|
59
|
+
# @param [String] name the database name.
|
|
60
60
|
# @param [Mongo::Connection] connection a connection object pointing to MongoDB. Note
|
|
61
61
|
# that databases are usually instantiated via the Connection class. See the examples below.
|
|
62
62
|
#
|
|
63
|
-
# @option
|
|
63
|
+
# @option opts [Boolean] :strict (False) If true, collections must exist to be accessed and must
|
|
64
64
|
# not exist to be created. See DB#collection and DB#create_collection.
|
|
65
65
|
#
|
|
66
|
-
# @option
|
|
66
|
+
# @option opts [Object, #create_pk(doc)] :pk (Mongo::ObjectId) A primary key factory object,
|
|
67
67
|
# which should take a hash and return a hash which merges the original hash with any primary key
|
|
68
68
|
# fields the factory wishes to inject. (NOTE: if the object already has a primary key,
|
|
69
69
|
# the factory should not inject a new key).
|
|
70
70
|
#
|
|
71
|
-
# @option
|
|
72
|
-
#
|
|
71
|
+
# @option opts [Boolean, Hash] :safe (false) Set the default safe-mode options
|
|
72
|
+
# propagated to Collection objects instantiated off of this DB. If no
|
|
73
73
|
# value is provided, the default value set on this instance's Connection object will be used. This
|
|
74
74
|
# default can be overridden upon instantiation of any collection by explicity setting a :safe value
|
|
75
75
|
# on initialization
|
|
76
|
-
# @option
|
|
76
|
+
# @option opts [Integer] :cache_time (300) Set the time that all ensure_index calls should cache the command.
|
|
77
77
|
#
|
|
78
78
|
# @core databases constructor_details
|
|
79
|
-
def initialize(
|
|
80
|
-
@name = Mongo::Support.validate_db_name(
|
|
79
|
+
def initialize(name, connection, opts={})
|
|
80
|
+
@name = Mongo::Support.validate_db_name(name)
|
|
81
81
|
@connection = connection
|
|
82
|
-
@strict =
|
|
83
|
-
@pk_factory =
|
|
84
|
-
@safe =
|
|
85
|
-
@cache_time =
|
|
82
|
+
@strict = opts[:strict]
|
|
83
|
+
@pk_factory = opts[:pk]
|
|
84
|
+
@safe = opts.fetch(:safe, @connection.safe)
|
|
85
|
+
@cache_time = opts[:cache_time] || 300 #5 minutes.
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
# Authenticate with the given username and password. Note that mongod
|
|
@@ -92,7 +92,8 @@ module Mongo
|
|
|
92
92
|
# @param [String] password
|
|
93
93
|
# @param [Boolean] save_auth
|
|
94
94
|
# Save this authentication to the connection object using Connection#add_auth. This
|
|
95
|
-
# will ensure that the authentication will be applied on database reconnect.
|
|
95
|
+
# will ensure that the authentication will be applied on database reconnect. Note
|
|
96
|
+
# that this value must be true when using connection pooling.
|
|
96
97
|
#
|
|
97
98
|
# @return [Boolean]
|
|
98
99
|
#
|
|
@@ -100,8 +101,19 @@ module Mongo
|
|
|
100
101
|
#
|
|
101
102
|
# @core authenticate authenticate-instance_method
|
|
102
103
|
def authenticate(username, password, save_auth=true)
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
if @connection.pool_size > 1
|
|
105
|
+
if !save_auth
|
|
106
|
+
raise MongoArgumentError, "If using connection pooling, :save_auth must be set to true."
|
|
107
|
+
end
|
|
108
|
+
@connection.authenticate_pools
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
issue_authentication(username, password, save_auth)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def issue_authentication(username, password, save_auth=true, opts={})
|
|
115
|
+
doc = command({:getnonce => 1}, :check_response => false, :socket => opts[:socket])
|
|
116
|
+
raise MongoDBError, "Error retrieving nonce: #{doc}" unless ok?(doc)
|
|
105
117
|
nonce = doc['nonce']
|
|
106
118
|
|
|
107
119
|
auth = BSON::OrderedHash.new
|
|
@@ -109,7 +121,7 @@ module Mongo
|
|
|
109
121
|
auth['user'] = username
|
|
110
122
|
auth['nonce'] = nonce
|
|
111
123
|
auth['key'] = Mongo::Support.auth_key(username, password, nonce)
|
|
112
|
-
if ok?(self.command(auth, :check_response => false))
|
|
124
|
+
if ok?(self.command(auth, :check_response => false, :socket => opts[:socket]))
|
|
113
125
|
if save_auth
|
|
114
126
|
@connection.add_auth(@name, username, password)
|
|
115
127
|
end
|
|
@@ -121,7 +133,7 @@ module Mongo
|
|
|
121
133
|
|
|
122
134
|
# Adds a stored Javascript function to the database which can executed
|
|
123
135
|
# server-side in map_reduce, db.eval and $where clauses.
|
|
124
|
-
#
|
|
136
|
+
#
|
|
125
137
|
# @param [String] function_name
|
|
126
138
|
# @param [String] code
|
|
127
139
|
#
|
|
@@ -179,14 +191,22 @@ module Mongo
|
|
|
179
191
|
end
|
|
180
192
|
|
|
181
193
|
# Deauthorizes use for this database for this connection. Also removes
|
|
182
|
-
# any saved
|
|
194
|
+
# any saved authentication in the connection class associated with this
|
|
183
195
|
# database.
|
|
184
196
|
#
|
|
185
197
|
# @raise [MongoDBError] if logging out fails.
|
|
186
198
|
#
|
|
187
199
|
# @return [Boolean]
|
|
188
|
-
def logout
|
|
189
|
-
|
|
200
|
+
def logout(opts={})
|
|
201
|
+
if @connection.pool_size > 1
|
|
202
|
+
@connection.logout_pools(@name)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
issue_logout(opts)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def issue_logout(opts={})
|
|
209
|
+
doc = command({:logout => 1}, :socket => opts[:socket])
|
|
190
210
|
if ok?(doc)
|
|
191
211
|
@connection.remove_auth(@name)
|
|
192
212
|
true
|
|
@@ -208,8 +228,8 @@ module Mongo
|
|
|
208
228
|
#
|
|
209
229
|
# @return [Array<Mongo::Collection>]
|
|
210
230
|
def collections
|
|
211
|
-
collection_names.map do |
|
|
212
|
-
Collection.new(
|
|
231
|
+
collection_names.map do |name|
|
|
232
|
+
Collection.new(name, self)
|
|
213
233
|
end
|
|
214
234
|
end
|
|
215
235
|
|
|
@@ -223,7 +243,7 @@ module Mongo
|
|
|
223
243
|
def collections_info(coll_name=nil)
|
|
224
244
|
selector = {}
|
|
225
245
|
selector[:name] = full_collection_name(coll_name) if coll_name
|
|
226
|
-
Cursor.new(Collection.new(
|
|
246
|
+
Cursor.new(Collection.new(SYSTEM_NAMESPACE_COLLECTION, self), :selector => selector)
|
|
227
247
|
end
|
|
228
248
|
|
|
229
249
|
# Create a collection.
|
|
@@ -233,52 +253,52 @@ module Mongo
|
|
|
233
253
|
#
|
|
234
254
|
# @param [String] name the name of the new collection.
|
|
235
255
|
#
|
|
236
|
-
# @option
|
|
256
|
+
# @option opts [Boolean] :capped (False) created a capped collection.
|
|
237
257
|
#
|
|
238
|
-
# @option
|
|
258
|
+
# @option opts [Integer] :size (Nil) If +capped+ is +true+, specifies the maximum number of
|
|
239
259
|
# bytes for the capped collection. If +false+, specifies the number of bytes allocated
|
|
240
260
|
# for the initial extent of the collection.
|
|
241
261
|
#
|
|
242
|
-
# @option
|
|
262
|
+
# @option opts [Integer] :max (Nil) If +capped+ is +true+, indicates the maximum number of records
|
|
243
263
|
# in a capped collection.
|
|
244
264
|
#
|
|
245
265
|
# @raise [MongoDBError] raised under two conditions: either we're in +strict+ mode and the collection
|
|
246
266
|
# already exists or collection creation fails on the server.
|
|
247
267
|
#
|
|
248
268
|
# @return [Mongo::Collection]
|
|
249
|
-
def create_collection(name,
|
|
269
|
+
def create_collection(name, opts={})
|
|
250
270
|
# Does the collection already exist?
|
|
251
271
|
if collection_names.include?(name)
|
|
252
272
|
if strict?
|
|
253
273
|
raise MongoDBError, "Collection #{name} already exists. Currently in strict mode."
|
|
254
274
|
else
|
|
255
|
-
return Collection.new(self,
|
|
275
|
+
return Collection.new(name, self, opts)
|
|
256
276
|
end
|
|
257
277
|
end
|
|
258
278
|
|
|
259
279
|
# Create a new collection.
|
|
260
280
|
oh = BSON::OrderedHash.new
|
|
261
281
|
oh[:create] = name
|
|
262
|
-
doc = command(oh.merge(
|
|
263
|
-
return Collection.new(
|
|
282
|
+
doc = command(oh.merge(opts || {}))
|
|
283
|
+
return Collection.new(name, self, :pk => @pk_factory) if ok?(doc)
|
|
264
284
|
raise MongoDBError, "Error creating collection: #{doc.inspect}"
|
|
265
285
|
end
|
|
266
286
|
|
|
267
287
|
# Get a collection by name.
|
|
268
288
|
#
|
|
269
289
|
# @param [String] name the collection name.
|
|
270
|
-
# @param [Hash]
|
|
290
|
+
# @param [Hash] opts any valid options that can be passed to Collection#new.
|
|
271
291
|
#
|
|
272
292
|
# @raise [MongoDBError] if collection does not already exist and we're in +strict+ mode.
|
|
273
293
|
#
|
|
274
294
|
# @return [Mongo::Collection]
|
|
275
|
-
def collection(name,
|
|
295
|
+
def collection(name, opts={})
|
|
276
296
|
if strict? && !collection_names.include?(name)
|
|
277
297
|
raise Mongo::MongoDBError, "Collection #{name} doesn't exist. Currently in strict mode."
|
|
278
298
|
else
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
Collection.new(
|
|
299
|
+
opts[:safe] = opts.fetch(:safe, @safe)
|
|
300
|
+
opts.merge!(:pk => @pk_factory) unless opts[:pk]
|
|
301
|
+
Collection.new(name, self, opts)
|
|
282
302
|
end
|
|
283
303
|
end
|
|
284
304
|
alias_method :[], :collection
|
|
@@ -403,7 +423,7 @@ module Mongo
|
|
|
403
423
|
def drop_index(collection_name, index_name)
|
|
404
424
|
oh = BSON::OrderedHash.new
|
|
405
425
|
oh[:deleteIndexes] = collection_name
|
|
406
|
-
oh[:index] = index_name
|
|
426
|
+
oh[:index] = index_name.to_s
|
|
407
427
|
doc = command(oh, :check_response => false)
|
|
408
428
|
ok?(doc) || raise(MongoDBError, "Error with drop_index command: #{doc.inspect}")
|
|
409
429
|
end
|
|
@@ -418,7 +438,7 @@ module Mongo
|
|
|
418
438
|
def index_information(collection_name)
|
|
419
439
|
sel = {:ns => full_collection_name(collection_name)}
|
|
420
440
|
info = {}
|
|
421
|
-
Cursor.new(Collection.new(
|
|
441
|
+
Cursor.new(Collection.new(SYSTEM_INDEX_COLLECTION, self), :selector => sel).each do |index|
|
|
422
442
|
info[index['name']] = index
|
|
423
443
|
end
|
|
424
444
|
info
|
|
@@ -455,14 +475,14 @@ module Mongo
|
|
|
455
475
|
#
|
|
456
476
|
# @option opts [Boolean] :check_response (true) If +true+, raises an exception if the
|
|
457
477
|
# command fails.
|
|
458
|
-
# @option opts [Socket] :
|
|
478
|
+
# @option opts [Socket] :socket a socket to use for sending the command. This is mainly for internal use.
|
|
459
479
|
#
|
|
460
480
|
# @return [Hash]
|
|
461
481
|
#
|
|
462
482
|
# @core commands command_instance-method
|
|
463
483
|
def command(selector, opts={})
|
|
464
484
|
check_response = opts.fetch(:check_response, true)
|
|
465
|
-
|
|
485
|
+
socket = opts[:socket]
|
|
466
486
|
raise MongoArgumentError, "command must be given a selector" unless selector.is_a?(Hash) && !selector.empty?
|
|
467
487
|
if selector.keys.length > 1 && RUBY_VERSION < '1.9' && selector.class != BSON::OrderedHash
|
|
468
488
|
raise MongoArgumentError, "DB#command requires an OrderedHash when hash contains multiple keys"
|
|
@@ -470,7 +490,7 @@ module Mongo
|
|
|
470
490
|
|
|
471
491
|
begin
|
|
472
492
|
result = Cursor.new(system_command_collection,
|
|
473
|
-
:limit => -1, :selector => selector, :socket =>
|
|
493
|
+
:limit => -1, :selector => selector, :socket => socket).next_document
|
|
474
494
|
rescue OperationFailure => ex
|
|
475
495
|
raise OperationFailure, "Database command '#{selector.keys.first}' failed: #{ex.message}"
|
|
476
496
|
end
|
|
@@ -558,7 +578,7 @@ module Mongo
|
|
|
558
578
|
#
|
|
559
579
|
# @return [Array] a list of documents containing profiling information.
|
|
560
580
|
def profiling_info
|
|
561
|
-
Cursor.new(Collection.new(
|
|
581
|
+
Cursor.new(Collection.new(SYSTEM_PROFILE_COLLECTION, self), :selector => {}).to_a
|
|
562
582
|
end
|
|
563
583
|
|
|
564
584
|
# Validate a named collection.
|
|
@@ -581,7 +601,7 @@ module Mongo
|
|
|
581
601
|
private
|
|
582
602
|
|
|
583
603
|
def system_command_collection
|
|
584
|
-
Collection.new(
|
|
604
|
+
Collection.new(SYSTEM_COMMAND_COLLECTION, self)
|
|
585
605
|
end
|
|
586
606
|
end
|
|
587
607
|
end
|
data/lib/mongo/exceptions.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
#
|
|
4
4
|
# --
|
|
5
|
-
# Copyright (C) 2008-
|
|
5
|
+
# Copyright (C) 2008-2011 10gen Inc.
|
|
6
6
|
#
|
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
8
|
# you may not use this file except in compliance with the License.
|
|
@@ -57,6 +57,9 @@ module Mongo
|
|
|
57
57
|
# Raised when a database operation fails.
|
|
58
58
|
class OperationFailure < MongoDBError; end
|
|
59
59
|
|
|
60
|
+
# Raised when a socket read operation times out.
|
|
61
|
+
class OperationTimeout < ::Timeout::Error; end
|
|
62
|
+
|
|
60
63
|
# Raised when a client attempts to perform an invalid operation.
|
|
61
64
|
class InvalidOperation < MongoDBError; end
|
|
62
65
|
|
data/lib/mongo/gridfs/grid.rb
CHANGED
data/lib/mongo/gridfs/grid_io.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
|
|
3
3
|
# --
|
|
4
|
-
# Copyright (C) 2008-
|
|
4
|
+
# Copyright (C) 2008-2011 10gen Inc.
|
|
5
5
|
#
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
# you may not use this file except in compliance with the License.
|
|
@@ -17,10 +17,6 @@
|
|
|
17
17
|
# ++
|
|
18
18
|
|
|
19
19
|
require 'digest/md5'
|
|
20
|
-
begin
|
|
21
|
-
require 'mime/types'
|
|
22
|
-
rescue LoadError
|
|
23
|
-
end
|
|
24
20
|
|
|
25
21
|
module Mongo
|
|
26
22
|
|
|
@@ -172,6 +168,91 @@ module Mongo
|
|
|
172
168
|
def tell
|
|
173
169
|
@file_position
|
|
174
170
|
end
|
|
171
|
+
alias :pos :tell
|
|
172
|
+
|
|
173
|
+
# Rewind the file. This is equivalent to seeking to the zeroth position.
|
|
174
|
+
#
|
|
175
|
+
# @return [Integer] the position of the file after rewinding (always zero).
|
|
176
|
+
def rewind
|
|
177
|
+
raise GridError, "file not opened for read" unless @mode[0] == ?r
|
|
178
|
+
seek(0)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Return a boolean indicating whether the position pointer is
|
|
182
|
+
# at the end of the file.
|
|
183
|
+
#
|
|
184
|
+
# @return [Boolean]
|
|
185
|
+
def eof
|
|
186
|
+
raise GridError, "file not opened for read #{@mode}" unless @mode[0] == ?r
|
|
187
|
+
@file_position >= @file_length
|
|
188
|
+
end
|
|
189
|
+
alias :eof? :eof
|
|
190
|
+
|
|
191
|
+
# Return the next line from a GridFS file. This probably
|
|
192
|
+
# makes sense only if you're storing plain text. This method
|
|
193
|
+
# has a somewhat tricky API, which it inherits from Ruby's
|
|
194
|
+
# StringIO#gets.
|
|
195
|
+
#
|
|
196
|
+
# @param [String, Integer] separator or length. If a separator,
|
|
197
|
+
# read up to the separator. If a length, read the +length+ number
|
|
198
|
+
# of bytes. If nil, read the entire file.
|
|
199
|
+
# @param [Integer] length If a separator is provided, then
|
|
200
|
+
# read until either finding the separator or
|
|
201
|
+
# passing over the +length+ number of bytes.
|
|
202
|
+
#
|
|
203
|
+
# @return [String]
|
|
204
|
+
def gets(separator="\n", length=nil)
|
|
205
|
+
if separator.nil?
|
|
206
|
+
read_all
|
|
207
|
+
elsif separator.is_a?(Integer)
|
|
208
|
+
read_length(separator)
|
|
209
|
+
elsif separator.length > 1
|
|
210
|
+
result = ''
|
|
211
|
+
len = 0
|
|
212
|
+
match_idx = 0
|
|
213
|
+
match_num = separator.length - 1
|
|
214
|
+
to_match = separator[match_idx].chr
|
|
215
|
+
if length
|
|
216
|
+
matcher = lambda {|idx, num| idx < num && len < length }
|
|
217
|
+
else
|
|
218
|
+
matcher = lambda {|idx, num| idx < num}
|
|
219
|
+
end
|
|
220
|
+
while matcher.call(match_idx, match_num) && char = getc
|
|
221
|
+
result << char
|
|
222
|
+
len += 1
|
|
223
|
+
if char == to_match
|
|
224
|
+
while match_idx < match_num do
|
|
225
|
+
match_idx += 1
|
|
226
|
+
to_match = separator[match_idx].chr
|
|
227
|
+
char = getc
|
|
228
|
+
result << char
|
|
229
|
+
if char != to_match
|
|
230
|
+
match_idx = 0
|
|
231
|
+
to_match = separator[match_idx].chr
|
|
232
|
+
break
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
result
|
|
238
|
+
else
|
|
239
|
+
result = ''
|
|
240
|
+
len = 0
|
|
241
|
+
while char = getc
|
|
242
|
+
result << char
|
|
243
|
+
len += 1
|
|
244
|
+
break if char == separator || (length ? len >= length : false)
|
|
245
|
+
end
|
|
246
|
+
result
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Return the next byte from the GridFS file.
|
|
251
|
+
#
|
|
252
|
+
# @return [String]
|
|
253
|
+
def getc
|
|
254
|
+
read_length(1)
|
|
255
|
+
end
|
|
175
256
|
|
|
176
257
|
# Creates or updates the document from the files collection that
|
|
177
258
|
# stores the chunks' metadata. The file becomes available only after
|
|
@@ -260,7 +341,7 @@ module Mongo
|
|
|
260
341
|
if length.nil?
|
|
261
342
|
to_read = remaining
|
|
262
343
|
else
|
|
263
|
-
to_read
|
|
344
|
+
to_read = length > remaining ? remaining : length
|
|
264
345
|
end
|
|
265
346
|
return nil unless remaining > 0
|
|
266
347
|
|
|
@@ -335,8 +416,8 @@ module Mongo
|
|
|
335
416
|
@files_id = opts.delete(:_id) || BSON::ObjectId.new
|
|
336
417
|
@content_type = opts.delete(:content_type) || (defined? MIME) && get_content_type || DEFAULT_CONTENT_TYPE
|
|
337
418
|
@chunk_size = opts.delete(:chunk_size) || DEFAULT_CHUNK_SIZE
|
|
338
|
-
@metadata = opts.delete(:metadata)
|
|
339
|
-
@aliases = opts.delete(:aliases)
|
|
419
|
+
@metadata = opts.delete(:metadata)
|
|
420
|
+
@aliases = opts.delete(:aliases)
|
|
340
421
|
@file_length = 0
|
|
341
422
|
opts.each {|k, v| self[k] = v}
|
|
342
423
|
check_existing_file if @safe
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
|
|
3
3
|
# --
|
|
4
|
-
# Copyright (C) 2008-
|
|
4
|
+
# Copyright (C) 2008-2011 10gen Inc.
|
|
5
5
|
#
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
# you may not use this file except in compliance with the License.
|
|
@@ -29,9 +29,11 @@ module Mongo
|
|
|
29
29
|
# Connection#arbiters. This is useful if your application needs to connect manually to nodes other
|
|
30
30
|
# than the primary.
|
|
31
31
|
#
|
|
32
|
-
# @param [Array] args A list of host-port pairs
|
|
33
|
-
# the examples below for exactly how to use the constructor.
|
|
32
|
+
# @param [Array] args A list of host-port pairs to be used as seed nodes followed by a
|
|
33
|
+
# hash containing any options. See the examples below for exactly how to use the constructor.
|
|
34
34
|
#
|
|
35
|
+
# @option options [String] :rs_name (nil) The name of the replica set to connect to. You
|
|
36
|
+
# can use this option to verify that you're connecting to the right replica set.
|
|
35
37
|
# @option options [Boolean, Hash] :safe (false) Set the default safe-mode options
|
|
36
38
|
# propogated to DB objects instantiated off of this Connection. This
|
|
37
39
|
# default can be overridden upon instantiation of any DB by explicity setting a :safe value
|
|
@@ -45,11 +47,15 @@ module Mongo
|
|
|
45
47
|
# this is the number of seconds to wait for a new connection to be released before throwing an exception.
|
|
46
48
|
# Note: this setting is relevant only for multi-threaded applications.
|
|
47
49
|
#
|
|
48
|
-
# @example Connect to a replica set and provide two seed nodes
|
|
50
|
+
# @example Connect to a replica set and provide two seed nodes. Note that the number of seed nodes does
|
|
51
|
+
# not have to be equal to the number of replica set members. The purpose of seed nodes is to permit
|
|
52
|
+
# the driver to find at least one replica set member even if a member is down.
|
|
49
53
|
# ReplSetConnection.new(['localhost', 30000], ['localhost', 30001])
|
|
50
54
|
#
|
|
51
|
-
# @example Connect to a replica set providing two seed nodes and
|
|
52
|
-
#
|
|
55
|
+
# @example Connect to a replica set providing two seed nodes and ensuring a connection to the replica set named 'prod':
|
|
56
|
+
# ReplSetConnection.new(['localhost', 30000], ['localhost', 30001], :rs_name => 'prod')
|
|
57
|
+
#
|
|
58
|
+
# @example Connect to a replica set providing two seed nodes and allowing reads from a secondary node:
|
|
53
59
|
# ReplSetConnection.new(['localhost', 30000], ['localhost', 30001], :read_secondary => true)
|
|
54
60
|
#
|
|
55
61
|
# @see http://api.mongodb.org/ruby/current/file.REPLICA_SETS.html Replica sets in Ruby
|
|
@@ -95,7 +101,7 @@ module Mongo
|
|
|
95
101
|
#
|
|
96
102
|
# @raise [ConnectionFailure] if unable to connect to any host or port.
|
|
97
103
|
def connect
|
|
98
|
-
|
|
104
|
+
close
|
|
99
105
|
@nodes_to_try = @nodes.clone
|
|
100
106
|
|
|
101
107
|
while connecting?
|
|
@@ -111,19 +117,47 @@ module Mongo
|
|
|
111
117
|
|
|
112
118
|
pick_secondary_for_read if @read_secondary
|
|
113
119
|
|
|
114
|
-
if
|
|
120
|
+
if connected?
|
|
121
|
+
BSON::BSON_CODER.update_max_bson_size(self)
|
|
122
|
+
else
|
|
115
123
|
if @secondary_pools.empty?
|
|
124
|
+
close # close any existing pools and sockets
|
|
116
125
|
raise ConnectionFailure, "Failed to connect any given host:port"
|
|
117
126
|
else
|
|
127
|
+
close # close any existing pools and sockets
|
|
118
128
|
raise ConnectionFailure, "Failed to connect to primary node."
|
|
119
129
|
end
|
|
120
130
|
end
|
|
121
131
|
end
|
|
132
|
+
alias :reconnect :connect
|
|
122
133
|
|
|
123
134
|
def connecting?
|
|
124
135
|
@nodes_to_try.length > 0
|
|
125
136
|
end
|
|
126
137
|
|
|
138
|
+
# The replica set primary's host name.
|
|
139
|
+
#
|
|
140
|
+
# @return [String]
|
|
141
|
+
def host
|
|
142
|
+
super
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# The replica set primary's port.
|
|
146
|
+
#
|
|
147
|
+
# @return [Integer]
|
|
148
|
+
def port
|
|
149
|
+
super
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Determine whether we're reading from a primary node. If false,
|
|
153
|
+
# this connection connects to a secondary node and @read_secondaries is true.
|
|
154
|
+
#
|
|
155
|
+
# @return [Boolean]
|
|
156
|
+
def read_primary?
|
|
157
|
+
!@read_pool
|
|
158
|
+
end
|
|
159
|
+
alias :primary? :read_primary?
|
|
160
|
+
|
|
127
161
|
# Close the connection to the database.
|
|
128
162
|
def close
|
|
129
163
|
super
|
|
@@ -131,13 +165,6 @@ module Mongo
|
|
|
131
165
|
@secondary_pools.each do |pool|
|
|
132
166
|
pool.close
|
|
133
167
|
end
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
# If a ConnectionFailure is raised, this method will be called
|
|
137
|
-
# to close the connection and reset connection values.
|
|
138
|
-
# TODO: what's the point of this method?
|
|
139
|
-
def reset_connection
|
|
140
|
-
super
|
|
141
168
|
@secondaries = []
|
|
142
169
|
@secondary_pools = []
|
|
143
170
|
@arbiters = []
|
|
@@ -145,6 +172,15 @@ module Mongo
|
|
|
145
172
|
@nodes_to_try = []
|
|
146
173
|
end
|
|
147
174
|
|
|
175
|
+
# If a ConnectionFailure is raised, this method will be called
|
|
176
|
+
# to close the connection and reset connection values.
|
|
177
|
+
# @deprecated
|
|
178
|
+
def reset_connection
|
|
179
|
+
close
|
|
180
|
+
warn "ReplSetConnection#reset_connection is now deprecated. " +
|
|
181
|
+
"Use ReplSetConnection#close instead."
|
|
182
|
+
end
|
|
183
|
+
|
|
148
184
|
# Is it okay to connect to a slave?
|
|
149
185
|
#
|
|
150
186
|
# @return [Boolean]
|
|
@@ -152,6 +188,20 @@ module Mongo
|
|
|
152
188
|
@read_secondary || @slave_ok
|
|
153
189
|
end
|
|
154
190
|
|
|
191
|
+
def authenticate_pools
|
|
192
|
+
super
|
|
193
|
+
@secondary_pools.each do |pool|
|
|
194
|
+
pool.authenticate_existing
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def logout_pools(db)
|
|
199
|
+
super
|
|
200
|
+
@secondary_pools.each do |pool|
|
|
201
|
+
pool.logout_existing(db)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
155
205
|
private
|
|
156
206
|
|
|
157
207
|
def check_is_master(node)
|
|
@@ -160,13 +210,17 @@ module Mongo
|
|
|
160
210
|
socket = TCPSocket.new(host, port)
|
|
161
211
|
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
162
212
|
|
|
163
|
-
config = self['admin'].command({:ismaster => 1}, :
|
|
213
|
+
config = self['admin'].command({:ismaster => 1}, :socket => socket)
|
|
164
214
|
|
|
165
215
|
check_set_name(config, socket)
|
|
166
216
|
rescue OperationFailure, SocketError, SystemCallError, IOError => ex
|
|
167
|
-
|
|
217
|
+
# It's necessary to rescue here. The #connect method will keep trying
|
|
218
|
+
# until it has no more nodes to try and raise a ConnectionFailure if
|
|
219
|
+
# it can't connect to a primary.
|
|
168
220
|
ensure
|
|
221
|
+
socket.close if socket
|
|
169
222
|
@nodes_tried << node
|
|
223
|
+
|
|
170
224
|
if config
|
|
171
225
|
nodes = []
|
|
172
226
|
nodes += config['hosts'] if config['hosts']
|
|
@@ -178,8 +232,6 @@ module Mongo
|
|
|
178
232
|
@logger.warn("MONGODB #{config['msg']}")
|
|
179
233
|
end
|
|
180
234
|
end
|
|
181
|
-
|
|
182
|
-
socket.close if socket
|
|
183
235
|
end
|
|
184
236
|
|
|
185
237
|
config
|
|
@@ -203,7 +255,7 @@ module Mongo
|
|
|
203
255
|
def check_set_name(config, socket)
|
|
204
256
|
if @replica_set
|
|
205
257
|
config = self['admin'].command({:replSetGetStatus => 1},
|
|
206
|
-
:
|
|
258
|
+
:socket => socket, :check_response => false)
|
|
207
259
|
|
|
208
260
|
if !Mongo::Support.ok?(config)
|
|
209
261
|
raise ReplicaSetConnectionError, config['errmsg']
|
data/lib/mongo/test.rb
ADDED