mongo 1.7.1 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/lib/mongo/cursor.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
# Copyright (C) 2008-
|
3
|
+
# Copyright (C) 2008-2012 10gen Inc.
|
4
4
|
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
@@ -26,7 +26,8 @@ module Mongo
|
|
26
26
|
attr_reader :collection, :selector, :fields,
|
27
27
|
:order, :hint, :snapshot, :timeout,
|
28
28
|
:full_collection_name, :transformer,
|
29
|
-
:options, :cursor_id, :show_disk_loc
|
29
|
+
:options, :cursor_id, :show_disk_loc,
|
30
|
+
:comment
|
30
31
|
|
31
32
|
# Create a new cursor.
|
32
33
|
#
|
@@ -38,7 +39,6 @@ module Mongo
|
|
38
39
|
# @core cursors constructor_details
|
39
40
|
def initialize(collection, opts={})
|
40
41
|
@cursor_id = nil
|
41
|
-
|
42
42
|
@db = collection.db
|
43
43
|
@collection = collection
|
44
44
|
@connection = @db.connection
|
@@ -55,6 +55,7 @@ module Mongo
|
|
55
55
|
@max_scan = opts.fetch(:max_scan, nil)
|
56
56
|
@return_key = opts.fetch(:return_key, nil)
|
57
57
|
@show_disk_loc = opts.fetch(:show_disk_loc, nil)
|
58
|
+
@comment = opts[:comment]
|
58
59
|
|
59
60
|
# Wire-protocol settings
|
60
61
|
@fields = convert_fields_for_query(opts[:fields])
|
@@ -209,9 +210,7 @@ module Mongo
|
|
209
210
|
# @raise [InvalidSortValueError] if the specified order is invalid.
|
210
211
|
def sort(order, direction=nil)
|
211
212
|
check_modifiable
|
212
|
-
|
213
213
|
order = [[order, direction]] unless direction.nil?
|
214
|
-
|
215
214
|
@order = order
|
216
215
|
self
|
217
216
|
end
|
@@ -229,7 +228,6 @@ module Mongo
|
|
229
228
|
def limit(number_to_return=nil)
|
230
229
|
return @limit unless number_to_return
|
231
230
|
check_modifiable
|
232
|
-
|
233
231
|
@limit = number_to_return
|
234
232
|
self
|
235
233
|
end
|
@@ -255,7 +253,7 @@ module Mongo
|
|
255
253
|
#
|
256
254
|
# Note that the batch size will take effect only on queries
|
257
255
|
# where the number to be returned is greater than 100.
|
258
|
-
#
|
256
|
+
#
|
259
257
|
# This can not override MongoDB's limit on the amount of data it will
|
260
258
|
# return to the client. Depending on server version this can be 4-16mb.
|
261
259
|
#
|
@@ -276,7 +274,7 @@ module Mongo
|
|
276
274
|
end
|
277
275
|
|
278
276
|
# Iterate over each document in this cursor, yielding it to the given
|
279
|
-
# block.
|
277
|
+
# block, if provided. An Enumerator is returned if no block is given.
|
280
278
|
#
|
281
279
|
# Iterating over an entire cursor will close it.
|
282
280
|
#
|
@@ -287,11 +285,18 @@ module Mongo
|
|
287
285
|
# puts doc['user']
|
288
286
|
# end
|
289
287
|
def each
|
290
|
-
|
291
|
-
|
288
|
+
if block_given? || !defined?(Enumerator)
|
289
|
+
while doc = self.next
|
290
|
+
yield doc
|
291
|
+
end
|
292
|
+
else
|
293
|
+
Enumerator.new do |yielder|
|
294
|
+
while doc = self.next
|
295
|
+
yielder.yield doc
|
296
|
+
end
|
297
|
+
end
|
292
298
|
end
|
293
299
|
end
|
294
|
-
|
295
300
|
# Receive all the documents from this cursor as an array of hashes.
|
296
301
|
#
|
297
302
|
# Notes:
|
@@ -411,7 +416,8 @@ module Mongo
|
|
411
416
|
:timeout => @timeout,
|
412
417
|
:max_scan => @max_scan,
|
413
418
|
:return_key => @return_key,
|
414
|
-
:show_disk_loc => @show_disk_loc
|
419
|
+
:show_disk_loc => @show_disk_loc,
|
420
|
+
:comment => @comment }
|
415
421
|
end
|
416
422
|
|
417
423
|
# Clean output for inspect.
|
@@ -528,7 +534,7 @@ module Mongo
|
|
528
534
|
ensure
|
529
535
|
checkin_socket(sock) unless @socket
|
530
536
|
end
|
531
|
-
|
537
|
+
|
532
538
|
@returned += @n_received
|
533
539
|
@cache += results
|
534
540
|
close_cursor_if_query_complete
|
@@ -583,13 +589,14 @@ module Mongo
|
|
583
589
|
spec['$maxScan'] = @max_scan if @max_scan
|
584
590
|
spec['$returnKey'] = true if @return_key
|
585
591
|
spec['$showDiskLoc'] = true if @show_disk_loc
|
592
|
+
spec['$comment'] = @comment if @comment
|
586
593
|
spec
|
587
594
|
end
|
588
595
|
|
589
596
|
# Returns true if the query contains order, explain, hint, or snapshot.
|
590
597
|
def query_contains_special_fields?
|
591
598
|
@order || @explain || @hint || @snapshot || @show_disk_loc ||
|
592
|
-
@max_scan || @return_key
|
599
|
+
@max_scan || @return_key || @comment
|
593
600
|
end
|
594
601
|
|
595
602
|
def close_cursor_if_query_complete
|
data/lib/mongo/db.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.
|
@@ -23,13 +23,14 @@ module Mongo
|
|
23
23
|
|
24
24
|
# A MongoDB database.
|
25
25
|
class DB
|
26
|
+
include Mongo::WriteConcern
|
26
27
|
|
27
|
-
SYSTEM_NAMESPACE_COLLECTION =
|
28
|
-
SYSTEM_INDEX_COLLECTION
|
29
|
-
SYSTEM_PROFILE_COLLECTION
|
30
|
-
SYSTEM_USER_COLLECTION
|
31
|
-
SYSTEM_JS_COLLECTION
|
32
|
-
SYSTEM_COMMAND_COLLECTION
|
28
|
+
SYSTEM_NAMESPACE_COLLECTION = 'system.namespaces'
|
29
|
+
SYSTEM_INDEX_COLLECTION = 'system.indexes'
|
30
|
+
SYSTEM_PROFILE_COLLECTION = 'system.profile'
|
31
|
+
SYSTEM_USER_COLLECTION = 'system.users'
|
32
|
+
SYSTEM_JS_COLLECTION = 'system.js'
|
33
|
+
SYSTEM_COMMAND_COLLECTION = '$cmd'
|
33
34
|
|
34
35
|
# Counter for generating unique request ids.
|
35
36
|
@@current_request_id = 0
|
@@ -44,10 +45,10 @@ module Mongo
|
|
44
45
|
# Returns the value of the +strict+ flag.
|
45
46
|
def strict?; @strict; end
|
46
47
|
|
47
|
-
# The name of the database and the local
|
48
|
-
attr_reader :name, :
|
48
|
+
# The name of the database and the local write concern options.
|
49
|
+
attr_reader :name, :write_concern
|
49
50
|
|
50
|
-
# The Mongo::
|
51
|
+
# The Mongo::MongoClient instance connecting to the MongoDB server.
|
51
52
|
attr_reader :connection
|
52
53
|
|
53
54
|
# The length of time that Collection.ensure_index should cache index calls
|
@@ -59,8 +60,8 @@ module Mongo
|
|
59
60
|
# Instances of DB are normally obtained by calling Mongo#db.
|
60
61
|
#
|
61
62
|
# @param [String] name the database name.
|
62
|
-
# @param [Mongo::
|
63
|
-
# that databases are usually instantiated via the
|
63
|
+
# @param [Mongo::MongoClient] client a connection object pointing to MongoDB. Note
|
64
|
+
# that databases are usually instantiated via the MongoClient class. See the examples below.
|
64
65
|
#
|
65
66
|
# @option opts [Boolean] :strict (False) If true, collections must exist to be accessed and must
|
66
67
|
# not exist to be created. See DB#collection and DB#create_collection.
|
@@ -70,21 +71,23 @@ module Mongo
|
|
70
71
|
# fields the factory wishes to inject. (NOTE: if the object already has a primary key,
|
71
72
|
# the factory should not inject a new key).
|
72
73
|
#
|
73
|
-
# @option opts [
|
74
|
-
#
|
75
|
-
#
|
76
|
-
# default can be overridden upon instantiation of any collection by
|
74
|
+
# @option opts [Hash] :w, :j, :wtimeout, :fsync Set the default write concern for this database.
|
75
|
+
# Propagated to Collection objects instantiated off of this DB. If no
|
76
|
+
# options are provided, the default write concern set on this instance's MongoClient object will be used. This
|
77
|
+
# default can be overridden upon instantiation of any collection by explicitly setting write concern values
|
77
78
|
# on initialization
|
78
79
|
#
|
79
80
|
# @option opts [Integer] :cache_time (300) Set the time that all ensure_index calls should cache the command.
|
80
81
|
#
|
81
82
|
# @core databases constructor_details
|
82
|
-
def initialize(name,
|
83
|
+
def initialize(name, client, opts={})
|
83
84
|
@name = Mongo::Support.validate_db_name(name)
|
84
|
-
@connection =
|
85
|
+
@connection = client
|
85
86
|
@strict = opts[:strict]
|
86
87
|
@pk_factory = opts[:pk]
|
87
|
-
|
88
|
+
|
89
|
+
@write_concern = get_write_concern(opts, client)
|
90
|
+
|
88
91
|
if value = opts[:read]
|
89
92
|
Mongo::Support.validate_read_preference(value)
|
90
93
|
else
|
@@ -102,7 +105,7 @@ module Mongo
|
|
102
105
|
# @param [String] username
|
103
106
|
# @param [String] password
|
104
107
|
# @param [Boolean] save_auth
|
105
|
-
# Save this authentication to the
|
108
|
+
# Save this authentication to the client object using MongoClient#add_auth. This
|
106
109
|
# will ensure that the authentication will be applied on database reconnect. Note
|
107
110
|
# that this value must be true when using connection pooling.
|
108
111
|
#
|
@@ -173,7 +176,7 @@ module Mongo
|
|
173
176
|
# @return [Boolean]
|
174
177
|
def remove_stored_function(function_name)
|
175
178
|
if self[SYSTEM_JS_COLLECTION].find_one({"_id" => function_name})
|
176
|
-
self[SYSTEM_JS_COLLECTION].remove({"_id" => function_name}, :
|
179
|
+
self[SYSTEM_JS_COLLECTION].remove({"_id" => function_name}, :w => 1)
|
177
180
|
else
|
178
181
|
return false
|
179
182
|
end
|
@@ -205,14 +208,14 @@ module Mongo
|
|
205
208
|
# @return [Boolean]
|
206
209
|
def remove_user(username)
|
207
210
|
if self[SYSTEM_USER_COLLECTION].find_one({:user => username})
|
208
|
-
self[SYSTEM_USER_COLLECTION].remove({:user => username}, :
|
211
|
+
self[SYSTEM_USER_COLLECTION].remove({:user => username}, :w => 1)
|
209
212
|
else
|
210
213
|
return false
|
211
214
|
end
|
212
215
|
end
|
213
216
|
|
214
|
-
# Deauthorizes use for this database for this connection. Also removes
|
215
|
-
# any saved authentication in the
|
217
|
+
# Deauthorizes use for this database for this client connection. Also removes
|
218
|
+
# any saved authentication in the MongoClient class associated with this
|
216
219
|
# database.
|
217
220
|
#
|
218
221
|
# @raise [MongoDBError] if logging out fails.
|
@@ -258,7 +261,7 @@ module Mongo
|
|
258
261
|
# a cursor which can be iterated over. For each collection, a hash
|
259
262
|
# will be yielded containing a 'name' string and, optionally, an 'options' hash.
|
260
263
|
#
|
261
|
-
# @param [String] coll_name return info for the
|
264
|
+
# @param [String] coll_name return info for the specified collection only.
|
262
265
|
#
|
263
266
|
# @return [Mongo::Cursor]
|
264
267
|
def collections_info(coll_name=nil)
|
@@ -323,7 +326,6 @@ module Mongo
|
|
323
326
|
"Currently in strict mode."
|
324
327
|
else
|
325
328
|
opts = opts.dup
|
326
|
-
opts[:safe] = opts.fetch(:safe, @safe)
|
327
329
|
opts.merge!(:pk => @pk_factory) unless opts[:pk]
|
328
330
|
Collection.new(name, self, opts)
|
329
331
|
end
|
@@ -368,9 +370,9 @@ module Mongo
|
|
368
370
|
get_last_error['err'] != nil
|
369
371
|
end
|
370
372
|
|
371
|
-
# Get the most recent error to have
|
373
|
+
# Get the most recent error to have occurred on this database.
|
372
374
|
#
|
373
|
-
# This command only returns errors that have
|
375
|
+
# This command only returns errors that have occurred since the last call to
|
374
376
|
# DB#reset_error_history - returns +nil+ if there is no such error.
|
375
377
|
#
|
376
378
|
# @return [String, Nil] the text of the error or +nil+ if no error has occurred.
|
data/lib/mongo/exceptions.rb
CHANGED
data/lib/mongo/gridfs/grid.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.
|
@@ -40,8 +40,8 @@ module Mongo
|
|
40
40
|
|
41
41
|
# Create indexes only if we're connected to a primary node.
|
42
42
|
connection = @db.connection
|
43
|
-
if (connection.class ==
|
44
|
-
(connection.class ==
|
43
|
+
if (connection.class == MongoClient && connection.read_primary?) ||
|
44
|
+
(connection.class == MongoReplicaSetClient && connection.primary)
|
45
45
|
@chunks.create_index([['files_id', Mongo::ASCENDING], ['n', Mongo::ASCENDING]], :unique => true)
|
46
46
|
end
|
47
47
|
end
|
@@ -49,7 +49,7 @@ module Mongo
|
|
49
49
|
# Store a file in the file store. This method is designed only for writing new files;
|
50
50
|
# if you need to update a given file, first delete it using Grid#delete.
|
51
51
|
#
|
52
|
-
# Note that
|
52
|
+
# Note that arbitrary metadata attributes can be saved to the file by passing
|
53
53
|
# them in as options.
|
54
54
|
#
|
55
55
|
# @param [String, #read] data a string or io-like object to store.
|
@@ -62,8 +62,9 @@ module Mongo
|
|
62
62
|
# the content type will may be inferred from the filename extension if the mime-types gem can be
|
63
63
|
# loaded. Otherwise, the content type 'binary/octet-stream' will be used.
|
64
64
|
# @option opts [Integer] (262144) :chunk_size size of file chunks in bytes.
|
65
|
-
# @option opts [Boolean] :
|
66
|
-
#
|
65
|
+
# @option opts [Boolean] :w (1) Set the write concern
|
66
|
+
# When :w > 0, the chunks sent to the server are validated using an md5 hash.
|
67
|
+
# If validation fails, an exception will be raised.
|
67
68
|
#
|
68
69
|
# @return [BSON::ObjectId] the file's id.
|
69
70
|
def put(data, opts={})
|
@@ -72,7 +73,7 @@ module Mongo
|
|
72
73
|
opts.merge!(default_grid_io_opts)
|
73
74
|
file = GridIO.new(@files, @chunks, filename, 'w', opts)
|
74
75
|
file.write(data)
|
75
|
-
file.close
|
76
|
+
file.close
|
76
77
|
file.files_id
|
77
78
|
end
|
78
79
|
|
@@ -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.
|
@@ -41,8 +41,8 @@ module Mongo
|
|
41
41
|
|
42
42
|
# Create indexes only if we're connected to a primary node.
|
43
43
|
connection = @db.connection
|
44
|
-
if (connection.class ==
|
45
|
-
(connection.class ==
|
44
|
+
if (connection.class == MongoClient && connection.read_primary?) ||
|
45
|
+
(connection.class == MongoReplicaSetClient && connection.primary)
|
46
46
|
@files.create_index([['filename', 1], ['uploadDate', -1]])
|
47
47
|
@chunks.create_index([['files_id', Mongo::ASCENDING], ['n', Mongo::ASCENDING]], :unique => true)
|
48
48
|
end
|
@@ -51,7 +51,7 @@ module Mongo
|
|
51
51
|
# Open a file for reading or writing. Note that the options for this method only apply
|
52
52
|
# when opening in 'w' mode.
|
53
53
|
#
|
54
|
-
# Note that
|
54
|
+
# Note that arbitrary metadata attributes can be saved to the file by passing
|
55
55
|
# them is as options.
|
56
56
|
#
|
57
57
|
# @param [String] filename the name of the file.
|
@@ -69,7 +69,8 @@ module Mongo
|
|
69
69
|
# @option opts [Boolean] :delete_old (false) ensure that old versions of the file are deleted. This option
|
70
70
|
# only work in 'w' mode. Certain precautions must be taken when deleting GridFS files. See the notes under
|
71
71
|
# GridFileSystem#delete.
|
72
|
-
# @option opts [
|
72
|
+
# @option opts [Hash] :w (1) Set the write concern
|
73
|
+
# When :w > 0, the chunks sent to the server
|
73
74
|
# will be validated using an md5 hash. If validation fails, an exception will be raised.
|
74
75
|
# @option opts [Integer] :versions (false) deletes all versions which exceed the number specified to
|
75
76
|
# retain ordered by uploadDate. This option only works in 'w' mode. Certain precautions must be taken when
|
data/lib/mongo/gridfs/grid_io.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.
|
@@ -22,7 +22,9 @@ module Mongo
|
|
22
22
|
|
23
23
|
# GridIO objects represent files in the GridFS specification. This class
|
24
24
|
# manages the reading and writing of file chunks and metadata.
|
25
|
-
class GridIO
|
25
|
+
class GridIO
|
26
|
+
include Mongo::WriteConcern
|
27
|
+
|
26
28
|
DEFAULT_CHUNK_SIZE = 256 * 1024
|
27
29
|
DEFAULT_CONTENT_TYPE = 'binary/octet-stream'
|
28
30
|
PROTECTED_ATTRS = [:files_id, :file_length, :client_md5, :server_md5]
|
@@ -48,20 +50,21 @@ module Mongo
|
|
48
50
|
# @option opts [String] :content_type ('binary/octet-stream') If no content type is specified,
|
49
51
|
# the content type will may be inferred from the filename extension if the mime-types gem can be
|
50
52
|
# loaded. Otherwise, the content type 'binary/octet-stream' will be used.
|
51
|
-
# @option opts [
|
53
|
+
# @option opts [Hash] :w (1) Set the default write concern
|
54
|
+
# When :w > 0, the chunks sent to the server
|
52
55
|
# will be validated using an md5 hash. If validation fails, an exception will be raised.
|
53
56
|
def initialize(files, chunks, filename, mode, opts={})
|
54
|
-
@files
|
55
|
-
@chunks
|
56
|
-
@filename
|
57
|
-
@mode
|
58
|
-
opts
|
59
|
-
@query
|
60
|
-
@query_opts
|
61
|
-
@fs_name
|
62
|
-
@
|
63
|
-
@local_md5
|
64
|
-
@custom_attrs
|
57
|
+
@files = files
|
58
|
+
@chunks = chunks
|
59
|
+
@filename = filename
|
60
|
+
@mode = mode
|
61
|
+
opts = opts.dup
|
62
|
+
@query = opts.delete(:query) || {}
|
63
|
+
@query_opts = opts.delete(:query_opts) || {}
|
64
|
+
@fs_name = opts.delete(:fs_name) || Grid::DEFAULT_FS_NAME
|
65
|
+
@write_concern = get_write_concern(opts)
|
66
|
+
@local_md5 = Digest::MD5.new if Mongo::WriteConcern.gle?(@write_concern)
|
67
|
+
@custom_attrs = {}
|
65
68
|
|
66
69
|
case @mode
|
67
70
|
when 'r' then init_read
|
@@ -113,13 +116,13 @@ module Mongo
|
|
113
116
|
def write(io)
|
114
117
|
raise GridError, "file not opened for write" unless @mode[0] == ?w
|
115
118
|
if io.is_a? String
|
116
|
-
if @
|
119
|
+
if Mongo::WriteConcern.gle?(@write_concern)
|
117
120
|
@local_md5.update(io)
|
118
121
|
end
|
119
122
|
write_string(io)
|
120
123
|
else
|
121
124
|
length = 0
|
122
|
-
if @
|
125
|
+
if Mongo::WriteConcern.gle?(@write_concern)
|
123
126
|
while(string = io.read(@chunk_size))
|
124
127
|
@local_md5.update(string)
|
125
128
|
length += write_string(string)
|
@@ -428,7 +431,7 @@ module Mongo
|
|
428
431
|
@aliases = opts.delete(:aliases)
|
429
432
|
@file_length = 0
|
430
433
|
opts.each {|k, v| self[k] = v}
|
431
|
-
check_existing_file if @
|
434
|
+
check_existing_file if Mongo::WriteConcern.gle?(@write_concern)
|
432
435
|
|
433
436
|
@current_chunk = create_chunk(0)
|
434
437
|
@file_position = 0
|
@@ -455,13 +458,13 @@ module Mongo
|
|
455
458
|
h
|
456
459
|
end
|
457
460
|
|
458
|
-
# Get a server-side md5 and validate against the client if running
|
461
|
+
# Get a server-side md5 and validate against the client if running with acknowledged writes
|
459
462
|
def get_md5
|
460
463
|
md5_command = BSON::OrderedHash.new
|
461
464
|
md5_command['filemd5'] = @files_id
|
462
465
|
md5_command['root'] = @fs_name
|
463
466
|
@server_md5 = @files.db.command(md5_command)['md5']
|
464
|
-
if @
|
467
|
+
if Mongo::WriteConcern.gle?(@write_concern)
|
465
468
|
@client_md5 = @local_md5.hexdigest
|
466
469
|
if @local_md5 == @server_md5
|
467
470
|
@server_md5
|