class Shrine::Storage::Gridfs
Attributes
bucket[R]
chunk_size[R]
client[R]
prefix[R]
Public Class Methods
new(client:, prefix: "fs", chunk_size: 256*1024, batch_size: 5 * 1024*1024, **options)
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 11 def initialize(client:, prefix: "fs", chunk_size: 256*1024, batch_size: 5 * 1024*1024, **options) @client = client @prefix = prefix @chunk_size = chunk_size @batch_size = batch_size @bucket = @client.database.fs(bucket_name: @prefix) @bucket.send(:ensure_indexes!) end
Public Instance Methods
clear!()
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 53 def clear! files_collection.find.delete_many chunks_collection.find.delete_many end
delete(id)
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 45 def delete(id) bucket.delete(bson_id(id)) rescue Mongo::Error::FileNotFound end
exists?(id)
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 41 def exists?(id) !!file_info(id) end
open(id, rewindable: true, **)
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 29 def open(id, rewindable: true, **) info = file_info(id) or raise Shrine::FileNotFound, "file #{id.inspect} not found on storage" stream = bucket.open_download_stream(bson_id(id)) Down::ChunkedIO.new( size: info[:length], chunks: stream.enum_for(:each), on_close: -> { stream.close }, rewindable: rewindable, ) end
upload(io, id, shrine_metadata: {}, **)
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 21 def upload(io, id, shrine_metadata: {}, **) if copyable?(io, id) copy(io, id, shrine_metadata: shrine_metadata) else create(io, id, shrine_metadata: shrine_metadata) end end
url(id, **)
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 50 def url(id, **) end
Protected Instance Methods
chunks_collection()
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 68 def chunks_collection bucket.chunks_collection end
file_info(id)
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 60 def file_info(id) bucket.find(_id: bson_id(id)).limit(1).first end
files_collection()
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 64 def files_collection bucket.files_collection end
Private Instance Methods
bson_id(id)
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 144 def bson_id(id) BSON::ObjectId(File.basename(id, ".*")) end
copy(io, id, shrine_metadata: {})
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 95 def copy(io, id, shrine_metadata: {}) source_storage = io.storage source_info = source_storage.file_info(io.id) dest_info = source_info.merge(_id: BSON::ObjectId.new) batch_size = (@batch_size.to_f / chunk_size).ceil chunk_batches = source_storage.chunks_collection .find(files_id: source_info[:_id]) .batch_size(batch_size).each_slice(batch_size) chunk_batches.each do |chunks| chunks.each do |chunk| chunk[:_id] = BSON::ObjectId.new chunk[:files_id] = dest_info[:_id] end chunks_collection.insert_many(chunks) chunks.each do |chunk| chunk[:data].data.clear # deallocate strings end end dest_info[:uploadDate] = Time.now.utc dest_info[:filename] = shrine_metadata["filename"] || id files_collection.insert_one(dest_info) id.replace(dest_info[:_id].to_s + File.extname(id)) end
copyable?(io, id)
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 124 def copyable?(io, id) io.is_a?(UploadedFile) && io.storage.is_a?(Storage::Gridfs) end
create(io, id, shrine_metadata: {})
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 74 def create(io, id, shrine_metadata: {}) file = create_file(id, shrine_metadata: shrine_metadata) until io.eof? chunk = io.read([@batch_size, chunk_size].max, buffer ||= "") grid_chunks = Mongo::Grid::File::Chunk.split(chunk, file.info, offset ||= 0) chunks_collection.insert_many(grid_chunks) offset += grid_chunks.count grid_chunks.each { |grid_chunk| grid_chunk.data.data.clear } # deallocate strings chunk.clear # deallocate string end files_collection.find(_id: file.id).update_one("$set" => { length: io.size, uploadDate: Time.now.utc, md5: file.info.md5.hexdigest, }) end
create_file(id, shrine_metadata: {})
click to toggle source
# File lib/shrine/storage/gridfs.rb, line 128 def create_file(id, shrine_metadata: {}) file = Mongo::Grid::File.new("", filename: shrine_metadata["filename"] || id, content_type: shrine_metadata["mime_type"] || "application/octet-stream", metadata: shrine_metadata, chunk_size: chunk_size, ) bucket.insert_one(file) id.replace(file.id.to_s + File.extname(id)) file.info.document[:md5] = Digest::MD5.new file end