fdo#70664 Implement Blob writing (firebird-sdbc).

Change-Id: Ia95c6e1a0ede2103aae25610baeb3c7a9642113a
This commit is contained in:
Andrzej Hunt
2013-12-05 13:58:59 +00:00
parent 9210cde1ea
commit cb4b290bcf
2 changed files with 126 additions and 10 deletions

View File

@@ -432,6 +432,43 @@ void SAL_CALL OPreparedStatement::setTimestamp(sal_Int32 nIndex, const DateTime&
}
// -------------------------------------------------------------------------
// void OPreaparedStatement::set
void OPreparedStatement::openBlobForWriting(isc_blob_handle& rBlobHandle, ISC_QUAD& rBlobId)
{
ISC_STATUS aErr;
aErr = isc_create_blob2(m_statusVector,
&m_pConnection->getDBHandle(),
&m_pConnection->getTransaction(),
&rBlobHandle,
&rBlobId,
0, // Blob parameter buffer length
0); // Blob parameter buffer handle
if (aErr)
{
evaluateStatusVector(m_statusVector,
"setBlob failed on " + m_sSqlStatement,
*this);
assert(false);
}
}
void OPreparedStatement::closeBlobAfterWriting(isc_blob_handle& rBlobHandle)
{
ISC_STATUS aErr;
aErr = isc_close_blob(m_statusVector,
&rBlobHandle);
if (aErr)
{
evaluateStatusVector(m_statusVector,
"isc_close_blob failed",
*this);
assert(false);
}
}
void SAL_CALL OPreparedStatement::setClob( sal_Int32 parameterIndex, const Reference< XClob >& x ) throw(SQLException, RuntimeException)
{
(void) parameterIndex;
@@ -440,16 +477,53 @@ void SAL_CALL OPreparedStatement::setClob( sal_Int32 parameterIndex, const Refer
checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
}
// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::setBlob( sal_Int32 parameterIndex, const Reference< XBlob >& x ) throw(SQLException, RuntimeException)
void SAL_CALL OPreparedStatement::setBlob(sal_Int32 nParameterIndex,
const Reference< XBlob >& xBlob)
throw (SQLException, RuntimeException)
{
(void) parameterIndex;
(void) x;
::osl::MutexGuard aGuard( m_aMutex );
::osl::MutexGuard aGuard(m_aMutex);
checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
isc_blob_handle aBlobHandle = 0;
ISC_QUAD aBlobId;
openBlobForWriting(aBlobHandle, aBlobId);
// Max segment size is 2^16 == SAL_MAX_UINT16
sal_uInt64 nDataWritten = 0;
ISC_STATUS aErr;
while (xBlob->length() - nDataWritten > 0)
{
sal_uInt64 nDataRemaining = xBlob->length() - nDataWritten;
sal_uInt16 nWriteSize = (nDataRemaining > SAL_MAX_UINT16) ? SAL_MAX_UINT16 : nDataRemaining;
aErr = isc_put_segment(m_statusVector,
&aBlobHandle,
nWriteSize,
(const char*) xBlob->getBytes(nDataWritten, nWriteSize).getConstArray());
nDataWritten += nWriteSize;
if (aErr)
break;
}
// We need to make sure we close the Blob even if their are errors, hence evaluate
// errors after closing.
closeBlobAfterWriting(aBlobHandle);
if (aErr)
{
evaluateStatusVector(m_statusVector,
"isc_put_segment failed",
*this);
assert(false);
}
setValue< ISC_QUAD >(nParameterIndex, aBlobId, SQL_BLOB);
}
// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::setArray( sal_Int32 parameterIndex, const Reference< XArray >& x ) throw(SQLException, RuntimeException)
@@ -503,15 +577,49 @@ void SAL_CALL OPreparedStatement::setObject( sal_Int32 parameterIndex, const Any
checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
}
// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::setBytes( sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException)
void SAL_CALL OPreparedStatement::setBytes(sal_Int32 nParameterIndex,
const Sequence< sal_Int8 >& xBytes)
throw (SQLException, RuntimeException)
{
(void) parameterIndex;
(void) x;
::osl::MutexGuard aGuard( m_aMutex );
::osl::MutexGuard aGuard(m_aMutex);
checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
isc_blob_handle aBlobHandle = 0;
ISC_QUAD aBlobId;
openBlobForWriting(aBlobHandle, aBlobId);
// Max segment size is 2^16 == SAL_MAX_UINT16
sal_uInt64 nDataWritten = 0;
ISC_STATUS aErr;
while (xBytes.getLength() - nDataWritten > 0)
{
sal_uInt64 nDataRemaining = xBytes.getLength() - nDataWritten;
sal_uInt16 nWriteSize = (nDataRemaining > SAL_MAX_UINT16) ? SAL_MAX_UINT16 : nDataRemaining;
aErr = isc_put_segment(m_statusVector,
&aBlobHandle,
nWriteSize,
(const char*) xBytes.getConstArray() + nDataWritten);
nDataWritten += nWriteSize;
if (aErr)
break;
}
// We need to make sure we close the Blob even if their are errors, hence evaluate
// errors after closing.
closeBlobAfterWriting(aBlobHandle);
if (aErr)
{
evaluateStatusVector(m_statusVector,
"isc_put_segment failed",
*this);
assert(false);
}
setValue< ISC_QUAD >(nParameterIndex, aBlobId, SQL_BLOB);
}
// -------------------------------------------------------------------------

View File

@@ -87,6 +87,14 @@ namespace connectivity
void ensurePrepared()
throw(::com::sun::star::sdbc::SQLException,
::com::sun::star::uno::RuntimeException);
/**
* Assumes that all necessary mutexes have been taken.
*/
void openBlobForWriting(isc_blob_handle& rBlobHandle, ISC_QUAD& rBlobId);
/**
* Assumes that all necessary mutexes have been taken.
*/
void closeBlobAfterWriting(isc_blob_handle& rBlobHandle);
protected:
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,