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/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
|