Class: Moped::GridFS::File
- Inherits:
-
Object
- Object
- Moped::GridFS::File
- Includes:
- AccessModes, Bucketable, Inspectable
- Defined in:
- lib/moped/gridfs/file.rb
Constant Summary collapse
- EMPTINESS =
''.force_encoding('BINARY')
- DEFAULT_CHUNK_SIZE =
255 * 1024
Constants included from AccessModes
Instance Attribute Summary collapse
-
#attributes ⇒ Object
readonly
Returns the value of attribute attributes.
-
#bucket ⇒ Object
readonly
Returns the value of attribute bucket.
-
#mode ⇒ Object
readonly
Returns the value of attribute mode.
-
#pos ⇒ Object
(also: #tell)
Returns the value of attribute pos.
Instance Method Summary collapse
- #default_chunk_size ⇒ Object
- #eof? ⇒ Boolean
-
#initialize(bucket, mode, selector) ⇒ File
constructor
A new instance of File.
- #inspect ⇒ Object
- #read(size = length) ⇒ Object
- #rewind ⇒ Object
- #write(data) ⇒ Object
Methods included from AccessModes
#append?, #read_only?, #read_write?, #readable?, #writable?, #write_only?
Methods included from Bucketable
#chunks_collection, #files_collection
Constructor Details
#initialize(bucket, mode, selector) ⇒ File
Returns a new instance of File.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# 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 |
Instance Attribute Details
#attributes ⇒ Object (readonly)
Returns the value of attribute attributes.
12 13 14 |
# File 'lib/moped/gridfs/file.rb', line 12 def attributes @attributes end |
#bucket ⇒ Object (readonly)
Returns the value of attribute bucket.
12 13 14 |
# File 'lib/moped/gridfs/file.rb', line 12 def bucket @bucket end |
#mode ⇒ Object (readonly)
Returns the value of attribute mode.
12 13 14 |
# File 'lib/moped/gridfs/file.rb', line 12 def mode @mode end |
#pos ⇒ Object Also known as: tell
Returns the value of attribute pos.
12 13 14 |
# File 'lib/moped/gridfs/file.rb', line 12 def pos @pos end |
Instance Method Details
#default_chunk_size ⇒ Object
139 140 141 |
# File 'lib/moped/gridfs/file.rb', line 139 def default_chunk_size DEFAULT_CHUNK_SIZE end |
#eof? ⇒ Boolean
58 59 60 61 62 |
# File 'lib/moped/gridfs/file.rb', line 58 def eof? raise "Not opened for reading" if write_only? pos >= length end |
#inspect ⇒ Object
143 144 145 |
# 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 |
#read(size = length) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# 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 ⇒ Object
54 55 56 |
# File 'lib/moped/gridfs/file.rb', line 54 def rewind self.pos = 0 end |
#write(data) ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# 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 |