mongo 1.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,9 @@
1
+ # encoding: UTF-8
2
+
1
3
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
4
 
3
5
  module Mongo
4
- VERSION = "1.0"
6
+ VERSION = "1.0.1"
5
7
  end
6
8
 
7
9
  module Mongo
@@ -40,6 +42,7 @@ require 'mongo/connection'
40
42
  require 'mongo/cursor'
41
43
  require 'mongo/db'
42
44
  require 'mongo/exceptions'
45
+ require 'mongo/gridfs/grid_ext'
43
46
  require 'mongo/gridfs/grid'
44
47
  require 'mongo/gridfs/grid_io'
45
48
  require 'mongo/gridfs/grid_file_system'
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  # --
2
4
  # Copyright (C) 2008-2010 10gen Inc.
3
5
  #
@@ -203,17 +205,22 @@ module Mongo
203
205
  #
204
206
  # @return [ObjectID] the _id of the saved document.
205
207
  #
206
- # @option opts [Boolean] :safe (+false+)
207
- # If true, check that the save succeeded. OperationFailure
208
- # will be raised on an error. Note that a safe check requires an extra
209
- # round-trip to the database.
210
- def save(doc, options={})
208
+ # @option opts [Boolean, Hash] :safe (+false+)
209
+ # run the operation in safe mode, which run a getlasterror command on the
210
+ # database to report any assertion. In addition, a hash can be provided to
211
+ # run an fsync and/or wait for replication of the save (>= 1.5.1). See the options
212
+ # for DB#error.
213
+ #
214
+ # @raise [OperationFailure] when :safe mode fails.
215
+ #
216
+ # @see DB#remove for options that can be passed to :safe.
217
+ def save(doc, opts={})
211
218
  if doc.has_key?(:_id) || doc.has_key?('_id')
212
219
  id = doc[:_id] || doc['_id']
213
- update({:_id => id}, doc, :upsert => true, :safe => options.delete(:safe))
220
+ update({:_id => id}, doc, :upsert => true, :safe => opts[:safe])
214
221
  id
215
222
  else
216
- insert(doc, :safe => options.delete(:safe))
223
+ insert(doc, :safe => opts[:safe])
217
224
  end
218
225
  end
219
226
 
@@ -226,10 +233,13 @@ module Mongo
226
233
  # the _id of the inserted document or a list of _ids of all inserted documents.
227
234
  # Note: the object may have been modified by the database's PK factory, if it has one.
228
235
  #
229
- # @option opts [Boolean] :safe (+false+)
230
- # If true, check that the save succeeded. OperationFailure
231
- # will be raised on an error. Note that a safe check requires an extra
232
- # round-trip to the database.
236
+ # @option opts [Boolean, Hash] :safe (+false+)
237
+ # run the operation in safe mode, which run a getlasterror command on the
238
+ # database to report any assertion. In addition, a hash can be provided to
239
+ # run an fsync and/or wait for replication of the insert (>= 1.5.1). See the options
240
+ # for DB#error.
241
+ #
242
+ # @see DB#remove for options that can be passed to :safe.
233
243
  #
234
244
  # @core insert insert-instance_method
235
245
  def insert(doc_or_docs, options={})
@@ -245,8 +255,11 @@ module Mongo
245
255
  # @param [Hash] selector
246
256
  # If specified, only matching documents will be removed.
247
257
  #
248
- # @option opts [Boolean] :safe [false] run the operation in safe mode, which
249
- # will call :getlasterror on the database and report any assertions.
258
+ # @option opts [Boolean, Hash] :safe (+false+)
259
+ # run the operation in safe mode, which run a getlasterror command on the
260
+ # database to report any assertion. In addition, a hash can be provided to
261
+ # run an fsync and/or wait for replication of the remove (>= 1.5.1). See the options
262
+ # for DB#error.
250
263
  #
251
264
  # @example remove all documents from the 'users' collection:
252
265
  # users.remove
@@ -260,6 +273,8 @@ module Mongo
260
273
  # @raise [Mongo::OperationFailure] an exception will be raised iff safe mode is enabled
261
274
  # and the operation fails.
262
275
  #
276
+ # @see DB#remove for options that can be passed to :safe.
277
+ #
263
278
  # @core remove remove-instance_method
264
279
  def remove(selector={}, opts={})
265
280
  # Initial byte is 0.
@@ -270,7 +285,7 @@ module Mongo
270
285
 
271
286
  if opts[:safe]
272
287
  @connection.send_message_with_safe_check(Mongo::Constants::OP_DELETE, message, @db.name,
273
- "#{@db.name}['#{@name}'].remove(#{selector.inspect})")
288
+ "#{@db.name}['#{@name}'].remove(#{selector.inspect})", opts[:safe])
274
289
  # the return value of send_message_with_safe_check isn't actually meaningful --
275
290
  # only the fact that it didn't raise an error is -- so just return true
276
291
  true
@@ -312,7 +327,7 @@ module Mongo
312
327
  message.put_array(BSON::BSON_CODER.serialize(document, false, true).to_a)
313
328
  if options[:safe]
314
329
  @connection.send_message_with_safe_check(Mongo::Constants::OP_UPDATE, message, @db.name,
315
- "#{@db.name}['#{@name}'].update(#{selector.inspect}, #{document.inspect})")
330
+ "#{@db.name}['#{@name}'].update(#{selector.inspect}, #{document.inspect})", options[:safe])
316
331
  else
317
332
  @connection.send_message(Mongo::Constants::OP_UPDATE, message,
318
333
  "#{@db.name}['#{@name}'].update(#{selector.inspect}, #{document.inspect})")
@@ -360,7 +375,7 @@ module Mongo
360
375
  # @core indexes create_index-instance_method
361
376
  def create_index(spec, opts={})
362
377
  opts.assert_valid_keys(:min, :max, :background, :unique, :dropDups)
363
- field_spec = OrderedHash.new
378
+ field_spec = BSON::OrderedHash.new
364
379
  if spec.is_a?(String) || spec.is_a?(Symbol)
365
380
  field_spec[spec.to_s] = 1
366
381
  elsif spec.is_a?(Array) && spec.all? {|field| field.is_a?(Array) }
@@ -432,7 +447,7 @@ module Mongo
432
447
  #
433
448
  # @core findandmodify find_and_modify-instance_method
434
449
  def find_and_modify(opts={})
435
- cmd = OrderedHash.new
450
+ cmd = BSON::OrderedHash.new
436
451
  cmd[:findandmodify] = @name
437
452
  cmd.merge!(opts)
438
453
  cmd[:sort] = Mongo::Support.format_order_clause(opts[:sort]) if opts[:sort]
@@ -465,7 +480,7 @@ module Mongo
465
480
  map = BSON::Code.new(map) unless map.is_a?(BSON::Code)
466
481
  reduce = BSON::Code.new(reduce) unless reduce.is_a?(BSON::Code)
467
482
 
468
- hash = OrderedHash.new
483
+ hash = BSON::OrderedHash.new
469
484
  hash['mapreduce'] = self.name
470
485
  hash['map'] = map
471
486
  hash['reduce'] = reduce
@@ -557,7 +572,7 @@ module Mongo
557
572
  # @return [Array] an array of distinct values.
558
573
  def distinct(key, query=nil)
559
574
  raise MongoArgumentError unless [String, Symbol].include?(key.class)
560
- command = OrderedHash.new
575
+ command = BSON::OrderedHash.new
561
576
  command[:distinct] = @name
562
577
  command[:key] = key.to_s
563
578
  command[:query] = query
@@ -639,7 +654,7 @@ module Mongo
639
654
  when nil
640
655
  nil
641
656
  else
642
- h = OrderedHash.new
657
+ h = BSON::OrderedHash.new
643
658
  hint.to_a.each { |k| h[k] = 1 }
644
659
  h
645
660
  end
@@ -657,7 +672,7 @@ module Mongo
657
672
  documents.each { |doc| message.put_array(BSON::BSON_CODER.serialize(doc, check_keys, true).to_a) }
658
673
  if safe
659
674
  @connection.send_message_with_safe_check(Mongo::Constants::OP_INSERT, message, @db.name,
660
- "#{@db.name}['#{collection_name}'].insert(#{documents.inspect})")
675
+ "#{@db.name}['#{collection_name}'].insert(#{documents.inspect})", safe)
661
676
  else
662
677
  @connection.send_message(Mongo::Constants::OP_INSERT, message,
663
678
  "#{@db.name}['#{collection_name}'].insert(#{documents.inspect})")
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  # --
2
4
  # Copyright (C) 2008-2010 10gen Inc.
3
5
  #
@@ -172,6 +174,9 @@ module Mongo
172
174
  # specificed in the list of auths. This method is called automatically
173
175
  # by DB#authenticate.
174
176
  #
177
+ # Note: this method will not actually issue an authentication command. To do that,
178
+ # either run Connection#apply_saved_authentication or DB#authenticate.
179
+ #
175
180
  # @param [String] db_name
176
181
  # @param [String] username
177
182
  # @param [String] password
@@ -266,7 +271,7 @@ module Mongo
266
271
  # @param [String] username username for authentication against from_db (>=1.3.x).
267
272
  # @param [String] password password for authentication against from_db (>=1.3.x).
268
273
  def copy_database(from, to, from_host="localhost", username=nil, password=nil)
269
- oh = OrderedHash.new
274
+ oh = BSON::OrderedHash.new
270
275
  oh[:copydb] = 1
271
276
  oh[:fromhost] = from_host
272
277
  oh[:fromdb] = from
@@ -275,7 +280,7 @@ module Mongo
275
280
  unless username && password
276
281
  raise MongoArgumentError, "Both username and password must be supplied for authentication."
277
282
  end
278
- nonce_cmd = OrderedHash.new
283
+ nonce_cmd = BSON::OrderedHash.new
279
284
  nonce_cmd[:copydbgetnonce] = 1
280
285
  nonce_cmd[:fromhost] = from_host
281
286
  result = self["admin"].command(nonce_cmd, true, true)
@@ -347,13 +352,17 @@ module Mongo
347
352
  # @param [BSON::ByteBuffer] message a message to send to the database.
348
353
  # @param [String] db_name the name of the database. used on call to get_last_error.
349
354
  # @param [String] log_message text version of +message+ for logging.
355
+ # @param [Hash] last_error_params parameters to be sent to getLastError. See DB#error for
356
+ # available options.
357
+ #
358
+ # @see DB#error for valid last error params.
350
359
  #
351
360
  # @return [Array]
352
361
  # An array whose indexes include [0] documents returned, [1] number of document received,
353
362
  # and [3] a cursor_id.
354
- def send_message_with_safe_check(operation, message, db_name, log_message=nil)
363
+ def send_message_with_safe_check(operation, message, db_name, log_message=nil, last_error_params=false)
355
364
  message_with_headers = add_message_headers(operation, message)
356
- message_with_check = last_error_message(db_name)
365
+ message_with_check = last_error_message(db_name, last_error_params)
357
366
  @logger.debug(" MONGODB #{log_message || message}") if @logger
358
367
  begin
359
368
  sock = checkout
@@ -366,7 +375,7 @@ module Mongo
366
375
  ensure
367
376
  checkin(sock)
368
377
  end
369
- if num_received == 1 && error = docs[0]['err']
378
+ if num_received == 1 && (error = docs[0]['err'] || docs[0]['errmsg'])
370
379
  raise Mongo::OperationFailure, error
371
380
  end
372
381
  [docs, num_received, cursor_id]
@@ -644,13 +653,21 @@ module Mongo
644
653
  [docs, number_received, cursor_id]
645
654
  end
646
655
 
647
- def last_error_message(db_name)
656
+ # Constructs a getlasterror message. This method is used exclusively by
657
+ # Connection#send_message_with_safe_check.
658
+ def last_error_message(db_name, opts)
648
659
  message = BSON::ByteBuffer.new
649
660
  message.put_int(0)
650
661
  BSON::BSON_RUBY.serialize_cstr(message, "#{db_name}.$cmd")
651
662
  message.put_int(0)
652
663
  message.put_int(-1)
653
- message.put_array(BSON::BSON_CODER.serialize({:getlasterror => 1}, false).unpack("C*"))
664
+ cmd = BSON::OrderedHash.new
665
+ cmd[:getlasterror] = 1
666
+ if opts.is_a?(Hash)
667
+ opts.assert_valid_keys(:w, :wtimeout, :fsync)
668
+ cmd.merge!(opts)
669
+ end
670
+ message.put_array(BSON::BSON_CODER.serialize(cmd, false).unpack("C*"))
654
671
  add_message_headers(Mongo::Constants::OP_QUERY, message)
655
672
  end
656
673
 
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  # Copyright (C) 2008-2010 10gen Inc.
2
4
  #
3
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -94,7 +96,7 @@ module Mongo
94
96
  #
95
97
  # @raise [OperationFailure] on a database error.
96
98
  def count
97
- command = OrderedHash["count", @collection.name,
99
+ command = BSON::OrderedHash["count", @collection.name,
98
100
  "query", @selector,
99
101
  "fields", @fields]
100
102
  response = @db.command(command)
@@ -299,10 +301,14 @@ module Mongo
299
301
  selector
300
302
  when nil
301
303
  {}
302
- when String
303
- {"$where" => Code.new(selector)}
304
- when Code
304
+ when BSON::Code
305
+ warn "Collection#find will no longer take a JavaScript string in future versions. " +
306
+ "Please specify your $where query explicitly."
305
307
  {"$where" => selector}
308
+ when String
309
+ warn "Collection#find will no longer take a JavaScript string in future versions. " +
310
+ "Please specify your $where query explicitly."
311
+ {"$where" => BSON::Code.new(selector)}
306
312
  end
307
313
  end
308
314
 
@@ -366,7 +372,7 @@ module Mongo
366
372
 
367
373
  def construct_query_spec
368
374
  return @selector if @selector.has_key?('$query')
369
- spec = OrderedHash.new
375
+ spec = BSON::OrderedHash.new
370
376
  spec['$query'] = @selector
371
377
  spec['$orderby'] = Mongo::Support.format_order_clause(@order) if @order
372
378
  spec['$hint'] = @hint if @hint && @hint.length > 0
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  # --
2
4
  # Copyright (C) 2008-2010 10gen Inc.
3
5
  #
@@ -89,7 +91,7 @@ module Mongo
89
91
  raise "error retrieving nonce: #{doc}" unless ok?(doc)
90
92
  nonce = doc['nonce']
91
93
 
92
- auth = OrderedHash.new
94
+ auth = BSON::OrderedHash.new
93
95
  auth['authenticate'] = 1
94
96
  auth['user'] = username
95
97
  auth['nonce'] = nonce
@@ -212,7 +214,7 @@ module Mongo
212
214
  end
213
215
 
214
216
  # Create a new collection.
215
- oh = OrderedHash.new
217
+ oh = BSON::OrderedHash.new
216
218
  oh[:create] = name
217
219
  doc = command(oh.merge(options || {}))
218
220
  ok = doc['ok']
@@ -247,11 +249,19 @@ module Mongo
247
249
  # Get the error message from the most recently executed database
248
250
  # operation for this connection.
249
251
  #
250
- # @return [String, Nil] either the text describing the error or nil if no
252
+ # @option opts [Boolean] :fsync (false)
253
+ # @option opts [Integer] :w (nil)
254
+ # @option opts [Integer] :wtimeout (nil)
255
+ #
256
+ # @return [String, Nil] either the text describing an error or nil if no
251
257
  # error has occurred.
252
- def error
253
- doc = command(:getlasterror => 1)
254
- raise MongoDBError, "error retrieving last error: #{doc}" unless ok?(doc)
258
+ def error(opts={})
259
+ opts.assert_valid_keys(:w, :wtimeout, :fsync)
260
+ cmd = BSON::OrderedHash.new
261
+ cmd[:getlasterror] = 1
262
+ cmd.merge!(opts) unless opts.empty?
263
+ doc = command(cmd)
264
+ raise MongoDBError, "error retrieving last error: #{doc.inspect}" unless ok?(doc)
255
265
  doc['err']
256
266
  end
257
267
 
@@ -329,7 +339,7 @@ module Mongo
329
339
  code = BSON::Code.new(code)
330
340
  end
331
341
 
332
- oh = OrderedHash.new
342
+ oh = BSON::OrderedHash.new
333
343
  oh[:$eval] = code
334
344
  oh[:args] = args
335
345
  doc = command(oh)
@@ -346,7 +356,7 @@ module Mongo
346
356
  #
347
357
  # @raise MongoDBError if there's an error renaming the collection.
348
358
  def rename_collection(from, to)
349
- oh = OrderedHash.new
359
+ oh = BSON::OrderedHash.new
350
360
  oh[:renameCollection] = "#{@name}.#{from}"
351
361
  oh[:to] = "#{@name}.#{to}"
352
362
  doc = command(oh, true)
@@ -363,7 +373,7 @@ module Mongo
363
373
  #
364
374
  # @raise MongoDBError if there's an error renaming the collection.
365
375
  def drop_index(collection_name, index_name)
366
- oh = OrderedHash.new
376
+ oh = BSON::OrderedHash.new
367
377
  oh[:deleteIndexes] = collection_name
368
378
  oh[:index] = index_name
369
379
  doc = command(oh)
@@ -494,7 +504,7 @@ module Mongo
494
504
  #
495
505
  # @core profiling profiling_level-instance_method
496
506
  def profiling_level
497
- oh = OrderedHash.new
507
+ oh = BSON::OrderedHash.new
498
508
  oh[:profile] = -1
499
509
  doc = command(oh)
500
510
  raise "Error with profile command: #{doc.inspect}" unless ok?(doc) && doc['was'].kind_of?(Numeric)
@@ -515,7 +525,7 @@ module Mongo
515
525
  #
516
526
  # @param [Symbol] level acceptable options are +:off+, +:slow_only+, or +:all+.
517
527
  def profiling_level=(level)
518
- oh = OrderedHash.new
528
+ oh = BSON::OrderedHash.new
519
529
  oh[:profile] = case level
520
530
  when :off
521
531
  0
@@ -1,3 +1,6 @@
1
+ # encoding: UTF-8
2
+
3
+ #
1
4
  # --
2
5
  # Copyright (C) 2008-2010 10gen Inc.
3
6
  #
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  # --
2
4
  # Copyright (C) 2008-2010 10gen Inc.
3
5
  #
@@ -18,6 +20,8 @@ module Mongo
18
20
 
19
21
  # Implementation of the MongoDB GridFS specification. A file store.
20
22
  class Grid
23
+ include GridExt::InstanceMethods
24
+
21
25
  DEFAULT_FS_NAME = 'fs'
22
26
 
23
27
  # Initialize a new Grid instance, consisting of a MongoDB database
@@ -44,15 +48,15 @@ module Mongo
44
48
  #
45
49
  # @param [String, #read] data a string or io-like object to store.
46
50
  #
47
- # @options opts [String] :filename (nil) a name for the file.
48
- # @options opts [Hash] :metadata ({}) any additional data to store with the file.
49
- # @options opts [ObjectID] :_id (ObjectID) a unique id for
51
+ # @option opts [String] :filename (nil) a name for the file.
52
+ # @option opts [Hash] :metadata ({}) any additional data to store with the file.
53
+ # @option opts [ObjectID] :_id (ObjectID) a unique id for
50
54
  # the file to be use in lieu of an automatically generated one.
51
- # @options opts [String] :content_type ('binary/octet-stream') If no content type is specified,
55
+ # @option opts [String] :content_type ('binary/octet-stream') If no content type is specified,
52
56
  # the content type will may be inferred from the filename extension if the mime-types gem can be
53
57
  # loaded. Otherwise, the content type 'binary/octet-stream' will be used.
54
- # @options opts [Integer] (262144) :chunk_size size of file chunks in bytes.
55
- # @options opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server
58
+ # @option opts [Integer] (262144) :chunk_size size of file chunks in bytes.
59
+ # @option opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server
56
60
  # will be validated using an md5 hash. If validation fails, an exception will be raised.
57
61
  #
58
62
  # @return [Mongo::ObjectID] the file's id.
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  # --
2
4
  # Copyright (C) 2008-2010 10gen Inc.
3
5
  #
@@ -15,16 +17,41 @@
15
17
  # ++
16
18
 
17
19
  module Mongo
18
- module ClassMethods
19
-
20
- def exists?(criteria)
21
- BSON::ObjectID:
22
- @files.find_one(query)
23
- end
20
+ module GridExt
21
+ module InstanceMethods
24
22
 
25
- def list(query={})
26
- @files.find(query)
23
+ # Check the existence of a file matching the given query selector.
24
+ #
25
+ # Note that this method can be used with both the Grid and GridFileSystem classes. Also
26
+ # keep in mind that if you're going to be performing lots of existence checks, you should
27
+ # keep an instance of Grid or GridFileSystem handy rather than instantiating for each existence
28
+ # check. Alternatively, simply keep a reference to the proper files collection and query that
29
+ # as needed. That's exactly how this methods works.
30
+ #
31
+ # @param [Hash] selector a query selector.
32
+ #
33
+ # @example
34
+ #
35
+ # # Check for the existence of a given filename
36
+ # @grid = GridFileSystem.new(@db)
37
+ # @grid.exist?(:filename => 'foo.txt')
38
+ #
39
+ # # Check for existence filename and content type
40
+ # @grid = GridFileSystem.new(@db)
41
+ # @grid.exist?(:filename => 'foo.txt', :content_type => 'image/jpg')
42
+ #
43
+ # # Check for existence by _id
44
+ # @grid = Grid.new(@db)
45
+ # @grid.exist?(:_id => BSON::ObjectID.from_string('4bddcd24beffd95a7db9b8c8'))
46
+ #
47
+ # # Check for existence by an arbitrary attribute.
48
+ # @grid = Grid.new(@db)
49
+ # @grid.exist?(:tags => {'$in' => ['nature', 'zen', 'photography']})
50
+ #
51
+ # @return [nil, Hash] either nil for the file's metadata as a hash.
52
+ def exist?(selector)
53
+ @files.find_one(selector)
54
+ end
27
55
  end
28
-
29
56
  end
30
57
  end
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  # --
2
4
  # Copyright (C) 2008-2010 10gen Inc.
3
5
  #
@@ -19,8 +21,9 @@ module Mongo
19
21
  # A file store built on the GridFS specification featuring
20
22
  # an API and behavior similar to that of a traditional file system.
21
23
  class GridFileSystem
24
+ include GridExt::InstanceMethods
22
25
 
23
- # Initialize a new Grid instance, consisting of a MongoDB database
26
+ # Initialize a new GridFileSystem instance, consisting of a MongoDB database
24
27
  # and a filesystem prefix if not using the default.
25
28
  #
26
29
  # @param [Mongo::DB] db a MongoDB database.
@@ -51,17 +54,17 @@ module Mongo
51
54
  # or writing to the file.
52
55
  # @param [Hash] opts see GridIO#new
53
56
  #
54
- # @options opts [Hash] :metadata ({}) any additional data to store with the file.
55
- # @options opts [ObjectID] :_id (ObjectID) a unique id for
57
+ # @option opts [Hash] :metadata ({}) any additional data to store with the file.
58
+ # @option opts [ObjectID] :_id (ObjectID) a unique id for
56
59
  # the file to be use in lieu of an automatically generated one.
57
- # @options opts [String] :content_type ('binary/octet-stream') If no content type is specified,
60
+ # @option opts [String] :content_type ('binary/octet-stream') If no content type is specified,
58
61
  # the content type will may be inferred from the filename extension if the mime-types gem can be
59
62
  # loaded. Otherwise, the content type 'binary/octet-stream' will be used.
60
- # @options opts [Integer] (262144) :chunk_size size of file chunks in bytes.
61
- # @options opts [Boolean] :delete_old (false) ensure that old versions of the file are deleted. This option
63
+ # @option opts [Integer] (262144) :chunk_size size of file chunks in bytes.
64
+ # @option opts [Boolean] :delete_old (false) ensure that old versions of the file are deleted. This option
62
65
  # only work in 'w' mode. Certain precautions must be taken when deleting GridFS files. See the notes under
63
66
  # GridFileSystem#delete.
64
- # @options opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server
67
+ # @option opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server
65
68
  # will be validated using an md5 hash. If validation fails, an exception will be raised.
66
69
  #
67
70
  # @example
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  # --
2
4
  # Copyright (C) 2008-2010 10gen Inc.
3
5
  #
@@ -43,14 +45,14 @@ module Mongo
43
45
  # @option opts [Hash] :query a query selector used when opening the file in 'r' mode.
44
46
  # @option opts [Hash] :query_opts any query options to be used when opening the file in 'r' mode.
45
47
  # @option opts [String] :fs_name the file system prefix.
46
- # @options opts [Integer] (262144) :chunk_size size of file chunks in bytes.
47
- # @options opts [Hash] :metadata ({}) any additional data to store with the file.
48
- # @options opts [ObjectID] :_id (ObjectID) a unique id for
48
+ # @option opts [Integer] (262144) :chunk_size size of file chunks in bytes.
49
+ # @option opts [Hash] :metadata ({}) any additional data to store with the file.
50
+ # @option opts [ObjectID] :_id (ObjectID) a unique id for
49
51
  # the file to be use in lieu of an automatically generated one.
50
- # @options opts [String] :content_type ('binary/octet-stream') If no content type is specified,
52
+ # @option opts [String] :content_type ('binary/octet-stream') If no content type is specified,
51
53
  # the content type will may be inferred from the filename extension if the mime-types gem can be
52
54
  # loaded. Otherwise, the content type 'binary/octet-stream' will be used.
53
- # @options opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server
55
+ # @option opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server
54
56
  # will be validated using an md5 hash. If validation fails, an exception will be raised.
55
57
  def initialize(files, chunks, filename, mode, opts={})
56
58
  @files = files
@@ -197,7 +199,7 @@ module Mongo
197
199
  private
198
200
 
199
201
  def create_chunk(n)
200
- chunk = OrderedHash.new
202
+ chunk = BSON::OrderedHash.new
201
203
  chunk['_id'] = BSON::ObjectID.new
202
204
  chunk['n'] = n
203
205
  chunk['files_id'] = @files_id
@@ -319,7 +321,7 @@ module Mongo
319
321
  end
320
322
 
321
323
  def to_mongo_object
322
- h = OrderedHash.new
324
+ h = BSON::OrderedHash.new
323
325
  h['_id'] = @files_id
324
326
  h['filename'] = @filename if @filename
325
327
  h['contentType'] = @content_type
@@ -335,7 +337,7 @@ module Mongo
335
337
 
336
338
  # Get a server-side md5 and validate against the client if running in safe mode.
337
339
  def get_md5
338
- md5_command = OrderedHash.new
340
+ md5_command = BSON::OrderedHash.new
339
341
  md5_command['filemd5'] = @files_id
340
342
  md5_command['root'] = @fs_name
341
343
  @server_md5 = @files.db.command(md5_command)['md5']
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  # --
2
4
  # Copyright (C) 2008-2010 10gen Inc.
3
5
  #
@@ -31,7 +33,7 @@ module Mongo #:nodoc:
31
33
  # <tt>array_as_sort_parameters([["field1", :asc], ["field2", :desc]])</tt> =>
32
34
  # <tt>{ "field1" => 1, "field2" => -1}</tt>
33
35
  def array_as_sort_parameters(value)
34
- order_by = OrderedHash.new
36
+ order_by = BSON::OrderedHash.new
35
37
  if value.first.is_a? Array
36
38
  value.each do |param|
37
39
  if (param.class.name == "String")
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  # --
2
4
  # Copyright (C) 2008-2010 10gen Inc.
3
5
  #
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  # --
2
4
  # Copyright (C) 2008-2010 10gen Inc.
3
5
  #
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  # --
2
4
  # Copyright (C) 2008-2010 10gen Inc.
3
5
  #
@@ -150,7 +150,7 @@ class Features14Test < Test::Unit::TestCase
150
150
  end
151
151
 
152
152
  should "use geoNear command to return distances from a point" do
153
- cmd = OrderedHash.new
153
+ cmd = BSON::OrderedHash.new
154
154
  cmd['geoNear'] = 'places'
155
155
  cmd['near'] = @empire_state
156
156
  cmd['num'] = 6
@@ -115,6 +115,39 @@ class TestCollection < Test::Unit::TestCase
115
115
  end
116
116
  end
117
117
 
118
+ if @@version >= "1.5.1"
119
+ def test_safe_mode_with_advanced_safe_with_invalid_options
120
+ assert_raise_error ArgumentError, "Unknown key(s): wtime" do
121
+ @@test.insert({:foo => 1}, :safe => {:w => 2, :wtime => 1, :fsync => true})
122
+ end
123
+ assert_raise_error ArgumentError, "Unknown key(s): wtime" do
124
+ @@test.update({:foo => 1}, {:foo => 2}, :safe => {:w => 2, :wtime => 1, :fsync => true})
125
+ end
126
+
127
+ assert_raise_error ArgumentError, "Unknown key(s): wtime" do
128
+ @@test.remove({:foo => 2}, :safe => {:w => 2, :wtime => 1, :fsync => true})
129
+ end
130
+ end
131
+
132
+ def test_safe_mode_with_w_failure
133
+ assert_raise_error OperationFailure, "timed out waiting for slaves" do
134
+ @@test.insert({:foo => 1}, :safe => {:w => 2, :wtimeout => 1, :fsync => true})
135
+ end
136
+ assert_raise_error OperationFailure, "timed out waiting for slaves" do
137
+ @@test.update({:foo => 1}, {:foo => 2}, :safe => {:w => 2, :wtimeout => 1, :fsync => true})
138
+ end
139
+ assert_raise_error OperationFailure, "timed out waiting for slaves" do
140
+ @@test.remove({:foo => 2}, :safe => {:w => 2, :wtimeout => 1, :fsync => true})
141
+ end
142
+ end
143
+
144
+ def test_safe_mode_with_write_and_fsync
145
+ assert @@test.insert({:foo => 1}, :safe => {:w => 1, :wtimeout => 1, :fsync => true})
146
+ assert @@test.update({:foo => 1}, {:foo => 2}, :safe => {:w => 1, :wtimeout => 1, :fsync => true})
147
+ assert @@test.remove({:foo => 2}, :safe => {:w => 1, :wtimeout => 1, :fsync => true})
148
+ end
149
+ end
150
+
118
151
  def test_update
119
152
  id1 = @@test.save("x" => 5)
120
153
  @@test.update({}, {"$inc" => {"x" => 1}})
@@ -272,6 +305,16 @@ class TestCollection < Test::Unit::TestCase
272
305
  end
273
306
  end
274
307
 
308
+ if @@version >= "1.5.1"
309
+ def test_fields_with_slice
310
+ @@test.save({:foo => [1, 2, 3, 4, 5, 6], :test => 'slice'})
311
+
312
+ doc = @@test.find_one({:test => 'slice'}, :fields => {'foo' => {'$slice' => [0, 3]}})
313
+ assert_equal [1, 2, 3], doc['foo']
314
+ @@test.remove
315
+ end
316
+ end
317
+
275
318
  def test_find_one
276
319
  id = @@test.save("hello" => "world", "foo" => "bar")
277
320
 
@@ -280,14 +323,14 @@ class TestCollection < Test::Unit::TestCase
280
323
  assert_equal @@test.find_one(nil), @@test.find_one()
281
324
  assert_equal @@test.find_one({}), @@test.find_one()
282
325
  assert_equal @@test.find_one("hello" => "world"), @@test.find_one()
283
- assert_equal @@test.find_one(OrderedHash["hello", "world"]), @@test.find_one()
326
+ assert_equal @@test.find_one(BSON::OrderedHash["hello", "world"]), @@test.find_one()
284
327
 
285
328
  assert @@test.find_one(nil, :fields => ["hello"]).include?("hello")
286
329
  assert !@@test.find_one(nil, :fields => ["foo"]).include?("hello")
287
330
  assert_equal ["_id"], @@test.find_one(nil, :fields => []).keys()
288
331
 
289
332
  assert_equal nil, @@test.find_one("hello" => "foo")
290
- assert_equal nil, @@test.find_one(OrderedHash["hello", "foo"])
333
+ assert_equal nil, @@test.find_one(BSON::OrderedHash["hello", "foo"])
291
334
  assert_equal nil, @@test.find_one(ObjectID.new)
292
335
 
293
336
  assert_raise TypeError do
@@ -3,7 +3,6 @@ require 'logger'
3
3
  require 'stringio'
4
4
  require 'thread'
5
5
 
6
- # NOTE: assumes Mongo is running
7
6
  class TestConnection < Test::Unit::TestCase
8
7
 
9
8
  include Mongo
@@ -1,7 +1,6 @@
1
1
  require 'test/test_helper'
2
2
  require 'logger'
3
3
 
4
- # NOTE: assumes Mongo is running
5
4
  class CursorTest < Test::Unit::TestCase
6
5
 
7
6
  include Mongo
@@ -1,6 +1,5 @@
1
1
  require 'test/test_helper'
2
2
 
3
- # NOTE: assumes Mongo is running
4
3
  class DBAPITest < Test::Unit::TestCase
5
4
  include Mongo
6
5
  include BSON
@@ -47,14 +46,14 @@ class DBAPITest < Test::Unit::TestCase
47
46
  end
48
47
 
49
48
  def test_save_ordered_hash
50
- oh = OrderedHash.new
49
+ oh = BSON::OrderedHash.new
51
50
  oh['a'] = -1
52
51
  oh['b'] = 'foo'
53
52
 
54
53
  oid = @@coll.save(oh)
55
54
  assert_equal 'foo', @@coll.find_one(oid)['b']
56
55
 
57
- oh = OrderedHash['a' => 1, 'b' => 'foo']
56
+ oh = BSON::OrderedHash['a' => 1, 'b' => 'foo']
58
57
  oid = @@coll.save(oh)
59
58
  assert_equal 'foo', @@coll.find_one(oid)['b']
60
59
  end
@@ -188,7 +187,7 @@ class DBAPITest < Test::Unit::TestCase
188
187
 
189
188
  # Sorting using ordered hash. You can use an unordered one, but then the
190
189
  # order of the keys won't be guaranteed thus your sort won't make sense.
191
- oh = OrderedHash.new
190
+ oh = BSON::OrderedHash.new
192
191
  oh['a'] = -1
193
192
  assert_raise InvalidSortValueError do
194
193
  docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => oh).to_a
@@ -470,8 +469,18 @@ class DBAPITest < Test::Unit::TestCase
470
469
  @@coll.insert('a' => 3)
471
470
 
472
471
  assert_equal 3, @@coll.count
473
- assert_equal 1, @@coll.find('$where' => Code.new('this.a > 2')).count()
474
- assert_equal 2, @@coll.find('$where' => Code.new('this.a > i', {'i' => 1})).count()
472
+ assert_equal 1, @@coll.find('$where' => BSON::Code.new('this.a > 2')).count()
473
+ assert_equal 2, @@coll.find('$where' => BSON::Code.new('this.a > i', {'i' => 1})).count()
474
+ end
475
+
476
+ def test_implicit_where
477
+ @@coll.remove
478
+ @@coll.insert('a' => 2)
479
+ @@coll.insert('a' => 3)
480
+
481
+ assert_equal 2, @@coll.count
482
+ assert_equal 1, @@coll.find('this.a > 2').count()
483
+ assert_equal 2, @@coll.find(BSON::Code.new('this.a > z', {'z' => 1})).to_a.length
475
484
  end
476
485
 
477
486
  def test_eval
@@ -1,6 +1,5 @@
1
1
  require 'test/test_helper'
2
2
 
3
- # NOTE: assumes Mongo is running
4
3
  class DBConnectionTest < Test::Unit::TestCase
5
4
 
6
5
  include Mongo
@@ -10,7 +10,6 @@ class TestPKFactory
10
10
  end
11
11
  end
12
12
 
13
- # NOTE: assumes Mongo is running
14
13
  class DBTest < Test::Unit::TestCase
15
14
 
16
15
  include Mongo
@@ -183,6 +182,24 @@ class DBTest < Test::Unit::TestCase
183
182
  assert_nil @@db.previous_error
184
183
  end
185
184
 
185
+ if @@version >= "1.5.1"
186
+ def test_failing_error_params
187
+ assert_raise_error Mongo::MongoDBError, "timed out waiting for slaves" do
188
+ @@db.error(:w => 2, :wtimeout => 10, :fsync => true)
189
+ end
190
+ end
191
+
192
+ def test_passing_error_params
193
+ assert_nil @@db.error(:w => 1, :wtimeout => 10, :fsync => true)
194
+ end
195
+
196
+ def test_invalid_error_params
197
+ assert_raise_error ArgumentError, "Unknown key(s): z" do
198
+ @@db.error(:z => 1, :wtimeout => 10, :fsync => true)
199
+ end
200
+ end
201
+ end
202
+
186
203
  def test_check_command_response
187
204
  command = {:forceerror => 1}
188
205
  assert_raise OperationFailure do
@@ -25,6 +25,15 @@ class GridFileSystemTest < Test::Unit::TestCase
25
25
  @grid = GridFileSystem.new(@db)
26
26
  end
27
27
 
28
+ should "return existence of the file" do
29
+ file = @grid.exist?(:filename => 'sample.file')
30
+ assert_equal 'sample.file', file['filename']
31
+ end
32
+
33
+ should "return nil if the file doesn't exist" do
34
+ assert_nil @grid.exist?(:filename => 'foo.file')
35
+ end
36
+
28
37
  should "read sample data" do
29
38
  data = @grid.open('sample.file', 'r') { |f| f.read }
30
39
  assert_equal data.length, @chunks_data.length
@@ -22,6 +22,15 @@ class GridTest < Test::Unit::TestCase
22
22
  @id = @grid.put(@data, :filename => 'sample', :metadata => {'app' => 'photos'})
23
23
  end
24
24
 
25
+ should "check existence" do
26
+ file = @grid.exist?(:filename => 'sample')
27
+ assert_equal 'sample', file['filename']
28
+ end
29
+
30
+ should "return nil if it doesn't exist" do
31
+ assert_nil @grid.exist?(:metadata => 'foo')
32
+ end
33
+
25
34
  should "retrieve the stored data" do
26
35
  data = @grid.get(@id).data
27
36
  assert_equal @data, data
@@ -23,7 +23,6 @@ require 'bson_ext/cbson' if ENV['C_EXT']
23
23
 
24
24
  MONGO_TEST_DB = 'mongo-ruby-test'
25
25
 
26
- # NOTE: most tests assume that MongoDB is running.
27
26
  class Test::Unit::TestCase
28
27
  include Mongo
29
28
  include BSON
@@ -42,4 +41,13 @@ class Test::Unit::TestCase
42
41
  end
43
42
  end
44
43
  end
44
+
45
+ def assert_raise_error(klass, message)
46
+ begin
47
+ yield
48
+ rescue => e
49
+ assert_equal klass, e.class
50
+ assert e.message.include?(message), "#{e.message} does not include #{message}."
51
+ end
52
+ end
45
53
  end
metadata CHANGED
@@ -1,11 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 1
7
- - 0
8
- version: "1.0"
4
+ version: 1.0.1
9
5
  platform: ruby
10
6
  authors:
11
7
  - Jim Menard
@@ -15,22 +11,19 @@ autorequire:
15
11
  bindir: bin
16
12
  cert_chain: []
17
13
 
18
- date: 2010-04-29 00:00:00 -04:00
14
+ date: 2010-05-07 00:00:00 -04:00
19
15
  default_executable:
20
16
  dependencies:
21
17
  - !ruby/object:Gem::Dependency
22
18
  name: bson
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
19
+ type: :runtime
20
+ version_requirement:
21
+ version_requirements: !ruby/object:Gem::Requirement
25
22
  requirements:
26
23
  - - "="
27
24
  - !ruby/object:Gem::Version
28
- segments:
29
- - 1
30
- - 0
31
- version: "1.0"
32
- type: :runtime
33
- version_requirements: *id001
25
+ version: 1.0.1
26
+ version:
34
27
  description: A Ruby driver for MongoDB. For more information about Mongo, see http://www.mongodb.org.
35
28
  email: mongodb-dev@googlegroups.com
36
29
  executables: []
@@ -85,20 +78,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
85
78
  requirements:
86
79
  - - ">="
87
80
  - !ruby/object:Gem::Version
88
- segments:
89
- - 0
90
81
  version: "0"
82
+ version:
91
83
  required_rubygems_version: !ruby/object:Gem::Requirement
92
84
  requirements:
93
85
  - - ">="
94
86
  - !ruby/object:Gem::Version
95
- segments:
96
- - 0
97
87
  version: "0"
88
+ version:
98
89
  requirements: []
99
90
 
100
91
  rubyforge_project:
101
- rubygems_version: 1.3.6
92
+ rubygems_version: 1.3.5
102
93
  signing_key:
103
94
  specification_version: 3
104
95
  summary: Ruby driver for the MongoDB