mongo 1.7.1 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. data/{LICENSE.txt → LICENSE} +0 -0
  2. data/README.md +124 -111
  3. data/Rakefile +9 -325
  4. data/VERSION +1 -0
  5. data/bin/mongo_console +4 -4
  6. data/examples/admin.rb +43 -0
  7. data/examples/capped.rb +22 -0
  8. data/examples/cursor.rb +48 -0
  9. data/examples/gridfs.rb +44 -0
  10. data/examples/index_test.rb +126 -0
  11. data/examples/info.rb +31 -0
  12. data/examples/queries.rb +74 -0
  13. data/examples/replica_set.rb +26 -0
  14. data/examples/simple.rb +25 -0
  15. data/examples/strict.rb +35 -0
  16. data/examples/types.rb +36 -0
  17. data/{test/load → examples/web}/thin/load.rb +3 -1
  18. data/{test/load → examples/web}/unicorn/load.rb +5 -3
  19. data/lib/mongo.rb +8 -10
  20. data/lib/mongo/collection.rb +134 -114
  21. data/lib/mongo/cursor.rb +21 -14
  22. data/lib/mongo/db.rb +30 -28
  23. data/lib/mongo/exceptions.rb +1 -1
  24. data/lib/mongo/gridfs/grid.rb +8 -7
  25. data/lib/mongo/gridfs/grid_ext.rb +1 -1
  26. data/lib/mongo/gridfs/grid_file_system.rb +6 -5
  27. data/lib/mongo/gridfs/grid_io.rb +22 -19
  28. data/lib/mongo/legacy.rb +82 -0
  29. data/lib/mongo/{connection.rb → mongo_client.rb} +82 -61
  30. data/lib/mongo/{repl_set_connection.rb → mongo_replica_set_client.rb} +54 -39
  31. data/lib/mongo/{sharded_connection.rb → mongo_sharded_client.rb} +9 -9
  32. data/lib/mongo/networking.rb +25 -20
  33. data/lib/mongo/util/conversions.rb +1 -1
  34. data/lib/mongo/util/core_ext.rb +1 -1
  35. data/lib/mongo/util/logging.rb +20 -4
  36. data/lib/mongo/util/node.rb +16 -16
  37. data/lib/mongo/util/pool.rb +56 -27
  38. data/lib/mongo/util/pool_manager.rb +28 -27
  39. data/lib/mongo/util/server_version.rb +1 -1
  40. data/lib/mongo/util/sharding_pool_manager.rb +8 -8
  41. data/lib/mongo/util/ssl_socket.rb +1 -5
  42. data/lib/mongo/util/support.rb +24 -8
  43. data/lib/mongo/util/tcp_socket.rb +0 -4
  44. data/lib/mongo/util/uri_parser.rb +54 -38
  45. data/lib/mongo/util/write_concern.rb +67 -0
  46. data/mongo.gemspec +21 -32
  47. data/test/auxillary/{1.4_features.rb → 1.4_feature_test.rb} +4 -5
  48. data/test/auxillary/authentication_test.rb +18 -20
  49. data/test/auxillary/autoreconnect_test.rb +3 -5
  50. data/test/auxillary/fork_test.rb +5 -7
  51. data/test/auxillary/repl_set_auth_test.rb +13 -15
  52. data/test/auxillary/slave_connection_test.rb +8 -7
  53. data/test/auxillary/threaded_authentication_test.rb +15 -17
  54. data/test/bson/binary_test.rb +1 -1
  55. data/test/bson/bson_test.rb +60 -36
  56. data/test/bson/byte_buffer_test.rb +1 -1
  57. data/test/bson/hash_with_indifferent_access_test.rb +2 -2
  58. data/test/bson/json_test.rb +1 -2
  59. data/test/bson/object_id_test.rb +1 -2
  60. data/test/bson/ordered_hash_test.rb +1 -1
  61. data/test/bson/timestamp_test.rb +1 -1
  62. data/test/{collection_test.rb → functional/collection_test.rb} +57 -57
  63. data/test/{connection_test.rb → functional/connection_test.rb} +75 -89
  64. data/test/{conversions_test.rb → functional/conversions_test.rb} +1 -1
  65. data/test/{cursor_fail_test.rb → functional/cursor_fail_test.rb} +3 -29
  66. data/test/{cursor_message_test.rb → functional/cursor_message_test.rb} +1 -1
  67. data/test/{cursor_test.rb → functional/cursor_test.rb} +5 -1
  68. data/test/{db_api_test.rb → functional/db_api_test.rb} +8 -9
  69. data/test/{db_connection_test.rb → functional/db_connection_test.rb} +3 -5
  70. data/test/{db_test.rb → functional/db_test.rb} +13 -13
  71. data/test/{grid_file_system_test.rb → functional/grid_file_system_test.rb} +2 -2
  72. data/test/{grid_io_test.rb → functional/grid_io_test.rb} +6 -6
  73. data/test/{grid_test.rb → functional/grid_test.rb} +4 -10
  74. data/test/{pool_test.rb → functional/pool_test.rb} +1 -1
  75. data/test/functional/safe_test.rb +84 -0
  76. data/test/{support_test.rb → functional/support_test.rb} +1 -1
  77. data/test/{threading_test.rb → functional/threading_test.rb} +9 -9
  78. data/test/{timeout_test.rb → functional/timeout_test.rb} +1 -1
  79. data/test/{uri_test.rb → functional/uri_test.rb} +1 -1
  80. data/test/functional/write_concern_test.rb +104 -0
  81. data/test/replica_set/basic_test.rb +139 -0
  82. data/test/replica_set/client_test.rb +255 -0
  83. data/test/replica_set/complex_connect_test.rb +62 -0
  84. data/test/replica_set/connection_test.rb +255 -0
  85. data/test/{replica_sets → replica_set}/count_test.rb +17 -14
  86. data/test/replica_set/cursor_test.rb +75 -0
  87. data/test/{replica_sets → replica_set}/insert_test.rb +19 -16
  88. data/test/replica_set/query_test.rb +64 -0
  89. data/test/replica_set/refresh_test.rb +153 -0
  90. data/test/{replica_sets → replica_set}/replication_ack_test.rb +21 -17
  91. data/test/sharded_cluster/basic_test.rb +31 -50
  92. data/test/support/hash_with_indifferent_access.rb +1 -1
  93. data/test/test_helper.rb +56 -9
  94. data/test/threading/threading_with_large_pool_test.rb +8 -8
  95. data/test/tools/mongo_config.rb +270 -58
  96. data/test/tools/mongo_config_test.rb +146 -0
  97. data/test/unit/client_test.rb +230 -0
  98. data/test/unit/collection_test.rb +45 -32
  99. data/test/unit/connection_test.rb +82 -74
  100. data/test/unit/cursor_test.rb +14 -6
  101. data/test/unit/db_test.rb +8 -8
  102. data/test/unit/grid_test.rb +11 -11
  103. data/test/unit/node_test.rb +24 -24
  104. data/test/unit/pool_manager_test.rb +13 -13
  105. data/test/unit/pool_test.rb +1 -1
  106. data/test/unit/read_test.rb +21 -26
  107. data/test/unit/safe_test.rb +52 -33
  108. data/test/unit/util_test.rb +55 -0
  109. data/test/unit/write_concern_test.rb +161 -0
  110. metadata +158 -171
  111. data/docs/CREDITS.md +0 -123
  112. data/docs/FAQ.md +0 -116
  113. data/docs/GRID_FS.md +0 -158
  114. data/docs/HISTORY.md +0 -392
  115. data/docs/READ_PREFERENCE.md +0 -99
  116. data/docs/RELEASES.md +0 -54
  117. data/docs/REPLICA_SETS.md +0 -113
  118. data/docs/TAILABLE_CURSORS.md +0 -51
  119. data/docs/TUTORIAL.md +0 -356
  120. data/docs/WRITE_CONCERN.md +0 -31
  121. data/lib/mongo/gridfs/grid_io_fix.rb +0 -38
  122. data/lib/mongo/version.rb +0 -3
  123. data/test/bson/test_helper.rb +0 -30
  124. data/test/replica_sets/basic_test.rb +0 -119
  125. data/test/replica_sets/complex_connect_test.rb +0 -57
  126. data/test/replica_sets/complex_read_preference_test.rb +0 -237
  127. data/test/replica_sets/connect_test.rb +0 -156
  128. data/test/replica_sets/cursor_test.rb +0 -70
  129. data/test/replica_sets/pooled_insert_test.rb +0 -57
  130. data/test/replica_sets/query_test.rb +0 -50
  131. data/test/replica_sets/read_preference_test.rb +0 -234
  132. data/test/replica_sets/refresh_test.rb +0 -156
  133. data/test/replica_sets/refresh_with_threads_test.rb +0 -60
  134. data/test/replica_sets/rs_test_helper.rb +0 -39
  135. data/test/safe_test.rb +0 -68
  136. data/test/sharded_cluster/mongo_config_test.rb +0 -126
  137. data/test/sharded_cluster/sc_test_helper.rb +0 -39
  138. data/test/tools/repl_set_manager.rb +0 -418
@@ -0,0 +1,82 @@
1
+ # encoding: UTF-8
2
+
3
+ # --
4
+ # Copyright (C) 2008-2012 10gen Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ # ++
18
+
19
+ module Mongo
20
+ module LegacyWriteConcern
21
+ @legacy_write_concern = true
22
+
23
+ def safe=(value)
24
+ @write_concern = value
25
+ end
26
+
27
+ def safe
28
+ if @write_concern[:w] == 0
29
+ return false
30
+ elsif @write_concern[:w] == 1
31
+ return true
32
+ else
33
+ return @write_concern
34
+ end
35
+ end
36
+
37
+ def self.from_uri(uri = ENV['MONGODB_URI'], extra_opts={})
38
+ parser = URIParser.new uri
39
+ parser.connection(extra_opts, true)
40
+ end
41
+ end
42
+ end
43
+
44
+ module Mongo
45
+ # @deprecated Use Mongo::MongoClient instead. Support will be removed after v2.0
46
+ class Connection < MongoClient
47
+ include Mongo::LegacyWriteConcern
48
+
49
+ def initialize(host=nil, port=nil, opts={})
50
+ write_concern_from_legacy(opts)
51
+ super
52
+ end
53
+ end
54
+
55
+ # @deprecated Use Mongo::MongoReplicaSetClient instead. Support will be removed after v2.0
56
+ class ReplSetConnection < MongoReplicaSetClient
57
+ include Mongo::LegacyWriteConcern
58
+
59
+ def initialize(*args)
60
+ if args.last.is_a?(Hash)
61
+ opts = args.pop
62
+ write_concern_from_legacy(opts)
63
+ args.push(opts)
64
+ end
65
+ super
66
+ end
67
+ end
68
+
69
+ # @deprecated Use Mongo::MongoShardedClient instead. Support will be removed after v2.0
70
+ class ShardedConnection < MongoShardedClient
71
+ include Mongo::LegacyWriteConcern
72
+
73
+ def initialize(*args)
74
+ if args.last.is_a?(Hash)
75
+ opts = args.pop
76
+ write_concern_from_legacy(opts)
77
+ args.push(opts)
78
+ end
79
+ super
80
+ end
81
+ end
82
+ end
@@ -1,7 +1,7 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  # --
4
- # Copyright (C) 2008-2011 10gen Inc.
4
+ # Copyright (C) 2008-2012 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.
@@ -19,30 +19,44 @@
19
19
  require 'set'
20
20
  require 'socket'
21
21
  require 'thread'
22
+
22
23
  module Mongo
23
24
 
24
25
  # Instantiates and manages self.connections to MongoDB.
25
- class Connection
26
+ class MongoClient
26
27
  include Mongo::Logging
27
28
  include Mongo::Networking
29
+ include Mongo::WriteConcern
28
30
 
29
- TCPSocket = Mongo::TCPSocket
30
- Mutex = ::Mutex
31
- ConditionVariable = ::ConditionVariable
32
-
33
- Thread.abort_on_exception = true
31
+ TCPSocket = Mongo::TCPSocket
32
+ Mutex = ::Mutex
33
+ ConditionVariable = ::ConditionVariable
34
34
 
35
- DEFAULT_HOST = 'localhost'
36
- DEFAULT_PORT = 27017
37
- DEFAULT_DB_NAME = 'test'
38
- GENERIC_OPTS = [:ssl, :auths, :pool_size, :pool_timeout, :timeout, :op_timeout, :connect_timeout, :safe, :logger, :connect]
39
- CONNECTION_OPTS = [:slave_ok]
35
+ DEFAULT_HOST = 'localhost'
36
+ DEFAULT_PORT = 27017
37
+ DEFAULT_DB_NAME = 'test'
38
+ GENERIC_OPTS = [:ssl, :auths, :logger, :connect]
39
+ TIMEOUT_OPTS = [:timeout, :op_timeout, :connect_timeout]
40
+ POOL_OPTS = [:pool_size, :pool_timeout]
41
+ WRITE_CONCERN_OPTS = [:w, :j, :fsync, :wtimeout]
42
+ CLIENT_ONLY_OPTS = [:slave_ok]
40
43
 
41
44
  mongo_thread_local_accessor :connections
42
45
 
43
- attr_reader :logger, :size, :auths, :primary, :safe, :host_to_try,
44
- :pool_size, :connect_timeout, :pool_timeout,
45
- :primary_pool, :socket_class, :op_timeout, :tag_sets, :acceptable_latency
46
+ attr_reader :logger,
47
+ :size,
48
+ :auths,
49
+ :primary,
50
+ :write_concern,
51
+ :host_to_try,
52
+ :pool_size,
53
+ :connect_timeout,
54
+ :pool_timeout,
55
+ :primary_pool,
56
+ :socket_class,
57
+ :op_timeout,
58
+ :tag_sets,
59
+ :acceptable_latency
46
60
 
47
61
  # Create a connection to single MongoDB instance.
48
62
  #
@@ -51,20 +65,20 @@ module Mongo
51
65
  # You may specify whether connection to slave is permitted.
52
66
  # In all cases, the default host is "localhost" and the default port is 27017.
53
67
  #
54
- # If you're connecting to a replica set, you'll need to use ReplSetConnection.new instead.
68
+ # If you're connecting to a replica set, you'll need to use MongoReplicaSetClient.new instead.
55
69
  #
56
70
  # Once connected to a replica set, you can find out which nodes are primary, secondary, and
57
- # arbiters with the corresponding accessors: Connection#primary, Connection#secondaries, and
58
- # Connection#arbiters. This is useful if your application needs to connect manually to nodes other
71
+ # arbiters with the corresponding accessors: MongoClient#primary, MongoClient#secondaries, and
72
+ # MongoClient#arbiters. This is useful if your application needs to connect manually to nodes other
59
73
  # than the primary.
60
74
  #
61
75
  # @param [String, Hash] host
62
76
  # @param [Integer] port specify a port number here if only one host is being specified.
63
77
  #
64
- # @option opts [Boolean, Hash] :safe (false) Set the default safe-mode options
65
- # propogated to DB objects instantiated off of this Connection. This
66
- # default can be overridden upon instantiation of any DB by explicity setting a :safe value
67
- # on initialization.
78
+ # @option opts [Hash] :w (1), :j (false), :wtimeout (false), :fsync (false) Set the default write concern
79
+ # options propagated to DB objects instantiated off of this MongoClient.
80
+ # This default can be overridden upon instantiation of any DB by explicitly setting an options hash
81
+ # on initialization. It can also be overridden at instantiation of a collection or at the time of a write operation.
68
82
  # @option opts [Boolean] :slave_ok (false) Must be set to +true+ when connecting
69
83
  # to a single, slave node.
70
84
  # @option opts [Logger, #debug] :logger (nil) A Logger instance for debugging driver ops. Note that
@@ -81,16 +95,16 @@ module Mongo
81
95
  # @option opts [Boolean] :ssl (false) If true, create the connection to the server using SSL.
82
96
  #
83
97
  # @example localhost, 27017 (or <code>ENV["MONGODB_URI"]</code> if available)
84
- # Mongo::Connection.new
98
+ # MongoClient.new
85
99
  #
86
100
  # @example localhost, 27017
87
- # Mongo::Connection.new("localhost")
101
+ # MongoClient.new("localhost")
88
102
  #
89
103
  # @example localhost, 3000, max 5 self.connections, with max 5 seconds of wait time.
90
- # Mongo::Connection.new("localhost", 3000, :pool_size => 5, :timeout => 5)
104
+ # MongoClient.new("localhost", 3000, :pool_size => 5, :timeout => 5)
91
105
  #
92
106
  # @example localhost, 3000, where this node may be a slave
93
- # Mongo::Connection.new("localhost", 3000, :slave_ok => true)
107
+ # MongoClient.new("localhost", 3000, :slave_ok => true)
94
108
  #
95
109
  # @see http://api.mongodb.org/ruby/current/file.REPLICA_SETS.html Replica sets in Ruby
96
110
  #
@@ -104,25 +118,27 @@ module Mongo
104
118
  if host.nil? and ENV.has_key?('MONGODB_URI')
105
119
  parser = URIParser.new ENV['MONGODB_URI']
106
120
  if parser.replicaset?
107
- raise MongoArgumentError, "Mongo::Connection.new called with no arguments, but ENV['MONGODB_URI'] implies a replica set."
121
+ raise MongoArgumentError, "Mongo::MongoClient.new called with no arguments, but ENV['MONGODB_URI'] implies a replica set."
108
122
  end
109
- opts = parser.connection_options.merge! opts
123
+ opts.merge!(parser.connection_options)
110
124
  @host_to_try = [parser.host, parser.port]
111
- elsif host.is_a?(String)
125
+ elsif host.is_a?(String) && (port || DEFAULT_PORT).respond_to?(:to_i)
112
126
  @host_to_try = [host, (port || DEFAULT_PORT).to_i]
127
+ elsif host || port
128
+ raise MongoArgumentError, "Mongo::MongoClient.new host or port argument error, host:#{host.inspect}, port:#{port.inspect}"
113
129
  else
114
130
  @host_to_try = [DEFAULT_HOST, DEFAULT_PORT]
115
131
  end
116
132
 
117
133
  # Host and port of current master.
118
134
  @host = @port = nil
119
-
135
+
120
136
  # Default maximum BSON object size
121
137
  @max_bson_size = Mongo::DEFAULT_MAX_BSON_SIZE
122
-
138
+
123
139
  # Lock for request ids.
124
140
  @id_lock = Mutex.new
125
-
141
+
126
142
  # Connection pool for primay node
127
143
  @primary = nil
128
144
  @primary_pool = nil
@@ -140,11 +156,11 @@ module Mongo
140
156
  # Initialize a connection to a MongoDB replica set using an array of seed nodes.
141
157
  #
142
158
  # The seed nodes specified will be used on the initial connection to the replica set, but note
143
- # that this list of nodes will be replced by the list of canonical nodes returned by running the
159
+ # that this list of nodes will be replaced by the list of canonical nodes returned by running the
144
160
  # is_master command on the replica set.
145
161
  #
146
162
  # @param nodes [Array] An array of arrays, each of which specifies a host and port.
147
- # @param opts [Hash] Any of the available options that can be passed to Connection.new.
163
+ # @param opts [Hash] Any of the available options that can be passed to MongoClient.new.
148
164
  #
149
165
  # @option opts [String] :rs_name (nil) The name of the replica set to connect to. An exception will be
150
166
  # raised if unable to connect to a replica set with this name.
@@ -152,31 +168,32 @@ module Mongo
152
168
  # to send reads to.
153
169
  #
154
170
  # @example
155
- # Mongo::Connection.multi([["db1.example.com", 27017], ["db2.example.com", 27017]])
171
+ # Mongo::MongoClient.multi([["db1.example.com", 27017], ["db2.example.com", 27017]])
156
172
  #
157
173
  # @example This connection will read from a random secondary node.
158
- # Mongo::Connection.multi([["db1.example.com", 27017], ["db2.example.com", 27017], ["db3.example.com", 27017]],
174
+ # Mongo::MongoClient.multi([["db1.example.com", 27017], ["db2.example.com", 27017], ["db3.example.com", 27017]],
159
175
  # :read_secondary => true)
160
176
  #
161
- # @return [Mongo::Connection]
177
+ # @return [Mongo::MongoClient]
162
178
  #
163
179
  # @deprecated
164
180
  def self.multi(nodes, opts={})
165
- warn "Connection.multi is now deprecated and will be removed in v2.0. Please use ReplSetConnection.new instead."
181
+ warn "MongoClient.multi is now deprecated and will be removed in v2.0. Please use MongoReplicaSetClient.new instead."
166
182
 
167
- ReplSetConnection.new(*(nodes+[opts]))
183
+ MongoReplicaSetClient.new(*(nodes+[opts]))
168
184
  end
169
185
 
170
186
  # Initialize a connection to MongoDB using the MongoDB URI spec.
171
187
  #
172
- # Since Connection.new cannot be used with any <code>ENV["MONGODB_URI"]</code> that has multiple hosts (implying a replicaset), you may use this when the type of your connection varies by environment and should be determined solely from <code>ENV["MONGODB_URI"]</code>.
188
+ # Since MongoClient.new cannot be used with any <code>ENV["MONGODB_URI"]</code> that has multiple hosts (implying a replicaset),
189
+ # you may use this when the type of your connection varies by environment and should be determined solely from <code>ENV["MONGODB_URI"]</code>.
173
190
  #
174
191
  # @param uri [String]
175
192
  # A string of the format mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/database]
176
193
  #
177
- # @param opts Any of the options available for Connection.new
194
+ # @param opts Any of the options available for MongoClient.new
178
195
  #
179
- # @return [Mongo::Connection, Mongo::ReplSetConnection]
196
+ # @return [Mongo::MongoClient, Mongo::MongoReplicaSetClient]
180
197
  def self.from_uri(uri = ENV['MONGODB_URI'], extra_opts={})
181
198
  parser = URIParser.new uri
182
199
  parser.connection(extra_opts)
@@ -223,7 +240,7 @@ module Mongo
223
240
 
224
241
  # Apply each of the saved database authentications.
225
242
  #
226
- # @return [Boolean] returns true if authentications exist and succeeed, false
243
+ # @return [Boolean] returns true if authentications exist and succeeds, false
227
244
  # if none exists.
228
245
  #
229
246
  # @raise [AuthenticationError] raises an exception if any one
@@ -239,11 +256,11 @@ module Mongo
239
256
 
240
257
  # Save an authentication to this connection. When connecting,
241
258
  # the connection will attempt to re-authenticate on every db
242
- # specificed in the list of auths. This method is called automatically
259
+ # specified in the list of auths. This method is called automatically
243
260
  # by DB#authenticate.
244
261
  #
245
262
  # Note: this method will not actually issue an authentication command. To do that,
246
- # either run Connection#apply_saved_authentication or DB#authenticate.
263
+ # either run MongoClient#apply_saved_authentication or DB#authenticate.
247
264
  #
248
265
  # @param [String] db_name
249
266
  # @param [String] username
@@ -274,7 +291,7 @@ module Mongo
274
291
  end
275
292
  end
276
293
 
277
- # Remove all authenication information stored in this connection.
294
+ # Remove all authentication information stored in this connection.
278
295
  #
279
296
  # @return [true] this operation return true because it always succeeds.
280
297
  def clear_auths
@@ -506,21 +523,21 @@ module Mongo
506
523
  end
507
524
 
508
525
  # Checkout a socket for reading (i.e., a secondary node).
509
- # Note: this is overridden in ReplSetConnection.
526
+ # Note: this is overridden in MongoReplicaSetClient.
510
527
  def checkout_reader(mode=:primary, tag_sets={}, acceptable_latency=15)
511
528
  connect unless connected?
512
529
  @primary_pool.checkout
513
530
  end
514
531
 
515
532
  # Checkout a socket for writing (i.e., a primary node).
516
- # Note: this is overridden in ReplSetConnection.
533
+ # Note: this is overridden in MongoReplicaSetClient.
517
534
  def checkout_writer
518
535
  connect unless connected?
519
536
  @primary_pool.checkout
520
537
  end
521
538
 
522
539
  # Check a socket back into its pool.
523
- # Note: this is overridden in ReplSetConnection.
540
+ # Note: this is overridden in MongoReplicaSetClient.
524
541
  def checkin(socket)
525
542
  if @primary_pool && socket && socket.pool
526
543
  socket.pool.checkin(socket)
@@ -530,7 +547,11 @@ module Mongo
530
547
  protected
531
548
 
532
549
  def valid_opts
533
- GENERIC_OPTS + CONNECTION_OPTS
550
+ GENERIC_OPTS +
551
+ CLIENT_ONLY_OPTS +
552
+ POOL_OPTS +
553
+ WRITE_CONCERN_OPTS +
554
+ TIMEOUT_OPTS
534
555
  end
535
556
 
536
557
  def check_opts(opts)
@@ -544,10 +565,10 @@ module Mongo
544
565
  # Parse option hash
545
566
  def setup(opts)
546
567
  # slave_ok can be true only if one node is specified
547
- @slave_ok = opts[:slave_ok]
548
-
568
+ @slave_ok = opts.delete(:slave_ok)
569
+
549
570
  # Determine whether to use SSL.
550
- @ssl = opts.fetch(:ssl, false)
571
+ @ssl = opts.delete(:ssl)
551
572
  if @ssl
552
573
  @socket_class = Mongo::SSLSocket
553
574
  else
@@ -555,27 +576,27 @@ module Mongo
555
576
  end
556
577
 
557
578
  # Authentication objects
558
- @auths = opts.fetch(:auths, [])
579
+ @auths = opts.delete(:auths) || []
559
580
 
560
581
  # Pool size and timeout.
561
- @pool_size = opts[:pool_size] || 1
582
+ @pool_size = opts.delete(:pool_size) || 1
562
583
  if opts[:timeout]
563
584
  warn "The :timeout option has been deprecated " +
564
585
  "and will be removed in the 2.0 release. Use :pool_timeout instead."
565
586
  end
566
- @pool_timeout = opts[:pool_timeout] || opts[:timeout] || 5.0
587
+ @pool_timeout = opts.delete(:pool_timeout) || opts.delete(:timeout) || 5.0
567
588
 
568
589
  # Timeout on socket read operation.
569
- @op_timeout = opts[:op_timeout] || nil
590
+ @op_timeout = opts.delete(:op_timeout) || nil
570
591
 
571
592
  # Timeout on socket connect.
572
- @connect_timeout = opts[:connect_timeout] || nil
573
-
574
- # Global safe option. This is false by default.
575
- @safe = opts[:safe] || false
593
+ @connect_timeout = opts.delete(:connect_timeout) || nil
576
594
 
577
595
  @logger = opts.fetch(:logger, nil)
578
596
 
597
+ # Connection level write concern options.
598
+ @write_concern = get_write_concern(opts)
599
+
579
600
  if @logger
580
601
  write_logging_startup_message
581
602
  end
@@ -1,7 +1,7 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  # --
4
- # Copyright (C) 2008-2011 10gen Inc.
4
+ # Copyright (C) 2008-2012 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.
@@ -19,29 +19,43 @@
19
19
  module Mongo
20
20
 
21
21
  # Instantiates and manages connections to a MongoDB replica set.
22
- class ReplSetConnection < Connection
23
-
24
- REPL_SET_OPTS = [:read, :refresh_mode, :refresh_interval, :read_secondary,
25
- :rs_name, :name, :tag_sets, :secondary_acceptable_latency_ms]
26
-
27
- attr_reader :replica_set_name, :seeds, :refresh_interval, :refresh_mode,
28
- :refresh_version, :manager, :tag_sets, :acceptable_latency
22
+ class MongoReplicaSetClient < MongoClient
23
+
24
+ REPL_SET_OPTS = [
25
+ :read,
26
+ :refresh_mode,
27
+ :refresh_interval,
28
+ :read_secondary,
29
+ :rs_name,
30
+ :name,
31
+ :tag_sets,
32
+ :secondary_acceptable_latency_ms
33
+ ]
34
+
35
+ attr_reader :replica_set_name,
36
+ :seeds,
37
+ :refresh_interval,
38
+ :refresh_mode,
39
+ :refresh_version,
40
+ :manager,
41
+ :tag_sets,
42
+ :acceptable_latency
29
43
 
30
44
  # Create a connection to a MongoDB replica set.
31
45
  #
32
46
  # If no args are provided, it will check <code>ENV["MONGODB_URI"]</code>.
33
47
  #
34
48
  # Once connected to a replica set, you can find out which nodes are primary, secondary, and
35
- # arbiters with the corresponding accessors: Connection#primary, Connection#secondaries, and
36
- # Connection#arbiters. This is useful if your application needs to connect manually to nodes other
49
+ # arbiters with the corresponding accessors: MongoClient#primary, MongoClient#secondaries, and
50
+ # MongoClient#arbiters. This is useful if your application needs to connect manually to nodes other
37
51
  # than the primary.
38
52
  #
39
53
  # @overload initialize(seeds=ENV["MONGODB_URI"], opts={})
40
54
  # @param [Array<String>, Array<Array(String, Integer)>] seeds
41
55
  #
42
- # @option opts [Boolean, Hash] :safe (false) Set the default safe-mode options
43
- # propagated to DB objects instantiated off of this Connection. This
44
- # default can be overridden upon instantiation of any DB by explicitly setting a :safe value
56
+ # @option opts [Hash] :w (1), :j (false), :wtimeout (false), :fsync (false) Set the default write concern
57
+ # propagated to DB objects instantiated off of this MongoReplicaSetClient. This
58
+ # default can be overridden upon instantiation of any DB by explicitly setting write concern values
45
59
  # on initialization.
46
60
  # @option opts [:primary, :primary_preferred, :secondary, :secondary_preferred, :nearest] :read_preference (:primary)
47
61
  # A "read preference" determines the candidate replica set members to which a query or command can be sent.
@@ -75,18 +89,18 @@ module Mongo
75
89
  # will always trigger a complete refresh. This option is useful when you want to add new nodes
76
90
  # or remove replica set nodes not currently in use by the driver.
77
91
  # @option opts [Integer] :refresh_interval (90) If :refresh_mode is enabled, this is the number of seconds
78
- # between calls to check the replica set's state.
92
+ # between calls to check the replica set's state.
79
93
  # @note the number of seed nodes does not have to be equal to the number of replica set members.
80
94
  # The purpose of seed nodes is to permit the driver to find at least one replica set member even if a member is down.
81
95
  #
82
96
  # @example Connect to a replica set and provide two seed nodes.
83
- # Mongo::ReplSetConnection.new(['localhost:30000', 'localhost:30001'])
97
+ # MongoReplicaSetClient.new(['localhost:30000', 'localhost:30001'])
84
98
  #
85
99
  # @example Connect to a replica set providing two seed nodes and ensuring a connection to the replica set named 'prod':
86
- # Mongo::ReplSetConnection.new(['localhost:30000', 'localhost:30001'], :name => 'prod')
100
+ # MongoReplicaSetClient.new(['localhost:30000', 'localhost:30001'], :name => 'prod')
87
101
  #
88
102
  # @example Connect to a replica set providing two seed nodes and allowing reads from a secondary node:
89
- # Mongo::ReplSetConnection.new(['localhost:30000', 'localhost:30001'], :read => :secondary)
103
+ # MongoReplicaSetClient.new(['localhost:30000', 'localhost:30001'], :read => :secondary)
90
104
  #
91
105
  # @see http://api.mongodb.org/ruby/current/file.REPLICA_SETS.html Replica sets in Ruby
92
106
  #
@@ -96,23 +110,24 @@ module Mongo
96
110
  def initialize(*args)
97
111
  opts = args.last.is_a?(Hash) ? args.pop : {}
98
112
  nodes = args
113
+ nodes = nodes.flatten(1) if nodes.first.is_a?(Array) && nodes.first.first.is_a?(Array)
99
114
 
100
115
  if nodes.empty? and ENV.has_key?('MONGODB_URI')
101
116
  parser = URIParser.new ENV['MONGODB_URI']
102
117
  if parser.direct?
103
- raise MongoArgumentError, "Mongo::ReplSetConnection.new called with no arguments, but ENV['MONGODB_URI'] implies a direct connection."
118
+ raise MongoArgumentError, "Mongo::MongoReplicaSetClient.new called with no arguments, but ENV['MONGODB_URI'] implies a direct connection."
104
119
  end
105
120
  opts = parser.connection_options.merge! opts
106
121
  nodes = [parser.nodes]
107
122
  end
108
123
 
109
124
  unless nodes.length > 0
110
- raise MongoArgumentError, "A ReplSetConnection requires at least one seed node."
125
+ raise MongoArgumentError, "A MongoReplicaSetClient requires at least one seed node."
111
126
  end
112
127
 
113
128
  # This is temporary until support for the old format is dropped
114
129
  if nodes.first.last.is_a?(Integer)
115
- warn "Initiating a ReplSetConnection with seeds passed as individual [host, port] array arguments is deprecated."
130
+ warn "Initiating a MongoReplicaSetClient with seeds passed as individual [host, port] array arguments is deprecated."
116
131
  warn "Please specify hosts as an array of 'host:port' strings; the old format will be removed in v2.0"
117
132
  @seeds = nodes
118
133
  else
@@ -149,11 +164,11 @@ module Mongo
149
164
  end
150
165
 
151
166
  def valid_opts
152
- GENERIC_OPTS + REPL_SET_OPTS
167
+ super + REPL_SET_OPTS - CLIENT_ONLY_OPTS
153
168
  end
154
169
 
155
170
  def inspect
156
- "<Mongo::ReplSetConnection:0x#{self.object_id.to_s(16)} @seeds=#{@seeds.inspect} " +
171
+ "<Mongo::MongoReplicaSetClient:0x#{self.object_id.to_s(16)} @seeds=#{@seeds.inspect} " +
157
172
  "@connected=#{@connected}>"
158
173
  end
159
174
 
@@ -184,7 +199,7 @@ module Mongo
184
199
  # Determine whether a replica set refresh is
185
200
  # required. If so, run a hard refresh. You can
186
201
  # force a hard refresh by running
187
- # ReplSetConnection#hard_refresh!
202
+ # MongoReplicaSetClient#hard_refresh!
188
203
  #
189
204
  # @return [Boolean] +true+ unless a hard refresh
190
205
  # is run and the refresh lock can't be acquired.
@@ -233,7 +248,7 @@ module Mongo
233
248
 
234
249
  # @deprecated
235
250
  def connecting?
236
- warn "ReplSetConnection#connecting? is deprecated and will be removed in v2.0."
251
+ warn "MongoReplicaSetClient#connecting? is deprecated and will be removed in v2.0."
237
252
  false
238
253
  end
239
254
 
@@ -252,8 +267,8 @@ module Mongo
252
267
  end
253
268
 
254
269
  def nodes
255
- warn "ReplSetConnection#nodes is DEPRECATED and will be removed in v2.0. " +
256
- "Please use ReplSetConnection#seeds instead."
270
+ warn "MongoReplicaSetClient#nodes is DEPRECATED and will be removed in v2.0. " +
271
+ "Please use MongoReplicaSetClient#seeds instead."
257
272
  @seeds
258
273
  end
259
274
 
@@ -291,8 +306,8 @@ module Mongo
291
306
  # @deprecated
292
307
  def reset_connection
293
308
  close
294
- warn "ReplSetConnection#reset_connection is now deprecated and will be removed in v2.0. " +
295
- "Use ReplSetConnection#close instead."
309
+ warn "MongoReplicaSetClient#reset_connection is now deprecated and will be removed in v2.0. " +
310
+ "Use MongoReplicaSetClient#close instead."
296
311
  end
297
312
 
298
313
  # Returns +true+ if it's okay to read from a secondary node.
@@ -335,7 +350,7 @@ module Mongo
335
350
  end
336
351
  socket
337
352
  end
338
-
353
+
339
354
  def checkout_reader(mode=@read, tag_sets=@tag_sets, acceptable_latency=@acceptable_latency)
340
355
  checkout do
341
356
  pool = read_pool(mode, tag_sets, acceptable_latency)
@@ -436,8 +451,8 @@ module Mongo
436
451
  # Parse option hash
437
452
  def setup(opts)
438
453
  # Refresh
439
- @refresh_mode = opts.fetch(:refresh_mode, false)
440
- @refresh_interval = opts.fetch(:refresh_interval, 90)
454
+ @refresh_mode = opts.delete(:refresh_mode) || false
455
+ @refresh_interval = opts.delete(:refresh_interval) || 90
441
456
 
442
457
  if @refresh_mode && @refresh_interval < 60
443
458
  @refresh_interval = 60 unless ENV['TEST_MODE'] = 'TRUE'
@@ -455,30 +470,30 @@ module Mongo
455
470
  if opts[:read_secondary]
456
471
  warn ":read_secondary options has now been deprecated and will " +
457
472
  "be removed in driver v2.0. Use the :read option instead."
458
- @read_secondary = opts.fetch(:read_secondary, false)
473
+ @read_secondary = opts.delete(:read_secondary) || false
459
474
  @read = :secondary_preferred
460
475
  else
461
- @read = opts.fetch(:read, :primary)
476
+ @read = opts.delete(:read) || :primary
462
477
  Mongo::Support.validate_read_preference(@read)
463
478
  end
464
479
 
465
- @tag_sets = opts.fetch(:tag_sets, [])
466
- @acceptable_latency = opts.fetch(:secondary_acceptable_latency_ms, 15)
480
+ @tag_sets = opts.delete(:tag_sets) || []
481
+ @acceptable_latency = opts.delete(:secondary_acceptable_latency_ms) || 15
467
482
 
468
483
  # Replica set name
469
484
  if opts[:rs_name]
470
485
  warn ":rs_name option has been deprecated and will be removed in v2.0. " +
471
486
  "Please use :name instead."
472
- @replica_set_name = opts[:rs_name]
487
+ @replica_set_name = opts.delete(:rs_name)
473
488
  else
474
- @replica_set_name = opts[:name]
489
+ @replica_set_name = opts.delete(:name)
475
490
  end
476
491
 
477
- opts[:connect_timeout] = opts[:connect_timeout] || 30
492
+ opts[:connect_timeout] = opts.delete(:connect_timeout) || 30
478
493
 
479
494
  super opts
480
495
  end
481
-
496
+
482
497
  def prune_managers
483
498
  @old_managers.each do |manager|
484
499
  if manager != @manager