Rebased ref, commits from common ancestor: commit d0a9f440e6860a225c5a0ae6222fa96bbc312dbe Author: Andrzej Hunt <andrzej.h...@collabora.com> Date: Wed Mar 19 20:28:45 2014 +0000
firebird-sdbc: upgrade Statement to use Sqlda wrapper. So much cleaner already :). Change-Id: I8d1709246d4cbcd3113fdd7d14c0885ddca37059 diff --git a/connectivity/source/drivers/firebird/PreparedStatement.cxx b/connectivity/source/drivers/firebird/PreparedStatement.cxx index d5e1213..3ddf3b5 100644 --- a/connectivity/source/drivers/firebird/PreparedStatement.cxx +++ b/connectivity/source/drivers/firebird/PreparedStatement.cxx @@ -56,7 +56,6 @@ OPreparedStatement::OPreparedStatement( Connection* _pConnection, :OStatementCommonBase(_pConnection) ,m_aTypeInfo(_TypeInfo) ,m_sSqlStatement(sql) - ,m_pOutSqlda(0) ,m_pInSqlda(0) { SAL_INFO("connectivity.firebird", "OPreparedStatement(). " @@ -82,8 +81,8 @@ void OPreparedStatement::ensurePrepared() } prepareAndDescribeStatement(m_sSqlStatement, - m_pOutSqlda, - m_pInSqlda); + m_aOutSqlda, + m_pInSqlda); aErr = isc_dsql_describe_bind(m_statusVector, @@ -152,7 +151,7 @@ Reference< XResultSetMetaData > SAL_CALL OPreparedStatement::getMetaData() ensurePrepared(); if(!m_xMetaData.is()) - m_xMetaData = new OResultSetMetaData(m_pConnection, m_pOutSqlda); + m_xMetaData = new OResultSetMetaData(m_pConnection, &m_aOutSqlda); return m_xMetaData; } @@ -169,12 +168,6 @@ void SAL_CALL OPreparedStatement::close() throw(SQLException, RuntimeException, free(m_pInSqlda); m_pInSqlda = 0; } - if (m_pOutSqlda) - { - freeSQLVAR(m_pOutSqlda); - free(m_pOutSqlda); - m_pOutSqlda = 0; - } } void SAL_CALL OPreparedStatement::disposing() @@ -286,7 +279,7 @@ sal_Bool SAL_CALL OPreparedStatement::execute() m_aMutex, uno::Reference< XInterface >(*this), m_aStatementHandle, - m_pOutSqlda); + &m_aOutSqlda); if (getStatementChangeCount() > 0) m_pConnection->notifyDatabaseModified(); diff --git a/connectivity/source/drivers/firebird/PreparedStatement.hxx b/connectivity/source/drivers/firebird/PreparedStatement.hxx index 90e89a8..688063a 100644 --- a/connectivity/source/drivers/firebird/PreparedStatement.hxx +++ b/connectivity/source/drivers/firebird/PreparedStatement.hxx @@ -21,6 +21,7 @@ #define CONNECTIVITY_FIREBIRD_PREPAREDSTATEMENT_HXX #include "Statement.hxx" +#include "wrapper/Sqlda.hxx" #include <cppuhelper/implbase5.hxx> @@ -69,7 +70,7 @@ namespace connectivity ::rtl::OUString m_sSqlStatement; ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > m_xMetaData; - XSQLDA* m_pOutSqlda; + wrapper::Sqlda m_aOutSqlda; XSQLDA* m_pInSqlda; void checkParameterIndex(sal_Int32 nParameterIndex) throw(::com::sun::star::sdbc::SQLException, diff --git a/connectivity/source/drivers/firebird/Statement.cxx b/connectivity/source/drivers/firebird/Statement.cxx index 94b9474..eb185a4 100644 --- a/connectivity/source/drivers/firebird/Statement.cxx +++ b/connectivity/source/drivers/firebird/Statement.cxx @@ -34,6 +34,7 @@ #include <com/sun/star/sdbc/FetchDirection.hpp> using namespace connectivity::firebird; +using namespace connectivity::firebird::wrapper; using namespace com::sun::star; using namespace com::sun::star::uno; @@ -84,13 +85,6 @@ void OStatement::disposeResultSet() checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed); OStatementCommonBase::disposeResultSet(); - - if (m_pSqlda) - { - freeSQLVAR(m_pSqlda); - free(m_pSqlda); - m_pSqlda = 0; - } } // ---- XStatement ----------------------------------------------------------- @@ -115,7 +109,7 @@ uno::Reference< XResultSet > SAL_CALL OStatement::executeQuery(const OUString& s disposeResultSet(); prepareAndDescribeStatement(sql, - m_pSqlda); + m_aSqlda); aErr = isc_dsql_execute(m_statusVector, &m_pConnection->getTransaction(), @@ -129,7 +123,7 @@ uno::Reference< XResultSet > SAL_CALL OStatement::executeQuery(const OUString& s m_aMutex, uno::Reference< XInterface >(*this), m_aStatementHandle, - m_pSqlda); + &m_aSqlda); // TODO: deal with cleanup diff --git a/connectivity/source/drivers/firebird/Statement.hxx b/connectivity/source/drivers/firebird/Statement.hxx index 15b81f2..ed18376 100644 --- a/connectivity/source/drivers/firebird/Statement.hxx +++ b/connectivity/source/drivers/firebird/Statement.hxx @@ -21,6 +21,7 @@ #define CONNECTIVITY_FIREBIRD_STATEMENT_HXX #include "StatementCommonBase.hxx" +#include "wrapper/Sqlda.hxx" #include <cppuhelper/implbase1.hxx> @@ -40,13 +41,12 @@ namespace connectivity protected: virtual ~OStatement(){} - XSQLDA* m_pSqlda; + wrapper::Sqlda m_aSqlda; public: // a constructor, which is required for returning objects: OStatement( Connection* _pConnection) - : OStatementCommonBase( _pConnection), - m_pSqlda(0) + : OStatementCommonBase( _pConnection) {} virtual void disposeResultSet(); diff --git a/connectivity/source/drivers/firebird/StatementCommonBase.cxx b/connectivity/source/drivers/firebird/StatementCommonBase.cxx index 93770c2..8a12fa9 100644 --- a/connectivity/source/drivers/firebird/StatementCommonBase.cxx +++ b/connectivity/source/drivers/firebird/StatementCommonBase.cxx @@ -28,6 +28,7 @@ #include <TConnection.hxx> using namespace ::connectivity::firebird; +using namespace ::connectivity::firebird::wrapper; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -123,35 +124,22 @@ void SAL_CALL OStatementCommonBase::close() } void OStatementCommonBase::prepareAndDescribeStatement(const OUString& sql, - XSQLDA*& pOutSqlda, - XSQLDA* pInSqlda) + Sqlda& rOutSqlda, + XSQLDA* pInSqlda) throw (SQLException) { MutexGuard aGuard(m_aMutex); freeStatementHandle(); - if (!pOutSqlda) - { - pOutSqlda = (XSQLDA*) malloc(XSQLDA_LENGTH(10)); - pOutSqlda->version = SQLDA_VERSION1; - pOutSqlda->sqln = 10; - } - ISC_STATUS aErr = 0; - aErr = isc_dsql_allocate_statement(m_statusVector, - &m_pConnection->getDBHandle(), - &m_aStatementHandle); - - if (aErr) - { - free(pOutSqlda); - pOutSqlda = 0; + if (isc_dsql_allocate_statement(m_statusVector, + &m_pConnection->getDBHandle(), + &m_aStatementHandle)) evaluateStatusVector(m_statusVector, "isc_dsql_allocate_statement", *this); - } aErr = isc_dsql_prepare(m_statusVector, &m_pConnection->getTransaction(), @@ -164,49 +152,12 @@ void OStatementCommonBase::prepareAndDescribeStatement(const OUString& sql, if (aErr) { // TODO: free statement handle? - free(pOutSqlda); - pOutSqlda = 0; evaluateStatusVector(m_statusVector, "isc_dsql_prepare", *this); } - aErr = isc_dsql_describe(m_statusVector, - &m_aStatementHandle, - 1, - pOutSqlda); - - - if (aErr) - { - // TODO: free statement handle, etc.? - free(pOutSqlda); - pOutSqlda = 0; - evaluateStatusVector(m_statusVector, - "isc_dsql_describe", - *this); - } - - // Ensure we have enough space in pOutSqlda - if (pOutSqlda->sqld > pOutSqlda->sqln) - { - int n = pOutSqlda->sqld; - free(pOutSqlda); - pOutSqlda = (XSQLDA*) malloc(XSQLDA_LENGTH(n)); - pOutSqlda->version = SQLDA_VERSION1; - aErr = isc_dsql_describe(m_statusVector, - &m_aStatementHandle, - 1, - pOutSqlda); - } - - // Process each XSQLVAR parameter structure in the output XSQLDA - if (aErr) - evaluateStatusVector(m_statusVector, - "isc_dsql_describe", - *this); - - mallocSQLVAR(pOutSqlda); + rOutSqlda.describeStatement(m_aStatementHandle); } // ---- XMultipleResults - UNSUPPORTED ---------------------------------------- diff --git a/connectivity/source/drivers/firebird/StatementCommonBase.hxx b/connectivity/source/drivers/firebird/StatementCommonBase.hxx index b1e0411..edd2016 100644 --- a/connectivity/source/drivers/firebird/StatementCommonBase.hxx +++ b/connectivity/source/drivers/firebird/StatementCommonBase.hxx @@ -21,6 +21,7 @@ #define CONNECTIVITY_FIREBIRD_STATEMENT_BASE_HXX #include "Connection.hxx" +#include "wrapper/Sqlda.hxx" #include <ibase.h> @@ -90,7 +91,7 @@ namespace connectivity virtual ~OStatementCommonBase(); void prepareAndDescribeStatement(const OUString& sqlIn, - XSQLDA*& pOutSqlda, + wrapper::Sqlda& aOutSqlda, XSQLDA* pInSqlda=0) throw (::com::sun::star::sdbc::SQLException); commit c9eeb8b93f06d890c363f6f264d19b4fcdcd67dc Author: Andrzej Hunt <andrzej.h...@collabora.com> Date: Wed Mar 19 20:15:11 2014 +0000 firebird-sdbc: Implement XSQLDA wrapper. Should hopefully help cleanup some of the madness when dealing with XSQLDAs manually. Change-Id: Ia8a477c08fc8d3b66cae11766551d396b881e4bf diff --git a/connectivity/Library_firebird_sdbc.mk b/connectivity/Library_firebird_sdbc.mk index 3f46e6e..0ad7611 100644 --- a/connectivity/Library_firebird_sdbc.mk +++ b/connectivity/Library_firebird_sdbc.mk @@ -18,6 +18,7 @@ $(eval $(call gb_Library_use_externals,firebird_sdbc,\ $(eval $(call gb_Library_set_include,firebird_sdbc,\ -I$(SRCDIR)/connectivity/source/inc \ + -I$(SRCDIR)/connectivity/source/drivers/firebird \ $$(INCLUDE) \ -I$(WORKDIR)/YaccTarget/connectivity/source/parse \ )) @@ -57,6 +58,7 @@ $(eval $(call gb_Library_add_exception_objects,firebird_sdbc,\ connectivity/source/drivers/firebird/User \ connectivity/source/drivers/firebird/Users \ connectivity/source/drivers/firebird/Util \ + connectivity/source/drivers/firebird/wrapper/Sqlda \ )) # vim: set noet sw=4 ts=4: diff --git a/connectivity/source/drivers/firebird/wrapper/Sqlda.cxx b/connectivity/source/drivers/firebird/wrapper/Sqlda.cxx new file mode 100644 index 0000000..9cca23d --- /dev/null +++ b/connectivity/source/drivers/firebird/wrapper/Sqlda.cxx @@ -0,0 +1,208 @@ +/* -*- 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 "Sqlda.hxx" +#include "Driver.hxx" +#include "Util.hxx" + +#include <assert.h> +#include <cstdlib> + +#include <sal/log.hxx> + +using namespace ::connectivity::firebird; +using namespace ::connectivity::firebird::wrapper; + +XSQLDA* lcl_allocateSqlda(unsigned int nLength) +{ + // We specifically calloc so that all the sqlvar->sqldata pointers are null + // allowing us to easily track whether they have been allocated or not. + XSQLDA* pSqlda = (XSQLDA*) calloc(1, XSQLDA_LENGTH(nLength)); + pSqlda->version = SQLDA_VERSION1; + pSqlda->sqln = nLength; + return pSqlda; +} + +void lcl_allocateSQLVAR(XSQLDA* pSqlda) +{ + XSQLVAR* pVar = pSqlda->sqlvar; + for (int i=0; i < pSqlda->sqld; i++, pVar++) + { + int dtype = (pVar->sqltype & ~1); /* drop flag bit for now */ + switch(dtype) { + case SQL_TEXT: + pVar->sqldata = (char*) malloc(sizeof(char)*pVar->sqllen); + break; + case SQL_VARYING: + // First two bytes define the length of string actually present, + // then we can have up to sqllen bytes of text. + pVar->sqldata = (char*) malloc(sizeof(char)*pVar->sqllen + 2); + break; + case SQL_SHORT: + pVar->sqldata = (char*) malloc(sizeof(sal_Int16)); + break; + case SQL_LONG: + pVar->sqldata = (char*) malloc(sizeof(sal_Int32)); + break; + case SQL_FLOAT: + pVar->sqldata = (char*) malloc(sizeof(float)); + break; + case SQL_DOUBLE: + pVar->sqldata = (char*) malloc(sizeof(double)); + break; + case SQL_D_FLOAT: + pVar->sqldata = (char*) malloc(sizeof(double)); + break; + case SQL_TIMESTAMP: + pVar->sqldata = (char*) malloc(sizeof(ISC_TIMESTAMP)); + break; + case SQL_BLOB: + pVar->sqldata = (char*) malloc(sizeof(ISC_QUAD)); + break; + case SQL_ARRAY: + assert(false); // TODO: implement + break; + case SQL_TYPE_TIME: + pVar->sqldata = (char*) malloc(sizeof(ISC_TIME)); + break; + case SQL_TYPE_DATE: + pVar->sqldata = (char*) malloc(sizeof(ISC_DATE)); + break; + case SQL_INT64: + pVar->sqldata = (char *)malloc(sizeof(sal_Int64)); + break; + case SQL_NULL: + assert(false); // TODO: implement + break; + case SQL_QUAD: + assert(false); // TODO: implement + break; + default: + SAL_WARN("connectivity.firebird", "Unknown type: " << dtype); + assert(false); + break; + } + if (pVar->sqltype & 1) + { + /* allocate variable to hold NULL status */ + pVar->sqlind = (short*) malloc(sizeof(short)); + } + } +} +void lcl_freeSQLVAR(XSQLDA* pSqlda) +{ + XSQLVAR* pVar = pSqlda->sqlvar; + for (int i=0; i < pSqlda->sqld; i++, pVar++) + { + int dtype = (pVar->sqltype & ~1); /* drop flag bit for now */ + switch(dtype) { + case SQL_TEXT: + case SQL_VARYING: + case SQL_SHORT: + case SQL_LONG: + case SQL_FLOAT: + case SQL_DOUBLE: + case SQL_D_FLOAT: + case SQL_TIMESTAMP: + case SQL_BLOB: + case SQL_INT64: + case SQL_TYPE_TIME: + case SQL_TYPE_DATE: + free(pVar->sqldata); + break; + case SQL_ARRAY: + assert(false); // TODO: implement + break; + case SQL_NULL: + assert(false); // TODO: implement + break; + case SQL_QUAD: + assert(false); // TODO: implement + break; + default: + SAL_WARN("connectivity.firebird", "Unknown type: " << dtype); + assert(false); + break; + } + + if (pVar->sqltype & 1) + { + free(pVar->sqlind); + } + } +} + +Sqlda::Sqlda() + : mpSqlda(0) +{ +} + +Sqlda::~Sqlda() +{ + if (mpSqlda) + { + lcl_freeSQLVAR(mpSqlda); + free(mpSqlda); + } +} + +void Sqlda::describeStatement(isc_stmt_handle& aStatementHandle) +{ + if (!mpSqlda) + { + mpSqlda = lcl_allocateSqlda(DEFAULT_SQLDA_SIZE); + } + else + { + // types might change, hence we need to completely wipe the + // sqldatas. + lcl_freeSQLVAR(mpSqlda); + } + + try + { + ISC_STATUS_ARRAY aStatusVector; + + if (isc_dsql_describe(aStatusVector, + &aStatementHandle, + FIREBIRD_SQL_DIALECT, + mpSqlda)) + evaluateStatusVector(aStatusVector, "isc_dsql_describe", 0); + + // We cannot know how much space we need until after the first call of + // isc_dsql_describe -- hence we need to check we have enough space + // afterwards, and reallocate as necessary. + if (mpSqlda->sqld > mpSqlda->sqln) + { + free(mpSqlda); + mpSqlda = lcl_allocateSqlda(mpSqlda->sqld); + } + + if (isc_dsql_describe(aStatusVector, + &aStatementHandle, + FIREBIRD_SQL_DIALECT, + mpSqlda)) + evaluateStatusVector(aStatusVector, "isc_dsql_describe", 0); + + lcl_allocateSQLVAR(mpSqlda); + } + catch (::com::sun::star::sdbc::SQLException e) + { + // We specifically free the sqlda since we are at an incomplete state + // where the sqlda might be partially populated, and the sqlvar's + // may or may not be allocated -- it is simplest to ensure consistency + // by freeing the sqlda unless we have successfully described it + // and allocated all sqlvars in it. + free(mpSqlda); + mpSqlda = 0; + throw e; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ \ No newline at end of file diff --git a/connectivity/source/drivers/firebird/wrapper/Sqlda.hxx b/connectivity/source/drivers/firebird/wrapper/Sqlda.hxx new file mode 100644 index 0000000..0c395db --- /dev/null +++ b/connectivity/source/drivers/firebird/wrapper/Sqlda.hxx @@ -0,0 +1,49 @@ +/* -*- 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 CONNECTIVITY_FIREBIRD_WRAPPER_SQLDA_HXX +#define CONNECTIVITY_FIREBIRD_WRAPPER_SQLDA_HXX + +#include <ibase.h> + +namespace connectivity +{ + namespace firebird + { + namespace wrapper + { + /* + * Default sqlvar length that we allocate. + */ + static const unsigned int DEFAULT_SQLDA_SIZE = 10; + + class Sqlda + { + private: + XSQLDA* mpSqlda; + + public: + Sqlda(); + ~Sqlda(); + XSQLDA* operator&() { return mpSqlda; }; + + /** + * Set up the Sqlda for a given statement, is equivalent to + * using isc_dsql_describe, but with all the details handled + * within. + */ + void describeStatement(isc_stmt_handle& aStatementHandle); + }; + } + } +} + +#endif // CONNECTIVITY_FIREBIRD_WRAPPER_SQLDA_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ \ No newline at end of file _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits