class Moped::GridFS::File
Constants
- DEFAULT_CHUNK_SIZE
- EMPTINESS
- PROTECTED_ATTRIBUTES
Attributes
attributes[R]
bucket[R]
mode[R]
pos[R]
tell[R]
Public Class Methods
new(bucket, mode, selector)
click to toggle source
# File lib/moped/gridfs/file.rb, line 14 def initialize(bucket, mode, selector) selector = parse_selector(selector) @mode = mode @bucket = bucket @cached_chunk = nil @pos = 0 raise ArgumentError.new("Invalid access mode #{mode}") unless ACCESS_MODES.include?(mode) document = files_collection.find(selector).first raise "No such file" if need_file? and !document if document and truncate? chunks_collection.find(files_id: document['_id']).remove_all files_collection.find(_id: document['_id']).remove_all @attributes = normalize_attributes(selector) else @attributes = normalize_attributes(document || selector) @attributes.freeze if read_only? end define_dynamic_accessors file_query.upsert(attributes) if writable? @pos = length if append_only? end
Public Instance Methods
default_chunk_size()
click to toggle source
# File lib/moped/gridfs/file.rb, line 139 def default_chunk_size DEFAULT_CHUNK_SIZE end
eof?()
click to toggle source
# File lib/moped/gridfs/file.rb, line 58 def eof? raise "Not opened for reading" if write_only? pos >= length end
inspect()
click to toggle source
# File lib/moped/gridfs/file.rb, line 143 def inspect build_inspect_string(bucket: bucket.name, _id: _id, mode: mode, filename: filename, length: length) end
pos=(value)
click to toggle source
# File lib/moped/gridfs/file.rb, line 46 def pos=(value) check_negative_value(value) @pos = (append_only? and value < length) ? length : value end
Also aliased as: seek
read(size = length)
click to toggle source
# File lib/moped/gridfs/file.rb, line 66 def read(size = length) raise "Not opened for reading" if write_only? check_negative_value(size) chunk_number = pos / chunk_size chunk_offset = pos % chunk_size data = EMPTINESS loop do break if data.size >= size break unless read_chunk(chunk_number) buffer = @cached_chunk[:data][chunk_offset..-1] data.empty? ? (data = buffer) : (data << buffer) chunk_number += 1 chunk_offset = 0 end data = data[0..size - 1] @pos += data.size data end
rewind()
click to toggle source
# File lib/moped/gridfs/file.rb, line 54 def rewind self.pos = 0 end
write(data)
click to toggle source
# File lib/moped/gridfs/file.rb, line 90 def write(data) raise "Not opened for writing" if read_only? data.force_encoding('BINARY') if data.respond_to?(:force_encoding) @pos = length if @pos > length @pos = length if append? chunk_number = pos / chunk_size chunk_offset = pos % chunk_size written = data.size new_length = 0 loop do if buffer = read_chunk(chunk_number) data = (chunk_offset.zero? ? EMPTINESS : buffer[0..chunk_offset - 1]) + data + (buffer[chunk_offset + data.size..-1] || EMPTINESS) end to_write = data[0..chunk_size - 1] || EMPTINESS break if to_write.empty? new_length = chunk_number * chunk_size + write_chunk(chunk_number, to_write) data = data[chunk_size..-1] || EMPTINESS break if data.empty? chunk_number += 1 chunk_offset = 0 end # Update internal position @pos += written # Calculate new md5 (if needed) md5 = bucket.md5(@attributes[:_id]) if written > 0 # Update if something changed updates = {} updates[:md5] = md5 if md5 updates[:length] = new_length if new_length > length change_attributes(updates) if updates.any? written end
Private Instance Methods
binarize(data)
click to toggle source
# File lib/moped/gridfs/file.rb, line 223 def binarize(data) BSON::Binary.new(:generic, data) end
change_attributes(hash)
click to toggle source
# File lib/moped/gridfs/file.rb, line 191 def change_attributes(hash) file_query.update('$set' => hash) @attributes.merge!(hash) end
check_negative_value(value)
click to toggle source
# File lib/moped/gridfs/file.rb, line 187 def check_negative_value(value) raise ArgumentError.new("negative value #{value} given") if value < 0 end
chunk(n)
click to toggle source
# File lib/moped/gridfs/file.rb, line 204 def chunk(n) chunk_query(n).first end
chunk_query(n)
click to toggle source
# File lib/moped/gridfs/file.rb, line 200 def chunk_query(n) chunks_collection.find(files_id: attributes[:_id], n: n) end
define_dynamic_accessors()
click to toggle source
# File lib/moped/gridfs/file.rb, line 169 def define_dynamic_accessors attributes.keys.each do |attrname| method_name = underscorize(attrname) __send__(:define_singleton_method, method_name) { attributes[attrname] } if writable? and !PROTECTED_ATTRIBUTES.include?(attrname) __send__(:define_singleton_method, :"#{method_name}=") do |value| change_attributes(:"#{attrname}" => value) end end end end
file_query()
click to toggle source
# File lib/moped/gridfs/file.rb, line 196 def file_query files_collection.find(_id: attributes[:_id]) end
normalize_attributes(provided)
click to toggle source
# File lib/moped/gridfs/file.rb, line 149 def normalize_attributes(provided) provided.keys.each do |key| provided[key.to_sym] = provided.delete(key) end attrs = {} attrs[:_id] = provided[:_id] ? BSON::ObjectId.from_string(provided[:_id]) : BSON::ObjectId.new attrs[:length] = (provided[:length] || 0).to_i attrs[:chunkSize] = (provided[:chunkSize] || provided[:chunk_size] || default_chunk_size).to_i attrs[:filename] = provided[:filename] || attrs[:_id].to_s attrs[:contentType] = provided[:content_type] || provided[:contentType] || 'application/octet-stream' attrs[:md5] = provided[:md5] attrs[:aliases] = provided[:aliases] || [] attrs[:metadata] = provided[:metadata] || {} attrs[:uploadDate] = provided[:upload_date] || provided[:uploadDate] || Time.now.utc attrs end
read_chunk(n)
click to toggle source
# File lib/moped/gridfs/file.rb, line 214 def read_chunk(n) return @cached_chunk[:data] if @cached_chunk and @cached_chunk[:n] == n readed = chunk(n) return unless readed @cached_chunk = {n: readed['n'], data: readed['data'].data} @cached_chunk[:data] end
underscorize(name)
click to toggle source
# File lib/moped/gridfs/file.rb, line 183 def underscorize(name) name.to_s.gsub(/([A-Z])/, '_\1').downcase.to_sym end
write_chunk(n, data)
click to toggle source
# File lib/moped/gridfs/file.rb, line 208 def write_chunk(n, data) chunk_query(n).upsert('$set' => {data: binarize(data)}) @cached_chunk = {n: n, data: data} data.size end