mongo 1.7.1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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