From 7b895233151a77800e27362fa4d2a7d58d20ff03 Mon Sep 17 00:00:00 2001 From: Kyle Banker Date: Wed, 5 May 2010 11:07:52 -0400 Subject: [PATCH] added Grid#exist? and GridFileSystem#exist? RUBY-122 --- lib/mongo.rb | 1 + lib/mongo/collection.rb | 2 +- lib/mongo/gridfs/grid.rb | 14 ++++--- lib/mongo/gridfs/grid_ext.rb | 55 ++++++++++++++++++++++++++++ lib/mongo/gridfs/grid_file_system.rb | 15 ++++---- lib/mongo/gridfs/grid_io.rb | 10 ++--- test/grid_file_system_test.rb | 9 +++++ test/grid_test.rb | 9 +++++ test/mongo_bson/bson_test.rb | 2 +- 9 files changed, 97 insertions(+), 20 deletions(-) create mode 100644 lib/mongo/gridfs/grid_ext.rb diff --git a/lib/mongo.rb b/lib/mongo.rb index efc4dfd..5913ddd 100644 --- a/lib/mongo.rb +++ b/lib/mongo.rb @@ -40,6 +40,7 @@ require 'mongo/connection' require 'mongo/cursor' require 'mongo/db' require 'mongo/exceptions' +require 'mongo/gridfs/grid_ext' require 'mongo/gridfs/grid' require 'mongo/gridfs/grid_io' require 'mongo/gridfs/grid_file_system' diff --git a/lib/mongo/collection.rb b/lib/mongo/collection.rb index 8574ba9..08f005b 100644 --- a/lib/mongo/collection.rb +++ b/lib/mongo/collection.rb @@ -209,7 +209,7 @@ module Mongo # run an fsync and/or wait for replication of the save (>= 1.5.1). See the options # for DB#error. # - # @raises [OperationFailure] when :safe mode fails. + # @raise [OperationFailure] when :safe mode fails. # # @see DB#remove for options that can be passed to :safe. def save(doc, opts={}) diff --git a/lib/mongo/gridfs/grid.rb b/lib/mongo/gridfs/grid.rb index 7c27b84..a2dea1e 100644 --- a/lib/mongo/gridfs/grid.rb +++ b/lib/mongo/gridfs/grid.rb @@ -18,6 +18,8 @@ module Mongo # Implementation of the MongoDB GridFS specification. A file store. class Grid + include GridExt::InstanceMethods + DEFAULT_FS_NAME = 'fs' # Initialize a new Grid instance, consisting of a MongoDB database @@ -44,15 +46,15 @@ module Mongo # # @param [String, #read] data a string or io-like object to store. # - # @options opts [String] :filename (nil) a name for the file. - # @options opts [Hash] :metadata ({}) any additional data to store with the file. - # @options opts [ObjectID] :_id (ObjectID) a unique id for + # @option opts [String] :filename (nil) a name for the file. + # @option opts [Hash] :metadata ({}) any additional data to store with the file. + # @option opts [ObjectID] :_id (ObjectID) a unique id for # the file to be use in lieu of an automatically generated one. - # @options opts [String] :content_type ('binary/octet-stream') If no content type is specified, + # @option opts [String] :content_type ('binary/octet-stream') If no content type is specified, # the content type will may be inferred from the filename extension if the mime-types gem can be # loaded. Otherwise, the content type 'binary/octet-stream' will be used. - # @options opts [Integer] (262144) :chunk_size size of file chunks in bytes. - # @options opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server + # @option opts [Integer] (262144) :chunk_size size of file chunks in bytes. + # @option opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server # will be validated using an md5 hash. If validation fails, an exception will be raised. # # @return [Mongo::ObjectID] the file's id. diff --git a/lib/mongo/gridfs/grid_ext.rb b/lib/mongo/gridfs/grid_ext.rb new file mode 100644 index 0000000..98a367d --- /dev/null +++ b/lib/mongo/gridfs/grid_ext.rb @@ -0,0 +1,55 @@ +# -- +# Copyright (C) 2008-2010 10gen Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ++ + +module Mongo + module GridExt + module InstanceMethods + + # Check the existence of a file matching the given query selector. + # + # Note that this method can be used with both the Grid and GridFileSystem classes. Also + # keep in mind that if you're going to be performing lots of existence checks, you should + # keep an instance of Grid or GridFileSystem handy rather than instantiating for each existence + # check. Alternatively, simply keep a reference to the proper files collection and query that + # as needed. That's exactly how this methods works. + # + # @param [Hash] selector a query selector. + # + # @example + # + # # Check for the existence of a given filename + # @grid = GridFileSystem.new(@db) + # @grid.exist?(:filename => 'foo.txt') + # + # # Check for existence filename and content type + # @grid = GridFileSystem.new(@db) + # @grid.exist?(:filename => 'foo.txt', :content_type => 'image/jpg') + # + # # Check for existence by _id + # @grid = Grid.new(@db) + # @grid.exist?(:_id => BSON::ObjectID.from_string('4bddcd24beffd95a7db9b8c8')) + # + # # Check for existence by an arbitrary attribute. + # @grid = Grid.new(@db) + # @grid.exist?(:tags => {'$in' => ['nature', 'zen', 'photography']}) + # + # @return [nil, Hash] either nil for the file's metadata as a hash. + def exist?(selector) + @files.find_one(selector) + end + end + end +end diff --git a/lib/mongo/gridfs/grid_file_system.rb b/lib/mongo/gridfs/grid_file_system.rb index e040da8..d740529 100644 --- a/lib/mongo/gridfs/grid_file_system.rb +++ b/lib/mongo/gridfs/grid_file_system.rb @@ -19,8 +19,9 @@ module Mongo # A file store built on the GridFS specification featuring # an API and behavior similar to that of a traditional file system. class GridFileSystem + include GridExt::InstanceMethods - # Initialize a new Grid instance, consisting of a MongoDB database + # Initialize a new GridFileSystem instance, consisting of a MongoDB database # and a filesystem prefix if not using the default. # # @param [Mongo::DB] db a MongoDB database. @@ -51,17 +52,17 @@ module Mongo # or writing to the file. # @param [Hash] opts see GridIO#new # - # @options opts [Hash] :metadata ({}) any additional data to store with the file. - # @options opts [ObjectID] :_id (ObjectID) a unique id for + # @option opts [Hash] :metadata ({}) any additional data to store with the file. + # @option opts [ObjectID] :_id (ObjectID) a unique id for # the file to be use in lieu of an automatically generated one. - # @options opts [String] :content_type ('binary/octet-stream') If no content type is specified, + # @option opts [String] :content_type ('binary/octet-stream') If no content type is specified, # the content type will may be inferred from the filename extension if the mime-types gem can be # loaded. Otherwise, the content type 'binary/octet-stream' will be used. - # @options opts [Integer] (262144) :chunk_size size of file chunks in bytes. - # @options opts [Boolean] :delete_old (false) ensure that old versions of the file are deleted. This option + # @option opts [Integer] (262144) :chunk_size size of file chunks in bytes. + # @option opts [Boolean] :delete_old (false) ensure that old versions of the file are deleted. This option # only work in 'w' mode. Certain precautions must be taken when deleting GridFS files. See the notes under # GridFileSystem#delete. - # @options opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server + # @option opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server # will be validated using an md5 hash. If validation fails, an exception will be raised. # # @example diff --git a/lib/mongo/gridfs/grid_io.rb b/lib/mongo/gridfs/grid_io.rb index 5fba742..bd7c221 100644 --- a/lib/mongo/gridfs/grid_io.rb +++ b/lib/mongo/gridfs/grid_io.rb @@ -43,14 +43,14 @@ module Mongo # @option opts [Hash] :query a query selector used when opening the file in 'r' mode. # @option opts [Hash] :query_opts any query options to be used when opening the file in 'r' mode. # @option opts [String] :fs_name the file system prefix. - # @options opts [Integer] (262144) :chunk_size size of file chunks in bytes. - # @options opts [Hash] :metadata ({}) any additional data to store with the file. - # @options opts [ObjectID] :_id (ObjectID) a unique id for + # @option opts [Integer] (262144) :chunk_size size of file chunks in bytes. + # @option opts [Hash] :metadata ({}) any additional data to store with the file. + # @option opts [ObjectID] :_id (ObjectID) a unique id for # the file to be use in lieu of an automatically generated one. - # @options opts [String] :content_type ('binary/octet-stream') If no content type is specified, + # @option opts [String] :content_type ('binary/octet-stream') If no content type is specified, # the content type will may be inferred from the filename extension if the mime-types gem can be # loaded. Otherwise, the content type 'binary/octet-stream' will be used. - # @options opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server + # @option opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server # will be validated using an md5 hash. If validation fails, an exception will be raised. def initialize(files, chunks, filename, mode, opts={}) @files = files diff --git a/test/grid_file_system_test.rb b/test/grid_file_system_test.rb index fb2c420..020db8c 100644 --- a/test/grid_file_system_test.rb +++ b/test/grid_file_system_test.rb @@ -25,6 +25,15 @@ class GridFileSystemTest < Test::Unit::TestCase @grid = GridFileSystem.new(@db) end + should "return existence of the file" do + file = @grid.exist?(:filename => 'sample.file') + assert_equal 'sample.file', file['filename'] + end + + should "return nil if the file doesn't exist" do + assert_nil @grid.exist?(:filename => 'foo.file') + end + should "read sample data" do data = @grid.open('sample.file', 'r') { |f| f.read } assert_equal data.length, @chunks_data.length diff --git a/test/grid_test.rb b/test/grid_test.rb index 2eb2663..6aab643 100644 --- a/test/grid_test.rb +++ b/test/grid_test.rb @@ -22,6 +22,15 @@ class GridTest < Test::Unit::TestCase @id = @grid.put(@data, :filename => 'sample', :metadata => {'app' => 'photos'}) end + should "check existence" do + file = @grid.exist?(:filename => 'sample') + assert_equal 'sample', file['filename'] + end + + should "return nil if it doesn't exist" do + assert_nil @grid.exist?(:metadata => 'foo') + end + should "retrieve the stored data" do data = @grid.get(@id).data assert_equal @data, data diff --git a/test/mongo_bson/bson_test.rb b/test/mongo_bson/bson_test.rb index 784fe80..0290802 100644 --- a/test/mongo_bson/bson_test.rb +++ b/test/mongo_bson/bson_test.rb @@ -369,7 +369,7 @@ class BSONTest < Test::Unit::TestCase # note we only test for _id here because in the general case we will # write duplicates for :key and "key". _id is a special case because - # we call has_key? to check for it's existance rather than just iterating + # we call has_key? to check for it's existence rather than just iterating # over it like we do for the rest of the keys. thus, things like # HashWithIndifferentAccess can cause problems for _id but not for other # keys. rather than require rails to test with HWIA directly, we do this