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.
- data/README.md +13 -13
- data/Rakefile +7 -10
- data/docs/{GridFS.md → GRID_FS.md} +0 -0
- data/docs/HISTORY.md +16 -0
- data/docs/READ_PREFERENCE.md +70 -10
- data/docs/TUTORIAL.md +2 -2
- data/lib/mongo.rb +2 -0
- data/lib/mongo/collection.rb +62 -11
- data/lib/mongo/connection.rb +31 -41
- data/lib/mongo/cursor.rb +42 -86
- data/lib/mongo/db.rb +10 -8
- data/lib/mongo/networking.rb +30 -65
- data/lib/mongo/repl_set_connection.rb +91 -170
- data/lib/mongo/sharded_connection.rb +221 -0
- data/lib/mongo/util/node.rb +29 -36
- data/lib/mongo/util/pool.rb +10 -3
- data/lib/mongo/util/pool_manager.rb +77 -90
- data/lib/mongo/util/sharding_pool_manager.rb +143 -0
- data/lib/mongo/util/support.rb +22 -2
- data/lib/mongo/util/tcp_socket.rb +10 -15
- data/lib/mongo/util/uri_parser.rb +17 -10
- data/lib/mongo/version.rb +1 -1
- data/test/collection_test.rb +133 -1
- data/test/connection_test.rb +50 -4
- data/test/db_api_test.rb +3 -3
- data/test/db_test.rb +6 -1
- data/test/replica_sets/basic_test.rb +3 -6
- data/test/replica_sets/complex_connect_test.rb +14 -2
- data/test/replica_sets/complex_read_preference_test.rb +237 -0
- data/test/replica_sets/connect_test.rb +47 -67
- data/test/replica_sets/count_test.rb +1 -1
- data/test/replica_sets/cursor_test.rb +70 -0
- data/test/replica_sets/read_preference_test.rb +171 -118
- data/test/replica_sets/refresh_test.rb +3 -3
- data/test/replica_sets/refresh_with_threads_test.rb +2 -2
- data/test/replica_sets/rs_test_helper.rb +2 -2
- data/test/sharded_cluster/basic_test.rb +112 -0
- data/test/sharded_cluster/mongo_config_test.rb +126 -0
- data/test/sharded_cluster/sc_test_helper.rb +39 -0
- data/test/test_helper.rb +3 -3
- data/test/threading/threading_with_large_pool_test.rb +1 -1
- data/test/tools/mongo_config.rb +307 -0
- data/test/tools/repl_set_manager.rb +12 -12
- data/test/unit/collection_test.rb +1 -1
- data/test/unit/cursor_test.rb +11 -6
- data/test/unit/db_test.rb +4 -0
- data/test/unit/grid_test.rb +2 -0
- data/test/unit/read_test.rb +39 -8
- data/test/uri_test.rb +4 -8
- 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](
|
29
|
-
2. [Replica Sets in Ruby](
|
30
|
-
3. [Write Concern in Ruby](
|
31
|
-
4. [Tailable Cursors in Ruby](
|
32
|
-
5. [Read Preference in Ruby](
|
33
|
-
6. [GridFS in Ruby](
|
34
|
-
7. [Frequently Asked Questions](
|
35
|
-
8. [History](
|
36
|
-
9. [Release plan](
|
37
|
-
10. [Credits](
|
38
|
-
|
39
|
-
Here's a quick code sample. Again, see the [MongoDB Ruby Tutorial](
|
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](
|
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.
|
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
|
176
|
+
system "yardoc -o #{out} --title MongoRuby-#{Mongo::VERSION}"
|
180
177
|
end
|
181
178
|
|
182
179
|
namespace :jenkins do
|
File without changes
|
data/docs/HISTORY.md
CHANGED
@@ -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
|
|
data/docs/READ_PREFERENCE.md
CHANGED
@@ -1,15 +1,22 @@
|
|
1
1
|
# Read Preference in Ruby
|
2
2
|
|
3
|
-
##
|
3
|
+
## About Read Preference
|
4
4
|
|
5
|
-
|
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
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
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
|
-
##
|
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
|
-
|
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.
|
data/docs/TUTORIAL.md
CHANGED
@@ -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(
|
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 '
|
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
|
|
data/lib/mongo.rb
CHANGED
@@ -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'
|
data/lib/mongo/collection.rb
CHANGED
@@ -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']
|
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,
|
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,
|
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
|
data/lib/mongo/connection.rb
CHANGED
@@ -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']
|
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
|
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']
|
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
|
-
:
|
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
|