summaryrefslogtreecommitdiff
path: root/connectivity
diff options
context:
space:
mode:
authorJulien Nabet <serval2412@yahoo.fr>2022-06-07 22:57:43 +0200
committerJulien Nabet <serval2412@yahoo.fr>2022-06-08 21:13:22 +0200
commita943e7ddd13315b18d7b33cd1b2f852144f54344 (patch)
treee4c302c891c5fa509faab1612141ee0c6fdd4ad6 /connectivity
parent12acdce71dd6b6af2c52ba8fa3248d3166418543 (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.cxx35
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.