Class: Mongo::Grid::FSBucket
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
Forwardable
|
|
Inherits: | Object |
Defined in: | lib/mongo/grid/fs_bucket.rb, lib/mongo/grid/stream.rb, lib/mongo/grid/stream/read.rb, lib/mongo/grid/stream/write.rb |
Overview
Represents a view of the GridFS in the database.
Constant Summary
-
CHUNKS_INDEX =
The specification for the chunks collection index.
{ :files_id => 1, :n => 1 }.freeze
-
DEFAULT_ROOT =
The default root prefix.
'fs'.freeze
-
FILES_INDEX =
The specification for the files collection index.
{ filename: 1, uploadDate: 1 }.freeze
Class Method Summary
-
.new(database, options = {}) ⇒ FSBucket
constructor
Create the GridFS.
Instance Attribute Summary
- #chunks_collection ⇒ Collection readonly
- #database ⇒ Database readonly
- #files_collection ⇒ Collection readonly
- #options ⇒ Hash readonly
Instance Method Summary
-
#delete(id, opts = {}) ⇒ Result
Remove a single file, identified by its id from the GridFS.
-
#delete_one(file, opts = {}) ⇒ Result
Remove a single file from the GridFS.
-
#download_to_stream(id, io)
Downloads the contents of the file specified by id and writes them to the destination io object.
-
#download_to_stream_by_name(filename, io, opts = {})
Downloads the contents of the stored file specified by filename and by the revision in options and writes the contents to the destination io object.
-
#drop(opts = {})
Drop the collections that implement this bucket.
-
#find(selector = nil, options = {}) ⇒ CollectionView
Find files collection documents matching a given selector.
-
#find_one(selector = nil) ⇒ Grid::File
deprecated
Deprecated.
Please use #find instead with a limit of -1. Will be removed in version 3.0.
-
#insert_one(file) ⇒ BSON::ObjectId
deprecated
Deprecated.
Please use #upload_from_stream or #open_upload_stream instead. Will be removed in version 3.0.
-
#open_download_stream(id, options = nil) {|The| ... } ⇒ Stream::Read
Opens a stream from which a file can be downloaded, specified by id.
-
#open_download_stream_by_name(filename, opts = {}) {|The| ... } ⇒ Stream::Read
Opens a stream from which the application can read the contents of the stored file specified by filename and the revision in options.
-
#open_upload_stream(filename, opts = {}) {|The| ... } ⇒ Stream::Write
Opens an upload stream to GridFS to which the contents of a file or blob can be written.
-
#prefix ⇒ String
Get the prefix for the GridFS.
-
#read_preference ⇒ BSON::Document
Get the read preference.
-
#upload_from_stream(filename, io, opts = {}) ⇒ BSON::ObjectId
Uploads a user file to a GridFS bucket.
-
#write_concern ⇒ Mongo::WriteConcern
Get the write concern.
- #chunks_name private
- #create_index_if_missing!(collection, index_spec, options = {}) private
- #ensure_indexes!(timeout_holder = nil) private
- #files_name private
- #operation_timeouts(opts = {}) ⇒ Hash private Internal use only Internal use only
- #read_stream(id, **opts) private
- #write_stream(filename, **opts) private
Constructor Details
.new(database, options = {}) ⇒ FSBucket
Create the GridFS.
# File 'lib/mongo/grid/fs_bucket.rb', line 70
def initialize(database, = {}) @database = database @options = .dup =begin WriteConcern object support if @options[:write_concern].is_a?(WriteConcern::Base) # Cache the instance so that we do not needlessly reconstruct it. @write_concern = @options[:write_concern] @options[:write_concern] = @write_concern.options end =end @options.freeze @chunks_collection = database[chunks_name] @files_collection = database[files_name] end
Instance Attribute Details
#chunks_collection ⇒ Collection (readonly)
# File 'lib/mongo/grid/fs_bucket.rb', line 88
attr_reader :chunks_collection
#database ⇒ Database (readonly)
# File 'lib/mongo/grid/fs_bucket.rb', line 93
attr_reader :database
#files_collection ⇒ Collection (readonly)
# File 'lib/mongo/grid/fs_bucket.rb', line 98
attr_reader :files_collection
#options ⇒ Hash
(readonly)
# File 'lib/mongo/grid/fs_bucket.rb', line 103
attr_reader :
Instance Method Details
#chunks_name (private)
# File 'lib/mongo/grid/fs_bucket.rb', line 513
def chunks_name "#{prefix}.#{Grid::File::Chunk::COLLECTION}" end
#create_index_if_missing!(collection, index_spec, options = {}) (private)
# File 'lib/mongo/grid/fs_bucket.rb', line 543
def create_index_if_missing!(collection, index_spec, = {}) indexes_view = collection.indexes begin if indexes_view.get(index_spec).nil? indexes_view.create_one(index_spec, ) end rescue Mongo::Error::OperationFailure::Family => e # proceed with index creation if a NamespaceNotFound error is thrown if e.code == 26 indexes_view.create_one(index_spec, ) else raise end end end
#delete(id, opts = {}) ⇒ Result
Remove a single file, identified by its id from the GridFS.
# File 'lib/mongo/grid/fs_bucket.rb', line 220
def delete(id, opts = {}) timeout_holder = CsotTimeoutHolder.new(operation_timeouts: operation_timeouts(opts)) result = files_collection .find({ :_id => id }, @options.merge(timeout_ms: timeout_holder.remaining_timeout_ms)) .delete_one(timeout_ms: timeout_holder.remaining_timeout_ms) chunks_collection .find({ :files_id => id }, @options.merge(timeout_ms: timeout_holder.remaining_timeout_ms)) .delete_many(timeout_ms: timeout_holder.remaining_timeout_ms) raise Error::FileNotFound.new(id, :id) if result.n == 0 result end
#delete_one(file, opts = {}) ⇒ Result
Remove a single file from the GridFS.
# File 'lib/mongo/grid/fs_bucket.rb', line 204
def delete_one(file, opts = {}) delete(file.id, opts) end
#download_to_stream(id, io)
Downloads the contents of the file specified by id and writes them to the destination io object.
# File 'lib/mongo/grid/fs_bucket.rb', line 271
def download_to_stream(id, io) open_download_stream(id) do |stream| stream.each do |chunk| io << chunk end end end
#download_to_stream_by_name(filename, io, opts = {})
Downloads the contents of the stored file specified by filename and by the revision in options and writes the contents to the destination io object.
Revision numbers are defined as follows: 0 = the original stored file 1 = the first revision 2 = the second revision etc…-2 = the second most recent revision -1 = the most recent revision
@example Download the original file.
fs.download_to_stream_by_name('some-file.txt', io, revision: 0)
# File 'lib/mongo/grid/fs_bucket.rb', line 364
def download_to_stream_by_name(filename, io, opts = {}) download_to_stream(open_download_stream_by_name(filename, opts).file_id, io) end
#drop(opts = {})
Drop the collections that implement this bucket.
# File 'lib/mongo/grid/fs_bucket.rb', line 493
def drop(opts = {}) context = Operation::Context.new(operation_timeouts: operation_timeouts(opts)) files_collection.drop(timeout_ms: context.remaining_timeout_ms) chunks_collection.drop(timeout_ms: context.remaining_timeout_ms) end
#ensure_indexes!(timeout_holder = nil) (private)
# File 'lib/mongo/grid/fs_bucket.rb', line 521
def ensure_indexes!(timeout_holder = nil) fc_idx = files_collection.find( {}, limit: 1, projection: { _id: 1 }, timeout_ms: timeout_holder&.remaining_timeout_ms ).first if fc_idx.nil? create_index_if_missing!(files_collection, FSBucket::FILES_INDEX) end cc_idx = chunks_collection.find( {}, limit: 1, projection: { _id: 1 }, timeout_ms: timeout_holder&.remaining_timeout_ms ).first if cc_idx.nil? create_index_if_missing!(chunks_collection, FSBucket::CHUNKS_INDEX, :unique => true) end end
#files_name (private)
# File 'lib/mongo/grid/fs_bucket.rb', line 517
def files_name "#{prefix}.#{Grid::File::Info::COLLECTION}" end
#find(selector = nil, options = {}) ⇒ CollectionView
Find files collection documents matching a given selector.
# File 'lib/mongo/grid/fs_bucket.rb', line 134
def find(selector = nil, = {}) opts = .merge(read: read_preference) if read_preference files_collection.find(selector, opts || ) end
#find_one(selector = nil) ⇒ Grid::File
Please use #find instead with a limit of -1. Will be removed in version 3.0.
Find a file in the GridFS.
# File 'lib/mongo/grid/fs_bucket.rb', line 155
def find_one(selector = nil) file_info = files_collection.find(selector).first return nil unless file_info chunks = chunks_collection.find(:files_id => file_info[:_id]).sort(:n => 1) Grid::File.new(chunks.to_a, Options::Mapper.transform(file_info, Grid::File::Info::MAPPINGS.invert)) end
#insert_one(file) ⇒ BSON::ObjectId
Please use #upload_from_stream or #open_upload_stream instead. Will be removed in version 3.0.
Insert a single file into the GridFS.
# File 'lib/mongo/grid/fs_bucket.rb', line 175
def insert_one(file) @indexes ||= ensure_indexes! chunks_collection.insert_many(file.chunks) files_collection.insert_one(file.info) file.id end
#open_download_stream(id, options = nil) {|The| ... } ⇒ Stream::Read
Opens a stream from which a file can be downloaded, specified by id.
# File 'lib/mongo/grid/fs_bucket.rb', line 248
def open_download_stream(id, = nil) = Utils.shallow_symbolize_keys( || {}) read_stream(id, ** ).tap do |stream| if block_given? begin yield stream ensure stream.close end end end end
#open_download_stream_by_name(filename, opts = {}) {|The| ... } ⇒ Stream::Read
Opens a stream from which the application can read the contents of the stored file specified by filename and the revision in options.
Revision numbers are defined as follows: 0 = the original stored file 1 = the first revision 2 = the second revision etc…-2 = the second most recent revision -1 = the most recent revision
@example Open a stream to download the original file.
fs.open_download_stream_by_name('some-file.txt', revision: 0)
# File 'lib/mongo/grid/fs_bucket.rb', line 313
def open_download_stream_by_name(filename, opts = {}, &block) revision = opts.fetch(:revision, -1) if revision < 0 skip = revision.abs - 1 sort = { 'uploadDate' => Mongo::Index::DESCENDING } else skip = revision sort = { 'uploadDate' => Mongo::Index::ASCENDING } end file_info_doc = files_collection.find({ filename: filename} , sort: sort, skip: skip, limit: -1).first unless file_info_doc raise Error::FileNotFound.new(filename, :filename) unless opts[:revision] raise Error::InvalidFileRevision.new(filename, opts[:revision]) end open_download_stream(file_info_doc[:_id], file_info_doc: file_info_doc, &block) end
#open_upload_stream(filename, opts = {}) {|The| ... } ⇒ Stream::Write
Opens an upload stream to GridFS to which the contents of a file or blob can be written.
# File 'lib/mongo/grid/fs_bucket.rb', line 394
def open_upload_stream(filename, opts = {}) opts = Utils.shallow_symbolize_keys(opts) write_stream(filename, **opts).tap do |stream| if block_given? begin yield stream ensure stream.close end end end end
#operation_timeouts(opts = {}) ⇒ Hash
(private)
# File 'lib/mongo/grid/fs_bucket.rb', line 563
def operation_timeouts(opts = {}) # TODO: We should re-evaluate if we need two timeouts separately. {}.tap do |result| if opts[:timeout_ms].nil? result[:inherited_timeout_ms] = database.timeout_ms else result[:operation_timeout_ms] = opts[:timeout_ms] end end end
#prefix ⇒ String
Get the prefix for the GridFS
# File 'lib/mongo/grid/fs_bucket.rb', line 190
def prefix @options[:fs_name] || @options[:bucket_name] || DEFAULT_ROOT end
#read_preference ⇒ BSON::Document
This method always returns a BSON::Document instance, even though the FSBucket
constructor specifies the type of :read
as a Hash, not as a BSON::Document.
Get the read preference.
#read_stream(id, **opts) (private)
#upload_from_stream(filename, io, opts = {}) ⇒ BSON::ObjectId
Uploads a user file to a GridFS bucket. Reads the contents of the user file from the source stream and uploads it as chunks in the chunks collection. After all the chunks have been uploaded, it creates a files collection document for the filename in the files collection.
# File 'lib/mongo/grid/fs_bucket.rb', line 435
def upload_from_stream(filename, io, opts = {}) open_upload_stream(filename, opts) do |stream| begin stream.write(io) # IOError and SystemCallError are for errors reading the io. # Error::SocketError and Error::SocketTimeoutError are for # writing to MongoDB. rescue IOError, SystemCallError, Error::SocketError, Error::SocketTimeoutError begin stream.abort rescue Error::OperationFailure end raise end end.file_id end
#write_concern ⇒ Mongo::WriteConcern
Get the write concern.
# File 'lib/mongo/grid/fs_bucket.rb', line 484
def write_concern @write_concern ||= if wco = @options[:write_concern] || @options[:write] WriteConcern.get(wco) else database.write_concern end end
#write_stream(filename, **opts) (private)
# File 'lib/mongo/grid/fs_bucket.rb', line 509
def write_stream(filename, **opts) Stream.get(self, Stream::WRITE_MODE, { filename: filename }.update( ).update(opts)) end