[Libreoffice-commits] core.git: Branch 'private/ajrhunt/firebird-improvement' - 2 commits - connectivity/Library_firebird_sdbc.mk connectivity/source
Andrzej Hunt
andrzej.hunt at collabora.com
Wed Mar 19 13:35:53 PDT 2014
Rebased ref, commits from common ancestor:
commit d0a9f440e6860a225c5a0ae6222fa96bbc312dbe
Author: Andrzej Hunt <andrzej.hunt at 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.hunt at 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
More information about the Libreoffice-commits
mailing list