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.
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +124 -111
- data/Rakefile +9 -325
- data/VERSION +1 -0
- data/bin/mongo_console +4 -4
- data/examples/admin.rb +43 -0
- data/examples/capped.rb +22 -0
- data/examples/cursor.rb +48 -0
- data/examples/gridfs.rb +44 -0
- data/examples/index_test.rb +126 -0
- data/examples/info.rb +31 -0
- data/examples/queries.rb +74 -0
- data/examples/replica_set.rb +26 -0
- data/examples/simple.rb +25 -0
- data/examples/strict.rb +35 -0
- data/examples/types.rb +36 -0
- data/{test/load → examples/web}/thin/load.rb +3 -1
- data/{test/load → examples/web}/unicorn/load.rb +5 -3
- data/lib/mongo.rb +8 -10
- data/lib/mongo/collection.rb +134 -114
- data/lib/mongo/cursor.rb +21 -14
- data/lib/mongo/db.rb +30 -28
- data/lib/mongo/exceptions.rb +1 -1
- data/lib/mongo/gridfs/grid.rb +8 -7
- data/lib/mongo/gridfs/grid_ext.rb +1 -1
- data/lib/mongo/gridfs/grid_file_system.rb +6 -5
- data/lib/mongo/gridfs/grid_io.rb +22 -19
- data/lib/mongo/legacy.rb +82 -0
- data/lib/mongo/{connection.rb → mongo_client.rb} +82 -61
- data/lib/mongo/{repl_set_connection.rb → mongo_replica_set_client.rb} +54 -39
- data/lib/mongo/{sharded_connection.rb → mongo_sharded_client.rb} +9 -9
- data/lib/mongo/networking.rb +25 -20
- data/lib/mongo/util/conversions.rb +1 -1
- data/lib/mongo/util/core_ext.rb +1 -1
- data/lib/mongo/util/logging.rb +20 -4
- data/lib/mongo/util/node.rb +16 -16
- data/lib/mongo/util/pool.rb +56 -27
- data/lib/mongo/util/pool_manager.rb +28 -27
- data/lib/mongo/util/server_version.rb +1 -1
- data/lib/mongo/util/sharding_pool_manager.rb +8 -8
- data/lib/mongo/util/ssl_socket.rb +1 -5
- data/lib/mongo/util/support.rb +24 -8
- data/lib/mongo/util/tcp_socket.rb +0 -4
- data/lib/mongo/util/uri_parser.rb +54 -38
- data/lib/mongo/util/write_concern.rb +67 -0
- data/mongo.gemspec +21 -32
- data/test/auxillary/{1.4_features.rb → 1.4_feature_test.rb} +4 -5
- data/test/auxillary/authentication_test.rb +18 -20
- data/test/auxillary/autoreconnect_test.rb +3 -5
- data/test/auxillary/fork_test.rb +5 -7
- data/test/auxillary/repl_set_auth_test.rb +13 -15
- data/test/auxillary/slave_connection_test.rb +8 -7
- data/test/auxillary/threaded_authentication_test.rb +15 -17
- data/test/bson/binary_test.rb +1 -1
- data/test/bson/bson_test.rb +60 -36
- data/test/bson/byte_buffer_test.rb +1 -1
- data/test/bson/hash_with_indifferent_access_test.rb +2 -2
- data/test/bson/json_test.rb +1 -2
- data/test/bson/object_id_test.rb +1 -2
- data/test/bson/ordered_hash_test.rb +1 -1
- data/test/bson/timestamp_test.rb +1 -1
- data/test/{collection_test.rb → functional/collection_test.rb} +57 -57
- data/test/{connection_test.rb → functional/connection_test.rb} +75 -89
- data/test/{conversions_test.rb → functional/conversions_test.rb} +1 -1
- data/test/{cursor_fail_test.rb → functional/cursor_fail_test.rb} +3 -29
- data/test/{cursor_message_test.rb → functional/cursor_message_test.rb} +1 -1
- data/test/{cursor_test.rb → functional/cursor_test.rb} +5 -1
- data/test/{db_api_test.rb → functional/db_api_test.rb} +8 -9
- data/test/{db_connection_test.rb → functional/db_connection_test.rb} +3 -5
- data/test/{db_test.rb → functional/db_test.rb} +13 -13
- data/test/{grid_file_system_test.rb → functional/grid_file_system_test.rb} +2 -2
- data/test/{grid_io_test.rb → functional/grid_io_test.rb} +6 -6
- data/test/{grid_test.rb → functional/grid_test.rb} +4 -10
- data/test/{pool_test.rb → functional/pool_test.rb} +1 -1
- data/test/functional/safe_test.rb +84 -0
- data/test/{support_test.rb → functional/support_test.rb} +1 -1
- data/test/{threading_test.rb → functional/threading_test.rb} +9 -9
- data/test/{timeout_test.rb → functional/timeout_test.rb} +1 -1
- data/test/{uri_test.rb → functional/uri_test.rb} +1 -1
- data/test/functional/write_concern_test.rb +104 -0
- data/test/replica_set/basic_test.rb +139 -0
- data/test/replica_set/client_test.rb +255 -0
- data/test/replica_set/complex_connect_test.rb +62 -0
- data/test/replica_set/connection_test.rb +255 -0
- data/test/{replica_sets → replica_set}/count_test.rb +17 -14
- data/test/replica_set/cursor_test.rb +75 -0
- data/test/{replica_sets → replica_set}/insert_test.rb +19 -16
- data/test/replica_set/query_test.rb +64 -0
- data/test/replica_set/refresh_test.rb +153 -0
- data/test/{replica_sets → replica_set}/replication_ack_test.rb +21 -17
- data/test/sharded_cluster/basic_test.rb +31 -50
- data/test/support/hash_with_indifferent_access.rb +1 -1
- data/test/test_helper.rb +56 -9
- data/test/threading/threading_with_large_pool_test.rb +8 -8
- data/test/tools/mongo_config.rb +270 -58
- data/test/tools/mongo_config_test.rb +146 -0
- data/test/unit/client_test.rb +230 -0
- data/test/unit/collection_test.rb +45 -32
- data/test/unit/connection_test.rb +82 -74
- data/test/unit/cursor_test.rb +14 -6
- data/test/unit/db_test.rb +8 -8
- data/test/unit/grid_test.rb +11 -11
- data/test/unit/node_test.rb +24 -24
- data/test/unit/pool_manager_test.rb +13 -13
- data/test/unit/pool_test.rb +1 -1
- data/test/unit/read_test.rb +21 -26
- data/test/unit/safe_test.rb +52 -33
- data/test/unit/util_test.rb +55 -0
- data/test/unit/write_concern_test.rb +161 -0
- metadata +158 -171
- data/docs/CREDITS.md +0 -123
- data/docs/FAQ.md +0 -116
- data/docs/GRID_FS.md +0 -158
- data/docs/HISTORY.md +0 -392
- data/docs/READ_PREFERENCE.md +0 -99
- data/docs/RELEASES.md +0 -54
- data/docs/REPLICA_SETS.md +0 -113
- data/docs/TAILABLE_CURSORS.md +0 -51
- data/docs/TUTORIAL.md +0 -356
- data/docs/WRITE_CONCERN.md +0 -31
- data/lib/mongo/gridfs/grid_io_fix.rb +0 -38
- data/lib/mongo/version.rb +0 -3
- data/test/bson/test_helper.rb +0 -30
- data/test/replica_sets/basic_test.rb +0 -119
- data/test/replica_sets/complex_connect_test.rb +0 -57
- data/test/replica_sets/complex_read_preference_test.rb +0 -237
- data/test/replica_sets/connect_test.rb +0 -156
- data/test/replica_sets/cursor_test.rb +0 -70
- data/test/replica_sets/pooled_insert_test.rb +0 -57
- data/test/replica_sets/query_test.rb +0 -50
- data/test/replica_sets/read_preference_test.rb +0 -234
- data/test/replica_sets/refresh_test.rb +0 -156
- data/test/replica_sets/refresh_with_threads_test.rb +0 -60
- data/test/replica_sets/rs_test_helper.rb +0 -39
- data/test/safe_test.rb +0 -68
- data/test/sharded_cluster/mongo_config_test.rb +0 -126
- data/test/sharded_cluster/sc_test_helper.rb +0 -39
- data/test/tools/repl_set_manager.rb +0 -418
data/examples/strict.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
|
3
|
+
require 'mongo'
|
4
|
+
|
5
|
+
include Mongo
|
6
|
+
|
7
|
+
host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
|
8
|
+
port = ENV['MONGO_RUBY_DRIVER_PORT'] || MongoClient::DEFAULT_PORT
|
9
|
+
|
10
|
+
puts "Connecting to #{host}:#{port}"
|
11
|
+
db = MongoClient.new(host, port).db('ruby-mongo-examples')
|
12
|
+
|
13
|
+
db.drop_collection('does-not-exist')
|
14
|
+
db.create_collection('test')
|
15
|
+
|
16
|
+
db.strict = true
|
17
|
+
|
18
|
+
begin
|
19
|
+
# Can't reference collection that does not exist
|
20
|
+
db.collection('does-not-exist')
|
21
|
+
puts "error: expected exception"
|
22
|
+
rescue => ex
|
23
|
+
puts "expected exception: #{ex}"
|
24
|
+
end
|
25
|
+
|
26
|
+
begin
|
27
|
+
# Can't create collection that already exists
|
28
|
+
db.create_collection('test')
|
29
|
+
puts "error: expected exception"
|
30
|
+
rescue => ex
|
31
|
+
puts "expected exception: #{ex}"
|
32
|
+
end
|
33
|
+
|
34
|
+
db.strict = false
|
35
|
+
db.drop_collection('test')
|
data/examples/types.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
|
3
|
+
require 'mongo'
|
4
|
+
require 'pp'
|
5
|
+
|
6
|
+
include Mongo
|
7
|
+
|
8
|
+
host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
|
9
|
+
port = ENV['MONGO_RUBY_DRIVER_PORT'] || MongoClient::DEFAULT_PORT
|
10
|
+
|
11
|
+
puts "Connecting to #{host}:#{port}"
|
12
|
+
db = MongoClient.new(host, port).db('ruby-mongo-examples')
|
13
|
+
coll = db.collection('test')
|
14
|
+
|
15
|
+
# Remove all records, if any
|
16
|
+
coll.remove
|
17
|
+
|
18
|
+
# Insert record with all sorts of values
|
19
|
+
coll.insert('array' => [1, 2, 3],
|
20
|
+
'string' => 'hello',
|
21
|
+
'hash' => {'a' => 1, 'b' => 2},
|
22
|
+
'date' => Time.now, # milliseconds only; microseconds are not stored
|
23
|
+
'oid' => ObjectID.new,
|
24
|
+
'binary' => Binary.new([1, 2, 3]),
|
25
|
+
'int' => 42,
|
26
|
+
'float' => 33.33333,
|
27
|
+
'regex' => /foobar/i,
|
28
|
+
'boolean' => true,
|
29
|
+
'where' => Code.new('this.x == 3'),
|
30
|
+
'dbref' => DBRef.new(coll.name, ObjectID.new),
|
31
|
+
'null' => nil,
|
32
|
+
'symbol' => :zildjian)
|
33
|
+
|
34
|
+
pp coll.find().next_document
|
35
|
+
|
36
|
+
coll.remove
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', '..', '..', 'lib', 'mongo')
|
2
2
|
require 'logger'
|
3
3
|
|
4
|
-
|
4
|
+
include Mongo
|
5
|
+
|
6
|
+
$con = MongoReplicaSetClient.new(['localhost:30000', 'localhost:30001'], :read => :secondary, :refresh_mode => :sync, :refresh_interval => 30)
|
5
7
|
$db = $con['foo']
|
6
8
|
|
7
9
|
class Load < Sinatra::Base
|
@@ -1,7 +1,9 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'mongo')
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'mongo')
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
include Mongo
|
4
|
+
|
5
|
+
$client = MongoClient.new('localhost', 27017)
|
6
|
+
$db = $client['foo']
|
5
7
|
|
6
8
|
class Load < Sinatra::Base
|
7
9
|
|
data/lib/mongo.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
#
|
3
3
|
# --
|
4
|
-
# Copyright (C) 2008-
|
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.
|
@@ -16,8 +16,6 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
# ++
|
18
18
|
|
19
|
-
require 'mongo/version'
|
20
|
-
|
21
19
|
module Mongo
|
22
20
|
ASCENDING = 1
|
23
21
|
DESCENDING = -1
|
@@ -54,6 +52,7 @@ require 'bson'
|
|
54
52
|
|
55
53
|
require 'mongo/util/conversions'
|
56
54
|
require 'mongo/util/support'
|
55
|
+
require 'mongo/util/write_concern'
|
57
56
|
require 'mongo/util/core_ext'
|
58
57
|
require 'mongo/util/logging'
|
59
58
|
require 'mongo/util/node'
|
@@ -65,18 +64,17 @@ require 'mongo/util/ssl_socket'
|
|
65
64
|
require 'mongo/util/tcp_socket'
|
66
65
|
require 'mongo/util/uri_parser'
|
67
66
|
|
68
|
-
|
67
|
+
|
69
68
|
require 'mongo/networking'
|
70
|
-
require 'mongo/
|
71
|
-
require 'mongo/
|
72
|
-
require 'mongo/
|
69
|
+
require 'mongo/mongo_client'
|
70
|
+
require 'mongo/mongo_replica_set_client'
|
71
|
+
require 'mongo/mongo_sharded_client'
|
72
|
+
require 'mongo/legacy'
|
73
|
+
require 'mongo/collection'
|
73
74
|
require 'mongo/cursor'
|
74
75
|
require 'mongo/db'
|
75
76
|
require 'mongo/exceptions'
|
76
77
|
require 'mongo/gridfs/grid_ext'
|
77
78
|
require 'mongo/gridfs/grid'
|
78
79
|
require 'mongo/gridfs/grid_io'
|
79
|
-
if RUBY_PLATFORM =~ /java/
|
80
|
-
require 'mongo/gridfs/grid_io_fix'
|
81
|
-
end
|
82
80
|
require 'mongo/gridfs/grid_file_system'
|
data/lib/mongo/collection.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
# --
|
4
|
-
# Copyright (C) 2008-
|
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.
|
@@ -20,11 +20,18 @@ module Mongo
|
|
20
20
|
# A named collection of documents in a database.
|
21
21
|
class Collection
|
22
22
|
include Mongo::Logging
|
23
|
+
include Mongo::WriteConcern
|
23
24
|
|
24
|
-
attr_reader :db,
|
25
|
+
attr_reader :db,
|
26
|
+
:name,
|
27
|
+
:pk_factory,
|
28
|
+
:hint,
|
29
|
+
:write_concern
|
25
30
|
|
26
31
|
# Read Preference
|
27
|
-
attr_accessor :read_preference,
|
32
|
+
attr_accessor :read_preference,
|
33
|
+
:tag_sets,
|
34
|
+
:acceptable_latency
|
28
35
|
|
29
36
|
# Initialize a collection object.
|
30
37
|
#
|
@@ -34,10 +41,10 @@ module Mongo
|
|
34
41
|
# @option opts [:create_pk] :pk (BSON::ObjectId) A primary key factory to use
|
35
42
|
# other than the default BSON::ObjectId.
|
36
43
|
#
|
37
|
-
# @option opts [
|
38
|
-
# for insert
|
39
|
-
# value is provided, the default
|
40
|
-
#
|
44
|
+
# @option opts [Hash] :w, :j, :wtimeout, :fsync Set the default write concern
|
45
|
+
# for +insert+, +update+, and +remove+ method called on this Collection instance. If no
|
46
|
+
# value is provided, the default values set on this instance's DB will be used. These option
|
47
|
+
# values can be overridden for any invocation of +insert+, +update+, or +remove+.
|
41
48
|
# @option options [:primary, :secondary] :read The default read preference for queries
|
42
49
|
# initiates from this connection object. If +:secondary+ is chosen, reads will be sent
|
43
50
|
# to one of the closest available secondary nodes. If a secondary node cannot be located, the
|
@@ -91,16 +98,16 @@ module Mongo
|
|
91
98
|
@connection = @db.connection
|
92
99
|
@logger = @connection.logger
|
93
100
|
@cache_time = @db.cache_time
|
94
|
-
@cache
|
101
|
+
@cache = Hash.new(0)
|
95
102
|
unless pk_factory
|
96
|
-
@
|
103
|
+
@write_concern = get_write_concern(opts, db)
|
97
104
|
if value = opts[:read]
|
98
105
|
Mongo::Support.validate_read_preference(value)
|
99
106
|
else
|
100
107
|
value = @db.read_preference
|
101
108
|
end
|
102
|
-
@read_preference
|
103
|
-
@tag_sets
|
109
|
+
@read_preference = value.is_a?(Hash) ? value.dup : value
|
110
|
+
@tag_sets = opts.fetch(:tag_sets, @db.tag_sets)
|
104
111
|
@acceptable_latency = opts.fetch(:acceptable_latency, @db.acceptable_latency)
|
105
112
|
end
|
106
113
|
@pk_factory = pk_factory || opts[:pk] || BSON::ObjectId
|
@@ -169,7 +176,7 @@ module Mongo
|
|
169
176
|
# to Ruby 1.8).
|
170
177
|
#
|
171
178
|
# @option opts [Array, Hash] :fields field names that should be returned in the result
|
172
|
-
# set ("_id" will be included unless
|
179
|
+
# set ("_id" will be included unless explicitly excluded). By limiting results to a certain subset of fields,
|
173
180
|
# you can cut down on network traffic and decoding time. If using a Hash, keys should be field
|
174
181
|
# names and values should be either 1 or 0, depending on whether you want to include or exclude
|
175
182
|
# the given field.
|
@@ -194,13 +201,14 @@ module Mongo
|
|
194
201
|
# @option opts [Boolean] :timeout (true) when +true+, the returned cursor will be subject to
|
195
202
|
# the normal cursor timeout behavior of the mongod process. When +false+, the returned cursor will
|
196
203
|
# never timeout. Note that disabling timeout will only work when #find is invoked with a block.
|
197
|
-
# This is to prevent any
|
204
|
+
# This is to prevent any inadvertent failure to close the cursor, as the cursor is explicitly
|
198
205
|
# closed when block code finishes.
|
199
206
|
# @option opts [Integer] :max_scan (nil) Limit the number of items to scan on both collection scans and indexed queries..
|
200
207
|
# @option opts [Boolean] :show_disk_loc (false) Return the disk location of each query result (for debugging).
|
201
208
|
# @option opts [Boolean] :return_key (false) Return the index key used to obtain the result (for debugging).
|
202
|
-
# @option opts [Block] :transformer (nil) a block for
|
209
|
+
# @option opts [Block] :transformer (nil) a block for transforming returned documents.
|
203
210
|
# This is normally used by object mappers to convert each returned document to an instance of a class.
|
211
|
+
# @option opts [String] :comment (nil) a comment to include in profiling logs
|
204
212
|
#
|
205
213
|
# @raise [ArgumentError]
|
206
214
|
# if timeout is set to false and find is not invoked in a block
|
@@ -210,22 +218,23 @@ module Mongo
|
|
210
218
|
#
|
211
219
|
# @core find find-instance_method
|
212
220
|
def find(selector={}, opts={})
|
213
|
-
opts
|
214
|
-
fields
|
215
|
-
fields
|
216
|
-
skip
|
217
|
-
limit
|
218
|
-
sort
|
219
|
-
hint
|
220
|
-
snapshot
|
221
|
-
batch_size
|
222
|
-
timeout
|
223
|
-
max_scan
|
224
|
-
return_key
|
225
|
-
transformer
|
226
|
-
show_disk_loc
|
227
|
-
|
228
|
-
|
221
|
+
opts = opts.dup
|
222
|
+
fields = opts.delete(:fields)
|
223
|
+
fields = ["_id"] if fields && fields.empty?
|
224
|
+
skip = opts.delete(:skip) || skip || 0
|
225
|
+
limit = opts.delete(:limit) || 0
|
226
|
+
sort = opts.delete(:sort)
|
227
|
+
hint = opts.delete(:hint)
|
228
|
+
snapshot = opts.delete(:snapshot)
|
229
|
+
batch_size = opts.delete(:batch_size)
|
230
|
+
timeout = (opts.delete(:timeout) == false) ? false : true
|
231
|
+
max_scan = opts.delete(:max_scan)
|
232
|
+
return_key = opts.delete(:return_key)
|
233
|
+
transformer = opts.delete(:transformer)
|
234
|
+
show_disk_loc = opts.delete(:show_disk_loc)
|
235
|
+
comment = opts.delete(:comment)
|
236
|
+
read = opts.delete(:read) || @read_preference
|
237
|
+
tag_sets = opts.delete(:tag_sets) || @tag_sets
|
229
238
|
acceptable_latency = opts.delete(:acceptable_latency) || @acceptable_latency
|
230
239
|
|
231
240
|
if timeout == false && !block_given?
|
@@ -241,27 +250,31 @@ module Mongo
|
|
241
250
|
raise RuntimeError, "Unknown options [#{opts.inspect}]" unless opts.empty?
|
242
251
|
|
243
252
|
cursor = Cursor.new(self, {
|
244
|
-
:selector
|
245
|
-
:fields
|
246
|
-
:skip
|
247
|
-
:limit
|
248
|
-
:order
|
249
|
-
:hint
|
250
|
-
:snapshot
|
251
|
-
:timeout
|
252
|
-
:batch_size
|
253
|
-
:transformer
|
254
|
-
:max_scan
|
255
|
-
:show_disk_loc
|
256
|
-
:return_key
|
257
|
-
:read
|
258
|
-
:tag_sets
|
253
|
+
:selector => selector,
|
254
|
+
:fields => fields,
|
255
|
+
:skip => skip,
|
256
|
+
:limit => limit,
|
257
|
+
:order => sort,
|
258
|
+
:hint => hint,
|
259
|
+
:snapshot => snapshot,
|
260
|
+
:timeout => timeout,
|
261
|
+
:batch_size => batch_size,
|
262
|
+
:transformer => transformer,
|
263
|
+
:max_scan => max_scan,
|
264
|
+
:show_disk_loc => show_disk_loc,
|
265
|
+
:return_key => return_key,
|
266
|
+
:read => read,
|
267
|
+
:tag_sets => tag_sets,
|
268
|
+
:comment => comment,
|
259
269
|
:acceptable_latency => acceptable_latency
|
260
270
|
})
|
261
271
|
|
262
272
|
if block_given?
|
263
|
-
|
264
|
-
|
273
|
+
begin
|
274
|
+
yield cursor
|
275
|
+
ensure
|
276
|
+
cursor.close
|
277
|
+
end
|
265
278
|
nil
|
266
279
|
else
|
267
280
|
cursor
|
@@ -306,20 +319,23 @@ module Mongo
|
|
306
319
|
#
|
307
320
|
# @return [ObjectId] the _id of the saved document.
|
308
321
|
#
|
309
|
-
# @option opts [
|
310
|
-
#
|
311
|
-
#
|
312
|
-
#
|
313
|
-
#
|
322
|
+
# @option opts [Hash] :w, :j, :wtimeout, :fsync Set the write concern for this operation.
|
323
|
+
# :w > 0 will run a +getlasterror+ command on the database to report any assertion.
|
324
|
+
# :j will confirm a write has been committed to the journal,
|
325
|
+
# :wtimeout specifies how long to wait for write confirmation,
|
326
|
+
# :fsync will confirm that a write has been fsynced.
|
327
|
+
# Options provided here will override any write concern options set on this collection,
|
328
|
+
# its database object, or the current connection. See the options
|
329
|
+
# for +DB#get_last_error+.
|
314
330
|
#
|
315
|
-
# @raise [OperationFailure]
|
331
|
+
# @raise [Mongo::OperationFailure] will be raised iff :w > 0 and the operation fails.
|
316
332
|
def save(doc, opts={})
|
317
333
|
if doc.has_key?(:_id) || doc.has_key?('_id')
|
318
334
|
id = doc[:_id] || doc['_id']
|
319
|
-
update({:_id => id}, doc, :upsert => true
|
335
|
+
update({:_id => id}, doc, opts.merge!({:upsert => true}))
|
320
336
|
id
|
321
337
|
else
|
322
|
-
insert(doc,
|
338
|
+
insert(doc, opts)
|
323
339
|
end
|
324
340
|
end
|
325
341
|
|
@@ -335,31 +351,34 @@ module Mongo
|
|
335
351
|
# 2nd, a list of invalid documents.
|
336
352
|
# Return this result format only when :collect_on_error is true.
|
337
353
|
#
|
338
|
-
# @option opts [
|
339
|
-
#
|
340
|
-
#
|
341
|
-
#
|
342
|
-
#
|
343
|
-
#
|
344
|
-
#
|
354
|
+
# @option opts [Hash] :w, :j, :wtimeout, :fsync Set the write concern for this operation.
|
355
|
+
# :w > 0 will run a +getlasterror+ command on the database to report any assertion.
|
356
|
+
# :j will confirm a write has been committed to the journal,
|
357
|
+
# :wtimeout specifies how long to wait for write confirmation,
|
358
|
+
# :fsync will confirm that a write has been fsynced.
|
359
|
+
# Options provided here will override any write concern options set on this collection,
|
360
|
+
# its database object, or the current connection. See the options
|
361
|
+
# for +DB#get_last_error+.
|
345
362
|
#
|
346
363
|
# @option opts [Boolean] :continue_on_error (+false+) If true, then
|
347
364
|
# continue a bulk insert even if one of the documents inserted
|
348
365
|
# triggers a database assertion (as in a duplicate insert, for instance).
|
349
|
-
# If not
|
366
|
+
# If not acknowledging writes, the list of ids returned will
|
350
367
|
# include the object ids of all documents attempted on insert, even
|
351
|
-
# if some are rejected on error. When
|
352
|
-
#
|
368
|
+
# if some are rejected on error. When acknowledging writes, any error will raise an
|
369
|
+
# OperationFailure exception.
|
353
370
|
# MongoDB v2.0+.
|
354
371
|
# @option opts [Boolean] :collect_on_error (+false+) if true, then
|
355
372
|
# collects invalid documents as an array. Note that this option changes the result format.
|
356
373
|
#
|
374
|
+
# @raise [Mongo::OperationFailure] will be raised iff :w > 0 and the operation fails.
|
375
|
+
#
|
357
376
|
# @core insert insert-instance_method
|
358
377
|
def insert(doc_or_docs, opts={})
|
359
378
|
doc_or_docs = [doc_or_docs] unless doc_or_docs.is_a?(Array)
|
360
379
|
doc_or_docs.collect! { |doc| @pk_factory.create_pk(doc) }
|
361
|
-
|
362
|
-
result = insert_documents(doc_or_docs, @name, true,
|
380
|
+
write_concern = get_write_concern(opts, self)
|
381
|
+
result = insert_documents(doc_or_docs, @name, true, write_concern, opts)
|
363
382
|
result.size > 1 ? result : result.first
|
364
383
|
end
|
365
384
|
alias_method :<<, :insert
|
@@ -369,12 +388,14 @@ module Mongo
|
|
369
388
|
# @param [Hash] selector
|
370
389
|
# If specified, only matching documents will be removed.
|
371
390
|
#
|
372
|
-
# @option opts [
|
373
|
-
#
|
374
|
-
#
|
375
|
-
#
|
376
|
-
#
|
377
|
-
#
|
391
|
+
# @option opts [Hash] :w, :j, :wtimeout, :fsync Set the write concern for this operation.
|
392
|
+
# :w > 0 will run a +getlasterror+ command on the database to report any assertion.
|
393
|
+
# :j will confirm a write has been committed to the journal,
|
394
|
+
# :wtimeout specifies how long to wait for write confirmation,
|
395
|
+
# :fsync will confirm that a write has been fsynced.
|
396
|
+
# Options provided here will override any write concern options set on this collection,
|
397
|
+
# its database object, or the current connection. See the options
|
398
|
+
# for +DB#get_last_error+.
|
378
399
|
#
|
379
400
|
# @example remove all documents from the 'users' collection:
|
380
401
|
# users.remove
|
@@ -383,24 +404,22 @@ module Mongo
|
|
383
404
|
# @example remove only documents that have expired:
|
384
405
|
# users.remove({:expire => {"$lte" => Time.now}})
|
385
406
|
#
|
386
|
-
# @return [Hash, true] Returns a Hash containing the last error object if
|
407
|
+
# @return [Hash, true] Returns a Hash containing the last error object if acknowledging writes
|
387
408
|
# Otherwise, returns true.
|
388
409
|
#
|
389
|
-
# @raise [Mongo::OperationFailure]
|
390
|
-
# and the operation fails.
|
410
|
+
# @raise [Mongo::OperationFailure] will be raised iff :w > 0 and the operation fails.
|
391
411
|
#
|
392
412
|
# @core remove remove-instance_method
|
393
413
|
def remove(selector={}, opts={})
|
394
|
-
|
395
|
-
safe = opts.fetch(:safe, @safe)
|
414
|
+
write_concern = get_write_concern(opts, self)
|
396
415
|
message = BSON::ByteBuffer.new("\0\0\0\0")
|
397
416
|
BSON::BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}")
|
398
417
|
message.put_int(0)
|
399
418
|
message.put_binary(BSON::BSON_CODER.serialize(selector, false, true, @connection.max_bson_size).to_s)
|
400
419
|
|
401
420
|
instrument(:remove, :database => @db.name, :collection => @name, :selector => selector) do
|
402
|
-
if
|
403
|
-
@connection.
|
421
|
+
if Mongo::WriteConcern.gle?(write_concern)
|
422
|
+
@connection.send_message_with_gle(Mongo::Constants::OP_DELETE, message, @db.name, nil, write_concern)
|
404
423
|
else
|
405
424
|
@connection.send_message(Mongo::Constants::OP_DELETE, message)
|
406
425
|
true
|
@@ -422,20 +441,24 @@ module Mongo
|
|
422
441
|
# @option opts [Boolean] :upsert (+false+) if true, performs an upsert (update or insert)
|
423
442
|
# @option opts [Boolean] :multi (+false+) update all documents matching the selector, as opposed to
|
424
443
|
# just the first matching document. Note: only works in MongoDB 1.1.3 or later.
|
425
|
-
# @option opts [
|
426
|
-
#
|
427
|
-
# will
|
428
|
-
#
|
429
|
-
#
|
430
|
-
#
|
431
|
-
#
|
432
|
-
#
|
444
|
+
# @option opts [Hash] :w, :j, :wtimeout, :fsync Set the write concern for this operation.
|
445
|
+
# :w > 0 will run a +getlasterror+ command on the database to report any assertion.
|
446
|
+
# :j will confirm a write has been committed to the journal,
|
447
|
+
# :wtimeout specifies how long to wait for write confirmation,
|
448
|
+
# :fsync will confirm that a write has been fsynced.
|
449
|
+
# Options provided here will override any write concern options set on this collection,
|
450
|
+
# its database object, or the current connection. See the options
|
451
|
+
# for +DB#get_last_error+.
|
452
|
+
#
|
453
|
+
# @return [Hash, true] Returns a Hash containing the last error object if acknowledging writes.
|
433
454
|
# Otherwise, returns true.
|
434
455
|
#
|
456
|
+
# @raise [Mongo::OperationFailure] will be raised iff :w > 0 and the operation fails.
|
457
|
+
#
|
435
458
|
# @core update update-instance_method
|
436
459
|
def update(selector, document, opts={})
|
437
460
|
# Initial byte is 0.
|
438
|
-
|
461
|
+
write_concern = get_write_concern(opts, self)
|
439
462
|
message = BSON::ByteBuffer.new("\0\0\0\0")
|
440
463
|
BSON::BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}")
|
441
464
|
update_options = 0
|
@@ -450,8 +473,8 @@ module Mongo
|
|
450
473
|
message.put_binary(BSON::BSON_CODER.serialize(document, check_keys, true, @connection.max_bson_size).to_s)
|
451
474
|
|
452
475
|
instrument(:update, :database => @db.name, :collection => @name, :selector => selector, :document => document) do
|
453
|
-
if
|
454
|
-
@connection.
|
476
|
+
if Mongo::WriteConcern.gle?(write_concern)
|
477
|
+
@connection.send_message_with_gle(Mongo::Constants::OP_UPDATE, message, @db.name, nil, write_concern)
|
455
478
|
else
|
456
479
|
@connection.send_message(Mongo::Constants::OP_UPDATE, message)
|
457
480
|
end
|
@@ -502,18 +525,17 @@ module Mongo
|
|
502
525
|
# @core indexes create_index-instance_method
|
503
526
|
def create_index(spec, opts={})
|
504
527
|
opts[:dropDups] = opts[:drop_dups] if opts[:drop_dups]
|
505
|
-
field_spec
|
506
|
-
opts
|
507
|
-
name
|
508
|
-
name
|
509
|
-
|
528
|
+
field_spec = parse_index_spec(spec)
|
529
|
+
opts = opts.dup
|
530
|
+
name = opts.delete(:name) || generate_index_name(field_spec)
|
531
|
+
name = name.to_s if name
|
510
532
|
generate_indexes(field_spec, name, opts)
|
511
533
|
name
|
512
534
|
end
|
513
535
|
|
514
536
|
# Calls create_index and sets a flag to not do so again for another X minutes.
|
515
537
|
# this time can be specified as an option when initializing a Mongo::DB object as options[:cache_time]
|
516
|
-
# Any changes to an index will be
|
538
|
+
# Any changes to an index will be propagated through regardless of cache time (e.g., a change of index direction)
|
517
539
|
#
|
518
540
|
# The parameters and options for this methods are the same as those for Collection#create_index.
|
519
541
|
#
|
@@ -528,12 +550,11 @@ module Mongo
|
|
528
550
|
#
|
529
551
|
# @return [String] the name of the index.
|
530
552
|
def ensure_index(spec, opts={})
|
531
|
-
now
|
553
|
+
now = Time.now.utc.to_i
|
532
554
|
opts[:dropDups] = opts[:drop_dups] if opts[:drop_dups]
|
533
|
-
field_spec
|
534
|
-
|
535
|
-
name
|
536
|
-
name = name.to_s if name
|
555
|
+
field_spec = parse_index_spec(spec)
|
556
|
+
name = opts[:name] || generate_index_name(field_spec)
|
557
|
+
name = name.to_s if name
|
537
558
|
|
538
559
|
if !@cache[name] || @cache[name] <= now
|
539
560
|
generate_indexes(field_spec, name, opts)
|
@@ -594,7 +615,7 @@ module Mongo
|
|
594
615
|
|
595
616
|
@db.command(cmd)['value']
|
596
617
|
end
|
597
|
-
|
618
|
+
|
598
619
|
# Perform an aggregation using the aggregation framework on the current collection.
|
599
620
|
# @note Aggregate requires server version >= 2.1.1
|
600
621
|
# @note Field References: Within an expression, field names must be quoted and prefixed by a dollar sign ($).
|
@@ -603,13 +624,13 @@ module Mongo
|
|
603
624
|
# coll.aggregate([ {"$project" => {"last_name" => 1, "first_name" => 1 }}, {"$match" => {"last_name" => "Jones"}} ])
|
604
625
|
#
|
605
626
|
# @param [Array] pipeline Should be a single array of pipeline operator hashes.
|
606
|
-
#
|
627
|
+
#
|
607
628
|
# '$project' Reshapes a document stream by including fields, excluding fields, inserting computed fields,
|
608
629
|
# renaming fields,or creating/populating fields that hold sub-documents.
|
609
630
|
#
|
610
631
|
# '$match' Query-like interface for filtering documents out of the aggregation pipeline.
|
611
632
|
#
|
612
|
-
# '$limit' Restricts the number of documents that pass through the
|
633
|
+
# '$limit' Restricts the number of documents that pass through the pipeline.
|
613
634
|
#
|
614
635
|
# '$skip' Skips over the specified number of documents and passes the rest along the pipeline.
|
615
636
|
#
|
@@ -636,10 +657,10 @@ module Mongo
|
|
636
657
|
unless Mongo::Support.ok?(result)
|
637
658
|
raise Mongo::OperationFailure, "aggregate failed: #{result['errmsg']}"
|
638
659
|
end
|
639
|
-
|
660
|
+
|
640
661
|
return result["result"]
|
641
662
|
end
|
642
|
-
|
663
|
+
|
643
664
|
# Perform a map-reduce operation on the current collection.
|
644
665
|
#
|
645
666
|
# @param [String, BSON::Code] map a map function, written in JavaScript.
|
@@ -655,7 +676,7 @@ module Mongo
|
|
655
676
|
# @option opts [String] :out (nil) a valid output type. In versions of MongoDB prior to v1.7.6,
|
656
677
|
# this option takes the name of a collection for the output results. In versions 1.7.6 and later,
|
657
678
|
# this option specifies the output type. See the core docs for available output types.
|
658
|
-
# @option opts [Boolean] :keeptemp (false) if true, the generated collection will be persisted. The
|
679
|
+
# @option opts [Boolean] :keeptemp (false) if true, the generated collection will be persisted. The default
|
659
680
|
# is false. Note that this option has no effect is versions of MongoDB > v1.7.6.
|
660
681
|
# @option opts [Boolean ] :verbose (false) if true, provides statistics on job execution time.
|
661
682
|
# @option opts [Boolean] :raw (false) if true, return the raw result object from the map_reduce command, and not
|
@@ -841,11 +862,10 @@ module Mongo
|
|
841
862
|
# @return [Array] an array of distinct values.
|
842
863
|
def distinct(key, query=nil)
|
843
864
|
raise MongoArgumentError unless [String, Symbol].include?(key.class)
|
844
|
-
command
|
865
|
+
command = BSON::OrderedHash.new
|
845
866
|
command[:distinct] = @name
|
846
867
|
command[:key] = key.to_s
|
847
868
|
command[:query] = query
|
848
|
-
|
849
869
|
@db.command(command)["values"]
|
850
870
|
end
|
851
871
|
|
@@ -977,7 +997,7 @@ module Mongo
|
|
977
997
|
selector.merge!(opts)
|
978
998
|
|
979
999
|
begin
|
980
|
-
insert_documents([selector], Mongo::DB::SYSTEM_INDEX_COLLECTION, false,
|
1000
|
+
insert_documents([selector], Mongo::DB::SYSTEM_INDEX_COLLECTION, false, {:w => 1})
|
981
1001
|
|
982
1002
|
rescue Mongo::OperationFailure => e
|
983
1003
|
if selector[:dropDups] && e.message =~ /^11000/
|
@@ -994,7 +1014,7 @@ module Mongo
|
|
994
1014
|
# Sends a Mongo::Constants::OP_INSERT message to the database.
|
995
1015
|
# Takes an array of +documents+, an optional +collection_name+, and a
|
996
1016
|
# +check_keys+ setting.
|
997
|
-
def insert_documents(documents, collection_name=@name, check_keys=true,
|
1017
|
+
def insert_documents(documents, collection_name=@name, check_keys=true, write_concern={}, flags={})
|
998
1018
|
if flags[:continue_on_error]
|
999
1019
|
message = BSON::ByteBuffer.new
|
1000
1020
|
message.put_int(1)
|
@@ -1026,8 +1046,8 @@ module Mongo
|
|
1026
1046
|
raise InvalidOperation, "Exceded maximum insert size of 16,777,216 bytes" if message.size > @connection.max_bson_size
|
1027
1047
|
|
1028
1048
|
instrument(:insert, :database => @db.name, :collection => collection_name, :documents => documents) do
|
1029
|
-
if
|
1030
|
-
@connection.
|
1049
|
+
if Mongo::WriteConcern.gle?(write_concern)
|
1050
|
+
@connection.send_message_with_gle(Mongo::Constants::OP_INSERT, message, @db.name, nil, write_concern)
|
1031
1051
|
else
|
1032
1052
|
@connection.send_message(Mongo::Constants::OP_INSERT, message)
|
1033
1053
|
end
|