mongo 1.1.5 → 1.2.rc0

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 CHANGED
@@ -12,7 +12,7 @@ This documentation includes other articles of interest, include:
12
12
  6. [History](http://api.mongodb.org/ruby/current/file.HISTORY.html).
13
13
  7. [Credits](http://api.mongodb.org/ruby/current/file.CREDITS.html).
14
14
 
15
- Here's a quick code sample. Again, see the [MongoDB Ruby Tutorial](file.TUTORIAL.html)
15
+ Here's a quick code sample. Again, see the [MongoDB Ruby Tutorial](http://api.mongodb.org/ruby/current/file.TUTORIAL.html)
16
16
  for much more:
17
17
 
18
18
  require 'rubygems'
data/docs/HISTORY.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # MongoDB Ruby Driver History
2
2
 
3
+ 1.2.rc0
4
+ 2011-1-5
5
+
6
+ Lots of cleanp and minor bug fixes.
7
+ * Issues resolved: http://jira.mongodb.org/browse/RUBY/fixforversion/10222
8
+ * Updated Java BSON to Java driver 2.4.
9
+ * Platform gem for JRuby bson.
10
+
3
11
  ### 1.1.5
4
12
  2010-12-15
5
13
 
data/docs/REPLICA_SETS.md CHANGED
@@ -38,18 +38,14 @@ every half second and time out after thirty seconds.
38
38
 
39
39
  # Ensure retry upon failure
40
40
  def rescue_connection_failure(max_retries=60)
41
- success = false
42
- retries = 0
43
- while !success
44
- begin
45
- yield
46
- success = true
47
- rescue Mongo::ConnectionFailure => ex
48
- retries += 1
49
- raise ex if retries >= max_retries
50
- sleep(0.5)
51
- end
52
- end
41
+ retries = 0
42
+ begin
43
+ yield
44
+ rescue Mongo::ConnectionFailure => ex
45
+ retries += 1
46
+ raise ex if retries > max_retries
47
+ sleep(0.5)
48
+ retry
53
49
  end
54
50
  end
55
51
 
data/lib/mongo.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
4
 
5
5
  module Mongo
6
- VERSION = "1.1.5"
6
+ VERSION = "1.2.rc0"
7
7
  end
8
8
 
9
9
  module Mongo
@@ -11,6 +11,8 @@ module Mongo
11
11
  DESCENDING = -1
12
12
  GEO2D = '2d'
13
13
 
14
+ DEFAULT_MAX_BSON_SIZE = 4 * 1024 * 1024
15
+
14
16
  module Constants
15
17
  OP_REPLY = 1
16
18
  OP_MSG = 1000
@@ -24,13 +24,13 @@ module Mongo
24
24
 
25
25
  # Initialize a collection object.
26
26
  #
27
- # @param [DB] db a MongoDB database instance.
28
27
  # @param [String, Symbol] name the name of the collection.
28
+ # @param [DB] db a MongoDB database instance.
29
29
  #
30
- # @option options [:create_pk] :pk (BSON::ObjectId) A primary key factory to use
30
+ # @option opts [:create_pk] :pk (BSON::ObjectId) A primary key factory to use
31
31
  # other than the default BSON::ObjectId.
32
32
  #
33
- # @option options [Boolean, Hash] :safe (false) Set the default safe-mode options
33
+ # @option opts [Boolean, Hash] :safe (false) Set the default safe-mode options
34
34
  # for insert, update, and remove method called on this Collection instance. If no
35
35
  # value is provided, the default value set on this instance's DB will be used. This
36
36
  # default can be overridden for any invocation of insert, update, or remove.
@@ -44,7 +44,13 @@ module Mongo
44
44
  # @return [Collection]
45
45
  #
46
46
  # @core collections constructor_details
47
- def initialize(db, name, options={})
47
+ def initialize(name, db, opts={})
48
+ if db.is_a?(String) && name.is_a?(Mongo::DB)
49
+ warn "Warning: the order of parameters to initialize a collection have changed. " +
50
+ "Please specify the collection name first, followed by the db."
51
+ db, name = name, db
52
+ end
53
+
48
54
  case name
49
55
  when Symbol, String
50
56
  else
@@ -63,10 +69,10 @@ module Mongo
63
69
  raise Mongo::InvalidNSName, "collection names must not start or end with '.'"
64
70
  end
65
71
 
66
- if options.respond_to?(:create_pk) || !options.is_a?(Hash)
72
+ if opts.respond_to?(:create_pk) || !opts.is_a?(Hash)
67
73
  warn "The method for specifying a primary key factory on a Collection has changed.\n" +
68
74
  "Please specify it as an option (e.g., :pk => PkFactory)."
69
- pk_factory = options
75
+ pk_factory = opts
70
76
  else
71
77
  pk_factory = nil
72
78
  end
@@ -77,9 +83,9 @@ module Mongo
77
83
  @cache_time = @db.cache_time
78
84
  @cache = Hash.new(0)
79
85
  unless pk_factory
80
- @safe = options.has_key?(:safe) ? options[:safe] : @db.safe
86
+ @safe = opts.fetch(:safe, @db.safe)
81
87
  end
82
- @pk_factory = pk_factory || options[:pk] || BSON::ObjectId
88
+ @pk_factory = pk_factory || opts[:pk] || BSON::ObjectId
83
89
  @hint = nil
84
90
  end
85
91
 
@@ -96,7 +102,7 @@ module Mongo
96
102
  # the specified sub-collection
97
103
  def [](name)
98
104
  name = "#{self.name}.#{name}"
99
- return Collection.new(db, name) if !db.strict? || db.collection_names.include?(name)
105
+ return Collection.new(name, db) if !db.strict? || db.collection_names.include?(name)
100
106
  raise "Collection #{name} doesn't exist. Currently in strict mode."
101
107
  end
102
108
 
@@ -134,7 +140,7 @@ module Mongo
134
140
  # to Ruby 1.8).
135
141
  #
136
142
  # @option opts [Array, Hash] :fields field names that should be returned in the result
137
- # set ("_id" will always be included). By limiting results to a certain subset of fields,
143
+ # set ("_id" will be included unless explicity excluded). By limiting results to a certain subset of fields,
138
144
  # you can cut down on network traffic and decoding time. If using a Hash, keys should be field
139
145
  # names and values should be either 1 or 0, depending on whether you want to include or exclude
140
146
  # the given field.
@@ -271,10 +277,10 @@ module Mongo
271
277
  # @see DB#remove for options that can be passed to :safe.
272
278
  #
273
279
  # @core insert insert-instance_method
274
- def insert(doc_or_docs, options={})
280
+ def insert(doc_or_docs, opts={})
275
281
  doc_or_docs = [doc_or_docs] unless doc_or_docs.is_a?(Array)
276
282
  doc_or_docs.collect! { |doc| @pk_factory.create_pk(doc) }
277
- safe = options.has_key?(:safe) ? options[:safe] : @safe
283
+ safe = opts.fetch(:safe, @safe)
278
284
  result = insert_documents(doc_or_docs, @name, true, safe)
279
285
  result.size > 1 ? result : result.first
280
286
  end
@@ -310,7 +316,7 @@ module Mongo
310
316
  # @core remove remove-instance_method
311
317
  def remove(selector={}, opts={})
312
318
  # Initial byte is 0.
313
- safe = opts.has_key?(:safe) ? opts[:safe] : @safe
319
+ safe = opts.fetch(:safe, @safe)
314
320
  message = BSON::ByteBuffer.new("\0\0\0\0")
315
321
  BSON::BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}")
316
322
  message.put_int(0)
@@ -336,8 +342,8 @@ module Mongo
336
342
  # a hash specifying the fields to be changed in the selected document,
337
343
  # or (in the case of an upsert) the document to be inserted
338
344
  #
339
- # @option [Boolean] :upsert (+false+) if true, performs an upsert (update or insert)
340
- # @option [Boolean] :multi (+false+) update all documents matching the selector, as opposed to
345
+ # @option opts [Boolean] :upsert (+false+) if true, performs an upsert (update or insert)
346
+ # @option opts [Boolean] :multi (+false+) update all documents matching the selector, as opposed to
341
347
  # just the first matching document. Note: only works in MongoDB 1.1.3 or later.
342
348
  # @option opts [Boolean] :safe (+false+)
343
349
  # If true, check that the save succeeded. OperationFailure
@@ -350,14 +356,14 @@ module Mongo
350
356
  # Otherwise, returns true.
351
357
  #
352
358
  # @core update update-instance_method
353
- def update(selector, document, options={})
359
+ def update(selector, document, opts={})
354
360
  # Initial byte is 0.
355
- safe = options.has_key?(:safe) ? options[:safe] : @safe
361
+ safe = opts.fetch(:safe, @safe)
356
362
  message = BSON::ByteBuffer.new("\0\0\0\0")
357
363
  BSON::BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}")
358
364
  update_options = 0
359
- update_options += 1 if options[:upsert]
360
- update_options += 2 if options[:multi]
365
+ update_options += 1 if opts[:upsert]
366
+ update_options += 2 if opts[:multi]
361
367
  message.put_int(update_options)
362
368
  message.put_binary(BSON::BSON_CODER.serialize(selector, false, true).to_s)
363
369
  message.put_binary(BSON::BSON_CODER.serialize(document, false, true).to_s)
@@ -415,6 +421,7 @@ module Mongo
415
421
  opts[:dropDups] = opts.delete(:drop_dups) if opts[:drop_dups]
416
422
  field_spec = parse_index_spec(spec)
417
423
  name = opts.delete(:name) || generate_index_name(field_spec)
424
+ name = name.to_s if name
418
425
 
419
426
  generate_indexes(field_spec, name, opts)
420
427
  name
@@ -437,18 +444,15 @@ module Mongo
437
444
  #
438
445
  # @return [String] the name of the index.
439
446
  def ensure_index(spec, opts={})
440
- valid = BSON::OrderedHash.new
441
447
  now = Time.now.utc.to_i
442
448
  field_spec = parse_index_spec(spec)
443
449
 
444
- field_spec.each do |key, value|
445
- cache_key = generate_index_name({key => value})
446
- timeout = @cache[cache_key] || 0
447
- valid[key] = value if timeout <= now
448
- end
450
+ name = opts.delete(:name) || generate_index_name(field_spec)
451
+ name = name.to_s if name
449
452
 
450
- name = opts.delete(:name) || generate_index_name(valid)
451
- generate_indexes(valid, name, opts) if valid.any?
453
+ if !@cache[name] || @cache[name] <= now
454
+ generate_indexes(field_spec, name, opts)
455
+ end
452
456
 
453
457
  # Reset the cache here in case there are any errors inserting. Best to be safe.
454
458
  @cache[name] = now + @cache_time
@@ -461,7 +465,7 @@ module Mongo
461
465
  #
462
466
  # @core indexes
463
467
  def drop_index(name)
464
- @cache[name] = nil
468
+ @cache[name.to_s] = nil
465
469
  @db.drop_index(@name, name)
466
470
  end
467
471
 
@@ -55,16 +55,16 @@ module Mongo
55
55
  # @param [String, Hash] host.
56
56
  # @param [Integer] port specify a port number here if only one host is being specified.
57
57
  #
58
- # @option options [Boolean, Hash] :safe (false) Set the default safe-mode options
58
+ # @option opts [Boolean, Hash] :safe (false) Set the default safe-mode options
59
59
  # propogated to DB objects instantiated off of this Connection. This
60
60
  # default can be overridden upon instantiation of any DB by explicity setting a :safe value
61
61
  # on initialization.
62
- # @option options [Boolean] :slave_ok (false) Must be set to +true+ when connecting
62
+ # @option opts [Boolean] :slave_ok (false) Must be set to +true+ when connecting
63
63
  # to a single, slave node.
64
- # @option options [Logger, #debug] :logger (nil) Logger instance to receive driver operation log.
65
- # @option options [Integer] :pool_size (1) The maximum number of socket connections allowed per
64
+ # @option opts [Logger, #debug] :logger (nil) Logger instance to receive driver operation log.
65
+ # @option opts [Integer] :pool_size (1) The maximum number of socket connections allowed per
66
66
  # connection pool. Note: this setting is relevant only for multi-threaded applications.
67
- # @option options [Float] :timeout (5.0) When all of the connections a pool are checked out,
67
+ # @option opts [Float] :timeout (5.0) When all of the connections a pool are checked out,
68
68
  # this is the number of seconds to wait for a new connection to be released before throwing an exception.
69
69
  # Note: this setting is relevant only for multi-threaded applications (which in Ruby are rare).
70
70
  #
@@ -86,16 +86,16 @@ module Mongo
86
86
  # driver fails to connect to a replica set with that name.
87
87
  #
88
88
  # @core connections
89
- def initialize(host=nil, port=nil, options={})
89
+ def initialize(host=nil, port=nil, opts={})
90
90
  @host_to_try = format_pair(host, port)
91
91
 
92
92
  # Host and port of current master.
93
93
  @host = @port = nil
94
94
 
95
95
  # slave_ok can be true only if one node is specified
96
- @slave_ok = options[:slave_ok]
96
+ @slave_ok = opts[:slave_ok]
97
97
 
98
- setup(options)
98
+ setup(opts)
99
99
  end
100
100
 
101
101
  # DEPRECATED
@@ -109,9 +109,9 @@ module Mongo
109
109
  # @param nodes [Array] An array of arrays, each of which specifies a host and port.
110
110
  # @param opts [Hash] Any of the available options that can be passed to Connection.new.
111
111
  #
112
- # @option options [String] :rs_name (nil) The name of the replica set to connect to. An exception will be
112
+ # @option opts [String] :rs_name (nil) The name of the replica set to connect to. An exception will be
113
113
  # raised if unable to connect to a replica set with this name.
114
- # @option options [Boolean] :read_secondary (false) When true, this connection object will pick a random slave
114
+ # @option opts [Boolean] :read_secondary (false) When true, this connection object will pick a random slave
115
115
  # to send reads to.
116
116
  #
117
117
  # @example
@@ -138,15 +138,19 @@ module Mongo
138
138
  #
139
139
  # @param opts Any of the options available for Connection.new
140
140
  #
141
- # @return [Mongo::Connection]
142
- def self.from_uri(uri, opts={})
143
- nodes, auths = Mongo::URIParser.parse(uri)
144
- opts.merge!({:auths => auths})
145
- if nodes.length == 1
146
- Connection.new(nodes[0][0], nodes[0][1], opts)
147
- elsif nodes.length > 1
148
- nodes << opts
149
- ReplSetConnection.new(*nodes)
141
+ # @return [Mongo::Connection, Mongo::ReplSetConnection]
142
+ def self.from_uri(string, extra_opts={})
143
+ uri = URIParser.new(string)
144
+ opts = uri.connection_options
145
+ opts.merge!(extra_opts)
146
+
147
+ if uri.nodes.length == 1
148
+ opts.merge!({:auths => uri.auths})
149
+ Connection.new(uri.nodes[0][0], uri.nodes[0][1], opts)
150
+ elsif uri.nodes.length > 1
151
+ nodes = uri.nodes.clone
152
+ nodes_with_opts = nodes << opts
153
+ ReplSetConnection.new(*nodes_with_opts)
150
154
  else
151
155
  raise MongoArgumentError, "No nodes specified. Please ensure that you've provided at least one node."
152
156
  end
@@ -259,12 +263,13 @@ module Mongo
259
263
  # See DB#new for valid options hash parameters.
260
264
  #
261
265
  # @param [String] db_name a valid database name.
266
+ # @param [Hash] opts options to be passed to the DB constructor.
262
267
  #
263
268
  # @return [Mongo::DB]
264
269
  #
265
270
  # @core databases db-instance_method
266
- def db(db_name, options={})
267
- DB.new(db_name, self, options)
271
+ def db(db_name, opts={})
272
+ DB.new(db_name, self, opts)
268
273
  end
269
274
 
270
275
  # Shortcut for returning a database. Use DB#db to accept options.
@@ -430,11 +435,19 @@ module Mongo
430
435
  reset_connection
431
436
 
432
437
  config = check_is_master(@host_to_try)
433
- if is_primary?(config)
438
+ if config
439
+ if config['ismaster'] == 1 || config['ismaster'] == true
440
+ @read_primary = true
441
+ elsif @slave_ok
442
+ @read_primary = false
443
+ end
444
+
434
445
  set_primary(@host_to_try)
435
446
  end
436
447
 
437
- if !connected?
448
+ if connected?
449
+ BSON::BSON_CODER.update_max_bson_size(self)
450
+ else
438
451
  raise ConnectionFailure, "Failed to connect to a master node at #{@host_to_try[0]}:#{@host_to_try[1]}"
439
452
  end
440
453
  end
@@ -450,12 +463,29 @@ module Mongo
450
463
  @primary_pool && @primary_pool.host && @primary_pool.port
451
464
  end
452
465
 
466
+ # Determine whether we're reading from a primary node. If false,
467
+ # this connection connects to a secondary node and @slave_ok is true.
468
+ #
469
+ # @return [Boolean]
470
+ def read_primary?
471
+ @read_primary
472
+ end
473
+
453
474
  # Close the connection to the database.
454
475
  def close
455
476
  @primary_pool.close if @primary_pool
456
477
  @primary_pool = nil
457
478
  end
458
479
 
480
+ # Returns the maximum BSON object size as returned by the core server.
481
+ # Use the 4MB default when the server doesn't report this.
482
+ #
483
+ # @return [Integer]
484
+ def max_bson_size
485
+ config = self['admin'].command({:ismaster => 1})
486
+ config['maxBsonObjectSize'] || Mongo::DEFAULT_MAX_BSON_SIZE
487
+ end
488
+
459
489
  # Checkout a socket for reading (i.e., a secondary node).
460
490
  # Note: this is overridden in ReplSetConnection.
461
491
  def checkout_reader
@@ -489,23 +519,22 @@ module Mongo
489
519
  protected
490
520
 
491
521
  # Generic initialization code.
492
- # @protected
493
- def setup(options)
522
+ def setup(opts)
494
523
  # Authentication objects
495
- @auths = options.fetch(:auths, [])
524
+ @auths = opts.fetch(:auths, [])
496
525
 
497
526
  # Lock for request ids.
498
527
  @id_lock = Mutex.new
499
528
 
500
529
  # Pool size and timeout.
501
- @pool_size = options[:pool_size] || 1
502
- @timeout = options[:timeout] || 5.0
530
+ @pool_size = opts[:pool_size] || 1
531
+ @timeout = opts[:timeout] || 5.0
503
532
 
504
533
  # Mutex for synchronizing pool access
505
534
  @connection_mutex = Mutex.new
506
535
 
507
536
  # Global safe option. This is false by default.
508
- @safe = options[:safe] || false
537
+ @safe = opts[:safe] || false
509
538
 
510
539
  # Create a mutex when a new key, in this case a socket,
511
540
  # is added to the hash.
@@ -518,9 +547,9 @@ module Mongo
518
547
  @primary = nil
519
548
  @primary_pool = nil
520
549
 
521
- @logger = options[:logger] || nil
550
+ @logger = opts[:logger] || nil
522
551
 
523
- should_connect = options.fetch(:connect, true)
552
+ should_connect = opts.fetch(:connect, true)
524
553
  connect if should_connect
525
554
  end
526
555
 
@@ -552,16 +581,6 @@ module Mongo
552
581
  @primary = nil
553
582
  end
554
583
 
555
- # Primary is defined as either a master node or a slave if
556
- # :slave_ok has been set to +true+.
557
- #
558
- # If a primary node is discovered, we set the the @host and @port and
559
- # apply any saved authentication.
560
- # TODO: simplify
561
- def is_primary?(config)
562
- config && (config['ismaster'] == 1 || config['ismaster'] == true) || @slave_ok
563
- end
564
-
565
584
  def check_is_master(node)
566
585
  begin
567
586
  host, port = *node
@@ -673,7 +692,7 @@ module Mongo
673
692
  #
674
693
  # Note: this method modifies message by reference.
675
694
  #
676
- # @returns [Integer] the request id used in the header
695
+ # @return [Integer] the request id used in the header
677
696
  def add_message_headers(message, operation)
678
697
  headers = [
679
698
  # Message size.
data/lib/mongo/cursor.rb CHANGED
@@ -33,26 +33,26 @@ module Mongo
33
33
  # @return [Cursor]
34
34
  #
35
35
  # @core cursors constructor_details
36
- def initialize(collection, options={})
36
+ def initialize(collection, opts={})
37
37
  @db = collection.db
38
38
  @collection = collection
39
39
  @connection = @db.connection
40
40
  @logger = @connection.logger
41
41
 
42
- @selector = options[:selector] || {}
43
- @fields = convert_fields_for_query(options[:fields])
44
- @skip = options[:skip] || 0
45
- @limit = options[:limit] || 0
46
- @order = options[:order]
47
- @hint = options[:hint]
48
- @snapshot = options[:snapshot]
49
- @timeout = options.has_key?(:timeout) ? options[:timeout] : true
50
- @explain = options[:explain]
51
- @socket = options[:socket]
52
- @tailable = options[:tailable] || false
42
+ @selector = opts[:selector] || {}
43
+ @fields = convert_fields_for_query(opts[:fields])
44
+ @skip = opts[:skip] || 0
45
+ @limit = opts[:limit] || 0
46
+ @order = opts[:order]
47
+ @hint = opts[:hint]
48
+ @snapshot = opts[:snapshot]
49
+ @timeout = opts.fetch(:timeout, true)
50
+ @explain = opts[:explain]
51
+ @socket = opts[:socket]
52
+ @tailable = opts[:tailable] || false
53
53
  @closed = false
54
54
  @query_run = false
55
- batch_size(options[:batch_size] || 0)
55
+ batch_size(opts[:batch_size] || 0)
56
56
 
57
57
  @full_collection_name = "#{@collection.db.name}.#{@collection.name}"
58
58
  @cache = []