mongo 1.3.0 → 1.12.5

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 (185) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/{LICENSE.txt → LICENSE} +1 -1
  4. data/README.md +122 -271
  5. data/Rakefile +25 -209
  6. data/VERSION +1 -0
  7. data/bin/mongo_console +31 -9
  8. data/lib/mongo/bulk_write_collection_view.rb +387 -0
  9. data/lib/mongo/collection.rb +576 -269
  10. data/lib/mongo/collection_writer.rb +364 -0
  11. data/lib/mongo/connection/node.rb +249 -0
  12. data/lib/mongo/connection/pool.rb +340 -0
  13. data/lib/mongo/connection/pool_manager.rb +320 -0
  14. data/lib/mongo/connection/sharding_pool_manager.rb +67 -0
  15. data/lib/mongo/connection/socket/socket_util.rb +37 -0
  16. data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
  17. data/lib/mongo/connection/socket/tcp_socket.rb +87 -0
  18. data/lib/mongo/connection/socket/unix_socket.rb +39 -0
  19. data/lib/mongo/connection/socket.rb +18 -0
  20. data/lib/mongo/connection.rb +7 -875
  21. data/lib/mongo/cursor.rb +403 -117
  22. data/lib/mongo/db.rb +444 -243
  23. data/lib/mongo/exception.rb +145 -0
  24. data/lib/mongo/functional/authentication.rb +455 -0
  25. data/lib/mongo/functional/logging.rb +85 -0
  26. data/lib/mongo/functional/read_preference.rb +183 -0
  27. data/lib/mongo/functional/scram.rb +556 -0
  28. data/lib/mongo/functional/uri_parser.rb +409 -0
  29. data/lib/mongo/functional/write_concern.rb +66 -0
  30. data/lib/mongo/functional.rb +20 -0
  31. data/lib/mongo/gridfs/grid.rb +30 -24
  32. data/lib/mongo/gridfs/grid_ext.rb +6 -10
  33. data/lib/mongo/gridfs/grid_file_system.rb +38 -20
  34. data/lib/mongo/gridfs/grid_io.rb +84 -75
  35. data/lib/mongo/gridfs.rb +18 -0
  36. data/lib/mongo/legacy.rb +140 -0
  37. data/lib/mongo/mongo_client.rb +697 -0
  38. data/lib/mongo/mongo_replica_set_client.rb +535 -0
  39. data/lib/mongo/mongo_sharded_client.rb +159 -0
  40. data/lib/mongo/networking.rb +372 -0
  41. data/lib/mongo/{util → utils}/conversions.rb +29 -8
  42. data/lib/mongo/{util → utils}/core_ext.rb +28 -18
  43. data/lib/mongo/{util → utils}/server_version.rb +4 -6
  44. data/lib/mongo/{util → utils}/support.rb +29 -31
  45. data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
  46. data/lib/mongo/utils.rb +19 -0
  47. data/lib/mongo.rb +51 -50
  48. data/mongo.gemspec +29 -32
  49. data/test/functional/authentication_test.rb +39 -0
  50. data/test/functional/bulk_api_stress_test.rb +133 -0
  51. data/test/functional/bulk_write_collection_view_test.rb +1198 -0
  52. data/test/functional/client_test.rb +627 -0
  53. data/test/functional/collection_test.rb +2175 -0
  54. data/test/functional/collection_writer_test.rb +83 -0
  55. data/test/{conversions_test.rb → functional/conversions_test.rb} +47 -3
  56. data/test/functional/cursor_fail_test.rb +57 -0
  57. data/test/functional/cursor_message_test.rb +56 -0
  58. data/test/functional/cursor_test.rb +683 -0
  59. data/test/functional/db_api_test.rb +835 -0
  60. data/test/functional/db_connection_test.rb +25 -0
  61. data/test/functional/db_test.rb +348 -0
  62. data/test/functional/grid_file_system_test.rb +285 -0
  63. data/test/{grid_io_test.rb → functional/grid_io_test.rb} +72 -11
  64. data/test/{grid_test.rb → functional/grid_test.rb} +88 -15
  65. data/test/functional/pool_test.rb +136 -0
  66. data/test/functional/safe_test.rb +98 -0
  67. data/test/functional/ssl_test.rb +29 -0
  68. data/test/functional/support_test.rb +62 -0
  69. data/test/functional/timeout_test.rb +60 -0
  70. data/test/functional/uri_test.rb +446 -0
  71. data/test/functional/write_concern_test.rb +118 -0
  72. data/test/helpers/general.rb +50 -0
  73. data/test/helpers/test_unit.rb +476 -0
  74. data/test/replica_set/authentication_test.rb +37 -0
  75. data/test/replica_set/basic_test.rb +189 -0
  76. data/test/replica_set/client_test.rb +393 -0
  77. data/test/replica_set/connection_test.rb +138 -0
  78. data/test/replica_set/count_test.rb +66 -0
  79. data/test/replica_set/cursor_test.rb +220 -0
  80. data/test/replica_set/insert_test.rb +157 -0
  81. data/test/replica_set/max_values_test.rb +151 -0
  82. data/test/replica_set/pinning_test.rb +105 -0
  83. data/test/replica_set/query_test.rb +73 -0
  84. data/test/replica_set/read_preference_test.rb +219 -0
  85. data/test/replica_set/refresh_test.rb +211 -0
  86. data/test/replica_set/replication_ack_test.rb +95 -0
  87. data/test/replica_set/ssl_test.rb +32 -0
  88. data/test/sharded_cluster/basic_test.rb +203 -0
  89. data/test/shared/authentication/basic_auth_shared.rb +260 -0
  90. data/test/shared/authentication/bulk_api_auth_shared.rb +249 -0
  91. data/test/shared/authentication/gssapi_shared.rb +176 -0
  92. data/test/shared/authentication/sasl_plain_shared.rb +96 -0
  93. data/test/shared/authentication/scram_shared.rb +92 -0
  94. data/test/shared/ssl_shared.rb +235 -0
  95. data/test/test_helper.rb +53 -94
  96. data/test/threading/basic_test.rb +120 -0
  97. data/test/tools/mongo_config.rb +708 -0
  98. data/test/tools/mongo_config_test.rb +160 -0
  99. data/test/unit/client_test.rb +381 -0
  100. data/test/unit/collection_test.rb +89 -53
  101. data/test/unit/connection_test.rb +282 -32
  102. data/test/unit/cursor_test.rb +206 -8
  103. data/test/unit/db_test.rb +55 -13
  104. data/test/unit/grid_test.rb +43 -16
  105. data/test/unit/mongo_sharded_client_test.rb +48 -0
  106. data/test/unit/node_test.rb +93 -0
  107. data/test/unit/pool_manager_test.rb +111 -0
  108. data/test/unit/read_pref_test.rb +406 -0
  109. data/test/unit/read_test.rb +159 -0
  110. data/test/unit/safe_test.rb +69 -36
  111. data/test/unit/sharding_pool_manager_test.rb +84 -0
  112. data/test/unit/write_concern_test.rb +175 -0
  113. data.tar.gz.sig +3 -0
  114. metadata +227 -216
  115. metadata.gz.sig +0 -0
  116. data/docs/CREDITS.md +0 -123
  117. data/docs/FAQ.md +0 -116
  118. data/docs/GridFS.md +0 -158
  119. data/docs/HISTORY.md +0 -244
  120. data/docs/RELEASES.md +0 -33
  121. data/docs/REPLICA_SETS.md +0 -72
  122. data/docs/TUTORIAL.md +0 -247
  123. data/docs/WRITE_CONCERN.md +0 -28
  124. data/lib/mongo/exceptions.rb +0 -71
  125. data/lib/mongo/gridfs/grid_io_fix.rb +0 -38
  126. data/lib/mongo/repl_set_connection.rb +0 -342
  127. data/lib/mongo/test.rb +0 -20
  128. data/lib/mongo/util/pool.rb +0 -177
  129. data/lib/mongo/util/uri_parser.rb +0 -185
  130. data/test/async/collection_test.rb +0 -224
  131. data/test/async/connection_test.rb +0 -24
  132. data/test/async/cursor_test.rb +0 -162
  133. data/test/async/worker_pool_test.rb +0 -99
  134. data/test/auxillary/1.4_features.rb +0 -166
  135. data/test/auxillary/authentication_test.rb +0 -68
  136. data/test/auxillary/autoreconnect_test.rb +0 -41
  137. data/test/auxillary/fork_test.rb +0 -30
  138. data/test/auxillary/repl_set_auth_test.rb +0 -58
  139. data/test/auxillary/slave_connection_test.rb +0 -36
  140. data/test/auxillary/threaded_authentication_test.rb +0 -101
  141. data/test/bson/binary_test.rb +0 -15
  142. data/test/bson/bson_test.rb +0 -649
  143. data/test/bson/byte_buffer_test.rb +0 -208
  144. data/test/bson/hash_with_indifferent_access_test.rb +0 -38
  145. data/test/bson/json_test.rb +0 -17
  146. data/test/bson/object_id_test.rb +0 -154
  147. data/test/bson/ordered_hash_test.rb +0 -204
  148. data/test/bson/timestamp_test.rb +0 -24
  149. data/test/collection_test.rb +0 -910
  150. data/test/connection_test.rb +0 -309
  151. data/test/cursor_fail_test.rb +0 -75
  152. data/test/cursor_message_test.rb +0 -43
  153. data/test/cursor_test.rb +0 -483
  154. data/test/db_api_test.rb +0 -726
  155. data/test/db_connection_test.rb +0 -15
  156. data/test/db_test.rb +0 -287
  157. data/test/grid_file_system_test.rb +0 -243
  158. data/test/load/resque/load.rb +0 -21
  159. data/test/load/resque/processor.rb +0 -26
  160. data/test/load/thin/load.rb +0 -24
  161. data/test/load/unicorn/load.rb +0 -23
  162. data/test/load/unicorn/unicorn.rb +0 -29
  163. data/test/replica_sets/connect_test.rb +0 -94
  164. data/test/replica_sets/connection_string_test.rb +0 -32
  165. data/test/replica_sets/count_test.rb +0 -35
  166. data/test/replica_sets/insert_test.rb +0 -53
  167. data/test/replica_sets/pooled_insert_test.rb +0 -55
  168. data/test/replica_sets/query_secondaries.rb +0 -96
  169. data/test/replica_sets/query_test.rb +0 -51
  170. data/test/replica_sets/replication_ack_test.rb +0 -66
  171. data/test/replica_sets/rs_test_helper.rb +0 -27
  172. data/test/safe_test.rb +0 -68
  173. data/test/support/hash_with_indifferent_access.rb +0 -186
  174. data/test/support/keys.rb +0 -45
  175. data/test/support_test.rb +0 -18
  176. data/test/threading/threading_with_large_pool_test.rb +0 -90
  177. data/test/threading_test.rb +0 -87
  178. data/test/tools/auth_repl_set_manager.rb +0 -14
  179. data/test/tools/load.rb +0 -58
  180. data/test/tools/repl_set_manager.rb +0 -266
  181. data/test/tools/sharding_manager.rb +0 -202
  182. data/test/tools/test.rb +0 -4
  183. data/test/unit/pool_test.rb +0 -9
  184. data/test/unit/repl_set_connection_test.rb +0 -59
  185. data/test/uri_test.rb +0 -91
@@ -1,20 +1,16 @@
1
- # encoding: UTF-8
2
-
3
- # --
4
- # Copyright (C) 2008-2011 10gen Inc.
1
+ # Copyright (C) 2009-2013 MongoDB, Inc.
5
2
  #
6
3
  # Licensed under the Apache License, Version 2.0 (the "License");
7
4
  # you may not use this file except in compliance with the License.
8
5
  # You may obtain a copy of the License at
9
6
  #
10
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # http://www.apache.org/licenses/LICENSE-2.0
11
8
  #
12
9
  # Unless required by applicable law or agreed to in writing, software
13
10
  # distributed under the License is distributed on an "AS IS" BASIS,
14
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
12
  # See the License for the specific language governing permissions and
16
13
  # limitations under the License.
17
- # ++
18
14
 
19
15
  module Mongo
20
16
 
@@ -39,17 +35,18 @@ module Mongo
39
35
 
40
36
  @default_query_opts = {:sort => [['filename', 1], ['uploadDate', -1]], :limit => 1}
41
37
 
42
- # Ensure indexes only if not connected to slave.
43
- unless db.connection.slave_ok?
44
- @files.create_index([['filename', 1], ['uploadDate', -1]])
45
- @chunks.create_index([['files_id', Mongo::ASCENDING], ['n', Mongo::ASCENDING]], :unique => true)
38
+ # This will create indexes only if we're connected to a primary node.
39
+ begin
40
+ @files.ensure_index([['filename', 1], ['uploadDate', -1]])
41
+ @chunks.ensure_index([['files_id', Mongo::ASCENDING], ['n', Mongo::ASCENDING]], :unique => true)
42
+ rescue Mongo::ConnectionFailure
46
43
  end
47
44
  end
48
45
 
49
46
  # Open a file for reading or writing. Note that the options for this method only apply
50
47
  # when opening in 'w' mode.
51
48
  #
52
- # Note that arbitary metadata attributes can be saved to the file by passing
49
+ # Note that arbitrary metadata attributes can be saved to the file by passing
53
50
  # them is as options.
54
51
  #
55
52
  # @param [String] filename the name of the file.
@@ -63,38 +60,59 @@ module Mongo
63
60
  # @option opts [String] :content_type ('binary/octet-stream') If no content type is specified,
64
61
  # the content type will may be inferred from the filename extension if the mime-types gem can be
65
62
  # loaded. Otherwise, the content type 'binary/octet-stream' will be used.
66
- # @option opts [Integer] (262144) :chunk_size size of file chunks in bytes.
63
+ # @option opts [Integer] (261120) :chunk_size size of file chunks in bytes.
67
64
  # @option opts [Boolean] :delete_old (false) ensure that old versions of the file are deleted. This option
68
65
  # only work in 'w' mode. Certain precautions must be taken when deleting GridFS files. See the notes under
69
66
  # GridFileSystem#delete.
70
- # @option opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server
71
- # will be validated using an md5 hash. If validation fails, an exception will be raised.
67
+ # @option opts [String, Integer, Symbol] :w (1) Set write concern
68
+ #
69
+ # Notes on write concern:
70
+ # When :w > 0, the chunks sent to the server
71
+ # will be validated using an md5 hash. If validation fails, an exception will be raised.
72
+ # @option opts [Integer] :versions (false) deletes all versions which exceed the number specified to
73
+ # retain ordered by uploadDate. This option only works in 'w' mode. Certain precautions must be taken when
74
+ # deleting GridFS files. See the notes under GridFileSystem#delete.
72
75
  #
73
76
  # @example
74
77
  #
75
78
  # # Store the text "Hello, world!" in the grid file system.
76
- # @grid = GridFileSystem.new(@db)
79
+ # @grid = Mongo::GridFileSystem.new(@db)
77
80
  # @grid.open('filename', 'w') do |f|
78
81
  # f.write "Hello, world!"
79
82
  # end
80
83
  #
81
84
  # # Output "Hello, world!"
82
- # @grid = GridFileSystem.new(@db)
85
+ # @grid = Mongo::GridFileSystem.new(@db)
83
86
  # @grid.open('filename', 'r') do |f|
84
87
  # puts f.read
85
88
  # end
86
89
  #
87
90
  # # Write a file on disk to the GridFileSystem
88
91
  # @file = File.open('image.jpg')
89
- # @grid = GridFileSystem.new(@db)
92
+ # @grid = Mongo::GridFileSystem.new(@db)
90
93
  # @grid.open('image.jpg, 'w') do |f|
91
94
  # f.write @file
92
95
  # end
93
96
  #
94
97
  # @return [Mongo::GridIO]
95
98
  def open(filename, mode, opts={})
99
+ opts = opts.dup
96
100
  opts.merge!(default_grid_io_opts(filename))
97
- del = opts.delete(:delete_old) && mode == 'w'
101
+ if mode == 'w'
102
+ begin
103
+ # Ensure there are the appropriate indexes, as state may have changed since instantiation of self.
104
+ # Recall that index definitions are cached with ensure_index so this statement won't unneccesarily repeat index creation.
105
+ @files.ensure_index([['filename', 1], ['uploadDate', -1]])
106
+ @chunks.ensure_index([['files_id', Mongo::ASCENDING], ['n', Mongo::ASCENDING]], :unique => true)
107
+ versions = opts.delete(:versions)
108
+ if opts.delete(:delete_old) || (versions && versions < 1)
109
+ versions = 1
110
+ end
111
+ rescue Mongo::ConnectionFailure => e
112
+ raise e, "Failed to create necessary indexes and write data."
113
+ return
114
+ end
115
+ end
98
116
  file = GridIO.new(@files, @chunks, filename, mode, opts)
99
117
  return file unless block_given?
100
118
  result = nil
@@ -102,9 +120,9 @@ module Mongo
102
120
  result = yield file
103
121
  ensure
104
122
  id = file.close
105
- if del
123
+ if versions
106
124
  self.delete do
107
- @files.find({'filename' => filename, '_id' => {'$ne' => id}}, :fields => ['_id'])
125
+ @files.find({'filename' => filename, '_id' => {'$ne' => id}}, :fields => ['_id'], :sort => ['uploadDate', -1], :skip => (versions - 1))
108
126
  end
109
127
  end
110
128
  end
@@ -1,20 +1,16 @@
1
- # encoding: UTF-8
2
-
3
- # --
4
- # Copyright (C) 2008-2011 10gen Inc.
1
+ # Copyright (C) 2009-2013 MongoDB, Inc.
5
2
  #
6
3
  # Licensed under the Apache License, Version 2.0 (the "License");
7
4
  # you may not use this file except in compliance with the License.
8
5
  # You may obtain a copy of the License at
9
6
  #
10
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # http://www.apache.org/licenses/LICENSE-2.0
11
8
  #
12
9
  # Unless required by applicable law or agreed to in writing, software
13
10
  # distributed under the License is distributed on an "AS IS" BASIS,
14
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
12
  # See the License for the specific language governing permissions and
16
13
  # limitations under the License.
17
- # ++
18
14
 
19
15
  require 'digest/md5'
20
16
 
@@ -23,7 +19,9 @@ module Mongo
23
19
  # GridIO objects represent files in the GridFS specification. This class
24
20
  # manages the reading and writing of file chunks and metadata.
25
21
  class GridIO
26
- DEFAULT_CHUNK_SIZE = 256 * 1024
22
+ include Mongo::WriteConcern
23
+
24
+ DEFAULT_CHUNK_SIZE = 255 * 1024
27
25
  DEFAULT_CONTENT_TYPE = 'binary/octet-stream'
28
26
  PROTECTED_ATTRS = [:files_id, :file_length, :client_md5, :server_md5]
29
27
 
@@ -41,26 +39,30 @@ module Mongo
41
39
  # @option opts [Hash] :query a query selector used when opening the file in 'r' mode.
42
40
  # @option opts [Hash] :query_opts any query options to be used when opening the file in 'r' mode.
43
41
  # @option opts [String] :fs_name the file system prefix.
44
- # @option opts [Integer] (262144) :chunk_size size of file chunks in bytes.
42
+ # @option opts [Integer] (261120) :chunk_size size of file chunks in bytes.
45
43
  # @option opts [Hash] :metadata ({}) any additional data to store with the file.
46
44
  # @option opts [ObjectId] :_id (ObjectId) a unique id for
47
45
  # the file to be use in lieu of an automatically generated one.
48
46
  # @option opts [String] :content_type ('binary/octet-stream') If no content type is specified,
49
47
  # the content type will may be inferred from the filename extension if the mime-types gem can be
50
48
  # loaded. Otherwise, the content type 'binary/octet-stream' will be used.
51
- # @option opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server
52
- # will be validated using an md5 hash. If validation fails, an exception will be raised.
49
+ # @option opts [String, Integer, Symbol] :w (1) Set the write concern
50
+ #
51
+ # Notes on write concern:
52
+ # When :w > 0, the chunks sent to the server
53
+ # will be validated using an md5 hash. If validation fails, an exception will be raised.
53
54
  def initialize(files, chunks, filename, mode, opts={})
54
- @files = files
55
- @chunks = chunks
56
- @filename = filename
57
- @mode = mode
58
- @query = opts.delete(:query) || {}
59
- @query_opts = opts.delete(:query_opts) || {}
60
- @fs_name = opts.delete(:fs_name) || Grid::DEFAULT_FS_NAME
61
- @safe = opts.delete(:safe) || false
62
- @local_md5 = Digest::MD5.new if @safe
63
- @custom_attrs = {}
55
+ @files = files
56
+ @chunks = chunks
57
+ @filename = filename
58
+ @mode = mode
59
+ opts = opts.dup
60
+ @query = opts.delete(:query) || {}
61
+ @query_opts = opts.delete(:query_opts) || {}
62
+ @fs_name = opts.delete(:fs_name) || Grid::DEFAULT_FS_NAME
63
+ @write_concern = get_write_concern(opts)
64
+ @local_md5 = Digest::MD5.new if Mongo::WriteConcern.gle?(@write_concern)
65
+ @custom_attrs = {}
64
66
 
65
67
  case @mode
66
68
  when 'r' then init_read
@@ -104,21 +106,19 @@ module Mongo
104
106
 
105
107
  # Write the given string (binary) data to the file.
106
108
  #
107
- # @param [String] string
108
- # the data to write
109
+ # @param [String] io the data to write.
109
110
  #
110
- # @return [Integer]
111
- # the number of bytes written.
111
+ # @return [Integer] the number of bytes written.
112
112
  def write(io)
113
113
  raise GridError, "file not opened for write" unless @mode[0] == ?w
114
114
  if io.is_a? String
115
- if @safe
115
+ if Mongo::WriteConcern.gle?(@write_concern)
116
116
  @local_md5.update(io)
117
117
  end
118
118
  write_string(io)
119
119
  else
120
120
  length = 0
121
- if @safe
121
+ if Mongo::WriteConcern.gle?(@write_concern)
122
122
  while(string = io.read(@chunk_size))
123
123
  @local_md5.update(string)
124
124
  length += write_string(string)
@@ -207,43 +207,9 @@ module Mongo
207
207
  elsif separator.is_a?(Integer)
208
208
  read_length(separator)
209
209
  elsif separator.length > 1
210
- result = ''
211
- len = 0
212
- match_idx = 0
213
- match_num = separator.length - 1
214
- to_match = separator[match_idx].chr
215
- if length
216
- matcher = lambda {|idx, num| idx < num && len < length }
217
- else
218
- matcher = lambda {|idx, num| idx < num}
219
- end
220
- while matcher.call(match_idx, match_num) && char = getc
221
- result << char
222
- len += 1
223
- if char == to_match
224
- while match_idx < match_num do
225
- match_idx += 1
226
- to_match = separator[match_idx].chr
227
- char = getc
228
- result << char
229
- if char != to_match
230
- match_idx = 0
231
- to_match = separator[match_idx].chr
232
- break
233
- end
234
- end
235
- end
236
- end
237
- result
210
+ read_to_string(separator, length)
238
211
  else
239
- result = ''
240
- len = 0
241
- while char = getc
242
- result << char
243
- len += 1
244
- break if char == separator || (length ? len >= length : false)
245
- end
246
- result
212
+ read_to_character(separator, length)
247
213
  end
248
214
  end
249
215
 
@@ -286,6 +252,7 @@ module Mongo
286
252
  return read_all unless block_given?
287
253
  while chunk = read(chunk_size)
288
254
  yield chunk
255
+ break if chunk.empty?
289
256
  end
290
257
  self
291
258
  end
@@ -307,7 +274,7 @@ module Mongo
307
274
  end
308
275
 
309
276
  def save_chunk(chunk)
310
- @chunks.insert(chunk)
277
+ @chunks.save(chunk)
311
278
  end
312
279
 
313
280
  def get_chunk(n)
@@ -316,21 +283,18 @@ module Mongo
316
283
  chunk
317
284
  end
318
285
 
319
- def last_chunk_number
320
- (@file_length / @chunk_size).to_i
321
- end
322
-
323
286
  # Read a file in its entirety.
324
287
  def read_all
325
288
  buf = ''
326
289
  if @current_chunk
327
290
  buf << @current_chunk['data'].to_s
328
- while chunk = get_chunk(@current_chunk['n'] + 1)
329
- buf << chunk['data'].to_s
330
- @current_chunk = chunk
291
+ while buf.size < @file_length
292
+ @current_chunk = get_chunk(@current_chunk['n'] + 1)
293
+ break if @current_chunk.nil?
294
+ buf << @current_chunk['data'].to_s
331
295
  end
296
+ @file_position = @file_length
332
297
  end
333
- @file_position = @file_length
334
298
  buf
335
299
  end
336
300
 
@@ -361,6 +325,48 @@ module Mongo
361
325
  buf
362
326
  end
363
327
 
328
+ def read_to_character(character="\n", length=nil)
329
+ result = ''
330
+ len = 0
331
+ while char = getc
332
+ result << char
333
+ len += 1
334
+ break if char == character || (length ? len >= length : false)
335
+ end
336
+ result.length > 0 ? result : nil
337
+ end
338
+
339
+ def read_to_string(string="\n", length=nil)
340
+ result = ''
341
+ len = 0
342
+ match_idx = 0
343
+ match_num = string.length - 1
344
+ to_match = string[match_idx].chr
345
+ if length
346
+ matcher = lambda {|idx, num| idx < num && len < length }
347
+ else
348
+ matcher = lambda {|idx, num| idx < num}
349
+ end
350
+ while matcher.call(match_idx, match_num) && char = getc
351
+ result << char
352
+ len += 1
353
+ if char == to_match
354
+ while match_idx < match_num do
355
+ match_idx += 1
356
+ to_match = string[match_idx].chr
357
+ char = getc
358
+ result << char
359
+ if char != to_match
360
+ match_idx = 0
361
+ to_match = string[match_idx].chr
362
+ break
363
+ end
364
+ end
365
+ end
366
+ end
367
+ result.length > 0 ? result : nil
368
+ end
369
+
364
370
  def cache_chunk_data
365
371
  @current_chunk_data = @current_chunk['data'].to_s
366
372
  if @current_chunk_data.respond_to?(:force_encoding)
@@ -413,6 +419,7 @@ module Mongo
413
419
 
414
420
  # Initialize the class for writing a file.
415
421
  def init_write(opts)
422
+ opts = opts.dup
416
423
  @files_id = opts.delete(:_id) || BSON::ObjectId.new
417
424
  @content_type = opts.delete(:content_type) || (defined? MIME) && get_content_type || DEFAULT_CONTENT_TYPE
418
425
  @chunk_size = opts.delete(:chunk_size) || DEFAULT_CHUNK_SIZE
@@ -420,7 +427,7 @@ module Mongo
420
427
  @aliases = opts.delete(:aliases)
421
428
  @file_length = 0
422
429
  opts.each {|k, v| self[k] = v}
423
- check_existing_file if @safe
430
+ check_existing_file if Mongo::WriteConcern.gle?(@write_concern)
424
431
 
425
432
  @current_chunk = create_chunk(0)
426
433
  @file_position = 0
@@ -447,15 +454,17 @@ module Mongo
447
454
  h
448
455
  end
449
456
 
450
- # Get a server-side md5 and validate against the client if running in safe mode.
457
+ # Get a server-side md5 and validate against the client if running with acknowledged writes
451
458
  def get_md5
452
459
  md5_command = BSON::OrderedHash.new
453
460
  md5_command['filemd5'] = @files_id
454
461
  md5_command['root'] = @fs_name
455
462
  @server_md5 = @files.db.command(md5_command)['md5']
456
- if @safe
463
+ if Mongo::WriteConcern.gle?(@write_concern)
457
464
  @client_md5 = @local_md5.hexdigest
458
- if @local_md5 != @server_md5
465
+ if @local_md5 == @server_md5
466
+ @server_md5
467
+ else
459
468
  raise GridMD5Failure, "File on server failed MD5 check"
460
469
  end
461
470
  else
@@ -0,0 +1,18 @@
1
+ # Copyright (C) 2009-2013 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'mongo/gridfs/grid_ext'
16
+ require 'mongo/gridfs/grid'
17
+ require 'mongo/gridfs/grid_file_system'
18
+ require 'mongo/gridfs/grid_io'
@@ -0,0 +1,140 @@
1
+ # Copyright (C) 2009-2013 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ module LegacyWriteConcern
17
+ @legacy_write_concern = true
18
+
19
+ def safe=(value)
20
+ @write_concern = value
21
+ end
22
+
23
+ def safe
24
+ if @write_concern[:w] == 0
25
+ return false
26
+ elsif @write_concern[:w] == 1
27
+ return true
28
+ else
29
+ return @write_concern
30
+ end
31
+ end
32
+
33
+ def self.from_uri(uri = ENV['MONGODB_URI'], extra_opts={})
34
+ parser = URIParser.new uri
35
+ parser.connection(extra_opts, true)
36
+ end
37
+ end
38
+ end
39
+
40
+ module Mongo
41
+ # @deprecated Use Mongo::MongoClient instead. Support will be removed after
42
+ # v2.0. Please see old documentation for the Connection class.
43
+ class Connection < MongoClient
44
+ include Mongo::LegacyWriteConcern
45
+
46
+ def initialize(*args)
47
+ if args.last.is_a?(Hash)
48
+ opts = args.pop
49
+ write_concern_from_legacy(opts)
50
+ args.push(opts)
51
+ end
52
+ super
53
+ end
54
+ end
55
+
56
+ # @deprecated Use Mongo::MongoReplicaSetClient instead. Support will be
57
+ # removed after v2.0. Please see old documentation for the
58
+ # ReplSetConnection class.
59
+ class ReplSetConnection < MongoReplicaSetClient
60
+ include Mongo::LegacyWriteConcern
61
+
62
+ def initialize(*args)
63
+ if args.last.is_a?(Hash)
64
+ opts = args.pop
65
+ write_concern_from_legacy(opts)
66
+ args.push(opts)
67
+ end
68
+ super
69
+ end
70
+ end
71
+
72
+ # @deprecated Use Mongo::MongoShardedClient instead. Support will be removed
73
+ # after v2.0. Please see old documentation for the ShardedConnection class.
74
+ class ShardedConnection < MongoShardedClient
75
+ include Mongo::LegacyWriteConcern
76
+
77
+ def initialize(*args)
78
+ if args.last.is_a?(Hash)
79
+ opts = args.pop
80
+ write_concern_from_legacy(opts)
81
+ args.push(opts)
82
+ end
83
+ super
84
+ end
85
+ end
86
+
87
+ class MongoClient
88
+ # @deprecated This method is no longer in use and never needs to be called
89
+ # directly. Support will be removed after v2.0
90
+ # Authentication of sockets is handled upon checkout and checkin.
91
+ def authenticate_pools
92
+ end
93
+
94
+ # @deprecated This method is no longer in use and never needs to be called
95
+ # directly. Support will be removed after v2.0
96
+ # Authentication of sockets is handled upon checkout and checkin.
97
+ def logout_pools(database)
98
+ end
99
+
100
+ # @deprecated This method is no longer in use and never needs to be called
101
+ # directly. Support will be removed after v2.0
102
+ def apply_saved_authentication
103
+ true
104
+ end
105
+ end
106
+
107
+ class MongoReplicaSetClient
108
+ # @deprecated This method is no longer in use and never needs to be called
109
+ # directly. Support will be removed after v2.0
110
+ # Authentication of sockets is handled upon checkout and checkin.
111
+ def authenticate_pools
112
+ end
113
+
114
+ # @deprecated This method is no longer in use and never needs to be called
115
+ # directly. Support will be removed after v2.0
116
+ # Authentication of sockets is handled upon checkout and checkin.
117
+ def logout_pools(database)
118
+ end
119
+ end
120
+
121
+ class DB
122
+ # @deprecated Please use MongoClient#issue_authentication instead. Support
123
+ # will be removed after v2.0
124
+ def issue_authentication(username, password, save_auth=true, opts={})
125
+ auth = Authentication.validate_credentials({
126
+ :db_name => self.name,
127
+ :username => username,
128
+ :password => password
129
+ })
130
+ opts[:save_auth] = save_auth
131
+ @client.issue_authentication(auth, opts)
132
+ end
133
+
134
+ # @deprecated Please use MongoClient#issue_logout instead. Support will be
135
+ # removed after v2.0
136
+ def issue_logout(opts={})
137
+ @client.issue_logout(self.name, opts)
138
+ end
139
+ end
140
+ end