Subject [OT?] Empty blob after upload of non-empty file
Author unordained
I'm not entirely sure where this problem is coming from, but we've been fighting in on and off for
almost two years now. We store new versions of our software in our database, such that when users
connect every morning, it checks for, and downloads the latest version of the software. (Release
early, release often?) We have a table of version numbers, (blobl) notes about them, and the binary
field containing the entire (monolithic) exe file. Sadly, or upload screen will randomly decide not
to upload the file, and we can't figure out why. It comes back every few months, lasts a while,
then magically stops, with no changes to the code. Right now the production server refuses to take
new rows, but my local development copy (from a couple of weeks ago) takes them just fine. I'm
running the same copy of the software against both databases, uploading a copy of itself.

We're doing it from Windows, and I know better than to try to upload an .exe file currently in use.
We make a copy of our exe, and run it, and use it to upload the other file. Normally works great.
The file size should be around 13 megs, but we're told the blob field contains 0 bytes after trying
to load it. Any ideas? Here's the code that uploads, and ... yeah. Any suggestions would be
helpful. I'm really wondering if it's not something like the database being slightly corrupted, and
our weekly backup/restore fixing it?

Our production server runs linux, has plenty of drive space, and is running FB 1.02, I believe. It
was doing this with previous versions as well, including IB 6 OpenSource.

For historical reasons, a row has already been inserted containing non-blob field data, and the
transaction is still open. No errors are thrown, nothing reported incorrectly. Before adding code
to check the size of the blob, the transaction would commit perfectly, and users would download a
zero-byte .exe file that wouldn't exactly run very well. They would continue using their existing
version of the software without really noticing (the call to execute the new copy would fail,
current in-memory copy would continue running.) We use IBX and normally wrap the calls thoroughly,
but this section is a little rougher (and older) than usual.

sql = "select * from prometheus_update where version_number = '" + version + "'";
dbDataSet->SelectSQL->Clear();
dbDataSet->SelectSQL->Add(sql.c_str());

sql = "update prometheus_update "
" set file_exe = :file_exe, comments = :comments where version_number = '" + version
+ "'";
dbDataSet->ModifySQL->Add(sql.c_str());

dbDataSet->Open();
dbDataSet->Edit();
inputFile.open(file_name.c_str(), ios::in || ios::nocreate);
if(inputFile)
{
inputFile.close();
dbDataSet->FieldByName("file_exe")->SetFieldType(ftBlob);
((TBlobField *)dbDataSet->FieldByName("file_exe"))->LoadFromFile(file_name.c_str());
int size_to_write = ((TBlobField *)dbDataSet->FieldByName("file_exe"))->BlobSize;
lblByteExe->Caption = ("Writing " + IntToString(size_to_write) + " byte exe").c_str();
Application->ProcessMessages();
dbDataSet->FieldByName("comments")->SetFieldType(ftBlob);
((TBlobField *)dbDataSet->FieldByName("comments"))->AsString = comments.c_str();
((TBlobField *)dbDataSet->FieldByName("comments"))->Modified = true;
dbDataSet->Post();
dbDataSet->Close();

sql = "select * from prometheus_update where version_number = '" + version + "'";
dbDataSet->SelectSQL->Clear();
dbDataSet->SelectSQL->Add(sql.c_str());
dbDataSet->Open();
dbDataSet->First();
int size_written = ((TBlobField *)dbDataSet->FieldByName("file_exe"))->BlobSize;
dbDataSet->Close();
if (size_written == size_to_write)
dbTransaction->Commit();
else
{
PSay("Size of uploaded exe differs from original exe!\n\n"
"original exe: " + IntToString(size_to_write) + " bytes\n"
"uploaded exe: " + IntToString(size_written) + " bytes", m_program_error, MB_OK);
dbTransaction->Rollback();
}
}
else
{
PSay("Could not open exe file for upload", m_program_error, MB_OK);
dbDataSet->Close();
dbTransaction->Rollback();
}