mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:03:02 +01:00
Implemented methods to manage blobs cache size at client side and maximum size of blob to transfer inline.
This commit is contained in:
parent
6cab8f2532
commit
f5032b5557
@ -521,6 +521,11 @@ version: // 3.0 => 4.0
|
||||
version: // 3.0.7 => 3.0.8, 4.0.0 => 4.0.1
|
||||
[notImplementedAction if ::FB_UsedInYValve then defaultAction else call deprecatedFree(status) endif]
|
||||
void free(Status status);
|
||||
|
||||
version: // 6.0
|
||||
// Inline blob transfer
|
||||
uint getMaxInlineBlobSize(Status status);
|
||||
void setMaxInlineBlobSize(Status status, uint size);
|
||||
}
|
||||
|
||||
interface Batch : ReferenceCounted
|
||||
@ -713,6 +718,15 @@ version: // 3.0.7 => 3.0.8, 4.0.0 => 4.0.1
|
||||
void detach(Status status);
|
||||
[notImplementedAction if ::FB_UsedInYValve then defaultAction else call deprecatedDropDatabase(status) endif]
|
||||
void dropDatabase(Status status);
|
||||
|
||||
version: // 6.0
|
||||
// Blob caching by client
|
||||
uint getMaxBlobCacheSize(Status status);
|
||||
void setMaxBlobCacheSize(Status status, uint size);
|
||||
|
||||
// Inline blob transfer
|
||||
uint getMaxInlineBlobSize(Status status);
|
||||
void setMaxInlineBlobSize(Status status, uint size);
|
||||
}
|
||||
|
||||
interface Service : ReferenceCounted
|
||||
|
@ -1869,7 +1869,7 @@ namespace Firebird
|
||||
}
|
||||
};
|
||||
|
||||
#define FIREBIRD_ISTATEMENT_VERSION 5u
|
||||
#define FIREBIRD_ISTATEMENT_VERSION 6u
|
||||
|
||||
class IStatement : public IReferenceCounted
|
||||
{
|
||||
@ -1891,6 +1891,8 @@ namespace Firebird
|
||||
void (CLOOP_CARG *setTimeout)(IStatement* self, IStatus* status, unsigned timeOut) CLOOP_NOEXCEPT;
|
||||
IBatch* (CLOOP_CARG *createBatch)(IStatement* self, IStatus* status, IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par) CLOOP_NOEXCEPT;
|
||||
void (CLOOP_CARG *free)(IStatement* self, IStatus* status) CLOOP_NOEXCEPT;
|
||||
unsigned (CLOOP_CARG *getMaxInlineBlobSize)(IStatement* self, IStatus* status) CLOOP_NOEXCEPT;
|
||||
void (CLOOP_CARG *setMaxInlineBlobSize)(IStatement* self, IStatus* status, unsigned size) CLOOP_NOEXCEPT;
|
||||
};
|
||||
|
||||
protected:
|
||||
@ -2064,6 +2066,33 @@ namespace Firebird
|
||||
static_cast<VTable*>(this->cloopVTable)->free(this, status);
|
||||
StatusType::checkException(status);
|
||||
}
|
||||
|
||||
template <typename StatusType> unsigned getMaxInlineBlobSize(StatusType* status)
|
||||
{
|
||||
if (cloopVTable->version < 6)
|
||||
{
|
||||
StatusType::setVersionError(status, "IStatement", cloopVTable->version, 6);
|
||||
StatusType::checkException(status);
|
||||
return 0;
|
||||
}
|
||||
StatusType::clearException(status);
|
||||
unsigned ret = static_cast<VTable*>(this->cloopVTable)->getMaxInlineBlobSize(this, status);
|
||||
StatusType::checkException(status);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename StatusType> void setMaxInlineBlobSize(StatusType* status, unsigned size)
|
||||
{
|
||||
if (cloopVTable->version < 6)
|
||||
{
|
||||
StatusType::setVersionError(status, "IStatement", cloopVTable->version, 6);
|
||||
StatusType::checkException(status);
|
||||
return;
|
||||
}
|
||||
StatusType::clearException(status);
|
||||
static_cast<VTable*>(this->cloopVTable)->setMaxInlineBlobSize(this, status, size);
|
||||
StatusType::checkException(status);
|
||||
}
|
||||
};
|
||||
|
||||
#define FIREBIRD_IBATCH_VERSION 4u
|
||||
@ -2499,7 +2528,7 @@ namespace Firebird
|
||||
}
|
||||
};
|
||||
|
||||
#define FIREBIRD_IATTACHMENT_VERSION 5u
|
||||
#define FIREBIRD_IATTACHMENT_VERSION 6u
|
||||
|
||||
class IAttachment : public IReferenceCounted
|
||||
{
|
||||
@ -2532,6 +2561,10 @@ namespace Firebird
|
||||
IReplicator* (CLOOP_CARG *createReplicator)(IAttachment* self, IStatus* status) CLOOP_NOEXCEPT;
|
||||
void (CLOOP_CARG *detach)(IAttachment* self, IStatus* status) CLOOP_NOEXCEPT;
|
||||
void (CLOOP_CARG *dropDatabase)(IAttachment* self, IStatus* status) CLOOP_NOEXCEPT;
|
||||
unsigned (CLOOP_CARG *getMaxBlobCacheSize)(IAttachment* self, IStatus* status) CLOOP_NOEXCEPT;
|
||||
void (CLOOP_CARG *setMaxBlobCacheSize)(IAttachment* self, IStatus* status, unsigned size) CLOOP_NOEXCEPT;
|
||||
unsigned (CLOOP_CARG *getMaxInlineBlobSize)(IAttachment* self, IStatus* status) CLOOP_NOEXCEPT;
|
||||
void (CLOOP_CARG *setMaxInlineBlobSize)(IAttachment* self, IStatus* status, unsigned size) CLOOP_NOEXCEPT;
|
||||
};
|
||||
|
||||
protected:
|
||||
@ -2800,6 +2833,60 @@ namespace Firebird
|
||||
static_cast<VTable*>(this->cloopVTable)->dropDatabase(this, status);
|
||||
StatusType::checkException(status);
|
||||
}
|
||||
|
||||
template <typename StatusType> unsigned getMaxBlobCacheSize(StatusType* status)
|
||||
{
|
||||
if (cloopVTable->version < 6)
|
||||
{
|
||||
StatusType::setVersionError(status, "IAttachment", cloopVTable->version, 6);
|
||||
StatusType::checkException(status);
|
||||
return 0;
|
||||
}
|
||||
StatusType::clearException(status);
|
||||
unsigned ret = static_cast<VTable*>(this->cloopVTable)->getMaxBlobCacheSize(this, status);
|
||||
StatusType::checkException(status);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename StatusType> void setMaxBlobCacheSize(StatusType* status, unsigned size)
|
||||
{
|
||||
if (cloopVTable->version < 6)
|
||||
{
|
||||
StatusType::setVersionError(status, "IAttachment", cloopVTable->version, 6);
|
||||
StatusType::checkException(status);
|
||||
return;
|
||||
}
|
||||
StatusType::clearException(status);
|
||||
static_cast<VTable*>(this->cloopVTable)->setMaxBlobCacheSize(this, status, size);
|
||||
StatusType::checkException(status);
|
||||
}
|
||||
|
||||
template <typename StatusType> unsigned getMaxInlineBlobSize(StatusType* status)
|
||||
{
|
||||
if (cloopVTable->version < 6)
|
||||
{
|
||||
StatusType::setVersionError(status, "IAttachment", cloopVTable->version, 6);
|
||||
StatusType::checkException(status);
|
||||
return 0;
|
||||
}
|
||||
StatusType::clearException(status);
|
||||
unsigned ret = static_cast<VTable*>(this->cloopVTable)->getMaxInlineBlobSize(this, status);
|
||||
StatusType::checkException(status);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename StatusType> void setMaxInlineBlobSize(StatusType* status, unsigned size)
|
||||
{
|
||||
if (cloopVTable->version < 6)
|
||||
{
|
||||
StatusType::setVersionError(status, "IAttachment", cloopVTable->version, 6);
|
||||
StatusType::checkException(status);
|
||||
return;
|
||||
}
|
||||
StatusType::clearException(status);
|
||||
static_cast<VTable*>(this->cloopVTable)->setMaxInlineBlobSize(this, status, size);
|
||||
StatusType::checkException(status);
|
||||
}
|
||||
};
|
||||
|
||||
#define FIREBIRD_ISERVICE_VERSION 5u
|
||||
@ -10525,6 +10612,8 @@ namespace Firebird
|
||||
this->setTimeout = &Name::cloopsetTimeoutDispatcher;
|
||||
this->createBatch = &Name::cloopcreateBatchDispatcher;
|
||||
this->free = &Name::cloopfreeDispatcher;
|
||||
this->getMaxInlineBlobSize = &Name::cloopgetMaxInlineBlobSizeDispatcher;
|
||||
this->setMaxInlineBlobSize = &Name::cloopsetMaxInlineBlobSizeDispatcher;
|
||||
}
|
||||
} vTable;
|
||||
|
||||
@ -10751,6 +10840,35 @@ namespace Firebird
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned CLOOP_CARG cloopgetMaxInlineBlobSizeDispatcher(IStatement* self, IStatus* status) CLOOP_NOEXCEPT
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
try
|
||||
{
|
||||
return static_cast<Name*>(self)->Name::getMaxInlineBlobSize(&status2);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(&status2);
|
||||
return static_cast<unsigned>(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopsetMaxInlineBlobSizeDispatcher(IStatement* self, IStatus* status, unsigned size) CLOOP_NOEXCEPT
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
try
|
||||
{
|
||||
static_cast<Name*>(self)->Name::setMaxInlineBlobSize(&status2, size);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(&status2);
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopaddRefDispatcher(IReferenceCounted* self) CLOOP_NOEXCEPT
|
||||
{
|
||||
try
|
||||
@ -10805,6 +10923,8 @@ namespace Firebird
|
||||
virtual void setTimeout(StatusType* status, unsigned timeOut) = 0;
|
||||
virtual IBatch* createBatch(StatusType* status, IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par) = 0;
|
||||
virtual void free(StatusType* status) = 0;
|
||||
virtual unsigned getMaxInlineBlobSize(StatusType* status) = 0;
|
||||
virtual void setMaxInlineBlobSize(StatusType* status, unsigned size) = 0;
|
||||
};
|
||||
|
||||
template <typename Name, typename StatusType, typename Base>
|
||||
@ -11630,6 +11750,10 @@ namespace Firebird
|
||||
this->createReplicator = &Name::cloopcreateReplicatorDispatcher;
|
||||
this->detach = &Name::cloopdetachDispatcher;
|
||||
this->dropDatabase = &Name::cloopdropDatabaseDispatcher;
|
||||
this->getMaxBlobCacheSize = &Name::cloopgetBlobCacheSizeDispatcher;
|
||||
this->setMaxBlobCacheSize = &Name::cloopsetBlobCacheSizeDispatcher;
|
||||
this->getMaxInlineBlobSize = &Name::cloopgetMaxInlineBlobSizeDispatcher;
|
||||
this->setMaxInlineBlobSize = &Name::cloopsetMaxInlineBlobSizeDispatcher;
|
||||
}
|
||||
} vTable;
|
||||
|
||||
@ -12014,6 +12138,64 @@ namespace Firebird
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned CLOOP_CARG cloopgetBlobCacheSizeDispatcher(IAttachment* self, IStatus* status) CLOOP_NOEXCEPT
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
try
|
||||
{
|
||||
return static_cast<Name*>(self)->Name::getMaxBlobCacheSize(&status2);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(&status2);
|
||||
return static_cast<unsigned>(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopsetBlobCacheSizeDispatcher(IAttachment* self, IStatus* status, unsigned size) CLOOP_NOEXCEPT
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
try
|
||||
{
|
||||
static_cast<Name*>(self)->Name::setMaxBlobCacheSize(&status2, size);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(&status2);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned CLOOP_CARG cloopgetMaxInlineBlobSizeDispatcher(IAttachment* self, IStatus* status) CLOOP_NOEXCEPT
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
try
|
||||
{
|
||||
return static_cast<Name*>(self)->Name::getMaxInlineBlobSize(&status2);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(&status2);
|
||||
return static_cast<unsigned>(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopsetMaxInlineBlobSizeDispatcher(IAttachment* self, IStatus* status, unsigned size) CLOOP_NOEXCEPT
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
try
|
||||
{
|
||||
static_cast<Name*>(self)->Name::setMaxInlineBlobSize(&status2, size);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(&status2);
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopaddRefDispatcher(IReferenceCounted* self) CLOOP_NOEXCEPT
|
||||
{
|
||||
try
|
||||
@ -12079,6 +12261,10 @@ namespace Firebird
|
||||
virtual IReplicator* createReplicator(StatusType* status) = 0;
|
||||
virtual void detach(StatusType* status) = 0;
|
||||
virtual void dropDatabase(StatusType* status) = 0;
|
||||
virtual unsigned getMaxBlobCacheSize(StatusType* status) = 0;
|
||||
virtual void setMaxBlobCacheSize(StatusType* status, unsigned size) = 0;
|
||||
virtual unsigned getMaxInlineBlobSize(StatusType* status) = 0;
|
||||
virtual void setMaxInlineBlobSize(StatusType* status, unsigned size) = 0;
|
||||
};
|
||||
|
||||
template <typename Name, typename StatusType, typename Base>
|
||||
|
@ -358,6 +358,8 @@ type
|
||||
IStatement_setTimeoutPtr = procedure(this: IStatement; status: IStatus; timeOut: Cardinal); cdecl;
|
||||
IStatement_createBatchPtr = function(this: IStatement; status: IStatus; inMetadata: IMessageMetadata; parLength: Cardinal; par: BytePtr): IBatch; cdecl;
|
||||
IStatement_freePtr = procedure(this: IStatement; status: IStatus); cdecl;
|
||||
IStatement_getMaxInlineBlobSizePtr = function(this: IStatement; status: IStatus): Cardinal; cdecl;
|
||||
IStatement_setMaxInlineBlobSizePtr = procedure(this: IStatement; status: IStatus; size: Cardinal); cdecl;
|
||||
IBatch_addPtr = procedure(this: IBatch; status: IStatus; count: Cardinal; inBuffer: Pointer); cdecl;
|
||||
IBatch_addBlobPtr = procedure(this: IBatch; status: IStatus; length: Cardinal; inBuffer: Pointer; blobId: ISC_QUADPtr; parLength: Cardinal; par: BytePtr); cdecl;
|
||||
IBatch_appendBlobDataPtr = procedure(this: IBatch; status: IStatus; length: Cardinal; inBuffer: Pointer); cdecl;
|
||||
@ -414,6 +416,10 @@ type
|
||||
IAttachment_createReplicatorPtr = function(this: IAttachment; status: IStatus): IReplicator; cdecl;
|
||||
IAttachment_detachPtr = procedure(this: IAttachment; status: IStatus); cdecl;
|
||||
IAttachment_dropDatabasePtr = procedure(this: IAttachment; status: IStatus); cdecl;
|
||||
IAttachment_getMaxBlobCacheSizePtr = function(this: IAttachment; status: IStatus): Cardinal; cdecl;
|
||||
IAttachment_setMaxBlobCacheSizePtr = procedure(this: IAttachment; status: IStatus; size: Cardinal); cdecl;
|
||||
IAttachment_getMaxInlineBlobSizePtr = function(this: IAttachment; status: IStatus): Cardinal; cdecl;
|
||||
IAttachment_setMaxInlineBlobSizePtr = procedure(this: IAttachment; status: IStatus; size: Cardinal); cdecl;
|
||||
IService_deprecatedDetachPtr = procedure(this: IService; status: IStatus); cdecl;
|
||||
IService_queryPtr = procedure(this: IService; status: IStatus; sendLength: Cardinal; sendItems: BytePtr; receiveLength: Cardinal; receiveItems: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl;
|
||||
IService_startPtr = procedure(this: IService; status: IStatus; spbLength: Cardinal; spb: BytePtr); cdecl;
|
||||
@ -1523,10 +1529,12 @@ type
|
||||
setTimeout: IStatement_setTimeoutPtr;
|
||||
createBatch: IStatement_createBatchPtr;
|
||||
free: IStatement_freePtr;
|
||||
getMaxInlineBlobSize: IStatement_getMaxInlineBlobSizePtr;
|
||||
setMaxInlineBlobSize: IStatement_setMaxInlineBlobSizePtr;
|
||||
end;
|
||||
|
||||
IStatement = class(IReferenceCounted)
|
||||
const VERSION = 5;
|
||||
const VERSION = 6;
|
||||
const PREPARE_PREFETCH_NONE = Cardinal($0);
|
||||
const PREPARE_PREFETCH_TYPE = Cardinal($1);
|
||||
const PREPARE_PREFETCH_INPUT_PARAMETERS = Cardinal($2);
|
||||
@ -1557,6 +1565,8 @@ type
|
||||
procedure setTimeout(status: IStatus; timeOut: Cardinal);
|
||||
function createBatch(status: IStatus; inMetadata: IMessageMetadata; parLength: Cardinal; par: BytePtr): IBatch;
|
||||
procedure free(status: IStatus);
|
||||
function getMaxInlineBlobSize(status: IStatus): Cardinal;
|
||||
procedure setMaxInlineBlobSize(status: IStatus; size: Cardinal);
|
||||
end;
|
||||
|
||||
IStatementImpl = class(IStatement)
|
||||
@ -1579,6 +1589,8 @@ type
|
||||
procedure setTimeout(status: IStatus; timeOut: Cardinal); virtual; abstract;
|
||||
function createBatch(status: IStatus; inMetadata: IMessageMetadata; parLength: Cardinal; par: BytePtr): IBatch; virtual; abstract;
|
||||
procedure free(status: IStatus); virtual; abstract;
|
||||
function getMaxInlineBlobSize(status: IStatus): Cardinal; virtual; abstract;
|
||||
procedure setMaxInlineBlobSize(status: IStatus; size: Cardinal); virtual; abstract;
|
||||
end;
|
||||
|
||||
BatchVTable = class(ReferenceCountedVTable)
|
||||
@ -1792,10 +1804,14 @@ type
|
||||
createReplicator: IAttachment_createReplicatorPtr;
|
||||
detach: IAttachment_detachPtr;
|
||||
dropDatabase: IAttachment_dropDatabasePtr;
|
||||
getMaxBlobCacheSize: IAttachment_getMaxBlobCacheSizePtr;
|
||||
setMaxBlobCacheSize: IAttachment_setMaxBlobCacheSizePtr;
|
||||
getMaxInlineBlobSize: IAttachment_getMaxInlineBlobSizePtr;
|
||||
setMaxInlineBlobSize: IAttachment_setMaxInlineBlobSizePtr;
|
||||
end;
|
||||
|
||||
IAttachment = class(IReferenceCounted)
|
||||
const VERSION = 5;
|
||||
const VERSION = 6;
|
||||
|
||||
procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr);
|
||||
function startTransaction(status: IStatus; tpbLength: Cardinal; tpb: BytePtr): ITransaction;
|
||||
@ -1823,6 +1839,10 @@ type
|
||||
function createReplicator(status: IStatus): IReplicator;
|
||||
procedure detach(status: IStatus);
|
||||
procedure dropDatabase(status: IStatus);
|
||||
function getMaxBlobCacheSize(status: IStatus): Cardinal;
|
||||
procedure setMaxBlobCacheSize(status: IStatus; size: Cardinal);
|
||||
function getMaxInlineBlobSize(status: IStatus): Cardinal;
|
||||
procedure setMaxInlineBlobSize(status: IStatus; size: Cardinal);
|
||||
end;
|
||||
|
||||
IAttachmentImpl = class(IAttachment)
|
||||
@ -1856,6 +1876,10 @@ type
|
||||
function createReplicator(status: IStatus): IReplicator; virtual; abstract;
|
||||
procedure detach(status: IStatus); virtual; abstract;
|
||||
procedure dropDatabase(status: IStatus); virtual; abstract;
|
||||
function getMaxBlobCacheSize(status: IStatus): Cardinal; virtual; abstract;
|
||||
procedure setMaxBlobCacheSize(status: IStatus; size: Cardinal); virtual; abstract;
|
||||
function getMaxInlineBlobSize(status: IStatus): Cardinal; virtual; abstract;
|
||||
procedure setMaxInlineBlobSize(status: IStatus; size: Cardinal); virtual; abstract;
|
||||
end;
|
||||
|
||||
ServiceVTable = class(ReferenceCountedVTable)
|
||||
@ -7220,6 +7244,29 @@ begin
|
||||
FbException.checkException(status);
|
||||
end;
|
||||
|
||||
function IStatement.getMaxInlineBlobSize(status: IStatus): Cardinal;
|
||||
begin
|
||||
if (vTable.version < 6) then begin
|
||||
FbException.setVersionError(status, 'IStatement', vTable.version, 6);
|
||||
Result := 0;
|
||||
end
|
||||
else begin
|
||||
Result := StatementVTable(vTable).getMaxInlineBlobSize(Self, status);
|
||||
end;
|
||||
FbException.checkException(status);
|
||||
end;
|
||||
|
||||
procedure IStatement.setMaxInlineBlobSize(status: IStatus; size: Cardinal);
|
||||
begin
|
||||
if (vTable.version < 6) then begin
|
||||
FbException.setVersionError(status, 'IStatement', vTable.version, 6);
|
||||
end
|
||||
else begin
|
||||
StatementVTable(vTable).setMaxInlineBlobSize(Self, status, size);
|
||||
end;
|
||||
FbException.checkException(status);
|
||||
end;
|
||||
|
||||
procedure IBatch.add(status: IStatus; count: Cardinal; inBuffer: Pointer);
|
||||
begin
|
||||
BatchVTable(vTable).add(Self, status, count, inBuffer);
|
||||
@ -7655,6 +7702,52 @@ begin
|
||||
FbException.checkException(status);
|
||||
end;
|
||||
|
||||
function IAttachment.getMaxBlobCacheSize(status: IStatus): Cardinal;
|
||||
begin
|
||||
if (vTable.version < 6) then begin
|
||||
FbException.setVersionError(status, 'IAttachment', vTable.version, 6);
|
||||
Result := 0;
|
||||
end
|
||||
else begin
|
||||
Result := AttachmentVTable(vTable).getMaxBlobCacheSize(Self, status);
|
||||
end;
|
||||
FbException.checkException(status);
|
||||
end;
|
||||
|
||||
procedure IAttachment.setMaxBlobCacheSize(status: IStatus; size: Cardinal);
|
||||
begin
|
||||
if (vTable.version < 6) then begin
|
||||
FbException.setVersionError(status, 'IAttachment', vTable.version, 6);
|
||||
end
|
||||
else begin
|
||||
AttachmentVTable(vTable).setMaxBlobCacheSize(Self, status, size);
|
||||
end;
|
||||
FbException.checkException(status);
|
||||
end;
|
||||
|
||||
function IAttachment.getMaxInlineBlobSize(status: IStatus): Cardinal;
|
||||
begin
|
||||
if (vTable.version < 6) then begin
|
||||
FbException.setVersionError(status, 'IAttachment', vTable.version, 6);
|
||||
Result := 0;
|
||||
end
|
||||
else begin
|
||||
Result := AttachmentVTable(vTable).getMaxInlineBlobSize(Self, status);
|
||||
end;
|
||||
FbException.checkException(status);
|
||||
end;
|
||||
|
||||
procedure IAttachment.setMaxInlineBlobSize(status: IStatus; size: Cardinal);
|
||||
begin
|
||||
if (vTable.version < 6) then begin
|
||||
FbException.setVersionError(status, 'IAttachment', vTable.version, 6);
|
||||
end
|
||||
else begin
|
||||
AttachmentVTable(vTable).setMaxInlineBlobSize(Self, status, size);
|
||||
end;
|
||||
FbException.checkException(status);
|
||||
end;
|
||||
|
||||
procedure IService.deprecatedDetach(status: IStatus);
|
||||
begin
|
||||
ServiceVTable(vTable).deprecatedDetach(Self, status);
|
||||
@ -11577,6 +11670,25 @@ begin
|
||||
end
|
||||
end;
|
||||
|
||||
function IStatementImpl_getMaxInlineBlobSizeDispatcher(this: IStatement; status: IStatus): Cardinal; cdecl;
|
||||
begin
|
||||
Result := 0;
|
||||
try
|
||||
Result := IStatementImpl(this).getMaxInlineBlobSize(status);
|
||||
except
|
||||
on e: Exception do FbException.catchException(status, e);
|
||||
end
|
||||
end;
|
||||
|
||||
procedure IStatementImpl_setMaxInlineBlobSizeDispatcher(this: IStatement; status: IStatus; size: Cardinal); cdecl;
|
||||
begin
|
||||
try
|
||||
IStatementImpl(this).setMaxInlineBlobSize(status, size);
|
||||
except
|
||||
on e: Exception do FbException.catchException(status, e);
|
||||
end
|
||||
end;
|
||||
|
||||
var
|
||||
IStatementImpl_vTable: StatementVTable;
|
||||
|
||||
@ -12253,6 +12365,44 @@ begin
|
||||
end
|
||||
end;
|
||||
|
||||
function IAttachmentImpl_getMaxBlobCacheSizeDispatcher(this: IAttachment; status: IStatus): Cardinal; cdecl;
|
||||
begin
|
||||
Result := 0;
|
||||
try
|
||||
Result := IAttachmentImpl(this).getMaxBlobCacheSize(status);
|
||||
except
|
||||
on e: Exception do FbException.catchException(status, e);
|
||||
end
|
||||
end;
|
||||
|
||||
procedure IAttachmentImpl_setMaxBlobCacheSizeDispatcher(this: IAttachment; status: IStatus; size: Cardinal); cdecl;
|
||||
begin
|
||||
try
|
||||
IAttachmentImpl(this).setMaxBlobCacheSize(status, size);
|
||||
except
|
||||
on e: Exception do FbException.catchException(status, e);
|
||||
end
|
||||
end;
|
||||
|
||||
function IAttachmentImpl_getMaxInlineBlobSizeDispatcher(this: IAttachment; status: IStatus): Cardinal; cdecl;
|
||||
begin
|
||||
Result := 0;
|
||||
try
|
||||
Result := IAttachmentImpl(this).getMaxInlineBlobSize(status);
|
||||
except
|
||||
on e: Exception do FbException.catchException(status, e);
|
||||
end
|
||||
end;
|
||||
|
||||
procedure IAttachmentImpl_setMaxInlineBlobSizeDispatcher(this: IAttachment; status: IStatus; size: Cardinal); cdecl;
|
||||
begin
|
||||
try
|
||||
IAttachmentImpl(this).setMaxInlineBlobSize(status, size);
|
||||
except
|
||||
on e: Exception do FbException.catchException(status, e);
|
||||
end
|
||||
end;
|
||||
|
||||
var
|
||||
IAttachmentImpl_vTable: AttachmentVTable;
|
||||
|
||||
@ -17319,7 +17469,7 @@ initialization
|
||||
IResultSetImpl_vTable.getInfo := @IResultSetImpl_getInfoDispatcher;
|
||||
|
||||
IStatementImpl_vTable := StatementVTable.create;
|
||||
IStatementImpl_vTable.version := 5;
|
||||
IStatementImpl_vTable.version := 6;
|
||||
IStatementImpl_vTable.addRef := @IStatementImpl_addRefDispatcher;
|
||||
IStatementImpl_vTable.release := @IStatementImpl_releaseDispatcher;
|
||||
IStatementImpl_vTable.getInfo := @IStatementImpl_getInfoDispatcher;
|
||||
@ -17337,6 +17487,8 @@ initialization
|
||||
IStatementImpl_vTable.setTimeout := @IStatementImpl_setTimeoutDispatcher;
|
||||
IStatementImpl_vTable.createBatch := @IStatementImpl_createBatchDispatcher;
|
||||
IStatementImpl_vTable.free := @IStatementImpl_freeDispatcher;
|
||||
IStatementImpl_vTable.getMaxInlineBlobSize := @IStatementImpl_getMaxInlineBlobSizeDispatcher;
|
||||
IStatementImpl_vTable.setMaxInlineBlobSize := @IStatementImpl_setMaxInlineBlobSizeDispatcher;
|
||||
|
||||
IBatchImpl_vTable := BatchVTable.create;
|
||||
IBatchImpl_vTable.version := 4;
|
||||
@ -17393,7 +17545,7 @@ initialization
|
||||
IEventsImpl_vTable.cancel := @IEventsImpl_cancelDispatcher;
|
||||
|
||||
IAttachmentImpl_vTable := AttachmentVTable.create;
|
||||
IAttachmentImpl_vTable.version := 5;
|
||||
IAttachmentImpl_vTable.version := 6;
|
||||
IAttachmentImpl_vTable.addRef := @IAttachmentImpl_addRefDispatcher;
|
||||
IAttachmentImpl_vTable.release := @IAttachmentImpl_releaseDispatcher;
|
||||
IAttachmentImpl_vTable.getInfo := @IAttachmentImpl_getInfoDispatcher;
|
||||
@ -17422,6 +17574,10 @@ initialization
|
||||
IAttachmentImpl_vTable.createReplicator := @IAttachmentImpl_createReplicatorDispatcher;
|
||||
IAttachmentImpl_vTable.detach := @IAttachmentImpl_detachDispatcher;
|
||||
IAttachmentImpl_vTable.dropDatabase := @IAttachmentImpl_dropDatabaseDispatcher;
|
||||
IAttachmentImpl_vTable.getMaxBlobCacheSize := @IAttachmentImpl_getMaxBlobCacheSizeDispatcher;
|
||||
IAttachmentImpl_vTable.setMaxBlobCacheSize := @IAttachmentImpl_setMaxBlobCacheSizeDispatcher;
|
||||
IAttachmentImpl_vTable.getMaxInlineBlobSize := @IAttachmentImpl_getMaxInlineBlobSizeDispatcher;
|
||||
IAttachmentImpl_vTable.setMaxInlineBlobSize := @IAttachmentImpl_setMaxInlineBlobSizeDispatcher;
|
||||
|
||||
IServiceImpl_vTable := ServiceVTable.create;
|
||||
IServiceImpl_vTable.version := 5;
|
||||
|
@ -307,6 +307,9 @@ public:
|
||||
JBatch* createBatch(Firebird::CheckStatusWrapper* status, Firebird::IMessageMetadata* inMetadata,
|
||||
unsigned parLength, const unsigned char* par) override;
|
||||
|
||||
unsigned getMaxInlineBlobSize(Firebird::CheckStatusWrapper* status) override;
|
||||
void setMaxInlineBlobSize(Firebird::CheckStatusWrapper* status, unsigned size) override;
|
||||
|
||||
public:
|
||||
JStatement(DsqlRequest* handle, StableAttachmentPart* sa, Firebird::Array<UCHAR>& meta);
|
||||
|
||||
@ -460,6 +463,10 @@ public:
|
||||
Firebird::IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par) override;
|
||||
Firebird::IReplicator* createReplicator(Firebird::CheckStatusWrapper* status) override;
|
||||
|
||||
unsigned getMaxBlobCacheSize(Firebird::CheckStatusWrapper* status) override;
|
||||
void setMaxBlobCacheSize(Firebird::CheckStatusWrapper* status, unsigned size) override;
|
||||
unsigned getMaxInlineBlobSize(Firebird::CheckStatusWrapper* status) override;
|
||||
void setMaxInlineBlobSize(Firebird::CheckStatusWrapper* status, unsigned size) override;
|
||||
public:
|
||||
explicit JAttachment(StableAttachmentPart* js);
|
||||
|
||||
|
@ -5308,6 +5308,28 @@ IReplicator* JAttachment::createReplicator(CheckStatusWrapper* user_status)
|
||||
return jr;
|
||||
}
|
||||
|
||||
unsigned JAttachment::getMaxBlobCacheSize(CheckStatusWrapper* status)
|
||||
{
|
||||
status->setErrors(Arg::Gds(isc_wish_list).value());
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JAttachment::setMaxBlobCacheSize(CheckStatusWrapper* status, unsigned size)
|
||||
{
|
||||
status->setErrors(Arg::Gds(isc_wish_list).value());
|
||||
}
|
||||
|
||||
unsigned JAttachment::getMaxInlineBlobSize(CheckStatusWrapper* status)
|
||||
{
|
||||
status->setErrors(Arg::Gds(isc_wish_list).value());
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JAttachment::setMaxInlineBlobSize(CheckStatusWrapper* status, unsigned size)
|
||||
{
|
||||
status->setErrors(Arg::Gds(isc_wish_list).value());
|
||||
}
|
||||
|
||||
|
||||
int JResultSet::fetchNext(CheckStatusWrapper* user_status, void* buffer)
|
||||
{
|
||||
@ -6090,6 +6112,17 @@ JBatch* JStatement::createBatch(Firebird::CheckStatusWrapper* status, Firebird::
|
||||
return batch;
|
||||
}
|
||||
|
||||
unsigned JStatement::getMaxInlineBlobSize(CheckStatusWrapper* status)
|
||||
{
|
||||
status->setErrors(Arg::Gds(isc_wish_list).value());
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JStatement::setMaxInlineBlobSize(CheckStatusWrapper* status, unsigned size)
|
||||
{
|
||||
status->setErrors(Arg::Gds(isc_wish_list).value());
|
||||
}
|
||||
|
||||
|
||||
JBatch::JBatch(DsqlBatch* handle, JStatement* aStatement, IMessageMetadata* aMetadata)
|
||||
: batch(handle),
|
||||
|
@ -699,6 +699,26 @@ public:
|
||||
Batch* createBatch(CheckStatusWrapper* status, IMessageMetadata* inMetadata,
|
||||
unsigned parLength, const unsigned char* par) override;
|
||||
|
||||
unsigned getMaxInlineBlobSize(CheckStatusWrapper* status) override
|
||||
{
|
||||
if (statement->rsr_rdb->rdb_port->port_protocol < PROTOCOL_INLINE_BLOB)
|
||||
{
|
||||
status->setErrors(Arg::Gds(isc_wish_list).value());
|
||||
return 0;
|
||||
}
|
||||
return statement->rsr_inline_blob_size;
|
||||
}
|
||||
|
||||
void setMaxInlineBlobSize(CheckStatusWrapper* status, unsigned size) override
|
||||
{
|
||||
if (statement->rsr_rdb->rdb_port->port_protocol < PROTOCOL_INLINE_BLOB)
|
||||
{
|
||||
status->setErrors(Arg::Gds(isc_wish_list).value());
|
||||
return;
|
||||
}
|
||||
statement->rsr_inline_blob_size = size;
|
||||
}
|
||||
|
||||
public:
|
||||
Statement(Rsr* handle, Attachment* a, unsigned aDialect)
|
||||
: metadata(getPool(), this, NULL),
|
||||
@ -909,6 +929,12 @@ public:
|
||||
|
||||
Replicator* createReplicator(CheckStatusWrapper* status) override;
|
||||
|
||||
unsigned getMaxBlobCacheSize(CheckStatusWrapper* status) override;
|
||||
void setMaxBlobCacheSize(CheckStatusWrapper* status, unsigned size) override;
|
||||
|
||||
unsigned getMaxInlineBlobSize(CheckStatusWrapper* status) override;
|
||||
void setMaxInlineBlobSize(CheckStatusWrapper* status, unsigned size) override;
|
||||
|
||||
public:
|
||||
Attachment(Rdb* handle, const PathName& path)
|
||||
: replicator(nullptr), rdb(handle), dbPath(getPool(), path)
|
||||
@ -2445,6 +2471,50 @@ Batch* Attachment::createBatch(CheckStatusWrapper* status, ITransaction* transac
|
||||
}
|
||||
|
||||
|
||||
unsigned Attachment::getMaxBlobCacheSize(CheckStatusWrapper* status)
|
||||
{
|
||||
if (rdb->rdb_port->port_protocol < PROTOCOL_INLINE_BLOB)
|
||||
{
|
||||
status->setErrors(Arg::Gds(isc_wish_list).value());
|
||||
return 0;
|
||||
}
|
||||
return rdb->rdb_blob_cache_size;
|
||||
}
|
||||
|
||||
|
||||
void Attachment::setMaxBlobCacheSize(CheckStatusWrapper* status, unsigned size)
|
||||
{
|
||||
if (rdb->rdb_port->port_protocol < PROTOCOL_INLINE_BLOB)
|
||||
{
|
||||
status->setErrors(Arg::Gds(isc_wish_list).value());
|
||||
return;
|
||||
}
|
||||
rdb->rdb_blob_cache_size = size;
|
||||
}
|
||||
|
||||
|
||||
unsigned Attachment::getMaxInlineBlobSize(CheckStatusWrapper* status)
|
||||
{
|
||||
if (rdb->rdb_port->port_protocol < PROTOCOL_INLINE_BLOB)
|
||||
{
|
||||
status->setErrors(Arg::Gds(isc_wish_list).value());
|
||||
return 0;
|
||||
}
|
||||
return rdb->rdb_inline_blob_size;
|
||||
}
|
||||
|
||||
|
||||
void Attachment::setMaxInlineBlobSize(CheckStatusWrapper* status, unsigned size)
|
||||
{
|
||||
if (rdb->rdb_port->port_protocol < PROTOCOL_INLINE_BLOB)
|
||||
{
|
||||
status->setErrors(Arg::Gds(isc_wish_list).value());
|
||||
return;
|
||||
}
|
||||
rdb->rdb_inline_blob_size = size;
|
||||
}
|
||||
|
||||
|
||||
Batch* Statement::createBatch(CheckStatusWrapper* status, IMessageMetadata* inMetadata,
|
||||
unsigned parLength, const unsigned char* par)
|
||||
{
|
||||
@ -3573,6 +3643,7 @@ ITransaction* Statement::execute(CheckStatusWrapper* status, ITransaction* apiTr
|
||||
sqldata->p_sqldata_out_message_number = 0; // out_msg_type
|
||||
sqldata->p_sqldata_timeout = statement->rsr_timeout;
|
||||
sqldata->p_sqldata_cursor_flags = 0;
|
||||
sqldata->p_sqldata_inline_blob_size = statement->rsr_inline_blob_size;
|
||||
|
||||
send_packet(port, packet);
|
||||
|
||||
@ -3752,6 +3823,7 @@ ResultSet* Statement::openCursor(CheckStatusWrapper* status, ITransaction* apiTr
|
||||
sqldata->p_sqldata_out_message_number = 0; // out_msg_type
|
||||
sqldata->p_sqldata_timeout = statement->rsr_timeout;
|
||||
sqldata->p_sqldata_cursor_flags = flags;
|
||||
sqldata->p_sqldata_inline_blob_size = statement->rsr_inline_blob_size;
|
||||
|
||||
{
|
||||
Cleanup msgClean([&message] {
|
||||
@ -3945,6 +4017,8 @@ ITransaction* Attachment::execute(CheckStatusWrapper* status, ITransaction* apiT
|
||||
ex_now->p_sqlst_out_blr.cstr_length = out_blr_length;
|
||||
ex_now->p_sqlst_out_blr.cstr_address = const_cast<unsigned char*>(out_blr);
|
||||
ex_now->p_sqlst_out_message_number = 0; // out_msg_type
|
||||
ex_now->p_sqlst_inline_blob_size = (packet->p_operation == op_exec_immediate2) ?
|
||||
rdb->rdb_inline_blob_size : 0;
|
||||
|
||||
send_packet(port, packet);
|
||||
|
||||
@ -4156,6 +4230,7 @@ Statement* Attachment::createStatement(CheckStatusWrapper* status, unsigned dial
|
||||
|
||||
statement->rsr_next = rdb->rdb_sql_requests;
|
||||
rdb->rdb_sql_requests = statement;
|
||||
statement->rsr_inline_blob_size = rdb->rdb_inline_blob_size;
|
||||
|
||||
Statement* s = FB_NEW Statement(statement, this, dialect);
|
||||
s->addRef();
|
||||
@ -9287,7 +9362,10 @@ static void release_blob( Rbl* blob)
|
||||
Rtr* transaction = blob->rbl_rtr;
|
||||
Rdb* rdb = blob->rbl_rdb;
|
||||
|
||||
if (!blob->isCached())
|
||||
if (blob->isCached())
|
||||
// Assume buffer was not resized while blob was cached
|
||||
rdb->decBlobCache(blob->rbl_buffer_length);
|
||||
else
|
||||
rdb->rdb_port->releaseObject(blob->rbl_id);
|
||||
|
||||
if (transaction->rtr_blobs.locate(blob->rbl_blob_id))
|
||||
|
@ -670,6 +670,8 @@ bool_t xdr_protocol(RemoteXdr* xdrs, PACKET* p)
|
||||
MAP(xdr_u_long, sqldata->p_sqldata_timeout);
|
||||
if (port->port_protocol >= PROTOCOL_FETCH_SCROLL)
|
||||
MAP(xdr_u_long, sqldata->p_sqldata_cursor_flags);
|
||||
if (port->port_protocol >= PROTOCOL_INLINE_BLOB)
|
||||
MAP(xdr_u_long, sqldata->p_sqldata_inline_blob_size);
|
||||
DEBUG_PRINTSIZE(xdrs, p->p_operation);
|
||||
return P_TRUE(xdrs, p);
|
||||
|
||||
@ -691,6 +693,10 @@ bool_t xdr_protocol(RemoteXdr* xdrs, PACKET* p)
|
||||
return P_FALSE(xdrs, p);
|
||||
}
|
||||
MAP(xdr_short, reinterpret_cast<SSHORT&>(prep_stmt->p_sqlst_out_message_number));
|
||||
|
||||
if (port->port_protocol >= PROTOCOL_INLINE_BLOB)
|
||||
MAP(xdr_u_long, prep_stmt->p_sqlst_inline_blob_size);
|
||||
|
||||
// Fall into ...
|
||||
|
||||
case op_exec_immediate:
|
||||
|
@ -630,6 +630,7 @@ typedef struct p_sqlst
|
||||
CSTRING p_sqlst_out_blr; // blr describing output message
|
||||
USHORT p_sqlst_out_message_number;
|
||||
USHORT p_sqlst_flags; // prepare flags
|
||||
ULONG p_sqlst_inline_blob_size; // maximum size of inlined blob
|
||||
} P_SQLST;
|
||||
|
||||
typedef struct p_sqldata
|
||||
@ -647,6 +648,7 @@ typedef struct p_sqldata
|
||||
ULONG p_sqldata_cursor_flags; // cursor flags
|
||||
P_FETCH p_sqldata_fetch_op; // Fetch operation
|
||||
SLONG p_sqldata_fetch_pos; // Fetch position
|
||||
ULONG p_sqldata_inline_blob_size; // maximum size of inlined blob
|
||||
} P_SQLDATA;
|
||||
|
||||
typedef struct p_sqlfree
|
||||
|
@ -985,6 +985,13 @@ void Rtr::setupInlineBlob(P_INLINE_BLOB* p_blob)
|
||||
Rbl* blb = rtr_inline_blob;
|
||||
rtr_inline_blob = nullptr;
|
||||
|
||||
blb->rbl_buffer_length = blb->rbl_data.getCapacity();
|
||||
if (!rtr_rdb->incBlobCache(blb->rbl_buffer_length))
|
||||
{
|
||||
delete blb;
|
||||
return;
|
||||
}
|
||||
|
||||
blb->rbl_blob_id = p_blob->p_blob_id;
|
||||
if (!rtr_blobs.add(blb))
|
||||
{
|
||||
@ -995,6 +1002,7 @@ void Rtr::setupInlineBlob(P_INLINE_BLOB* p_blob)
|
||||
fb_assert(blb != old);
|
||||
delete blb;
|
||||
|
||||
rtr_rdb->decBlobCache(blb->rbl_buffer_length);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -104,6 +104,9 @@ const ULONG MAX_ROWS_PER_BATCH = 1000;
|
||||
|
||||
const ULONG MAX_BATCH_CACHE_SIZE = 1024 * 1024; // 1 MB
|
||||
|
||||
const ULONG DEFAULT_BLOBS_CACHE_SIZE = 10 * 1024 * 1024; // 10 MB
|
||||
const ULONG DEFAULT_INLINE_BLOB_SIZE = BLOB_LENGTH;
|
||||
|
||||
// fwd. decl.
|
||||
namespace Firebird {
|
||||
class Exception;
|
||||
@ -181,15 +184,44 @@ private:
|
||||
public:
|
||||
std::atomic<int> rdb_async_lock; // Atomic to avoid >1 async calls at once
|
||||
|
||||
ULONG rdb_inline_blob_size; // default max size of blob that can be transfered inline
|
||||
ULONG rdb_blob_cache_size; // limit on cached blobs size
|
||||
ULONG rdb_cached_blobs_size; // actual size of cached blobs
|
||||
ULONG rdb_cached_blobs_count; // actual count of cached blobs
|
||||
|
||||
public:
|
||||
Rdb() :
|
||||
rdb_iface(NULL), rdb_port(0),
|
||||
rdb_transactions(0), rdb_requests(0), rdb_events(0), rdb_sql_requests(0),
|
||||
rdb_id(0), rdb_async_thread_id(0), rdb_async_lock(0)
|
||||
rdb_id(0), rdb_async_thread_id(0), rdb_async_lock(0),
|
||||
rdb_inline_blob_size(DEFAULT_INLINE_BLOB_SIZE), rdb_blob_cache_size(DEFAULT_BLOBS_CACHE_SIZE),
|
||||
rdb_cached_blobs_size(0), rdb_cached_blobs_count(0)
|
||||
{
|
||||
}
|
||||
|
||||
static ISC_STATUS badHandle() { return isc_bad_db_handle; }
|
||||
|
||||
// Increment blob cache usage.
|
||||
// Return false if blob cache have not enough space for a blob of given size.
|
||||
bool incBlobCache(ULONG size)
|
||||
{
|
||||
if (rdb_cached_blobs_size + size > rdb_blob_cache_size)
|
||||
return false;
|
||||
|
||||
rdb_cached_blobs_size += size;
|
||||
rdb_cached_blobs_count++;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Decrement blob cache usage.
|
||||
void decBlobCache(ULONG size)
|
||||
{
|
||||
fb_assert(rdb_cached_blobs_size >= size);
|
||||
fb_assert(rdb_cached_blobs_count > 0);
|
||||
|
||||
rdb_cached_blobs_size -= size;
|
||||
rdb_cached_blobs_count--;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -550,6 +582,7 @@ struct Rsr : public Firebird::GlobalStorage, public TypedHandle<rem_type_rsr>
|
||||
|
||||
P_FETCH rsr_fetch_operation; // Last performed fetch operation
|
||||
SLONG rsr_fetch_position; // and position
|
||||
unsigned int rsr_inline_blob_size; // max size of blob that can be transfered inline
|
||||
|
||||
struct BatchStream
|
||||
{
|
||||
@ -604,7 +637,7 @@ public:
|
||||
rsr_rows_pending(0), rsr_msgs_waiting(0), rsr_reorder_level(0), rsr_batch_count(0),
|
||||
rsr_cursor_name(getPool()), rsr_delayed_format(false), rsr_timeout(0), rsr_self(NULL),
|
||||
rsr_batch_size(0), rsr_batch_flags(0), rsr_batch_ics(NULL),
|
||||
rsr_fetch_operation(fetch_next), rsr_fetch_position(0)
|
||||
rsr_fetch_operation(fetch_next), rsr_fetch_position(0), rsr_inline_blob_size(0)
|
||||
{ }
|
||||
|
||||
~Rsr()
|
||||
@ -1612,10 +1645,10 @@ public:
|
||||
private:
|
||||
bool tryKeyType(const KnownServerKey& srvKey, InternalCryptKey* cryptKey);
|
||||
|
||||
void sendInlineBlobs(PACKET*, Rtr* rtr, UCHAR* message, const rem_fmt* format);
|
||||
void sendInlineBlobs(PACKET*, Rtr* rtr, UCHAR* message, const rem_fmt* format, ULONG maxSize);
|
||||
|
||||
// return false if any error retrieving blob happens
|
||||
bool sendInlineBlob(PACKET*, Rtr* rtr, SQUAD blobId);
|
||||
bool sendInlineBlob(PACKET*, Rtr* rtr, SQUAD blobId, ULONG maxSize);
|
||||
};
|
||||
|
||||
|
||||
|
@ -3512,8 +3512,9 @@ ISC_STATUS rem_port::execute_immediate(P_OP op, P_SQLST * exnow, PACKET* sendL)
|
||||
{
|
||||
this->port_statement->rsr_format = this->port_statement->rsr_select_format;
|
||||
|
||||
if (out_msg)
|
||||
sendInlineBlobs(sendL, transaction, out_msg, port_statement->rsr_select_format);
|
||||
if (out_msg && exnow->p_sqlst_inline_blob_size)
|
||||
sendInlineBlobs(sendL, transaction, out_msg, port_statement->rsr_select_format,
|
||||
exnow->p_sqlst_inline_blob_size);
|
||||
|
||||
sendL->p_operation = op_sql_response;
|
||||
sendL->p_sqldata.p_sqldata_messages =
|
||||
@ -3950,12 +3951,15 @@ ISC_STATUS rem_port::execute_statement(P_OP op, P_SQLDATA* sqldata, PACKET* send
|
||||
iMsgBuffer.metadata, iMsgBuffer.buffer, oMsgBuffer.metadata, oMsgBuffer.buffer);
|
||||
}
|
||||
|
||||
statement->rsr_inline_blob_size = sqldata->p_sqldata_inline_blob_size;
|
||||
|
||||
if (op == op_execute2)
|
||||
{
|
||||
this->port_statement->rsr_format = this->port_statement->rsr_select_format;
|
||||
|
||||
if (out_msg)
|
||||
sendInlineBlobs(sendL, transaction, out_msg, port_statement->rsr_select_format);
|
||||
if (out_msg && statement->rsr_inline_blob_size)
|
||||
sendInlineBlobs(sendL, transaction, out_msg, port_statement->rsr_select_format,
|
||||
statement->rsr_inline_blob_size);
|
||||
|
||||
sendL->p_operation = op_sql_response;
|
||||
sendL->p_sqldata.p_sqldata_messages =
|
||||
@ -4256,12 +4260,12 @@ ISC_STATUS rem_port::fetch(P_SQLDATA * sqldata, PACKET* sendL, bool scroll)
|
||||
}
|
||||
|
||||
// send blob data inline
|
||||
if (statement->haveBlobs())
|
||||
if (statement->haveBlobs() && statement->rsr_inline_blob_size)
|
||||
{
|
||||
AutoSaveRestore op(&sendL->p_operation);
|
||||
|
||||
sendInlineBlobs(sendL, statement->rsr_rtr, message->msg_buffer,
|
||||
statement->rsr_select_format);
|
||||
statement->rsr_select_format, statement->rsr_inline_blob_size);
|
||||
}
|
||||
|
||||
// There's a buffer waiting -- send it
|
||||
@ -5996,7 +6000,8 @@ ISC_STATUS rem_port::seek_blob(P_SEEK* seek, PACKET* sendL)
|
||||
}
|
||||
|
||||
|
||||
void rem_port::sendInlineBlobs(PACKET* sendL, Rtr* rtr, UCHAR* message, const rem_fmt* format)
|
||||
void rem_port::sendInlineBlobs(PACKET* sendL, Rtr* rtr, UCHAR* message,
|
||||
const rem_fmt* format, ULONG maxSize)
|
||||
{
|
||||
if (port_protocol < PROTOCOL_INLINE_BLOB || port_type == XNET)
|
||||
return;
|
||||
@ -6016,13 +6021,13 @@ void rem_port::sendInlineBlobs(PACKET* sendL, Rtr* rtr, UCHAR* message, const re
|
||||
if (*blobId == NULL_BLOB)
|
||||
continue;
|
||||
|
||||
if (!sendInlineBlob(sendL, rtr, *blobId))
|
||||
if (!sendInlineBlob(sendL, rtr, *blobId, maxSize))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool rem_port::sendInlineBlob(PACKET* sendL, Rtr* rtr, SQUAD blobId)
|
||||
bool rem_port::sendInlineBlob(PACKET* sendL, Rtr* rtr, SQUAD blobId, ULONG maxSize)
|
||||
{
|
||||
P_INLINE_BLOB* p_blob = &sendL->p_inline_blob;
|
||||
|
||||
@ -6039,7 +6044,7 @@ bool rem_port::sendInlineBlob(PACKET* sendL, Rtr* rtr, SQUAD blobId)
|
||||
return false;
|
||||
|
||||
// ask blob info
|
||||
const UCHAR items[] = {
|
||||
const UCHAR items[] = {
|
||||
isc_info_blob_num_segments,
|
||||
isc_info_blob_max_segment,
|
||||
isc_info_blob_total_length,
|
||||
@ -6087,8 +6092,7 @@ bool rem_port::sendInlineBlob(PACKET* sendL, Rtr* rtr, SQUAD blobId)
|
||||
if (!total_length)
|
||||
return true;
|
||||
|
||||
// todo: set max inline blob size
|
||||
if (total_length > 16384)
|
||||
if (total_length > maxSize)
|
||||
return true;
|
||||
|
||||
if (!segmented)
|
||||
|
@ -477,6 +477,9 @@ public:
|
||||
YBatch* createBatch(Firebird::CheckStatusWrapper* status, Firebird::IMessageMetadata* inMetadata,
|
||||
unsigned parLength, const unsigned char* par);
|
||||
|
||||
unsigned getMaxInlineBlobSize(Firebird::CheckStatusWrapper* status) override;
|
||||
void setMaxInlineBlobSize(Firebird::CheckStatusWrapper* status, unsigned size) override;
|
||||
|
||||
public:
|
||||
AtomicAttPtr attachment;
|
||||
Firebird::Mutex statementMutex;
|
||||
@ -579,6 +582,11 @@ public:
|
||||
Firebird::IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par);
|
||||
YReplicator* createReplicator(Firebird::CheckStatusWrapper* status);
|
||||
|
||||
unsigned getMaxBlobCacheSize(Firebird::CheckStatusWrapper* status) override;
|
||||
void setMaxBlobCacheSize(Firebird::CheckStatusWrapper* status, unsigned size) override;
|
||||
unsigned getMaxInlineBlobSize(Firebird::CheckStatusWrapper* status) override;
|
||||
void setMaxInlineBlobSize(Firebird::CheckStatusWrapper* status, unsigned size) override;
|
||||
|
||||
public:
|
||||
Firebird::IProvider* provider;
|
||||
Firebird::PathName dbPath;
|
||||
|
@ -4582,6 +4582,36 @@ YBatch* YStatement::createBatch(CheckStatusWrapper* status, IMessageMetadata* in
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
unsigned YStatement::getMaxInlineBlobSize(CheckStatusWrapper* status)
|
||||
{
|
||||
try
|
||||
{
|
||||
YEntry<YStatement> entry(status, this);
|
||||
return entry.next()->getMaxInlineBlobSize(status);
|
||||
}
|
||||
catch (const Exception& e)
|
||||
{
|
||||
e.stuffException(status);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void YStatement::setMaxInlineBlobSize(CheckStatusWrapper* status, unsigned size)
|
||||
{
|
||||
try
|
||||
{
|
||||
YEntry<YStatement> entry(status, this);
|
||||
entry.next()->setMaxInlineBlobSize(status, size);
|
||||
}
|
||||
catch (const Exception& e)
|
||||
{
|
||||
e.stuffException(status);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
IscStatement::~IscStatement()
|
||||
@ -6220,6 +6250,66 @@ YReplicator* YAttachment::createReplicator(CheckStatusWrapper* status)
|
||||
}
|
||||
|
||||
|
||||
unsigned YAttachment::getMaxBlobCacheSize(CheckStatusWrapper* status)
|
||||
{
|
||||
try
|
||||
{
|
||||
YEntry<YAttachment> entry(status, this);
|
||||
return entry.next()->getMaxBlobCacheSize(status);
|
||||
}
|
||||
catch (const Exception& e)
|
||||
{
|
||||
e.stuffException(status);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void YAttachment::setMaxBlobCacheSize(CheckStatusWrapper* status, unsigned size)
|
||||
{
|
||||
try
|
||||
{
|
||||
YEntry<YAttachment> entry(status, this);
|
||||
entry.next()->setMaxBlobCacheSize(status, size);
|
||||
}
|
||||
catch (const Exception& e)
|
||||
{
|
||||
e.stuffException(status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned YAttachment::getMaxInlineBlobSize(CheckStatusWrapper* status)
|
||||
{
|
||||
try
|
||||
{
|
||||
YEntry<YAttachment> entry(status, this);
|
||||
return entry.next()->getMaxInlineBlobSize(status);
|
||||
}
|
||||
catch (const Exception& e)
|
||||
{
|
||||
e.stuffException(status);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void YAttachment::setMaxInlineBlobSize(CheckStatusWrapper* status, unsigned size)
|
||||
{
|
||||
try
|
||||
{
|
||||
YEntry<YAttachment> entry(status, this);
|
||||
entry.next()->setMaxInlineBlobSize(status, size);
|
||||
}
|
||||
catch (const Exception& e)
|
||||
{
|
||||
e.stuffException(status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user