Class: Mongo::Connection
Overview
Instantiates and manages connections to MongoDB.
Constant Summary collapse
- DEFAULT_PORT =
27017
- STANDARD_HEADER_SIZE =
16
- RESPONSE_HEADER_SIZE =
20
- MONGODB_URI_MATCHER =
/(([.\w\d]+):([\w\d]+)@)?([.\w\d]+)(:([\w\d]+))?(\/([-\d\w]+))?/
- MONGODB_URI_SPEC =
"mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/database]"
- @@current_request_id =
Counter for generating unique request ids.
0
Instance Attribute Summary collapse
-
#auths ⇒ Object
readonly
Returns the value of attribute auths.
-
#checked_out ⇒ Object
readonly
Returns the value of attribute checked_out.
-
#host ⇒ Object
readonly
Returns the value of attribute host.
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
-
#nodes ⇒ Object
readonly
Returns the value of attribute nodes.
-
#port ⇒ Object
readonly
Returns the value of attribute port.
-
#size ⇒ Object
readonly
Returns the value of attribute size.
-
#sockets ⇒ Object
readonly
Returns the value of attribute sockets.
Class Method Summary collapse
-
.from_uri(uri, opts = {}) ⇒ Mongo::Connection
Initialize a connection to MongoDB using the MongoDB URI spec:.
-
.paired(nodes, opts = {}) ⇒ Mongo::Connection
Initialize a paired connection to MongoDB.
Instance Method Summary collapse
-
#[](db_name) ⇒ Mongo::DB
Shortcut for returning a database.
-
#add_auth(db_name, username, password) ⇒ Hash
Save an authentication to this connection.
-
#apply_saved_authentication ⇒ Boolean
Apply each of the saved database authentications.
-
#clear_auths ⇒ true
Remove all authenication information stored in this connection.
-
#close ⇒ Object
Close the connection to the database.
-
#connect_to_master ⇒ Object
Create a new socket and attempt to connect to master.
-
#connected? ⇒ Boolean
Are we connected to MongoDB? This is determined by checking whether host and port have values, since they’re set to nil on calls to #close.
-
#copy_database(from, to, from_host = "localhost") ⇒ Object
Copy the database
from
on the local server toto
on the specifiedhost
. -
#database_info ⇒ Hash
Return a hash with all database names and their respective sizes on disk.
-
#database_names ⇒ Array
Return an array of database names.
-
#db(db_name, options = {}) ⇒ Mongo::DB
Return a database with the given name.
-
#drop_database(name) ⇒ Object
Drop a database.
-
#format_pair(pair_or_host, port) ⇒ Object
Returns an array of host-port pairs.
-
#get_request_id ⇒ Object
Increment and return the next available request id.
-
#initialize(pair_or_host = nil, port = nil, options = {}) ⇒ Connection
constructor
Create a connection to MongoDB.
-
#pair_val_to_connection(a) ⇒ Object
Convert an argument containing a host name string and a port number integer into a [host, port] pair array.
-
#parse_uri(string) ⇒ Object
Parse a MongoDB URI.
-
#receive_message(operation, message, log_message = nil, socket = nil) ⇒ Array
Sends a message to the database and waits for the response.
-
#remove_auth(db_name) ⇒ Boolean
Remove a saved authentication for this connection.
-
#send_message(operation, message, log_message = nil) ⇒ True
Send a message to MongoDB, adding the necessary headers.
-
#send_message_with_safe_check(operation, message, db_name, log_message = nil) ⇒ Array
Sends a message to the database, waits for a response, and raises an exception if the operation has failed.
-
#server_info ⇒ Hash
Get the build information for the current connection.
-
#server_version ⇒ Mongo::ServerVersion
Get the build version of the current server.
-
#slave_ok? ⇒ Boolean
Is it okay to connect to a slave?.
Constructor Details
#initialize(pair_or_host = nil, port = nil, options = {}) ⇒ Connection
Create a connection to MongoDB. Specify either one or a pair of servers, along with a maximum connection pool size and timeout.
If connecting to just one server, you may specify whether connection to slave is permitted. In all cases, the default host is “localhost” and the default port is 27017.
When specifying a pair, pair_or_host
, is a hash with two keys: :left and :right. Each key maps to either
-
a server name, in which case port is 27017,
-
a port number, in which case the server is “localhost”, or
-
an array containing [server_name, port_number]
Note that there are a few issues when using connection pooling with Ruby 1.9 on Windows. These should be resolved in the next release.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/mongo/connection.rb', line 92 def initialize(pair_or_host=nil, port=nil, ={}) @auths = [] if block_given? @nodes = yield self else @nodes = format_pair(pair_or_host, port) end # Host and port of current master. @host = @port = nil # Lock for request ids. @id_lock = Mutex.new # Pool size and timeout. @size = [:pool_size] || 1 @timeout = [:timeout] || 5.0 # Mutex for synchronizing pool access @connection_mutex = Mutex.new @safe_mutex = Mutex.new # Condition variable for signal and wait @queue = ConditionVariable.new @sockets = [] @checked_out = [] if [:auto_reconnect] warn(":auto_reconnect is deprecated. see http://www.mongodb.org/display/DOCS/Replica+Pairs+in+Ruby") end # slave_ok can be true only if one node is specified @slave_ok = [:slave_ok] && @nodes.length == 1 @logger = [:logger] || nil @options = should_connect = [:connect].nil? ? true : [:connect] connect_to_master if should_connect end |
Instance Attribute Details
#auths ⇒ Object (readonly)
Returns the value of attribute auths.
36 37 38 |
# File 'lib/mongo/connection.rb', line 36 def auths @auths end |
#checked_out ⇒ Object (readonly)
Returns the value of attribute checked_out.
36 37 38 |
# File 'lib/mongo/connection.rb', line 36 def checked_out @checked_out end |
#host ⇒ Object (readonly)
Returns the value of attribute host.
36 37 38 |
# File 'lib/mongo/connection.rb', line 36 def host @host end |
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
36 37 38 |
# File 'lib/mongo/connection.rb', line 36 def logger @logger end |
#nodes ⇒ Object (readonly)
Returns the value of attribute nodes.
36 37 38 |
# File 'lib/mongo/connection.rb', line 36 def nodes @nodes end |
#port ⇒ Object (readonly)
Returns the value of attribute port.
36 37 38 |
# File 'lib/mongo/connection.rb', line 36 def port @port end |
#size ⇒ Object (readonly)
Returns the value of attribute size.
36 37 38 |
# File 'lib/mongo/connection.rb', line 36 def size @size end |
#sockets ⇒ Object (readonly)
Returns the value of attribute sockets.
36 37 38 |
# File 'lib/mongo/connection.rb', line 36 def sockets @sockets end |
Class Method Details
.from_uri(uri, opts = {}) ⇒ Mongo::Connection
Initialize a connection to MongoDB using the MongoDB URI spec:
168 169 170 171 172 |
# File 'lib/mongo/connection.rb', line 168 def self.from_uri(uri, opts={}) new(nil, nil, opts) do |con| con.parse_uri(uri) end end |
.paired(nodes, opts = {}) ⇒ Mongo::Connection
Initialize a paired connection to MongoDB.
149 150 151 152 153 154 155 156 157 158 |
# File 'lib/mongo/connection.rb', line 149 def self.paired(nodes, opts={}) unless nodes.length == 2 && nodes.all? {|n| n.is_a? Array} raise MongoArgumentError, "Connection.paired requires that exactly two nodes be specified." end # Block returns an array, the first element being an array of nodes and the second an array # of authorizations for the database. new(nil, nil, opts) do |con| [con.pair_val_to_connection(nodes[0]), con.pair_val_to_connection(nodes[1])] end end |
Instance Method Details
#[](db_name) ⇒ Mongo::DB
Shortcut for returning a database. Use DB#db to accept options.
267 268 269 |
# File 'lib/mongo/connection.rb', line 267 def [](db_name) DB.new(db_name, self, :logger => @logger) end |
#add_auth(db_name, username, password) ⇒ Hash
Save an authentication to this connection. When connecting, the connection will attempt to re-authenticate on every db specificed in the list of auths.
198 199 200 201 202 203 204 205 206 |
# File 'lib/mongo/connection.rb', line 198 def add_auth(db_name, username, password) remove_auth(db_name) auth = {} auth['db_name'] = db_name auth['username'] = username auth['password'] = password @auths << auth auth end |
#apply_saved_authentication ⇒ Boolean
Apply each of the saved database authentications.
181 182 183 184 185 186 187 |
# File 'lib/mongo/connection.rb', line 181 def apply_saved_authentication return false if @auths.empty? @auths.each do |auth| self[auth['db_name']].authenticate(auth['username'], auth['password'], false) end true end |
#clear_auths ⇒ true
Remove all authenication information stored in this connection.
225 226 227 228 |
# File 'lib/mongo/connection.rb', line 225 def clear_auths @auths = [] true end |
#close ⇒ Object
Close the connection to the database.
449 450 451 452 453 454 455 456 |
# File 'lib/mongo/connection.rb', line 449 def close @sockets.each do |sock| sock.close end @host = @port = nil @sockets.clear @checked_out.clear end |
#connect_to_master ⇒ Object
Create a new socket and attempt to connect to master. If successful, sets host and port to master and returns the socket.
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 |
# File 'lib/mongo/connection.rb', line 410 def connect_to_master close @host = @port = nil for node_pair in @nodes host, port = *node_pair begin socket = TCPSocket.new(host, port) socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) # If we're connected to master, set the @host and @port result = self['admin'].command({:ismaster => 1}, false, false, socket) if result['ok'] == 1 && ((is_master = result['ismaster'] == 1) || @slave_ok) @host, @port = host, port apply_saved_authentication end # Note: slave_ok can be true only when connecting to a single node. if @nodes.length == 1 && !is_master && !@slave_ok raise ConfigurationError, "Trying to connect directly to slave; " + "if this is what you want, specify :slave_ok => true." end break if is_master || @slave_ok rescue SocketError, SystemCallError, IOError => ex socket.close if socket close false end end raise ConnectionFailure, "failed to connect to any given host:port" unless socket end |
#connected? ⇒ Boolean
Are we connected to MongoDB? This is determined by checking whether host and port have values, since they’re set to nil on calls to #close.
444 445 446 |
# File 'lib/mongo/connection.rb', line 444 def connected? @host && @port end |
#copy_database(from, to, from_host = "localhost") ⇒ Object
Copy the database from
on the local server to to
on the specified host
. host
defaults to ‘localhost’ if no value is provided.
284 285 286 287 288 289 290 291 |
# File 'lib/mongo/connection.rb', line 284 def copy_database(from, to, from_host="localhost") oh = OrderedHash.new oh[:copydb] = 1 oh[:fromhost] = from_host oh[:fromdb] = from oh[:todb] = to self["admin"].command(oh, false, true) end |
#database_info ⇒ Hash
Return a hash with all database names and their respective sizes on disk.
234 235 236 237 238 239 |
# File 'lib/mongo/connection.rb', line 234 def database_info doc = self['admin'].command({:listDatabases => 1}, false, true) returning({}) do |info| doc['databases'].each { |db| info[db['name']] = db['sizeOnDisk'].to_i } end end |
#database_names ⇒ Array
Return an array of database names.
244 245 246 |
# File 'lib/mongo/connection.rb', line 244 def database_names database_info.keys end |
#db(db_name, options = {}) ⇒ Mongo::DB
Return a database with the given name. See DB#new for valid options hash parameters.
256 257 258 |
# File 'lib/mongo/connection.rb', line 256 def db(db_name, ={}) DB.new(db_name, self, .merge(:logger => @logger)) end |
#drop_database(name) ⇒ Object
Drop a database.
274 275 276 |
# File 'lib/mongo/connection.rb', line 274 def drop_database(name) self[name].command(:dropDatabase => 1) end |
#format_pair(pair_or_host, port) ⇒ Object
Returns an array of host-port pairs.
463 464 465 466 467 468 469 470 471 472 473 474 475 476 |
# File 'lib/mongo/connection.rb', line 463 def format_pair(pair_or_host, port) case pair_or_host when String [[pair_or_host, port ? port.to_i : DEFAULT_PORT]] when Hash warn "Initializing a paired connection with Connection.new is deprecated. Use Connection.pair instead." connections = [] connections << pair_val_to_connection(pair_or_host[:left]) connections << pair_val_to_connection(pair_or_host[:right]) connections when nil [['localhost', DEFAULT_PORT]] end end |
#get_request_id ⇒ Object
Increment and return the next available request id.
return [Integer]
296 297 298 299 300 301 302 |
# File 'lib/mongo/connection.rb', line 296 def get_request_id request_id = '' @id_lock.synchronize do request_id = @@current_request_id += 1 end request_id end |
#pair_val_to_connection(a) ⇒ Object
Convert an argument containing a host name string and a port number integer into a [host, port] pair array.
482 483 484 485 486 487 488 489 490 491 492 493 |
# File 'lib/mongo/connection.rb', line 482 def pair_val_to_connection(a) case a when nil ['localhost', DEFAULT_PORT] when String [a, DEFAULT_PORT] when Integer ['localhost', a] when Array a end end |
#parse_uri(string) ⇒ Object
Parse a MongoDB URI. This method is used by Connection.from_uri. Returns an array of nodes and an array of db authorizations, if applicable.
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 |
# File 'lib/mongo/connection.rb', line 499 def parse_uri(string) if string =~ /^mongodb:\/\// string = string[10..-1] else raise MongoArgumentError, "MongoDB URI must match this spec: #{MONGODB_URI_SPEC}" end nodes = [] auths = [] specs = string.split(',') specs.each do |spec| matches = MONGODB_URI_MATCHER.match(spec) if !matches raise MongoArgumentError, "MongoDB URI must match this spec: #{MONGODB_URI_SPEC}" end uname = matches[2] pwd = matches[3] host = matches[4] port = matches[6] || DEFAULT_PORT if !(port.to_s =~ /^\d+$/) raise MongoArgumentError, "Invalid port #{port}; port must be specified as digits." end port = port.to_i db = matches[8] if (uname || pwd || db) && !(uname && pwd && db) raise MongoArgumentError, "MongoDB URI must include all three of username, password, " + "and db if any one of these is specified." else add_auth(db, uname, pwd) end nodes << [host, port] end nodes end |
#receive_message(operation, message, log_message = nil, socket = nil) ⇒ Array
Sends a message to the database and waits for the response.
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 |
# File 'lib/mongo/connection.rb', line 389 def (operation, , =nil, socket=nil) = (operation, ).to_s @logger.debug(" MONGODB #{ || }") if @logger begin sock = socket || checkout result = '' @safe_mutex.synchronize do (, sock) result = receive(sock) end ensure checkin(sock) end result end |
#remove_auth(db_name) ⇒ Boolean
Remove a saved authentication for this connection.
213 214 215 216 217 218 219 220 |
# File 'lib/mongo/connection.rb', line 213 def remove_auth(db_name) return unless @auths if @auths.reject! { |a| a['db_name'] == db_name } true else false end end |
#send_message(operation, message, log_message = nil) ⇒ True
Send a message to MongoDB, adding the necessary headers.
336 337 338 339 340 341 342 343 344 345 |
# File 'lib/mongo/connection.rb', line 336 def (operation, , =nil) @logger.debug(" MONGODB #{ || }") if @logger begin = (operation, ).to_s socket = checkout (, socket) ensure checkin(socket) end end |
#send_message_with_safe_check(operation, message, db_name, log_message = nil) ⇒ Array
Sends a message to the database, waits for a response, and raises an exception if the operation has failed.
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 |
# File 'lib/mongo/connection.rb', line 358 def (operation, , db_name, =nil) = (operation, ) = (db_name) @logger.debug(" MONGODB #{ || }") if @logger begin sock = checkout = .append!().to_s docs = num_received = cursor_id = '' @safe_mutex.synchronize do (, sock) docs, num_received, cursor_id = receive(sock) end ensure checkin(sock) end if num_received == 1 && error = docs[0]['err'] raise Mongo::OperationFailure, error end [docs, num_received, cursor_id] end |
#server_info ⇒ Hash
Get the build information for the current connection.
307 308 309 |
# File 'lib/mongo/connection.rb', line 307 def server_info self["admin"].command({:buildinfo => 1}, false, true) end |
#server_version ⇒ Mongo::ServerVersion
Get the build version of the current server.
315 316 317 |
# File 'lib/mongo/connection.rb', line 315 def server_version ServerVersion.new(server_info["version"]) end |
#slave_ok? ⇒ Boolean
Is it okay to connect to a slave?
322 323 324 |
# File 'lib/mongo/connection.rb', line 322 def slave_ok? @slave_ok end |