Class Amalgalite::Blob
In: lib/amalgalite/blob.rb
Parent: Object

This is the interface to allow Blob objects to be written to and read from the SQLite database. When using statements, use a Blob object as the wrapper around the source to be written to the row, and a Blob object is returned if the the type mapping warrents during select queries.

For instance during an insert:

  blob_column = db.schema.tables['blobs'].columsn['data']
  db.execute("INSERT INTO blobs(name, data) VALUES ( $name, $blob )",
            { "$name" => "/path/to/file",
              "$blob" => Amalgalite::Blob.new( :file => '/path/to/file',
                                               :column => blob_column) } )

  db.execute("INSERT INTO blobs(id, data) VALUES ($id, $blob )",
            { "$name" => 'blobname',
              "$blob" => Amalgalite::Blob.new( :io => "something with .read and .length methods",
                                               :column => blob_column) } )

On select the blob data needs to be read into an IO object

  all_rows = db.execute("SELECT name, blob FROM blobs WHERE name = '/path/to/file' ")
  blob_row = all_rows.first
  blob_row['blob'].write_to_file( blob_row['name'] )

Or write to an IO object

  blob_results = {}
  db.execute("SELECT name, blob FROM blobs") do |row|
    io = StringIO.new
    row['blob'].write_to_io( io )
    blob_results[row['name']] = io
    # or use a shortcut
    # blob_results[row['name']] = row['blob'].to_string_io
  end

If using a Blob as a conditional, for instance in a WHERE clause then the Blob must resolvable to a String.

  db.execute("SELECT FROM blobs(name, data) WHERE data = $blob",
            { "$blob' => Amalgalite::Blob.new( :string => "A string of data" ) })

Methods

Classes and Modules

Class Amalgalite::Blob::Error

Attributes

block_size  [R]  the size in bytes of the blocks of data to move from the source
column  [R]  the column the blob is associated with
length  [R]  the size in bytes of the of the blob
source  [R]  the object representing the source of the blob

Public Class methods

[Source]

    # File lib/amalgalite/blob.rb, line 55
55:       def default_block_size
56:         @default_block_size ||= 8192
57:       end

Initialize a new blob, it takes a single parameter, a hash which describes the source of the blob. The keys of the hash are one of:

  :file    : the value is the path to a file on the file system
  :io      : the value is an object that responds to the the methods +read+
             and +length+.  +read+ should have the behavior of IO#read
  :db_blob : not normally used by an end user, used to initialize a blob
             object that is returned from an SQL query.
  :string  : used when a Blob is part of a WHERE clause or result

And additional key of :block_size may be used to indicate the maximum size of a single block of data to move from the source to the destination, this defaults ot 8192.

[Source]

     # File lib/amalgalite/blob.rb, line 87
 87:     def initialize( params )
 88:       if (Blob.valid_source_params & params.keys).size > 1 then
 89:         raise Blob::Error, "Only a one of #{Blob.valid_source_params.join(', ')} is allowed to initialize a Blob.  #{params.keys.join(', ')} were sent"
 90:       end
 91: 
 92:       @source                  = nil
 93:       @source_length           = 0
 94:       @close_source_after_read = false
 95:       @incremental             = true
 96:       @block_size              = params[:block_size] || Blob.default_block_size
 97:       @column                  = params[:column]     
 98: 
 99:       raise Blob::Error, "A :column parameter is required for a Blob" unless @column or params.has_key?( :string )
100: 
101:       if params.has_key?( :file ) then
102:         @source = File.open( params[:file], "r" )
103:         @length = File.size( params[:file] )
104:         @close_source_after_read = true
105:       elsif params.has_key?( :io ) then
106:         @source = params[:io]
107:         @length = @source.length
108:       elsif params.has_key?( :db_blob ) then
109:         @source = params[:db_blob]
110:         @length = @source.length
111:         @close_source_after_read = true
112:       elsif params.has_key?( :string ) then
113:         @source = params[:string]
114:         @length = @source.length
115:         @incremental = false
116:       end
117:     end

[Source]

    # File lib/amalgalite/blob.rb, line 51
51:       def valid_source_params
52:         @valid_source_params ||= [ :file, :io, :string, :db_blob ]
53:       end

Public Instance methods

close the source when done reading from it

[Source]

     # File lib/amalgalite/blob.rb, line 122
122:     def close_source_after_read?
123:       @close_source_after_read
124:     end

is this an incremental Blob or not

[Source]

     # File lib/amalgalite/blob.rb, line 129
129:     def incremental?
130:       @incremental
131:     end

conver the blob to a string

[Source]

     # File lib/amalgalite/blob.rb, line 153
153:     def to_s
154:       to_string_io.string
155:     end

write the Blob contents to a StringIO

[Source]

     # File lib/amalgalite/blob.rb, line 160
160:     def to_string_io
161:       sio = StringIO.new
162:       write_to_io( sio )
163:       return sio
164:     end

Write the Blob contents to the column. This assumes that the row_id to insert into is the last row that was inserted into the db

[Source]

     # File lib/amalgalite/blob.rb, line 179
179:     def write_to_column!
180:       last_rowid = column.schema.db.last_insert_rowid
181:       SQLite3::Blob.new( column.schema.db.api, column.db, column.table, column.name, last_rowid, "w" ) do |sqlite_blob|
182:         write_to_io( sqlite_blob )
183:       end
184:     end

Write the Blob contents to a File.

[Source]

     # File lib/amalgalite/blob.rb, line 169
169:     def write_to_file( filename, modestring="w" )
170:       File.open(filename, modestring) do |f|
171:         write_to_io( f )
172:       end
173:     end

Write the Blob to an IO object

[Source]

     # File lib/amalgalite/blob.rb, line 136
136:     def write_to_io( io )
137:       if source.respond_to?( :read ) then
138:         while buf = source.read( block_size ) do
139:           io.write( buf )
140:         end
141:       else
142:         io.write( source.to_s )
143:       end
144: 
145:       if close_source_after_read? then
146:         source.close
147:       end
148:     end

[Validate]