summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamás Bunth <btomi96@gmail.com>2017-01-10 20:26:05 +0100
committerTamás Bunth <btomi96@gmail.com>2017-01-14 12:13:32 +0000
commit882db8709f4ebc9f170cf743f39434d791b34b14 (patch)
treeded4c2875d152b653072d3bc71812f1a30cdb3cf
parent2a4b291d3bfb378776388f67670d877c658fce47 (diff)
tdf#70433 tdf#104734 implement sdbc XClob
And use it in getClob, so LO can display clob values like the return value of the built-in List function. Change-Id: I395016e945dbeb2c6bb3737b6345d40ff9f48089 Reviewed-on: https://gerrit.libreoffice.org/32938 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tamás Bunth <btomi96@gmail.com>
-rw-r--r--connectivity/Library_firebird_sdbc.mk1
-rw-r--r--connectivity/source/drivers/firebird/Clob.cxx100
-rw-r--r--connectivity/source/drivers/firebird/Clob.hxx76
-rw-r--r--connectivity/source/drivers/firebird/Connection.cxx14
-rw-r--r--connectivity/source/drivers/firebird/Connection.hxx5
-rw-r--r--connectivity/source/drivers/firebird/ResultSet.cxx10
6 files changed, 205 insertions, 1 deletions
diff --git a/connectivity/Library_firebird_sdbc.mk b/connectivity/Library_firebird_sdbc.mk
index 43fa363f7551..0247f08f3de9 100644
--- a/connectivity/Library_firebird_sdbc.mk
+++ b/connectivity/Library_firebird_sdbc.mk
@@ -41,6 +41,7 @@ $(eval $(call gb_Library_set_componentfile,firebird_sdbc,connectivity/source/dri
$(eval $(call gb_Library_add_exception_objects,firebird_sdbc,\
connectivity/source/drivers/firebird/Blob \
+ connectivity/source/drivers/firebird/Clob \
connectivity/source/drivers/firebird/Catalog \
connectivity/source/drivers/firebird/Column \
connectivity/source/drivers/firebird/Columns \
diff --git a/connectivity/source/drivers/firebird/Clob.cxx b/connectivity/source/drivers/firebird/Clob.cxx
new file mode 100644
index 000000000000..65cd03e10942
--- /dev/null
+++ b/connectivity/source/drivers/firebird/Clob.cxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "Clob.hxx"
+#include "Blob.hxx"
+#include "Connection.hxx"
+#include "Util.hxx"
+
+#include <connectivity/dbexception.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+
+using namespace ::connectivity::firebird;
+
+using namespace ::osl;
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+
+Clob::Clob(isc_db_handle* pDatabaseHandle,
+ isc_tr_handle* pTransactionHandle,
+ ISC_QUAD& aBlobID):
+ Clob_BASE(m_aMutex),
+ m_aBlob(pDatabaseHandle, pTransactionHandle, aBlobID)
+{
+}
+
+void SAL_CALL Clob::disposing()
+{
+ m_aBlob.disposing();
+ Clob_BASE::disposing();
+}
+
+sal_Int64 SAL_CALL Clob::length()
+ throw(SQLException, RuntimeException, std::exception)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(Clob_BASE::rBHelper.bDisposed);
+
+ // read the entire blob
+ // TODO FIXME better solution?
+ uno::Sequence < sal_Int8 > aEntireBlob = m_aBlob.getBytes( 1, m_aBlob.length());
+ OUString sEntireClob ( reinterpret_cast< sal_Char *>( aEntireBlob.getArray() ),
+ aEntireBlob.getLength(),
+ RTL_TEXTENCODING_UTF8 );
+ return sEntireClob.getLength();
+}
+
+OUString SAL_CALL Clob::getSubString(sal_Int64 nPosition,
+ sal_Int32 nLength)
+ throw(SQLException, RuntimeException, std::exception)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(Clob_BASE::rBHelper.bDisposed);
+
+ // read the entire blob
+ // TODO FIXME better solution?
+ // TODO FIXME Assume indexing of nPosition starts at position 1.
+ uno::Sequence < sal_Int8 > aEntireBlob = m_aBlob.getBytes( 1, m_aBlob.length());
+ OUString sEntireClob ( reinterpret_cast< sal_Char *>( aEntireBlob.getArray() ),
+ aEntireBlob.getLength(),
+ RTL_TEXTENCODING_UTF8 );
+
+ if( nPosition + nLength - 1 > sEntireClob.getLength() )
+ throw lang::IllegalArgumentException("nPosition out of range", *this, 0);
+
+ return sEntireClob.copy(nPosition - 1 , nLength);
+}
+
+uno::Reference< XInputStream > SAL_CALL Clob::getCharacterStream()
+ throw(SQLException, RuntimeException, std::exception)
+{
+ return m_aBlob.getBinaryStream();
+}
+
+sal_Int64 SAL_CALL Clob::position(const OUString& /*rPattern*/,
+ sal_Int32 /*nStart*/)
+ throw(SQLException, RuntimeException, std::exception)
+{
+ ::dbtools::throwFeatureNotImplementedSQLException("Clob::position", *this);
+ return 0;
+}
+
+sal_Int64 SAL_CALL Clob::positionOfClob(const Reference <XClob >& /*rPattern*/,
+ sal_Int64 /*aStart*/)
+ throw(SQLException, RuntimeException, std::exception)
+{
+ ::dbtools::throwFeatureNotImplementedSQLException("Blob::positionOfBlob", *this);
+ return 0;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/firebird/Clob.hxx b/connectivity/source/drivers/firebird/Clob.hxx
new file mode 100644
index 000000000000..bbe47f6b8966
--- /dev/null
+++ b/connectivity/source/drivers/firebird/Clob.hxx
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CLOB_HXX
+#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CLOB_HXX
+
+#include "Blob.hxx"
+
+#include <cppuhelper/compbase.hxx>
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/sdbc/XClob.hpp>
+
+namespace connectivity
+{
+ namespace firebird
+ {
+ typedef ::cppu::WeakComponentImplHelper< css::sdbc::XClob >
+ Clob_BASE;
+
+ class Clob :
+ public Clob_BASE
+ {
+ protected:
+ ::osl::Mutex m_aMutex;
+
+ /*
+ * In Firebird Clob (textual Blob) is a subtype of blob,
+ * hence we store the data in a Blob, and the Clob class is
+ * a wrapper around that.
+ */
+ connectivity::firebird::Blob m_aBlob;
+
+ public:
+ Clob(isc_db_handle* pDatabaseHandle,
+ isc_tr_handle* pTransactionHandle,
+ ISC_QUAD& aBlobID);
+
+ // ---- XClob ----------------------------------------------------
+ virtual sal_Int64 SAL_CALL
+ length()
+ throw(css::sdbc::SQLException,
+ css::uno::RuntimeException, std::exception) override;
+ virtual ::rtl::OUString SAL_CALL
+ getSubString(sal_Int64 aPosition, sal_Int32 aLength)
+ throw(css::sdbc::SQLException,
+ css::uno::RuntimeException, std::exception) override;
+ virtual css::uno::Reference< css::io::XInputStream > SAL_CALL
+ getCharacterStream()
+ throw(css::sdbc::SQLException,
+ css::uno::RuntimeException, std::exception) override;
+ virtual sal_Int64 SAL_CALL
+ position(const ::rtl::OUString& rPattern,
+ sal_Int32 aStart)
+ throw(css::sdbc::SQLException,
+ css::uno::RuntimeException, std::exception) override;
+ virtual sal_Int64 SAL_CALL
+ positionOfClob(const ::css::uno::Reference< ::css::sdbc::XClob >& rPattern,
+ sal_Int64 aStart)
+ throw(css::sdbc::SQLException,
+ css::uno::RuntimeException, std::exception) override;
+ // ---- OComponentHelper ------------------------------------------
+ virtual void SAL_CALL disposing() override;
+ };
+ }
+
+}
+
+#endif // INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CLOB_HXX
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx
index 48ebba59d62c..54ee5efdd7c9 100644
--- a/connectivity/source/drivers/firebird/Connection.cxx
+++ b/connectivity/source/drivers/firebird/Connection.cxx
@@ -373,6 +373,20 @@ Reference< XBlob> Connection::createBlob(ISC_QUAD* pBlobId)
return xReturn;
}
+Reference< XClob> Connection::createClob(ISC_QUAD* pBlobId)
+ throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(Connection_BASE::rBHelper.bDisposed);
+
+ Reference< XClob > xReturn = new Clob(&m_aDBHandle,
+ &m_aTransactionHandle,
+ *pBlobId);
+
+ m_aStatements.push_back(WeakReferenceHelper(xReturn));
+ return xReturn;
+}
+
//----- XConnection ----------------------------------------------------------
Reference< XStatement > SAL_CALL Connection::createStatement( )
diff --git a/connectivity/source/drivers/firebird/Connection.hxx b/connectivity/source/drivers/firebird/Connection.hxx
index a8b352797b82..420f0d7a283f 100644
--- a/connectivity/source/drivers/firebird/Connection.hxx
+++ b/connectivity/source/drivers/firebird/Connection.hxx
@@ -20,6 +20,7 @@
#ifndef INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CONNECTION_HXX
#define INCLUDED_CONNECTIVITY_SOURCE_DRIVERS_FIREBIRD_CONNECTION_HXX
+#include "Clob.hxx"
#include "Blob.hxx"
#include "SubComponent.hxx"
@@ -210,6 +211,10 @@ namespace connectivity
createBlob(ISC_QUAD* pBlobID)
throw(css::sdbc::SQLException,
css::uno::RuntimeException);
+ css::uno::Reference< css::sdbc::XClob>
+ createClob(ISC_QUAD* pBlobID)
+ throw(css::sdbc::SQLException,
+ css::uno::RuntimeException);
/**
* Create and/or connect to the sdbcx Catalog. This is completely
diff --git a/connectivity/source/drivers/firebird/ResultSet.cxx b/connectivity/source/drivers/firebird/ResultSet.cxx
index 7a939402641b..cc9dedc24cc0 100644
--- a/connectivity/source/drivers/firebird/ResultSet.cxx
+++ b/connectivity/source/drivers/firebird/ResultSet.cxx
@@ -746,7 +746,15 @@ uno::Reference< XClob > SAL_CALL OResultSet::getClob( sal_Int32 columnIndex ) th
MutexGuard aGuard(m_rMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- return nullptr;
+ int aSqlSubType = m_pSqlda->sqlvar[columnIndex-1].sqlsubtype;
+
+ SAL_WARN_IF(aSqlSubType != 1,
+ "connectivity.firebird", "wrong subtype, not a textual blob");
+
+ ISC_QUAD* pBlobID = safelyRetrieveValue< ISC_QUAD* >(columnIndex, SQL_BLOB);
+ if (!pBlobID)
+ return nullptr;
+ return m_pConnection->createClob(pBlobID);
}
uno::Reference< XBlob > SAL_CALL OResultSet::getBlob(sal_Int32 columnIndex)