connectivity/source/drivers/firebird/PreparedStatement.cxx | 35 ++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-)
New commits: commit 605298a6e06ccb02b206f90fb9d0b8f831349fd8 Author: Julien Nabet <serval2...@yahoo.fr> AuthorDate: Tue Jun 7 22:57:43 2022 +0200 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Thu Jun 9 09:44:51 2022 +0200 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: Julien Nabet <serval2...@yahoo.fr> (cherry picked from commit a943e7ddd13315b18d7b33cd1b2f852144f54344) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135392 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/connectivity/source/drivers/firebird/PreparedStatement.cxx b/connectivity/source/drivers/firebird/PreparedStatement.cxx index 392785b9c816..3209f9d02aea 100644 --- a/connectivity/source/drivers/firebird/PreparedStatement.cxx +++ b/connectivity/source/drivers/firebird/PreparedStatement.cxx @@ -52,6 +52,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) @@ -663,10 +665,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.