mongo 1.6.4 → 1.7.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/README.md +13 -13
  2. data/Rakefile +7 -10
  3. data/docs/{GridFS.md → GRID_FS.md} +0 -0
  4. data/docs/HISTORY.md +16 -0
  5. data/docs/READ_PREFERENCE.md +70 -10
  6. data/docs/TUTORIAL.md +2 -2
  7. data/lib/mongo.rb +2 -0
  8. data/lib/mongo/collection.rb +62 -11
  9. data/lib/mongo/connection.rb +31 -41
  10. data/lib/mongo/cursor.rb +42 -86
  11. data/lib/mongo/db.rb +10 -8
  12. data/lib/mongo/networking.rb +30 -65
  13. data/lib/mongo/repl_set_connection.rb +91 -170
  14. data/lib/mongo/sharded_connection.rb +221 -0
  15. data/lib/mongo/util/node.rb +29 -36
  16. data/lib/mongo/util/pool.rb +10 -3
  17. data/lib/mongo/util/pool_manager.rb +77 -90
  18. data/lib/mongo/util/sharding_pool_manager.rb +143 -0
  19. data/lib/mongo/util/support.rb +22 -2
  20. data/lib/mongo/util/tcp_socket.rb +10 -15
  21. data/lib/mongo/util/uri_parser.rb +17 -10
  22. data/lib/mongo/version.rb +1 -1
  23. data/test/collection_test.rb +133 -1
  24. data/test/connection_test.rb +50 -4
  25. data/test/db_api_test.rb +3 -3
  26. data/test/db_test.rb +6 -1
  27. data/test/replica_sets/basic_test.rb +3 -6
  28. data/test/replica_sets/complex_connect_test.rb +14 -2
  29. data/test/replica_sets/complex_read_preference_test.rb +237 -0
  30. data/test/replica_sets/connect_test.rb +47 -67
  31. data/test/replica_sets/count_test.rb +1 -1
  32. data/test/replica_sets/cursor_test.rb +70 -0
  33. data/test/replica_sets/read_preference_test.rb +171 -118
  34. data/test/replica_sets/refresh_test.rb +3 -3
  35. data/test/replica_sets/refresh_with_threads_test.rb +2 -2
  36. data/test/replica_sets/rs_test_helper.rb +2 -2
  37. data/test/sharded_cluster/basic_test.rb +112 -0
  38. data/test/sharded_cluster/mongo_config_test.rb +126 -0
  39. data/test/sharded_cluster/sc_test_helper.rb +39 -0
  40. data/test/test_helper.rb +3 -3
  41. data/test/threading/threading_with_large_pool_test.rb +1 -1
  42. data/test/tools/mongo_config.rb +307 -0
  43. data/test/tools/repl_set_manager.rb +12 -12
  44. data/test/unit/collection_test.rb +1 -1
  45. data/test/unit/cursor_test.rb +11 -6
  46. data/test/unit/db_test.rb +4 -0
  47. data/test/unit/grid_test.rb +2 -0
  48. data/test/unit/read_test.rb +39 -8
  49. data/test/uri_test.rb +4 -8
  50. metadata +144 -127
data/README.md CHANGED
@@ -25,18 +25,18 @@ For the reference manual, use the links in the upper-left and upper-right corner
25
25
 
26
26
  This documentation has other articles of interest, including:
27
27
 
28
- 1. [A tutorial](docs/TUTORIAL.md).
29
- 2. [Replica Sets in Ruby](docs/REPLICA_SETS.md).
30
- 3. [Write Concern in Ruby](docs/WRITE_CONCERN.md).
31
- 4. [Tailable Cursors in Ruby](docs/TAILABLE_CURSORS.md).
32
- 5. [Read Preference in Ruby](docs/READ_PREFERENCE.md).
33
- 6. [GridFS in Ruby](docs/GridFS.md).
34
- 7. [Frequently Asked Questions](docs/FAQ.md).
35
- 8. [History](docs/HISTORY.md).
36
- 9. [Release plan](docs/RELEASES.md).
37
- 10. [Credits](docs/CREDITS.md).
38
-
39
- Here's a quick code sample. Again, see the [MongoDB Ruby Tutorial](docs/TUTORIAL.md)
28
+ 1. [A tutorial](file.TUTORIAL.html).
29
+ 2. [Replica Sets in Ruby](file.REPLICA_SETS.html).
30
+ 3. [Write Concern in Ruby](file.WRITE_CONCERN.html).
31
+ 4. [Tailable Cursors in Ruby](file.TAILABLE_CURSORS.html).
32
+ 5. [Read Preference in Ruby](file.READ_PREFERENCE.html).
33
+ 6. [GridFS in Ruby](file.GRID_FS.html).
34
+ 7. [Frequently Asked Questions](file.FAQ.html).
35
+ 8. [History](file.HISTORY.html).
36
+ 9. [Release plan](file.RELEASES.html).
37
+ 10. [Credits](file.CREDITS.html).
38
+
39
+ Here's a quick code sample. Again, see the [MongoDB Ruby Tutorial](file.TUTORIAL.html)
40
40
  for much more:
41
41
 
42
42
  require 'rubygems'
@@ -104,7 +104,7 @@ That's all there is to it!
104
104
 
105
105
  # Examples
106
106
 
107
- For extensive examples, see the [MongoDB Ruby Tutorial](http://api.mongodb.org/ruby/current/file.TUTORIAL.html).
107
+ For extensive examples, see the [MongoDB Ruby Tutorial](file.TUTORIAL.html).
108
108
 
109
109
  Bundled with the driver are many examples, located in the "docs/examples" subdirectory. Samples include using
110
110
  the driver and using the GridFS class GridStore. MongoDB must be running for
data/Rakefile CHANGED
@@ -99,56 +99,53 @@ namespace :test do
99
99
  desc "Run the replica set test suite"
100
100
  Rake::TestTask.new(:rs) do |t|
101
101
  t.test_files = FileList['test/replica_sets/*_test.rb']
102
- t.verbose = true
103
102
  t.ruby_opts << '-w'
104
103
  end
105
104
 
106
105
  desc "Run the replica set test suite"
107
106
  Rake::TestTask.new(:rs_no_threads) do |t|
108
107
  t.test_files = FileList['test/replica_sets/*_test.rb'] - ["test/replica_sets/refresh_with_threads_test.rb"]
109
- t.verbose = true
108
+ t.ruby_opts << '-w'
109
+ end
110
+
111
+ desc "Run the sharded cluster test suite"
112
+ Rake::TestTask.new(:sc) do |t|
113
+ t.test_files = FileList['test/sharded_cluster/*_test.rb']
110
114
  t.ruby_opts << '-w'
111
115
  end
112
116
 
113
117
  Rake::TestTask.new(:unit) do |t|
114
118
  t.test_files = FileList['test/unit/*_test.rb']
115
- t.verbose = true
116
119
  t.ruby_opts << '-w'
117
120
  end
118
121
 
119
122
  Rake::TestTask.new(:functional) do |t|
120
123
  t.test_files = FileList['test/*_test.rb']
121
- t.verbose = true
122
124
  t.ruby_opts << '-w'
123
125
  end
124
126
 
125
127
  Rake::TestTask.new(:pooled_threading) do |t|
126
128
  t.test_files = FileList['test/threading/*_test.rb']
127
- t.verbose = true
128
129
  t.ruby_opts << '-w'
129
130
  end
130
131
 
131
132
  Rake::TestTask.new(:auto_reconnect) do |t|
132
133
  t.test_files = FileList['test/auxillary/autoreconnect_test.rb']
133
- t.verbose = true
134
134
  t.ruby_opts << '-w'
135
135
  end
136
136
 
137
137
  Rake::TestTask.new(:authentication) do |t|
138
138
  t.test_files = FileList['test/auxillary/authentication_test.rb']
139
- t.verbose = true
140
139
  t.ruby_opts << '-w'
141
140
  end
142
141
 
143
142
  Rake::TestTask.new(:new_features) do |t|
144
143
  t.test_files = FileList['test/auxillary/1.4_features.rb']
145
- t.verbose = true
146
144
  t.ruby_opts << '-w'
147
145
  end
148
146
 
149
147
  Rake::TestTask.new(:bson) do |t|
150
148
  t.test_files = FileList['test/bson/*_test.rb']
151
- t.verbose = true
152
149
  t.ruby_opts << '-w'
153
150
  end
154
151
 
@@ -176,7 +173,7 @@ task :ydoc do
176
173
  require './lib/mongo/version.rb'
177
174
  out = File.join('ydoc', Mongo::VERSION)
178
175
  FileUtils.rm_rf('ydoc')
179
- system "yardoc lib/**/*.rb lib/mongo/**/*.rb lib/bson/**/*.rb -e ./yard/yard_ext.rb -p yard/templates -o #{out} --title MongoRuby-#{Mongo::VERSION} --files docs/TUTORIAL.md,docs/GridFS.md,docs/FAQ.md,docs/REPLICA_SETS.md,docs/WRITE_CONCERN.md,docs/READ_PREFERENCE.md,docs/HISTORY.md,docs/CREDITS.md,docs/RELEASES.md,docs/CREDITS.md,docs/TAILABLE_CURSORS.md"
176
+ system "yardoc -o #{out} --title MongoRuby-#{Mongo::VERSION}"
180
177
  end
181
178
 
182
179
  namespace :jenkins do
File without changes
@@ -1,5 +1,21 @@
1
1
  # MongoDB Ruby Driver History
2
2
 
3
+ ### 1.7.0
4
+ 2012-08-20
5
+
6
+ * Added testing and full support for MongoDB 2.1 & 2.2
7
+ * Added Aggregation Framework helper method
8
+ * Added support for Mongos high availability
9
+ * Modified and added new read preferences (details in documentation)
10
+ * Added support for data center awareness (tag_sets)
11
+ * Fixed bug which attempted to close cursors on wrong replica set member
12
+
13
+ ### 1.6.4
14
+ 2012-06-06
15
+
16
+ * Added ability to declare sort ordering via an ordered hash
17
+ * Addresses major compatability issue with mongoid created by v1.6.3
18
+
3
19
  ### 1.6.3
4
20
  2012-06-05
5
21
 
@@ -1,15 +1,22 @@
1
1
  # Read Preference in Ruby
2
2
 
3
- ## Setting the read preference
3
+ ## About Read Preference
4
4
 
5
- You can using the `:read` option to specify a query's read preference. There are for now two possible options:
5
+ Read preferences determine the candidate replica set members to which a query or command can be sent. They consist of a *mode* specified as a symbol and an array of hashes known as *tag_sets*.
6
6
 
7
- @collection.find({:doc => 'foo'}, :read => :primary)
8
- @collection.find({:doc => 'foo'}, :read => :secondary)
7
+ Read preference mode is configured by providing the read option to a connection, database, collection, or cursor.
9
8
 
10
- In the first case, the query will be directed to the primary node in a replica set. In the second, the query will be sent
11
- to a secondary node. The driver will attempt to choose a secondary node that's nearby, as determined by ping time. If more
12
- than one secondary node is closeby (e.g, responds to pings within 10ms), then a random node within this subset will be chosen.
9
+ @collection.find({:doc => 'foo'}, :read => :primary) # read from primary only
10
+ @collection.find({:doc => 'foo'}, :read => :secondary) # read from secondaries only
11
+
12
+ Used in conjunction with tag_sets:
13
+
14
+ @collection.find({:name => 'foo'}, :read => :secondary_preferred, :tag_sets => [{:continent => 'USA'}])
15
+
16
+ *Please Note*: Behavior of some read preference modes have changed in version 1.7.0:
17
+
18
+ * `:secondary_preferred` mode is now used to prefer reads from secondary members (before this was the behavior of `:secondary`).
19
+ * `:secondary_only` mode (which only allowed reads from secondaries) is now called `:secondary`.
13
20
 
14
21
  ## Read preference inheritance
15
22
 
@@ -33,7 +40,60 @@ You can examine the read preference on any object by calling its `read_preferenc
33
40
  @db.read_preference
34
41
  @collection.read_preference
35
42
 
36
- ## Future work
43
+ ## Modes
44
+
45
+ You can using the `:read` option to specify a query's read preference mode. There are five possible options.
46
+
47
+ ### :primary
48
+
49
+ With primary, all read operations from the client will use the primary member only. This is the default read preference.
50
+
51
+ If the primary is unavailable, all operations with this preference produce an error or throw an exception. Primary read preference modes are not compatible with read preferences modes that use tag sets If you specify a tag set with primary, the driver will produce an error.
52
+
53
+ ### :primary_preferred
54
+
55
+ With the primaryPreferred read preference mode, operations will read from the primary member of the set in most situations. However, if the primary is unavailable, as is the case during failover situations, then these read operations can read from secondary members.
56
+
57
+ When the read preference includes a tag set, the client will first read from the primary, if it is available, and then from secondaries that match the specified tags. If there are no secondaries with tags that match the specified tags, this read operation will produce an error.
58
+
59
+ ### :secondary
60
+
61
+ With the secondary read preference mode, operations will read from the secondary member of the set if available. However, if there are no secondaries available, then these operations will produce an error or exception.
62
+
63
+ Most sets have at least one secondary, but there are situations where there may not be an available secondary. For example, a set with a primary, a secondary, and an arbiter may not have any secondaries if a member is ever in recovering mode.
64
+
65
+ When the read preference includes a tag set, the client will attempt to find a secondary members that match the specified tag set and directs reads to a random secondary from among the nearest group. If there are no secondaries with tags that match the specified tag set, this read operation will produce an error.
66
+
67
+ ### :secondary_preferred
68
+
69
+ With the secondaryPreferred, operations will read from secondary members, but in situations where the set only has a primary instance, the read operation will use the set’s primary.
70
+
71
+ When secondaryPreferred reads from a secondary and the read preference includes a tag set, the client will attempt to find a secondary members that match the specified tag set and directs reads to a random secondary from among the nearest group. If there are no secondaries with tags that match the specified tag set, this read operation will produce an error.
72
+
73
+ ### :nearest
74
+
75
+ With the nearest, the driver will read from the nearest member of the set according to the member selection process nearest read operations will not have any consideration for the type of the set member. Reads in nearest mode may read from both primaries and secondaries.
76
+
77
+ Set this mode when you want minimize the effect of network latency on read operations without preference for current or stale data.
78
+
79
+ If you specify a tag set, the client will attempt to find a secondary members that match the specified tag set and directs reads to a random secondary from among the nearest group.
80
+
81
+ ## Tag Sets
82
+
83
+ Tag sets can be used in for data center awareness by filtering secondary read operations. Primary reads occur independent of any tags.
84
+
85
+ A member matches a tag set if its tags match all the tags in the set. For example, a member tagged "{ dc: 'ny', rack: 2, size: 'large' }" matches the tag set "{ dc: 'ny', rack: 2 }". A member's extra tags don't affect whether it's a match.
86
+
87
+ Here is an example of a query which sends read operations to members in rack 2.
88
+
89
+ @collection.find({:name => 'foo'}, :read => :secondary_preferred, :tag_sets => [{:rack => '2'}])
90
+
91
+ Tag set keys may be symbols or strings. Tag set values should be specified using strings. The `to_s` method will be called on any values provided in the tag set.
92
+
93
+ Tag sets are used in conjunction with read preference mode. In this example, because we specified a mode of secondary_preferred, if no secondaries can be found that match the tag_set `{:rack => '2'}` then the primary will be used for the query.
94
+
95
+ If only one tag set is provided, the set can be passed as a single hash parameter iteself without the enclosing array.
96
+
97
+ @collection.find({:name => 'foo'}, :read => :secondary_preferred, :tag_sets => {:rack => '2'})
37
98
 
38
- In the v2.0 release of the driver, you'll also be able to specify a read preference consisting of a set of tags. This way,
39
- you'll be able to direct reads to a replica set member. You can follow this issue's progress here: (https://jira.mongodb.org/browse/RUBY-326).
99
+ Specifiying tag_sets for mode `:primary` is considered an error and will raise a MongoArgumentError as tag_sets do not affect selection of primary members and only primary members can be selected in that particular mode.
@@ -180,7 +180,7 @@ Direction defaults to ascending order but can be specified as Mongo::ASCENDING,
180
180
  coll.find.sort(:i)
181
181
 
182
182
  # Sort in descending order by :i
183
- coll.find.sort([:i, :desc])
183
+ coll.find.sort(:i => :desc)
184
184
 
185
185
  #### Counting Documents in a Collection
186
186
 
@@ -208,7 +208,7 @@ Use the `:fields` option to specify fields to return.
208
208
 
209
209
  #### Querying with Regular Expressions
210
210
 
211
- Regular expressions can be used to query MongoDB. To find all names that begin with 'a':
211
+ Regular expressions can be used to query MongoDB. To find all names that begin with 'M':
212
212
 
213
213
  puts coll.find({"name" => /^M/}).to_a
214
214
 
@@ -59,6 +59,7 @@ require 'mongo/util/logging'
59
59
  require 'mongo/util/node'
60
60
  require 'mongo/util/pool'
61
61
  require 'mongo/util/pool_manager'
62
+ require 'mongo/util/sharding_pool_manager'
62
63
  require 'mongo/util/server_version'
63
64
  require 'mongo/util/ssl_socket'
64
65
  require 'mongo/util/tcp_socket'
@@ -68,6 +69,7 @@ require 'mongo/collection'
68
69
  require 'mongo/networking'
69
70
  require 'mongo/connection'
70
71
  require 'mongo/repl_set_connection'
72
+ require 'mongo/sharded_connection'
71
73
  require 'mongo/cursor'
72
74
  require 'mongo/db'
73
75
  require 'mongo/exceptions'
@@ -23,6 +23,9 @@ module Mongo
23
23
 
24
24
  attr_reader :db, :name, :pk_factory, :hint, :safe
25
25
 
26
+ # Read Preference
27
+ attr_accessor :read_preference, :tag_sets, :acceptable_latency
28
+
26
29
  # Initialize a collection object.
27
30
  #
28
31
  # @param [String, Symbol] name the name of the collection.
@@ -97,6 +100,8 @@ module Mongo
97
100
  value = @db.read_preference
98
101
  end
99
102
  @read_preference = value.is_a?(Hash) ? value.dup : value
103
+ @tag_sets = opts.fetch(:tag_sets, @db.tag_sets)
104
+ @acceptable_latency = opts.fetch(:acceptable_latency, @db.acceptable_latency)
100
105
  end
101
106
  @pk_factory = pk_factory || opts[:pk] || BSON::ObjectId
102
107
  @hint = nil
@@ -109,7 +114,7 @@ module Mongo
109
114
  #
110
115
  # @return [Boolean]
111
116
  def capped?
112
- @db.command({:collstats => @name})['capped'] == 1
117
+ [1, true].include? @db.command({:collstats => @name})['capped']
113
118
  end
114
119
 
115
120
  # Return a sub-collection of this collection by name. If 'users' is a collection, then
@@ -220,6 +225,8 @@ module Mongo
220
225
  transformer = opts.delete(:transformer)
221
226
  show_disk_loc = opts.delete(:show_disk_loc)
222
227
  read = opts.delete(:read) || @read_preference
228
+ tag_sets = opts.delete(:tag_sets) || @tag_sets
229
+ acceptable_latency = opts.delete(:acceptable_latency) || @acceptable_latency
223
230
 
224
231
  if timeout == false && !block_given?
225
232
  raise ArgumentError, "Collection#find must be invoked with a block when timeout is disabled."
@@ -247,7 +254,9 @@ module Mongo
247
254
  :max_scan => max_scan,
248
255
  :show_disk_loc => show_disk_loc,
249
256
  :return_key => return_key,
250
- :read => read
257
+ :read => read,
258
+ :tag_sets => tag_sets,
259
+ :acceptable_latency => acceptable_latency
251
260
  })
252
261
 
253
262
  if block_given?
@@ -432,9 +441,13 @@ module Mongo
432
441
  update_options = 0
433
442
  update_options += 1 if opts[:upsert]
434
443
  update_options += 2 if opts[:multi]
444
+
445
+ # Determine if update document has modifiers and check keys if so
446
+ check_keys = document.keys.first.to_s.start_with?("$") ? false : true
447
+
435
448
  message.put_int(update_options)
436
449
  message.put_binary(BSON::BSON_CODER.serialize(selector, false, true).to_s)
437
- message.put_binary(BSON::BSON_CODER.serialize(document, false, true, @connection.max_bson_size).to_s)
450
+ message.put_binary(BSON::BSON_CODER.serialize(document, check_keys, true, @connection.max_bson_size).to_s)
438
451
 
439
452
  instrument(:update, :database => @db.name, :collection => @name, :selector => selector, :document => document) do
440
453
  if safe
@@ -581,7 +594,52 @@ module Mongo
581
594
 
582
595
  @db.command(cmd)['value']
583
596
  end
597
+
598
+ # Perform an aggregation using the aggregation framework on the current collection.
599
+ # @note Aggregate requires server version >= 2.1.1
600
+ # @note Field References: Within an expression, field names must be quoted and prefixed by a dollar sign ($).
601
+ #
602
+ # @example Define the pipeline as an array of operator hashes:
603
+ # coll.aggregate([ {"$project" => {"last_name" => 1, "first_name" => 1 }}, {"$match" => {"last_name" => "Jones"}} ])
604
+ #
605
+ # @param [Array] pipeline Should be a single array of pipeline operator hashes.
606
+ #
607
+ # '$project' Reshapes a document stream by including fields, excluding fields, inserting computed fields,
608
+ # renaming fields,or creating/populating fields that hold sub-documents.
609
+ #
610
+ # '$match' Query-like interface for filtering documents out of the aggregation pipeline.
611
+ #
612
+ # '$limit' Restricts the number of documents that pass through the pipline.
613
+ #
614
+ # '$skip' Skips over the specified number of documents and passes the rest along the pipeline.
615
+ #
616
+ # '$unwind' Peels off elements of an array individually, returning one document for each member.
617
+ #
618
+ # '$group' Groups documents for calculating aggregate values.
619
+ #
620
+ # '$sort' Sorts all input documents and returns them to the pipeline in sorted order.
621
+ #
622
+ # @return [Array] An Array with the aggregate command's results.
623
+ #
624
+ # @raise MongoArgumentError if operators either aren't supplied or aren't in the correct format.
625
+ # @raise MongoOperationFailure if the aggregate command fails.
626
+ #
627
+ def aggregate(pipeline=nil)
628
+ raise MongoArgumentError, "pipeline must be an array of operators" unless pipeline.class == Array
629
+ raise MongoArgumentError, "pipeline operators must be hashes" unless pipeline.all? { |op| op.class == Hash }
584
630
 
631
+ hash = BSON::OrderedHash.new
632
+ hash['aggregate'] = self.name
633
+ hash['pipeline'] = pipeline
634
+
635
+ result = @db.command(hash)
636
+ unless Mongo::Support.ok?(result)
637
+ raise Mongo::OperationFailure, "aggregate failed: #{result['errmsg']}"
638
+ end
639
+
640
+ return result["result"]
641
+ end
642
+
585
643
  # Perform a map-reduce operation on the current collection.
586
644
  #
587
645
  # @param [String, BSON::Code] map a map function, written in JavaScript.
@@ -714,13 +772,6 @@ module Mongo
714
772
  end
715
773
  end
716
774
 
717
- # The value of the read preference. This will be
718
- # either +:primary+, +:secondary+, or an object
719
- # representing the tags to be read from.
720
- def read_preference
721
- @read_preference
722
- end
723
-
724
775
  private
725
776
 
726
777
  def new_group(opts={})
@@ -972,7 +1023,7 @@ module Mongo
972
1023
  message.put_binary(BSON::BSON_CODER.serialize(doc, check_keys, true, @connection.max_bson_size).to_s)
973
1024
  end
974
1025
  end
975
- raise InvalidOperation, "Exceded maximum insert size of 16,000,000 bytes" if message.size > 16_000_000
1026
+ raise InvalidOperation, "Exceded maximum insert size of 16,777,216 bytes" if message.size > @connection.max_bson_size
976
1027
 
977
1028
  instrument(:insert, :database => @db.name, :collection => collection_name, :documents => documents) do
978
1029
  if safe
@@ -34,6 +34,7 @@ module Mongo
34
34
 
35
35
  DEFAULT_HOST = 'localhost'
36
36
  DEFAULT_PORT = 27017
37
+ DEFAULT_DB_NAME = 'test'
37
38
  GENERIC_OPTS = [:ssl, :auths, :pool_size, :pool_timeout, :timeout, :op_timeout, :connect_timeout, :safe, :logger, :connect]
38
39
  CONNECTION_OPTS = [:slave_ok]
39
40
 
@@ -41,7 +42,7 @@ module Mongo
41
42
 
42
43
  attr_reader :logger, :size, :auths, :primary, :safe, :host_to_try,
43
44
  :pool_size, :connect_timeout, :pool_timeout,
44
- :primary_pool, :socket_class, :op_timeout
45
+ :primary_pool, :socket_class, :op_timeout, :tag_sets, :acceptable_latency
45
46
 
46
47
  # Create a connection to single MongoDB instance.
47
48
  #
@@ -101,11 +102,11 @@ module Mongo
101
102
  # @core self.connections
102
103
  def initialize(host=nil, port=nil, opts={})
103
104
  if host.nil? and ENV.has_key?('MONGODB_URI')
104
- parser = URIParser.new ENV['MONGODB_URI'], opts
105
+ parser = URIParser.new ENV['MONGODB_URI']
105
106
  if parser.replicaset?
106
107
  raise MongoArgumentError, "Mongo::Connection.new called with no arguments, but ENV['MONGODB_URI'] implies a replica set."
107
108
  end
108
- opts = parser.connection_options
109
+ opts = parser.connection_options.merge! opts
109
110
  @host_to_try = [parser.host, parser.port]
110
111
  elsif host.is_a?(String)
111
112
  @host_to_try = [host, (port || DEFAULT_PORT).to_i]
@@ -126,6 +127,10 @@ module Mongo
126
127
  @primary = nil
127
128
  @primary_pool = nil
128
129
 
130
+ # Not set for direct connection
131
+ @tag_sets = {}
132
+ @acceptable_latency = 15
133
+
129
134
  check_opts(opts)
130
135
  setup(opts)
131
136
  end
@@ -173,8 +178,8 @@ module Mongo
173
178
  #
174
179
  # @return [Mongo::Connection, Mongo::ReplSetConnection]
175
180
  def self.from_uri(uri = ENV['MONGODB_URI'], extra_opts={})
176
- parser = URIParser.new uri, extra_opts
177
- parser.connection
181
+ parser = URIParser.new uri
182
+ parser.connection(extra_opts)
178
183
  end
179
184
 
180
185
  # The host name used for this connection.
@@ -206,7 +211,7 @@ module Mongo
206
211
  #
207
212
  # @return [Boolean]
208
213
  def locked?
209
- self['admin']['$cmd.sys.inprog'].find_one['fsyncLock'] == 1
214
+ [1, true].include? self['admin']['$cmd.sys.inprog'].find_one['fsyncLock']
210
215
  end
211
216
 
212
217
  # Unlock a previously fsync-locked mongod process.
@@ -312,7 +317,13 @@ module Mongo
312
317
  # @return [Mongo::DB]
313
318
  #
314
319
  # @core databases db-instance_method
315
- def db(db_name, opts={})
320
+ def db(db_name=nil, opts={})
321
+ if !db_name && uri = ENV['MONGODB_URI']
322
+ db_name = uri[%r{/([^/\?]+)(\?|$)}, 1]
323
+ end
324
+
325
+ db_name ||= DEFAULT_DB_NAME
326
+
316
327
  DB.new(db_name, self, opts)
317
328
  end
318
329
 
@@ -327,6 +338,15 @@ module Mongo
327
338
  DB.new(db_name, self)
328
339
  end
329
340
 
341
+ def refresh
342
+ end
343
+
344
+ def pin_pool(pool)
345
+ end
346
+
347
+ def unpin_pool(pool)
348
+ end
349
+
330
350
  # Drop a database.
331
351
  #
332
352
  # @param [String] name name of an existing database.
@@ -464,7 +484,7 @@ module Mongo
464
484
  # The value of the read preference.
465
485
  def read_preference
466
486
  if slave_ok?
467
- :secondary
487
+ :secondary_preferred
468
488
  else
469
489
  :primary
470
490
  end
@@ -485,15 +505,9 @@ module Mongo
485
505
  @max_bson_size
486
506
  end
487
507
 
488
- # Prefer primary pool but fall back to secondary
489
- def checkout_best
490
- connect unless connected?
491
- @primary_pool.checkout
492
- end
493
-
494
508
  # Checkout a socket for reading (i.e., a secondary node).
495
509
  # Note: this is overridden in ReplSetConnection.
496
- def checkout_reader
510
+ def checkout_reader(mode=:primary, tag_sets={}, acceptable_latency=15)
497
511
  connect unless connected?
498
512
  @primary_pool.checkout
499
513
  end
@@ -505,38 +519,14 @@ module Mongo
505
519
  @primary_pool.checkout
506
520
  end
507
521
 
508
- # Checkin a socket used for reading.
509
- # Note: this is overridden in ReplSetConnection.
510
- def checkin_reader(socket)
511
- checkin(socket)
512
- end
513
-
514
- # Checkin a socket used for writing.
515
- # Note: this is overridden in ReplSetConnection.
516
- def checkin_writer(socket)
517
- checkin(socket)
518
- end
519
-
520
522
  # Check a socket back into its pool.
523
+ # Note: this is overridden in ReplSetConnection.
521
524
  def checkin(socket)
522
- if @primary_pool && socket
525
+ if @primary_pool && socket && socket.pool
523
526
  socket.pool.checkin(socket)
524
527
  end
525
528
  end
526
529
 
527
- # Excecutes block with the best available socket
528
- def best_available_socket
529
- socket = nil
530
- begin
531
- socket = checkout_best
532
- yield socket
533
- ensure
534
- if socket
535
- socket.pool.checkin(socket)
536
- end
537
- end
538
- end
539
-
540
530
  protected
541
531
 
542
532
  def valid_opts