summaryrefslogtreecommitdiff
path: root/connectivity/source
diff options
context:
space:
mode:
authorJulien Nabet <serval2412@yahoo.fr>2022-06-07 22:57:43 +0200
committerAndras Timar <andras.timar@collabora.com>2022-06-09 11:02:07 +0200
commit474b1154c2eeadf3fef10d795ee96aeac9ac96fe (patch)
treede15fd3a79d7eb705c2a2b907b8ed3b1af8d58d1 /connectivity/source
parentcd40969931beed2e568366eb55f73a3471974d42 (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: Julien Nabet <serval2412@yahoo.fr> (cherry picked from commit a943e7ddd13315b18d7b33cd1b2f852144f54344) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135392 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'connectivity/source')
-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 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.