diff options
author | Julien Nabet <serval2412@yahoo.fr> | 2022-06-07 22:57:43 +0200 |
---|---|---|
committer | Julien Nabet <serval2412@yahoo.fr> | 2022-06-08 21:13:22 +0200 |
commit | a943e7ddd13315b18d7b33cd1b2f852144f54344 (patch) | |
tree | e4c302c891c5fa509faab1612141ee0c6fdd4ad6 /connectivity | |
parent | 12acdce71dd6b6af2c52ba8fa3248d3166418543 (diff) |
tdf#149470: Firebird, Clob may need several segments to store a very long input
Change-Id: I85c7789f46d834d2ae1b251f915382f833bd529d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135480
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Reviewed-by: Julien Nabet <serval2412@yahoo.fr>
Tested-by: Jenkins
Diffstat (limited to 'connectivity')
-rw-r--r-- | connectivity/source/drivers/firebird/PreparedStatement.cxx | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/connectivity/source/drivers/firebird/PreparedStatement.cxx b/connectivity/source/drivers/firebird/PreparedStatement.cxx index 9cd9157a7d6d..816c38d5c7e3 100644 --- a/connectivity/source/drivers/firebird/PreparedStatement.cxx +++ b/connectivity/source/drivers/firebird/PreparedStatement.cxx @@ -50,6 +50,8 @@ using namespace com::sun::star::util; IMPLEMENT_SERVICE_INFO(OPreparedStatement,"com.sun.star.sdbcx.firebird.PreparedStatement","com.sun.star.sdbc.PreparedStatement"); +constexpr size_t MAX_SIZE_SEGMENT = 65535; // max value of a segment of CLOB, if we want more than 65535 bytes, we need more segments + OPreparedStatement::OPreparedStatement( Connection* _pConnection, const OUString& sql) @@ -661,10 +663,41 @@ void OPreparedStatement::setClob( sal_Int32 nParameterIndex, const OUString& rSt OString sData = OUStringToOString( rStr, RTL_TEXTENCODING_UTF8); - ISC_STATUS aErr = isc_put_segment( m_statusVector, + size_t nDataSize = sData.getLength(); + ISC_STATUS aErr = 0; + // we can't store more than MAX_SIZE_SEGMENT in a segment + if (nDataSize <= MAX_SIZE_SEGMENT) + { + aErr = isc_put_segment( m_statusVector, &aBlobHandle, sData.getLength(), sData.getStr() ); + } + else + { + // if we need more, let's split the input and first let's calculate the nb of entire chunks needed + size_t nNbEntireChunks = nDataSize / MAX_SIZE_SEGMENT; + for (size_t i = 0; i < nNbEntireChunks; ++i) + { + OString strCurrentChunk = sData.copy(i * MAX_SIZE_SEGMENT, MAX_SIZE_SEGMENT); + aErr = isc_put_segment( m_statusVector, + &aBlobHandle, + strCurrentChunk.getLength(), + strCurrentChunk.getStr() ); + if (aErr) + break; + } + size_t nRemainingBytes = nDataSize - (nNbEntireChunks * MAX_SIZE_SEGMENT); + if (nRemainingBytes && !aErr) + { + // then copy the remaining + OString strCurrentChunk = sData.copy(nNbEntireChunks * MAX_SIZE_SEGMENT, nRemainingBytes); + aErr = isc_put_segment( m_statusVector, + &aBlobHandle, + strCurrentChunk.getLength(), + strCurrentChunk.getStr() ); + } + } // We need to make sure we close the Blob even if there are errors, hence evaluate // errors after closing. |