Class: Amalgalite::Blob

Inherits:
Object
  • Object
show all
Defined in:
lib/amalgalite/blob.rb

Overview

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'].columns['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" ) })

Defined Under Namespace

Classes: Error

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params) ⇒ Blob

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.

Raises:



87
88
89
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
# File 'lib/amalgalite/blob.rb', line 87

def initialize( params )
  if (Blob.valid_source_params & params.keys).size > 1 then
    raise Blob::Error, "Only a one of #{Blob.valid_source_params.join(', ')} is allowed to initialize a Blob.  #{params.keys.join(', ')} were sent"
  end

  @source                  = nil
  @source_length           = 0
  @close_source_after_read = false
  @incremental             = true
  @block_size              = params[:block_size] || Blob.default_block_size
  @column                  = params[:column]     

  raise Blob::Error, "A :column parameter is required for a Blob" unless @column or params.has_key?( :string )

  if params.has_key?( :file ) then
    @source = File.open( params[:file], "r" )
    @length = File.size( params[:file] )
    @close_source_after_read = true
  elsif params.has_key?( :io ) then
    @source = params[:io]
    @length = @source.length
  elsif params.has_key?( :db_blob ) then
    @source = params[:db_blob]
    @length = @source.length
    @close_source_after_read = true
  elsif params.has_key?( :string ) then
    @source = params[:string]
    @length = @source.length
    @incremental = false
  end
end

Instance Attribute Details

#block_sizeObject (readonly)

the size in bytes of the blocks of data to move from the source



67
68
69
# File 'lib/amalgalite/blob.rb', line 67

def block_size
  @block_size
end

#columnObject (readonly)

the column the blob is associated with



70
71
72
# File 'lib/amalgalite/blob.rb', line 70

def column
  @column
end

#lengthObject (readonly)

the size in bytes of the of the blob



64
65
66
# File 'lib/amalgalite/blob.rb', line 64

def length
  @length
end

#sourceObject (readonly)

the object representing the source of the blob



61
62
63
# File 'lib/amalgalite/blob.rb', line 61

def source
  @source
end

Class Method Details

.default_block_sizeObject



55
56
57
# File 'lib/amalgalite/blob.rb', line 55

def default_block_size
  @default_block_size ||= 8192
end

.valid_source_paramsObject



51
52
53
# File 'lib/amalgalite/blob.rb', line 51

def valid_source_params
  @valid_source_params ||= [ :file, :io, :string, :db_blob ]
end

Instance Method Details

#close_source_after_read?Boolean

close the source when done reading from it

Returns:



122
123
124
# File 'lib/amalgalite/blob.rb', line 122

def close_source_after_read?
  @close_source_after_read
end

#incremental?Boolean

is this an incremental Blob or not

Returns:



129
130
131
# File 'lib/amalgalite/blob.rb', line 129

def incremental?
  @incremental
end

#to_sObject

conver the blob to a string



153
154
155
# File 'lib/amalgalite/blob.rb', line 153

def to_s
  to_string_io.string
end

#to_string_ioObject

write the Blob contents to a StringIO



160
161
162
163
164
# File 'lib/amalgalite/blob.rb', line 160

def to_string_io
  sio = StringIO.new
  write_to_io( sio )
  return sio
end

#write_to_column!Object

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



179
180
181
182
183
184
# File 'lib/amalgalite/blob.rb', line 179

def write_to_column!
  last_rowid = column.schema.db.last_insert_rowid
  SQLite3::Blob.new( column.schema.db.api, column.db, column.table, column.name, last_rowid, "w" ) do |sqlite_blob|
    write_to_io( sqlite_blob )
  end
end

#write_to_file(filename, modestring = "w") ⇒ Object

Write the Blob contents to a File.



169
170
171
172
173
# File 'lib/amalgalite/blob.rb', line 169

def write_to_file( filename, modestring="w" )
  File.open(filename, modestring) do |f|
    write_to_io( f )
  end
end

#write_to_io(io) ⇒ Object

Write the Blob to an IO object



136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/amalgalite/blob.rb', line 136

def write_to_io( io )
  if source.respond_to?( :read ) then
    while buf = source.read( block_size ) do
      io.write( buf )
    end
  else
    io.write( source.to_s )
  end

  if close_source_after_read? then
    source.close
  end
end