diff options
author | Andrzej J.R. Hunt <andrzej@ahunt.org> | 2013-08-27 13:27:23 +0100 |
---|---|---|
committer | Andrzej J.R. Hunt <andrzej@ahunt.org> | 2013-08-27 20:58:31 +0100 |
commit | 73aaa4da674ac8389ee8269e4d7c827d7e642e26 (patch) | |
tree | 3b48e8fa1719c8765f0e743b6bb598c88149ebde /connectivity | |
parent | eb6ab3bc045701e3d4b8751751700d8375f89fcc (diff) |
Implement retrieving change count for executeUpdate. (firebird-sdbc)
Change-Id: Ied47f421dc801bb6790bed49b28d3231844e6ee5
Diffstat (limited to 'connectivity')
4 files changed, 97 insertions, 14 deletions
diff --git a/connectivity/source/drivers/firebird/PreparedStatement.cxx b/connectivity/source/drivers/firebird/PreparedStatement.cxx index 764574820e2a..1898777a814e 100644 --- a/connectivity/source/drivers/firebird/PreparedStatement.cxx +++ b/connectivity/source/drivers/firebird/PreparedStatement.cxx @@ -306,10 +306,7 @@ sal_Int32 SAL_CALL OPreparedStatement::executeUpdate() throw(SQLException, RuntimeException) { execute(); - // TODO: get the number of rows changed -- look in Statement::executeUpdate for details - // 1 is a temporary hack so that things like dbaccess's keyset which rely - // on the value work correctly. - return 1; + return getStatementChangeCount(); } Reference< XResultSet > SAL_CALL OPreparedStatement::executeQuery() diff --git a/connectivity/source/drivers/firebird/Statement.cxx b/connectivity/source/drivers/firebird/Statement.cxx index 32b6243f6bc9..59f89de4a2df 100644 --- a/connectivity/source/drivers/firebird/Statement.cxx +++ b/connectivity/source/drivers/firebird/Statement.cxx @@ -116,6 +116,8 @@ sal_Int32 SAL_CALL OStatement::executeUpdate(const OUString& sql) evaluateStatusVector(m_statusVector, sql, *this); // TODO: get number of changed rows with SELECT ROW_COUNT (use executeQuery) // return getUpdateCount(); + // We can't use return getStatementChangeCount(); since that depends + // on having the statement handle, so maybe just use executeQuery instead? return 0; } @@ -152,7 +154,7 @@ uno::Reference< XResultSet > SAL_CALL OStatement::executeQuery(const OUString& s evaluateStatusVector(m_statusVector, sql, *this); - if (isDDLStatement(m_aStatementHandle)) + if (isDDLStatement()) m_pConnection->commit(); return m_xResultSet; diff --git a/connectivity/source/drivers/firebird/StatementCommonBase.cxx b/connectivity/source/drivers/firebird/StatementCommonBase.cxx index f7a3a3c30cac..77e00522a1cb 100644 --- a/connectivity/source/drivers/firebird/StatementCommonBase.cxx +++ b/connectivity/source/drivers/firebird/StatementCommonBase.cxx @@ -344,32 +344,112 @@ uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OStatementC return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper()); } -bool OStatementCommonBase::isDDLStatement(isc_stmt_handle& aStatementHandle) +short OStatementCommonBase::getSqlInfoItem(char aInfoItem) throw (SQLException) { ISC_STATUS_ARRAY aStatusVector; ISC_STATUS aErr; - char aInfoItems[] = {isc_info_sql_stmt_type}; + char aInfoItems[] = {aInfoItem}; char aResultsBuffer[8]; aErr = isc_dsql_sql_info(aStatusVector, - &aStatementHandle, + &m_aStatementHandle, sizeof(aInfoItems), aInfoItems, sizeof(aResultsBuffer), aResultsBuffer); - if (!aErr && aResultsBuffer[0] == isc_info_sql_stmt_type) + if (!aErr && aResultsBuffer[0] == aInfoItem) { const short aBytes = (short) isc_vax_integer(aResultsBuffer+1, 2); - const short aStatementType = (short) isc_vax_integer(aResultsBuffer+3, aBytes); - if (aStatementType == isc_info_sql_stmt_ddl) - return true; + return (short) isc_vax_integer(aResultsBuffer+3, aBytes); } + evaluateStatusVector(aStatusVector, "isc_dsq_sql_info", *this); - return false; + return 0; +} + +bool OStatementCommonBase::isDDLStatement() + throw (SQLException) +{ + if (getSqlInfoItem(isc_info_sql_stmt_type) == isc_info_sql_stmt_ddl) + return true; + else + return false; +} + +sal_Int32 OStatementCommonBase::getStatementChangeCount() + throw (SQLException) +{ + const short aStatementType = getSqlInfoItem(isc_info_sql_stmt_type); + + + + ISC_STATUS_ARRAY aStatusVector; + ISC_STATUS aErr; + + // This is somewhat undocumented so I'm just guessing and hoping for the best. + char aInfoItems[] = {isc_info_sql_records}; + char aResultsBuffer[1024]; + + aErr = isc_dsql_sql_info(aStatusVector, + &m_aStatementHandle, + sizeof(aInfoItems), + aInfoItems, + sizeof(aResultsBuffer), + aResultsBuffer); + + if (aErr) + { + evaluateStatusVector(aStatusVector, + "isc_dsq_sql_info", + *this); + return 0; + } + + short aDesiredInfoType = 0; + switch (aStatementType) + { + case isc_info_sql_stmt_select: + aDesiredInfoType = isc_info_req_select_count; + break; + case isc_info_sql_stmt_insert: + aDesiredInfoType = isc_info_req_insert_count; + break; + case isc_info_sql_stmt_update: + aDesiredInfoType = isc_info_req_update_count; + break; + case isc_info_sql_stmt_delete: + aDesiredInfoType = isc_info_req_delete_count; + break; + default: + throw SQLException(); // TODO: better error message? + } + + char* pResults = aResultsBuffer; + if (((short) *pResults++) == isc_info_sql_records) + { +// const short aTotalLength = (short) isc_vax_integer(pResults, 2); + pResults += 2; + + // Seems to be of form TOKEN (1 byte), LENGTH (2 bytes), DATA (LENGTH bytes) + while (*pResults != isc_info_rsb_end) + { + const char aToken = *pResults; + const short aLength = (short) isc_vax_integer(pResults+1, 2); + + if (aToken == aDesiredInfoType) + { + return sal_Int32(isc_vax_integer(pResults + 3, aLength)); + } + + pResults += (3 + aLength); + } + } + + return 0; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/firebird/StatementCommonBase.hxx b/connectivity/source/drivers/firebird/StatementCommonBase.hxx index bb4fc3c14910..46377fcf5c71 100644 --- a/connectivity/source/drivers/firebird/StatementCommonBase.hxx +++ b/connectivity/source/drivers/firebird/StatementCommonBase.hxx @@ -92,7 +92,11 @@ namespace connectivity XSQLDA* pInSqlda=0) throw (::com::sun::star::sdbc::SQLException); - bool isDDLStatement(isc_stmt_handle& aStatementHandle) + short getSqlInfoItem(char aInfoItem) + throw (::com::sun::star::sdbc::SQLException); + bool isDDLStatement() + throw (::com::sun::star::sdbc::SQLException); + sal_Int32 getStatementChangeCount() throw (::com::sun::star::sdbc::SQLException); public: |