Rollup of misc fixes to make LoadBlobFromFile work

This commit is contained in:
Paul Reeves 2023-02-02 16:11:00 +01:00
parent c8fb94b176
commit cfcfa28082

View File

@ -29,6 +29,8 @@
#include <ibase.h> #include <ibase.h>
#include <firebird/UdrCppEngine.h> #include <firebird/UdrCppEngine.h>
#include <firebird/Message.h>
#include "UdrCppTemplates.h" #include "UdrCppTemplates.h"
#include <cassert> #include <cassert>
@ -183,7 +185,7 @@ FB_UDR_MESSAGE(OutMessage,
AutoRelease<IAttachment> att; AutoRelease<IAttachment> att;
AutoRelease<ITransaction> tra; AutoRelease<ITransaction> tra;
AutoRelease<IBlob> blob; ISC_STATUS_ARRAY statusVector = {0};
FB_UDR_EXECUTE_FUNCTION FB_UDR_EXECUTE_FUNCTION
{ {
@ -193,57 +195,58 @@ FB_UDR_EXECUTE_FUNCTION
return; return;
} }
std::ifstream FileReader; std::ifstream FileReader;
FileReader.open( in->afilename.str , std::ifstream::binary ); FileReader.open( in->afilename.str , std::ifstream::binary );
if (! FileReader.is_open()) { if (! FileReader.is_open()) {
out->result = -2; out->ablobNull = FB_TRUE;
return; return;
} }
try { try {
att.reset(context->getAttachment(status)); att.reset(context->getAttachment(status));
tra.reset(context->getTransaction(status)); tra.reset(context->getTransaction(status));
blob.reset(att->openBlob(status, tra, &in->ablob, 0, nullptr)); AutoRelease<IBlob> blob(att->createBlob(status, tra, &out->ablob, 0, nullptr));
if (blob == nullptr) { if (blob == nullptr) {
out->result = -1; out->ablobNull = FB_TRUE;
return; return;
} }
std::vector<char> Buffer (MaxSegmentSize, 0); std::vector<std::uint8_t> Buffer (MaxSegmentSize, 0);
std::streamsize DataSize; std::streamsize DataSize;
while ( FileReader.good() ) { while ( FileReader.good() ) {
FileReader.read( Buffer.data(), Buffer.size() ); FileReader.read( (char *)Buffer.data(), Buffer.size() );
DataSize = FileReader.gcount(); DataSize = FileReader.gcount();
// fail seems to be here...
// Probably need to declare buffer differently.
blob->putSegment( status, DataSize, Buffer.data() ); blob->putSegment( status, DataSize, Buffer.data() );
out->result += DataSize;
// Perhaps test for badbit here? // Perhaps test for badbit here?
} }
if (FileReader.bad()) { // Something went wrong if (FileReader.bad()) { // Something went wrong
// What to do? // What to do?
out->resultNull = FB_TRUE; out->ablobNull = FB_TRUE;
// What do we do with the partially written blob? Is cancel enough? // What do we do with the partially written blob? Is cancel enough?
blob->cancel( status ); blob->cancel( status );
// Should we reset result to 0?
} }
// ****** IT IS VITAL TO SET THIS IF WRITING TO BLOB SUCCEEDED ********
out->ablobNull = FB_FALSE;
blob->close( status ); blob->close( status );
blob->release(); blob->release();
Buffer.clear(); Buffer.clear();
FileReader.close();
} }
catch (...) catch ( const FbException& error )
{ {
throw Firebird::FbException(status, statusVector);
}
catch (...) {
// This generates an unrecognised C++ exception, which is insufficient. // This generates an unrecognised C++ exception, which is insufficient.
throw std::runtime_error("Error writing stream to BLOB."); throw std::runtime_error("Error writing stream to BLOB.");
} }
FileReader.close();
out->result = 1;
} }