1

I am using the following tcl code to store a file from my deskstop into a Sqlite database as blob data ($fileText is a path to a text file):

sqlite3 db Docs.db
set fileID [open $fileText RDONLY]
fconfigure $fileID -translation binary
set content [read $fileID]
close $fileID
db eval {insert into Document (Doc) VALUES ($content)}
db close

I have found many resources on how to open the blob data to read and write to it, but I cannot find any resources on opening the blob data as a file. For example, if $fileText was a pdf, how would I open it, from Sqlite, as a pdf?

1 Answer 1

2

When you say “open as a PDF”, I assume that you mean that you want some external program to see the data as a file? The only ways to do that are either:

  1. Do some clever shenanigans with user-mode filesystems on Linux (or the equivalent on your OS) so that the database can be actually mounted, or
  2. Copy the data from the database into a temporary file with the right name (hint: keep that as a separate column in that table).

There's also presenting it all as a webserver, but that's really the second with a browser in the mix; the data is still copied.

On the other hand, if all you want to do is have the data as a stream that you can read or write from Tcl, the sqlite3 package has what you need:

dbcmd incrblob ?-readonly? ?db? table column rowid

Which returns a standard channel handle (though not one backed up by an OS handle, so be careful if using as a redirection with exec).


[EDIT]: Here's how to getthe data out (replace ... with a clause to get the right row, of course):

# Open the DB
sqlite3 db Docs.db

# Open the file to write to
set fileID [open $fileText w]
fconfigure $fileID -translation binary

# Write the BLOB
db eval {SELECT Doc FROM Document WHERE ... LIMIT 1} row {
    puts -nonewline $fileID $row(Doc)
}

# We're done!
close $fileID
db close

Don't worry about the size of the BLOB; the Tcl sqlite3 package passes it around efficiently. If you're still concerned, here's the other way (again, you'll need to replace ... appropriately):

# Open the DB
sqlite3 db Docs.db

# Open the file to write to
set fileOut [open $fileText w]
fconfigure $fileOut -translation binary

# Get the BLOB as a (read-only) channel
set fdBlob [db incrblob -readonly Document Doc ...]
fconfigure $fdBlob -translation binary

# Do the copy 
fcopy $fileOut $fdBlob

# We're done!
close $fdBlob
close $fileOut
db close
Sign up to request clarification or add additional context in comments.

3 Comments

Hi Donald - thanks for your feedback. I was hoping to develop a tcl tk frontend that would allow an end user to upload a pdf file (to sqlite), and then be able to download the pdf for usage, like a standard file database. The upload part seems simple enough, using binary/blob data. I might be doing something wrong. Is opening a i/o channel my only option with blob data or can the data be opened as a file, similar to opening a file from a web driven Db?
@DFM: SQLite keeps the BLOB in the database, so opening it as a file directly isn't going to work (well, not without egregious hacks as in point 1 of my answer). Copy it out. NB: copying out is only a few lines of code.
Hi Donald - Copying the data out works well. As a test, instead of puts..., I copied it out to a text box widget, since I am not using a shell. I found that copying out pdf or Word doc blob data gives me unrecognized characters, most likely because of the format. How would I compile this data back into a pdf or Word doc?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.