mongo 1.8.2 → 1.8.3.rc0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. data.tar.gz.sig +0 -0
  2. data/LICENSE +1 -1
  3. data/README.md +2 -7
  4. data/VERSION +1 -1
  5. data/lib/mongo.rb +2 -18
  6. data/lib/mongo/collection.rb +20 -24
  7. data/lib/mongo/cursor.rb +30 -35
  8. data/lib/mongo/db.rb +1 -19
  9. data/lib/mongo/exceptions.rb +0 -19
  10. data/lib/mongo/gridfs/grid.rb +18 -29
  11. data/lib/mongo/gridfs/grid_ext.rb +0 -18
  12. data/lib/mongo/gridfs/grid_file_system.rb +17 -26
  13. data/lib/mongo/gridfs/grid_io.rb +0 -18
  14. data/lib/mongo/legacy.rb +0 -18
  15. data/lib/mongo/mongo_client.rb +11 -33
  16. data/lib/mongo/mongo_replica_set_client.rb +29 -56
  17. data/lib/mongo/mongo_sharded_client.rb +38 -50
  18. data/lib/mongo/networking.rb +5 -4
  19. data/lib/mongo/util/conversions.rb +0 -17
  20. data/lib/mongo/util/core_ext.rb +0 -18
  21. data/lib/mongo/util/node.rb +16 -3
  22. data/lib/mongo/util/pool.rb +46 -36
  23. data/lib/mongo/util/pool_manager.rb +102 -71
  24. data/lib/mongo/util/read_preference.rb +4 -2
  25. data/lib/mongo/util/server_version.rb +0 -17
  26. data/lib/mongo/util/sharding_pool_manager.rb +4 -23
  27. data/lib/mongo/util/socket_util.rb +20 -0
  28. data/lib/mongo/util/ssl_socket.rb +10 -19
  29. data/lib/mongo/util/support.rb +0 -18
  30. data/lib/mongo/util/tcp_socket.rb +1 -9
  31. data/lib/mongo/util/thread_local_variable_manager.rb +0 -18
  32. data/lib/mongo/util/uri_parser.rb +87 -82
  33. data/lib/mongo/util/write_concern.rb +0 -18
  34. data/mongo.gemspec +4 -1
  35. data/test/auxillary/pool_reuse_test.rb +65 -0
  36. data/test/functional/collection_test.rb +92 -3
  37. data/test/functional/connection_test.rb +30 -6
  38. data/test/functional/db_api_test.rb +11 -0
  39. data/test/functional/timeout_test.rb +23 -0
  40. data/test/functional/uri_test.rb +69 -0
  41. data/test/replica_set/client_test.rb +0 -22
  42. data/test/replica_set/cursor_test.rb +11 -5
  43. data/test/replica_set/refresh_test.rb +0 -0
  44. data/test/replica_set/z_cluster_shutdown.rb +13 -0
  45. data/test/sharded_cluster/basic_test.rb +46 -32
  46. data/test/test_helper.rb +26 -1
  47. data/test/threading/basic_test.rb +10 -9
  48. data/test/tools/mongo_config.rb +6 -2
  49. data/test/unit/collection_test.rb +1 -1
  50. data/test/unit/grid_test.rb +20 -13
  51. data/test/unit/mongo_sharded_client_test.rb +32 -0
  52. data/test/unit/pool_manager_test.rb +28 -14
  53. metadata +45 -12
  54. metadata.gz.sig +0 -0
Binary file
data/LICENSE CHANGED
@@ -175,7 +175,7 @@
175
175
 
176
176
  END OF TERMS AND CONDITIONS
177
177
 
178
- Copyright 2008-2010 10gen, Inc.
178
+ Copyright (C) 2008-2013 10gen, Inc.
179
179
 
180
180
  Licensed under the Apache License, Version 2.0 (the "License");
181
181
  you may not use this file except in compliance with the License.
data/README.md CHANGED
@@ -1,7 +1,4 @@
1
- [![Build Status][travis-img]][travis-url]
2
- [![Jenkins Status][jenkins-img]][jenkins-url]
3
- [![Code Climate][codeclimate-img]][codeclimate-url]
4
- [![Latest Version][version-img]][version-url]
1
+ [![Build Status][travis-img]][travis-url] [![Jenkins Status][jenkins-img]][jenkins-url] [![Code Climate][codeclimate-img]][codeclimate-url]
5
2
 
6
3
  [travis-img]: https://secure.travis-ci.org/mongodb/mongo-ruby-driver.png
7
4
  [travis-url]: http://travis-ci.org/mongodb/mongo-ruby-driver
@@ -9,8 +6,6 @@
9
6
  [codeclimate-url]: https://codeclimate.com/github/mongodb/mongo-ruby-driver
10
7
  [jenkins-img]: https://jenkins.10gen.com/job/mongo-ruby-driver/badge/icon
11
8
  [jenkins-url]: https://jenkins.10gen.com/job/mongo-ruby-driver/
12
- [version-img]: https://badge.fury.io/rb/mongo.png
13
- [version-url]: http://badge.fury.io/rb/mongo
14
9
  [api-url]: http://api.mongodb.org/ruby/current
15
10
 
16
11
  # Documentation
@@ -339,7 +334,7 @@ See [credits](https://github.com/mongodb/mongo-ruby-driver/wiki/Credits).
339
334
 
340
335
  # License
341
336
 
342
- Copyright 2008-2010 10gen Inc.
337
+ Copyright (C) 2008-2013 10gen Inc.
343
338
 
344
339
  Licensed under the Apache License, Version 2.0 (the "License");
345
340
  you may not use this file except in compliance with the License.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.8.2
1
+ 1.8.3.rc0
@@ -1,21 +1,3 @@
1
- # encoding: UTF-8
2
- #
3
- # --
4
- # Copyright (C) 2008-2012 10gen Inc.
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- # ++
18
-
19
1
  module Mongo
20
2
  ASCENDING = 1
21
3
  DESCENDING = -1
@@ -23,6 +5,7 @@ module Mongo
23
5
  GEOHAYSTACK = 'geoHaystack'
24
6
 
25
7
  DEFAULT_MAX_BSON_SIZE = 4 * 1024 * 1024
8
+ DEFAULT_MAX_MESSAGE_SIZE = DEFAULT_MAX_BSON_SIZE * 2
26
9
 
27
10
  module Constants
28
11
  OP_REPLY = 1
@@ -62,6 +45,7 @@ require 'mongo/util/pool'
62
45
  require 'mongo/util/pool_manager'
63
46
  require 'mongo/util/sharding_pool_manager'
64
47
  require 'mongo/util/server_version'
48
+ require 'mongo/util/socket_util'
65
49
  require 'mongo/util/ssl_socket'
66
50
  require 'mongo/util/tcp_socket'
67
51
  require 'mongo/util/unix_socket'
@@ -1,20 +1,3 @@
1
- # encoding: UTF-8
2
-
3
- # --
4
- # Copyright (C) 2008-2012 10gen Inc.
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
-
18
1
  module Mongo
19
2
 
20
3
  # A named collection of documents in a database.
@@ -155,6 +138,13 @@ module Mongo
155
138
  self
156
139
  end
157
140
 
141
+ # Set a hint field using a named index.
142
+ # @param [String] hinted index name
143
+ def named_hint=(hint=nil)
144
+ @hint = hint
145
+ self
146
+ end
147
+
158
148
  # Query the database.
159
149
  #
160
150
  # The +selector+ argument is a prototype document that all results must
@@ -193,6 +183,8 @@ module Mongo
193
183
  # be specified as Mongo::ASCENDING (or :ascending / :asc) or Mongo::DESCENDING (or :descending / :desc)
194
184
  # @option opts [String, Array, OrderedHash] :hint hint for query optimizer, usually not necessary if
195
185
  # using MongoDB > 1.1
186
+ # @option opts [String] :named_hint for specifying a named index as a hint, will be overriden by :hint
187
+ # if :hint is also provided.
196
188
  # @option opts [Boolean] :snapshot (false) if true, snapshot mode will be used for this query.
197
189
  # Snapshot mode assures no duplicates are returned, or objects missed, which were preset at both the start and
198
190
  # end of the query's execution.
@@ -227,6 +219,7 @@ module Mongo
227
219
  limit = opts.delete(:limit) || 0
228
220
  sort = opts.delete(:sort)
229
221
  hint = opts.delete(:hint)
222
+ named_hint = opts.delete(:named_hint)
230
223
  snapshot = opts.delete(:snapshot)
231
224
  batch_size = opts.delete(:batch_size)
232
225
  timeout = (opts.delete(:timeout) == false) ? false : true
@@ -257,7 +250,7 @@ module Mongo
257
250
  :skip => skip,
258
251
  :limit => limit,
259
252
  :order => sort,
260
- :hint => hint,
253
+ :hint => hint || named_hint,
261
254
  :snapshot => snapshot,
262
255
  :timeout => timeout,
263
256
  :batch_size => batch_size,
@@ -416,7 +409,7 @@ module Mongo
416
409
  # @core remove remove-instance_method
417
410
  def remove(selector={}, opts={})
418
411
  write_concern = get_write_concern(opts, self)
419
- message = BSON::ByteBuffer.new("\0\0\0\0")
412
+ message = BSON::ByteBuffer.new("\0\0\0\0", @connection.max_message_size)
420
413
  BSON::BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}")
421
414
  message.put_int(0)
422
415
  message.put_binary(BSON::BSON_CODER.serialize(selector, false, true, @connection.max_bson_size).to_s)
@@ -464,7 +457,7 @@ module Mongo
464
457
  def update(selector, document, opts={})
465
458
  # Initial byte is 0.
466
459
  write_concern = get_write_concern(opts, self)
467
- message = BSON::ByteBuffer.new("\0\0\0\0")
460
+ message = BSON::ByteBuffer.new("\0\0\0\0", @connection.max_message_size)
468
461
  BSON::BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@name}")
469
462
  update_options = 0
470
463
  update_options += 1 if opts[:upsert]
@@ -474,7 +467,7 @@ module Mongo
474
467
  check_keys = document.keys.first.to_s.start_with?("$") ? false : true
475
468
 
476
469
  message.put_int(update_options)
477
- message.put_binary(BSON::BSON_CODER.serialize(selector, false, true).to_s)
470
+ message.put_binary(BSON::BSON_CODER.serialize(selector, false, true, @connection.max_bson_size).to_s)
478
471
  message.put_binary(BSON::BSON_CODER.serialize(document, check_keys, true, @connection.max_bson_size).to_s)
479
472
 
480
473
  instrument(:update, :database => @db.name, :collection => @name, :selector => selector, :document => document) do
@@ -1065,11 +1058,11 @@ module Mongo
1065
1058
  # Takes an array of +documents+, an optional +collection_name+, and a
1066
1059
  # +check_keys+ setting.
1067
1060
  def insert_documents(documents, collection_name=@name, check_keys=true, write_concern={}, flags={})
1061
+ message = BSON::ByteBuffer.new("", @connection.max_message_size)
1068
1062
  if flags[:continue_on_error]
1069
- message = BSON::ByteBuffer.new
1070
1063
  message.put_int(1)
1071
1064
  else
1072
- message = BSON::ByteBuffer.new("\0\0\0\0")
1065
+ message.put_int(0)
1073
1066
  end
1074
1067
 
1075
1068
  collect_on_error = !!flags[:collect_on_error]
@@ -1093,7 +1086,10 @@ module Mongo
1093
1086
  message.put_binary(BSON::BSON_CODER.serialize(doc, check_keys, true, @connection.max_bson_size).to_s)
1094
1087
  end
1095
1088
  end
1096
- raise InvalidOperation, "Exceded maximum insert size of 16,777,216 bytes" if message.size > @connection.max_bson_size
1089
+
1090
+ if message.size > @connection.max_message_size
1091
+ raise InvalidOperation, "Exceded maximum insert size of #{@connection.max_message_size} bytes"
1092
+ end
1097
1093
 
1098
1094
  instrument(:insert, :database => @db.name, :collection => collection_name, :documents => documents) do
1099
1095
  if Mongo::WriteConcern.gle?(write_concern)
@@ -1,19 +1,3 @@
1
- # encoding: UTF-8
2
-
3
- # Copyright (C) 2008-2012 10gen Inc.
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
-
17
1
  module Mongo
18
2
 
19
3
  # A cursor over query results. Returned objects are hashes.
@@ -66,7 +50,8 @@ module Mongo
66
50
  @options = 0
67
51
 
68
52
  # Use this socket for the query
69
- @socket = opts[:socket]
53
+ @socket = opts[:socket]
54
+ @pool = nil
70
55
 
71
56
  @closed = false
72
57
  @query_run = false
@@ -197,7 +182,7 @@ module Mongo
197
182
  #
198
183
  # @param [Symbol, Array, Hash, OrderedHash] order either 1) a key to sort by 2)
199
184
  # an array of [key, direction] pairs to sort by or 3) a hash of
200
- # field => direction pairs to sort by. Direction should be specified as
185
+ # field => direction pairs to sort by. Direction should be specified as
201
186
  # Mongo::ASCENDING (or :ascending / :asc) or Mongo::DESCENDING
202
187
  # (or :descending / :desc)
203
188
  #
@@ -339,7 +324,16 @@ module Mongo
339
324
  message.put_int(1)
340
325
  message.put_long(@cursor_id)
341
326
  log(:debug, "Cursor#close #{@cursor_id}")
342
- @connection.send_message(Mongo::Constants::OP_KILL_CURSORS, message, :socket => @socket)
327
+ begin
328
+ socket = @pool.checkout
329
+ @connection.send_message(
330
+ Mongo::Constants::OP_KILL_CURSORS,
331
+ message,
332
+ :socket => socket
333
+ )
334
+ ensure
335
+ socket.checkin
336
+ end
343
337
  end
344
338
  @cursor_id = 0
345
339
  @closed = true
@@ -468,23 +462,23 @@ module Mongo
468
462
  #
469
463
  # Upon ConnectionFailure, tries query 3 times if socket was not provided
470
464
  # and the query is either not a command or is a secondary_ok command.
471
- #
465
+ #
472
466
  # Pins pools upon successful read and unpins pool upon ConnectionFailure
473
467
  #
474
468
  def send_initial_query
475
469
  tries = 0
476
470
  instrument(:find, instrument_payload) do
477
471
  begin
478
- tries += 1
479
472
  message = construct_query_message
480
- sock = @socket || checkout_socket_from_connection
473
+ socket = @socket || checkout_socket_from_connection
481
474
  results, @n_received, @cursor_id = @connection.receive_message(
482
- Mongo::Constants::OP_QUERY, message, nil, sock, @command,
475
+ Mongo::Constants::OP_QUERY, message, nil, socket, @command,
483
476
  nil, @options & OP_QUERY_EXHAUST != 0)
484
477
  rescue ConnectionFailure => ex
478
+ socket.close if socket
479
+ @connection.refresh
485
480
  if tries < 3 && !@socket && (!@command || Mongo::Support::secondary_ok?(@selector))
486
- @connection.unpin_pool(sock.pool) if sock
487
- @connection.refresh
481
+ tries += 1
488
482
  retry
489
483
  else
490
484
  raise ex
@@ -492,9 +486,8 @@ module Mongo
492
486
  rescue OperationFailure, OperationTimeout => ex
493
487
  raise ex
494
488
  ensure
495
- checkin_socket(sock) unless @socket
489
+ socket.checkin unless @socket || socket.nil?
496
490
  end
497
- @connection.pin_pool(sock.pool) if !@command && !@socket
498
491
  @returned += @n_received
499
492
  @cache += results
500
493
  @query_run = true
@@ -523,13 +516,13 @@ module Mongo
523
516
  message.put_long(@cursor_id)
524
517
  log(:debug, "cursor.refresh() for cursor #{@cursor_id}") if @logger
525
518
 
526
- sock = @socket || checkout_socket_from_connection
519
+ socket = checkout_socket_from_connection
527
520
 
528
521
  begin
529
522
  results, @n_received, @cursor_id = @connection.receive_message(
530
- Mongo::Constants::OP_GET_MORE, message, nil, sock, @command, nil)
523
+ Mongo::Constants::OP_GET_MORE, message, nil, socket, @command, nil)
531
524
  ensure
532
- checkin_socket(sock) unless @socket
525
+ socket.checkin
533
526
  end
534
527
 
535
528
  @returned += @n_received
@@ -540,14 +533,16 @@ module Mongo
540
533
  def checkout_socket_from_connection
541
534
  begin
542
535
  if @command && !Mongo::Support::secondary_ok?(@selector)
543
- @connection.checkout_reader(:primary)
536
+ socket = @connection.checkout_reader(:primary)
544
537
  else
545
- @connection.checkout_reader(@read, @tag_sets, @acceptable_latency)
538
+ socket = @connection.checkout_reader(@read, @tag_sets, @acceptable_latency)
546
539
  end
547
540
  rescue SystemStackError, NoMemoryError, SystemCallError => ex
548
541
  @connection.close
549
542
  raise ex
550
543
  end
544
+ @pool = socket.pool
545
+ socket
551
546
  end
552
547
 
553
548
  def checkin_socket(sock)
@@ -555,14 +550,14 @@ module Mongo
555
550
  end
556
551
 
557
552
  def construct_query_message
558
- message = BSON::ByteBuffer.new
553
+ message = BSON::ByteBuffer.new("", @connection.max_message_size)
559
554
  message.put_int(@options)
560
555
  BSON::BSON_RUBY.serialize_cstr(message, "#{@db.name}.#{@collection.name}")
561
556
  message.put_int(@skip)
562
557
  message.put_int(@limit)
563
558
  spec = query_contains_special_fields? ? construct_query_spec : @selector
564
- message.put_binary(BSON::BSON_CODER.serialize(spec, false).to_s)
565
- message.put_binary(BSON::BSON_CODER.serialize(@fields, false).to_s) if @fields
559
+ message.put_binary(BSON::BSON_CODER.serialize(spec, false, false, @connection.max_bson_size).to_s)
560
+ message.put_binary(BSON::BSON_CODER.serialize(@fields, false, false, @connection.max_bson_size).to_s) if @fields
566
561
  message
567
562
  end
568
563
 
@@ -1,21 +1,3 @@
1
- # encoding: UTF-8
2
-
3
- # --
4
- # Copyright (C) 2008-2012 10gen Inc.
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- # ++
18
-
19
1
  require 'socket'
20
2
  require 'thread'
21
3
 
@@ -127,7 +109,7 @@ module Mongo
127
109
  socket = @connection.checkout_reader(:primary_preferred)
128
110
  issue_authentication(username, password, save_auth, :socket => socket)
129
111
  ensure
130
- socket.pool.checkin(socket) if socket
112
+ socket.checkin if socket
131
113
  end
132
114
 
133
115
  @connection.authenticate_pools
@@ -1,22 +1,3 @@
1
- # encoding: UTF-8
2
-
3
- #
4
- # --
5
- # Copyright (C) 2008-2012 10gen Inc.
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
- # ++
19
-
20
1
  module Mongo
21
2
  # Generic Mongo Ruby Driver exception class.
22
3
  class MongoRubyError < StandardError; end
@@ -1,21 +1,3 @@
1
- # encoding: UTF-8
2
-
3
- # --
4
- # Copyright (C) 2008-2012 10gen Inc.
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- # ++
18
-
19
1
  module Mongo
20
2
 
21
3
  # Implementation of the MongoDB GridFS specification. A file store.
@@ -38,11 +20,11 @@ module Mongo
38
20
  @chunks = @db["#{fs_name}.chunks"]
39
21
  @fs_name = fs_name
40
22
 
41
- # Create indexes only if we're connected to a primary node.
23
+ # This will create indexes only if we're connected to a primary node.
42
24
  connection = @db.connection
43
- if (connection.class == MongoClient && connection.read_primary?) ||
44
- (connection.class == MongoReplicaSetClient && connection.primary)
45
- @chunks.create_index([['files_id', Mongo::ASCENDING], ['n', Mongo::ASCENDING]], :unique => true)
25
+ begin
26
+ @chunks.ensure_index([['files_id', Mongo::ASCENDING], ['n', Mongo::ASCENDING]], :unique => true)
27
+ rescue Mongo::ConnectionFailure
46
28
  end
47
29
  end
48
30
 
@@ -70,13 +52,20 @@ module Mongo
70
52
  #
71
53
  # @return [BSON::ObjectId] the file's id.
72
54
  def put(data, opts={})
73
- opts = opts.dup
74
- filename = opts.delete(:filename)
75
- opts.merge!(default_grid_io_opts)
76
- file = GridIO.new(@files, @chunks, filename, 'w', opts)
77
- file.write(data)
78
- file.close
79
- file.files_id
55
+ begin
56
+ # Ensure there is an index on files_id and n, as state may have changed since instantiation of self.
57
+ # Recall that index definitions are cached with ensure_index so this statement won't unneccesarily repeat index creation.
58
+ @chunks.ensure_index([['files_id', Mongo::ASCENDING], ['n', Mongo::ASCENDING]], :unique => true)
59
+ opts = opts.dup
60
+ filename = opts.delete(:filename)
61
+ opts.merge!(default_grid_io_opts)
62
+ file = GridIO.new(@files, @chunks, filename, 'w', opts)
63
+ file.write(data)
64
+ file.close
65
+ file.files_id
66
+ rescue Mongo::ConnectionFailure => e
67
+ raise e, "Failed to create necessary index and write data."
68
+ end
80
69
  end
81
70
 
82
71
  # Read a file from the file store.