Class Mongo::GridIO
In: lib/mongo/gridfs/grid_io_fix.rb
lib/mongo/gridfs/grid_io.rb
Parent: Object

GridIO objects represent files in the GridFS specification. This class manages the reading and writing of file chunks and metadata.

Methods

[]   []=   close   data   each   eof   eof?   get_md5   getc   gets   inspect   new   pos   read   rewind   seek   tell   write  

Constants

DEFAULT_CHUNK_SIZE = 256 * 1024
DEFAULT_CONTENT_TYPE = 'binary/octet-stream'
PROTECTED_ATTRS = [:files_id, :file_length, :client_md5, :server_md5]

Attributes

chunk_size  [R] 
client_md5  [R] 
content_type  [R] 
file_length  [R] 
file_position  [R] 
filename  [R] 
files_id  [R] 
metadata  [R] 
server_md5  [R] 
upload_date  [R] 

Public Class methods

Create a new GridIO object. Note that most users will not need to use this class directly; the Grid and GridFileSystem classes will instantiate this class

@param [Mongo::Collection] files a collection for storing file metadata. @param [Mongo::Collection] chunks a collection for storing file chunks. @param [String] filename the name of the file to open or write. @param [String] mode ‘r’ or ‘w’ or reading or creating a file.

@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. @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.

@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.

@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.

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 53
    def initialize(files, chunks, filename, mode, opts={})
      @files        = files
      @chunks       = chunks
      @filename     = filename
      @mode         = mode
      opts          = opts.dup
      @query        = opts.delete(:query) || {}
      @query_opts   = opts.delete(:query_opts) || {}
      @fs_name      = opts.delete(:fs_name) || Grid::DEFAULT_FS_NAME
      @safe         = opts.delete(:safe) || false
      @local_md5    = Digest::MD5.new if @safe
      @custom_attrs = {}

      case @mode
        when 'r' then init_read
        when 'w' then init_write(opts)
        else
          raise GridError, "Invalid file mode #{@mode}. Mode should be 'r' or 'w'."
      end
    end

Public Instance methods

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 74
    def [](key)
      @custom_attrs[key] || instance_variable_get("@#{key.to_s}")
    end

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 78
    def []=(key, value)
      if PROTECTED_ATTRS.include?(key.to_sym)
        warn "Attempting to overwrite protected value."
        return nil
      else
        @custom_attrs[key] = value
      end
    end

Creates or updates the document from the files collection that stores the chunks’ metadata. The file becomes available only after this method has been called.

This method will be invoked automatically when on GridIO#open is passed a block. Otherwise, it must be called manually.

@return [BSON::ObjectId]

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 232
    def close
      if @mode[0] == ?w
        if @current_chunk['n'].zero? && @chunk_position.zero?
          warn "Warning: Storing a file with zero length."
        end
        @upload_date = Time.now.utc
        id = @files.insert(to_mongo_object)
      end
      id
    end
data(length=nil)

Alias for read

Read a chunk of the data from the file and yield it to the given block.

Note that this method reads from the current file position.

@yield Yields on chunk per iteration as defined by this file‘s

  chunk size.

@return [Mongo::GridIO] self

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 252
    def each
      return read_all unless block_given?
      while chunk = read(chunk_size) 
        yield chunk
        break if chunk.empty?
      end
      self
    end

Return a boolean indicating whether the position pointer is at the end of the file.

@return [Boolean]

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 186
    def eof
      raise GridError, "file not opened for read #{@mode}" unless @mode[0] == ?r
      @file_position >= @file_length
    end
eof?()

Alias for eof

This fixes a comparson issue in JRuby 1.9

[Source]

# File lib/mongo/gridfs/grid_io_fix.rb, line 23
    def get_md5
      md5_command            = BSON::OrderedHash.new
      md5_command['filemd5'] = @files_id
      md5_command['root']    = @fs_name
      @server_md5 = @files.db.command(md5_command)['md5']
      if @safe
        @client_md5 = @local_md5.hexdigest
        if @local_md5.to_s != @server_md5.to_s
          raise GridMD5Failure, "File on server failed MD5 check"
        end
      else
        @server_md5
      end
    end

Return the next byte from the GridFS file.

@return [String]

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 220
    def getc
      read_length(1)
    end

Return the next line from a GridFS file. This probably makes sense only if you‘re storing plain text. This method has a somewhat tricky API, which it inherits from Ruby‘s StringIO#gets.

@param [String, Integer] separator or length. If a separator,

  read up to the separator. If a length, read the +length+ number
  of bytes. If nil, read the entire file.

@param [Integer] length If a separator is provided, then

  read until either finding the separator or
  passing over the +length+ number of bytes.

@return [String]

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 205
    def gets(separator="\n", length=nil)
      if separator.nil?
        read_all
      elsif separator.is_a?(Integer)
        read_length(separator)
      elsif separator.length > 1
        read_to_string(separator, length)
      else
        read_to_character(separator, length)
      end
    end

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 261
    def inspect
      "#<GridIO _id: #{@files_id}>"
    end
pos()

Alias for tell

Read the data from the file. If a length if specified, will read from the current file position.

@param [Integer] length

@return [String]

  the data in the file

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 94
    def read(length=nil)
      return '' if @file_length.zero?
      if length == 0
        return ''
      elsif length.nil? && @file_position.zero?
        read_all
      else
        read_length(length)
      end
    end

Rewind the file. This is equivalent to seeking to the zeroth position.

@return [Integer] the position of the file after rewinding (always zero).

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 177
    def rewind
      raise GridError, "file not opened for read" unless @mode[0] == ?r
      seek(0)
    end

Position the file pointer at the provided location.

@param [Integer] pos

  the number of bytes to advance the file pointer. this can be a negative
  number.

@param [Integer] whence

  one of IO::SEEK_CUR, IO::SEEK_END, or IO::SEEK_SET

@return [Integer] the new file position

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 145
    def seek(pos, whence=IO::SEEK_SET)
      raise GridError, "Seek is only allowed in read mode." unless @mode == 'r'
      target_pos = case whence
                   when IO::SEEK_CUR
                     @file_position + pos
                   when IO::SEEK_END
                     @file_length + pos
                   when IO::SEEK_SET
                     pos
                   end

      new_chunk_number = (target_pos / @chunk_size).to_i
      if new_chunk_number != @current_chunk['n']
        save_chunk(@current_chunk) if @mode[0] == ?w
        @current_chunk = get_chunk(new_chunk_number)
      end
      @file_position  = target_pos
      @chunk_position = @file_position % @chunk_size
      @file_position
    end

The current position of the file.

@return [Integer]

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 169
    def tell
      @file_position
    end

Write the given string (binary) data to the file.

@param [String] string

  the data to write

@return [Integer]

  the number of bytes written.

[Source]

# File lib/mongo/gridfs/grid_io.rb, line 113
    def write(io)
      raise GridError, "file not opened for write" unless @mode[0] == ?w
      if io.is_a? String
        if @safe
          @local_md5.update(io)
        end
        write_string(io)
      else
        length = 0
        if @safe
          while(string = io.read(@chunk_size))
            @local_md5.update(string)
            length += write_string(string)
          end
        else
          while(string = io.read(@chunk_size))
            length += write_string(string)
          end
        end
        length
      end
    end

[Validate]