diff options
author | Tamás Bunth <btomi96@gmail.com> | 2017-01-10 20:26:05 +0100 |
---|---|---|
committer | Tamás Bunth <btomi96@gmail.com> | 2017-01-14 12:13:32 +0000 |
commit | 882db8709f4ebc9f170cf743f39434d791b34b14 (patch) | |
tree | ded4c2875d152b653072d3bc71812f1a30cdb3cf | |
parent | 2a4b291d3bfb378776388f67670d877c658fce47 (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.mk | 1 | ||||
-rw-r--r-- | connectivity/source/drivers/firebird/Clob.cxx | 100 | ||||
-rw-r--r-- | connectivity/source/drivers/firebird/Clob.hxx | 76 | ||||
-rw-r--r-- | connectivity/source/drivers/firebird/Connection.cxx | 14 | ||||
-rw-r--r-- | connectivity/source/drivers/firebird/Connection.hxx | 5 | ||||
-rw-r--r-- | connectivity/source/drivers/firebird/ResultSet.cxx | 10 |
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) |