connectivity/source/drivers/firebird/PreparedStatement.cxx | 44 +-- connectivity/source/drivers/firebird/ResultSet.cxx | 181 +++++++++---- connectivity/source/drivers/firebird/ResultSet.hxx | 24 + 3 files changed, 175 insertions(+), 74 deletions(-)
New commits: commit c856ab73af3ab108f64e0c9d9857c35a4849f030 Author: Andrzej J.R. Hunt <[email protected]> Date: Thu Sep 19 20:35:50 2013 +0100 Cleanup ResultSet exceptions. Change-Id: I77e4fd5fffe45446050f8a1dfbcc8cc27290c786 diff --git a/connectivity/source/drivers/firebird/ResultSet.cxx b/connectivity/source/drivers/firebird/ResultSet.cxx index 087453d..0700e11 100644 --- a/connectivity/source/drivers/firebird/ResultSet.cxx +++ b/connectivity/source/drivers/firebird/ResultSet.cxx @@ -278,15 +278,18 @@ sal_Bool SAL_CALL OResultSet::relative(sal_Int32 row) throw(SQLException, Runtim } } -void SAL_CALL OResultSet::checkColumnIndex(sal_Int32 index) +void SAL_CALL OResultSet::checkColumnIndex(sal_Int32 nIndex) throw (SQLException, RuntimeException) { MutexGuard aGuard(m_rMutex); checkDisposed(OResultSet_BASE::rBHelper.bDisposed); - if( index < 1 || index > m_fieldCount ) + if( nIndex < 1 || nIndex > m_fieldCount ) { - throw SQLException( "Column Index is outwith valid range", *this, OUString(), 1, Any() ); + ::dbtools::throwSQLException( + "No column " + OUString::number(nIndex), + ::dbtools::SQL_COLUMN_NOT_FOUND, + *this); } } @@ -298,7 +301,10 @@ void SAL_CALL OResultSet::checkRowIndex() if((m_currentRow < 1) || m_bIsAfterLastRow) { - throw SQLException( "Row index is out of valid range.", *this, OUString(),1, Any() ); + ::dbtools::throwSQLException( + "Invalid Row", + ::dbtools::SQL_INVALID_CURSOR_POSITION, + *this); } } commit 65719df3e38e16feecf025f4773562dfa2011f28 Author: Andrzej J.R. Hunt <[email protected]> Date: Thu Sep 19 20:33:38 2013 +0100 Cleanup exceptions in PreparedStatement. Change-Id: Ice11ec8131a00335db48a05661bbe0285bb53fea diff --git a/connectivity/source/drivers/firebird/PreparedStatement.cxx b/connectivity/source/drivers/firebird/PreparedStatement.cxx index 574bc06..d578450 100644 --- a/connectivity/source/drivers/firebird/PreparedStatement.cxx +++ b/connectivity/source/drivers/firebird/PreparedStatement.cxx @@ -316,16 +316,11 @@ void SAL_CALL OPreparedStatement::setNull(sal_Int32 nIndex, sal_Int32 /*nSqlType setParameterNull(nIndex, true); } -void SAL_CALL OPreparedStatement::setBoolean(sal_Int32 nIndex, sal_Bool x) +void SAL_CALL OPreparedStatement::setBoolean(sal_Int32 /*nIndex*/, sal_Bool /*bValue*/) throw(SQLException, RuntimeException) { - (void) nIndex; - (void) x; - MutexGuard aGuard(m_aMutex); - checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed); - - // TODO: decide how to deal with bools. Probably just as a byte, although - // it might be best to just determine the db type and set as appropriate? + // FIREBIRD3: will need to be implemented. + ::dbtools::throwFunctionNotSupportedException("XParameters::setBoolean", *this); } template <typename T> @@ -355,9 +350,7 @@ void OPreparedStatement::setValue(sal_Int32 nIndex, T& nValue, ISC_SHORT nType) void SAL_CALL OPreparedStatement::setByte(sal_Int32 /*nIndex*/, sal_Int8 /*nValue*/) throw(SQLException, RuntimeException) { - ::dbtools::throwFunctionNotSupportedException("setByte not supported in firebird", - *this, - Any()); + ::dbtools::throwFunctionNotSupportedException("XParameters::setByte", *this); } void SAL_CALL OPreparedStatement::setShort(sal_Int32 nIndex, sal_Int16 nValue) @@ -588,8 +581,12 @@ void OPreparedStatement::checkParameterIndex(sal_Int32 nParameterIndex) { ensurePrepared(); if ((nParameterIndex == 0) || (nParameterIndex > m_pInSqlda->sqld)) - throw SQLException(); - // TODO: sane error message here. + { + ::dbtools::throwSQLException( + "No column " + OUString::number(nParameterIndex), + ::dbtools::SQL_COLUMN_NOT_FOUND, + *this); + } } void OPreparedStatement::setParameterNull(sal_Int32 nParameterIndex, commit 101040a13010edca81d1ad127726d4118f00c5e0 Author: Andrzej J.R. Hunt <[email protected]> Date: Thu Sep 19 20:18:20 2013 +0100 Set sane default for type. Change-Id: Ib63e6abd7b378671d1e01bf9357dd811ae88fc40 diff --git a/connectivity/source/drivers/firebird/ResultSet.cxx b/connectivity/source/drivers/firebird/ResultSet.cxx index 0fdcc09..087453d 100644 --- a/connectivity/source/drivers/firebird/ResultSet.cxx +++ b/connectivity/source/drivers/firebird/ResultSet.cxx @@ -550,14 +550,14 @@ sal_Bool SAL_CALL OResultSet::getBoolean(sal_Int32 nColumnIndex) throw(SQLException, RuntimeException) { // Not a native firebird type hence we always have to convert. - return safelyRetrieveValue< ORowSetValue >(nColumnIndex, 0); + return safelyRetrieveValue< ORowSetValue >(nColumnIndex); } sal_Int8 SAL_CALL OResultSet::getByte(sal_Int32 nColumnIndex) throw(SQLException, RuntimeException) { // Not a native firebird type hence we always have to convert. - return safelyRetrieveValue< ORowSetValue >(nColumnIndex, 0); + return safelyRetrieveValue< ORowSetValue >(nColumnIndex); } Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes(sal_Int32 columnIndex) @@ -603,7 +603,7 @@ OUString SAL_CALL OResultSet::getString(sal_Int32 nIndex) throw(SQLException, RuntimeException) { // TODO: special handling for char type? - return safelyRetrieveValue< OUString >(nIndex, 0); + return safelyRetrieveValue< OUString >(nIndex); } Date SAL_CALL OResultSet::getDate(sal_Int32 nIndex) diff --git a/connectivity/source/drivers/firebird/ResultSet.hxx b/connectivity/source/drivers/firebird/ResultSet.hxx index 6a1ede0..db68c06 100644 --- a/connectivity/source/drivers/firebird/ResultSet.hxx +++ b/connectivity/source/drivers/firebird/ResultSet.hxx @@ -99,7 +99,7 @@ namespace connectivity template <typename T> T safelyRetrieveValue( const sal_Int32 nColumnIndex, - const ISC_SHORT nType); + const ISC_SHORT nType = 0); // OIdPropertyArrayUsageHelper virtual ::cppu::IPropertyArrayHelper* createArrayHelper() const; commit 831f01b7395fd84449e133e1300cc8fa85d42bd3 Author: Andrzej J.R. Hunt <[email protected]> Date: Thu Sep 19 20:15:24 2013 +0100 Move type conversion into template.` Change-Id: I7b646673eacf2abbac8a2bcfa744f840ff344c84 diff --git a/connectivity/source/drivers/firebird/ResultSet.cxx b/connectivity/source/drivers/firebird/ResultSet.cxx index b6df5b5..0fdcc09 100644 --- a/connectivity/source/drivers/firebird/ResultSet.cxx +++ b/connectivity/source/drivers/firebird/ResultSet.cxx @@ -368,13 +368,21 @@ bool OResultSet::isNull(const sal_Int32 nColumnIndex) return false; } -ORowSetValue OResultSet::retrieveConvertibleValue(const sal_Int32 nColumnIndex) +template <typename T> +T OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT nType) { - MutexGuard aGuard(m_rMutex); - checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + if ((m_bWasNull = isNull(nColumnIndex))) + return T(); - checkColumnIndex(nColumnIndex); - checkRowIndex(); + if ((m_pSqlda->sqlvar[nColumnIndex-1].sqltype & ~1) == nType) + return *((T*) m_pSqlda->sqlvar[nColumnIndex-1].sqldata); + else + return retrieveValue< ORowSetValue >(nColumnIndex, 0); +} + +template <> +ORowSetValue OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT /*nType*/) +{ // See http://wiki.openoffice.org/wiki/Documentation/DevGuide/Database/Using_the_getXXX_Methods // (bottom of page) for a chart of possible conversions, we should allow all // of these -- Blob/Clob will probably need some specialist handling especially @@ -399,39 +407,25 @@ ORowSetValue OResultSet::retrieveConvertibleValue(const sal_Int32 nColumnIndex) return getFloat(nColumnIndex); case SQL_TIMESTAMP: return getTimestamp(nColumnIndex); -// case SQL_BLOB: -// return DataType::BLOB; -// case SQL_ARRAY: -// return DataType::ARRAY; case SQL_TYPE_TIME: return getTime(nColumnIndex); case SQL_TYPE_DATE: return getTime(nColumnIndex); case SQL_INT64: return getLong(nColumnIndex); + case SQL_BLOB: case SQL_NULL: - assert(false); // We shouldn't really be returning this ever since - // detection is separate. -// case SQL_QUAD: // Is a "Blob ID" according to the docs -// return 0; // TODO: verify + case SQL_QUAD: + case SQL_ARRAY: + // TODO: these are all invalid conversions, so maybe we should + // throw an exception? + return ORowSetValue(); default: assert(false); return ORowSetValue(); } } -template <typename T> -T OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT nType) -{ - if ((m_bWasNull = isNull(nColumnIndex))) - return T(); - - if ((m_pSqlda->sqlvar[nColumnIndex-1].sqltype & ~1) == nType) - return *((T*) m_pSqlda->sqlvar[nColumnIndex-1].sqldata); - else - return retrieveConvertibleValue(nColumnIndex); -} - template <> Date OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT /*nType*/) { @@ -446,7 +440,7 @@ Date OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT /*n } else { - return retrieveConvertibleValue(nColumnIndex); + return retrieveValue< ORowSetValue >(nColumnIndex, 0); } } @@ -466,7 +460,7 @@ Time OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT /*n } else { - return retrieveConvertibleValue(nColumnIndex); + return retrieveValue< ORowSetValue >(nColumnIndex, 0); } } @@ -487,16 +481,13 @@ DateTime OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT } else { - return retrieveConvertibleValue(nColumnIndex); + return retrieveValue< ORowSetValue >(nColumnIndex, 0); } } template <> OUString OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT /*nType*/) { - if ((m_bWasNull = isNull(nColumnIndex))) - return OUString(); - // &~1 to remove the "can contain NULL" indicator int aSqlType = m_pSqlda->sqlvar[nColumnIndex-1].sqltype & ~1; if (aSqlType == SQL_TEXT ) @@ -516,7 +507,7 @@ OUString OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT } else { - return retrieveConvertibleValue(nColumnIndex); + return retrieveValue< ORowSetValue >(nColumnIndex, 0); } } @@ -524,8 +515,6 @@ template <> ISC_QUAD* OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT nType) { // TODO: this is probably wrong - if ((m_bWasNull = isNull(nColumnIndex))) - return 0; if ((m_pSqlda->sqlvar[nColumnIndex-1].sqltype & ~1) == nType) return (ISC_QUAD*) m_pSqlda->sqlvar[nColumnIndex-1].sqldata; else @@ -541,6 +530,9 @@ T OResultSet::safelyRetrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT checkColumnIndex(nColumnIndex); checkRowIndex(); + if ((m_bWasNull = isNull(nColumnIndex))) + return T(); + return retrieveValue< T >(nColumnIndex, nType); } @@ -558,14 +550,14 @@ sal_Bool SAL_CALL OResultSet::getBoolean(sal_Int32 nColumnIndex) throw(SQLException, RuntimeException) { // Not a native firebird type hence we always have to convert. - return retrieveConvertibleValue(nColumnIndex); + return safelyRetrieveValue< ORowSetValue >(nColumnIndex, 0); } sal_Int8 SAL_CALL OResultSet::getByte(sal_Int32 nColumnIndex) throw(SQLException, RuntimeException) { // Not a native firebird type hence we always have to convert. - return retrieveConvertibleValue(nColumnIndex); + return safelyRetrieveValue< ORowSetValue >(nColumnIndex, 0); } Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes(sal_Int32 columnIndex) diff --git a/connectivity/source/drivers/firebird/ResultSet.hxx b/connectivity/source/drivers/firebird/ResultSet.hxx index fbaed5a..6a1ede0 100644 --- a/connectivity/source/drivers/firebird/ResultSet.hxx +++ b/connectivity/source/drivers/firebird/ResultSet.hxx @@ -94,13 +94,6 @@ namespace connectivity bool isNull(const sal_Int32 nColumnIndex); - /** - * Retrieves a value to an ORowSetValue allowing for conversion - * at will. Should only be used if conversion is needed to avoid - * any performance hit otherwise. - */ - ORowSetValue retrieveConvertibleValue(const sal_Int32 nColumnIndex); - template <typename T> T retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT nType); @@ -207,6 +200,10 @@ namespace connectivity OResultSet::retrieveValue( const sal_Int32 nColumnIndex, const ISC_SHORT nType); + template <> ::connectivity::ORowSetValue + OResultSet::retrieveValue( + const sal_Int32 nColumnIndex, + const ISC_SHORT nType); template <> ::com::sun::star::util::Time OResultSet::retrieveValue( const sal_Int32 nColumnIndex, commit 79f1c6e50ed303494b5c39cc6b2a448b264f7c28 Author: Andrzej J.R. Hunt <[email protected]> Date: Thu Sep 19 20:02:07 2013 +0100 Use conversion for Byte/Bool. These are both non-native to firebird, hence always have to be converted from whatever data we have. Change-Id: I6e6843d95ee4f5cf0cd5953251796150f325f800 diff --git a/connectivity/source/drivers/firebird/ResultSet.cxx b/connectivity/source/drivers/firebird/ResultSet.cxx index c5af439..b6df5b5 100644 --- a/connectivity/source/drivers/firebird/ResultSet.cxx +++ b/connectivity/source/drivers/firebird/ResultSet.cxx @@ -370,6 +370,11 @@ bool OResultSet::isNull(const sal_Int32 nColumnIndex) ORowSetValue OResultSet::retrieveConvertibleValue(const sal_Int32 nColumnIndex) { + MutexGuard aGuard(m_rMutex); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + checkColumnIndex(nColumnIndex); + checkRowIndex(); // See http://wiki.openoffice.org/wiki/Documentation/DevGuide/Database/Using_the_getXXX_Methods // (bottom of page) for a chart of possible conversions, we should allow all // of these -- Blob/Clob will probably need some specialist handling especially @@ -549,22 +554,18 @@ sal_Bool SAL_CALL OResultSet::wasNull() throw(SQLException, RuntimeException) } // ---- XRow: Simple Numerical types ------------------------------------------ -sal_Bool SAL_CALL OResultSet::getBoolean(sal_Int32 columnIndex) +sal_Bool SAL_CALL OResultSet::getBoolean(sal_Int32 nColumnIndex) throw(SQLException, RuntimeException) { -// // TODO: maybe retrieve as string and test for "true", "t", "1" etc. instead? -// return safelyRetrieveValue< bool >(columnIndex); - (void) columnIndex; - return sal_False; + // Not a native firebird type hence we always have to convert. + return retrieveConvertibleValue(nColumnIndex); } -sal_Int8 SAL_CALL OResultSet::getByte( sal_Int32 columnIndex ) +sal_Int8 SAL_CALL OResultSet::getByte(sal_Int32 nColumnIndex) throw(SQLException, RuntimeException) { - // TODO: this doesn't exist in firebird, we have to always convert. -// return safelyRetrieveValue< sal_Int8 >(columnIndex); - (void) columnIndex; - return 0; + // Not a native firebird type hence we always have to convert. + return retrieveConvertibleValue(nColumnIndex); } Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes(sal_Int32 columnIndex) commit 52841daec985e04bff77ee6eb1d70af0238e0eae Author: Andrzej J.R. Hunt <[email protected]> Date: Thu Sep 19 19:50:31 2013 +0100 Throw sane exception when wrong type used in PreparedStatement. Change-Id: Ie9577ed021930c56f3270aa30306d89365c1b3b1 diff --git a/connectivity/source/drivers/firebird/PreparedStatement.cxx b/connectivity/source/drivers/firebird/PreparedStatement.cxx index d1261d4..574bc06 100644 --- a/connectivity/source/drivers/firebird/PreparedStatement.cxx +++ b/connectivity/source/drivers/firebird/PreparedStatement.cxx @@ -222,12 +222,13 @@ void SAL_CALL OPreparedStatement::setString(sal_Int32 nParameterIndex, case SQL_TEXT: memcpy(pVar->sqldata, str.getStr(), str.getLength()); // Fill remainder with spaces - // TODO: would 0 be better here for filling? memset(pVar->sqldata + str.getLength(), ' ', pVar->sqllen - str.getLength()); break; default: - // TODO: sane error message - throw SQLException(); + ::dbtools::throwSQLException( + "Incorrect type for setString", + ::dbtools::SQL_INVALID_SQL_DATA_TYPE, + *this); } } @@ -341,7 +342,12 @@ void OPreparedStatement::setValue(sal_Int32 nIndex, T& nValue, ISC_SHORT nType) XSQLVAR* pVar = m_pInSqlda->sqlvar + (nIndex - 1); if ((pVar->sqltype & ~1) != nType) - throw SQLException(); // TODO: cast instead? + { + ::dbtools::throwSQLException( + "Incorrect type for setString", + ::dbtools::SQL_INVALID_SQL_DATA_TYPE, + *this); + } memcpy(pVar->sqldata, &nValue, sizeof(nValue)); } commit a11b6d5356f191f1d4d7ce48e80ce3f2534dc190 Author: Andrzej J.R. Hunt <[email protected]> Date: Thu Sep 19 19:41:18 2013 +0100 Don't throw unnecessary exception. Even an empty ResultSet can be valid, and no other drivers do this. Change-Id: Ie3aee718f0187d039dbd0c53fc32a71be4a1d9e9 diff --git a/connectivity/source/drivers/firebird/PreparedStatement.cxx b/connectivity/source/drivers/firebird/PreparedStatement.cxx index eb2fc17..d1261d4 100644 --- a/connectivity/source/drivers/firebird/PreparedStatement.cxx +++ b/connectivity/source/drivers/firebird/PreparedStatement.cxx @@ -300,12 +300,7 @@ sal_Int32 SAL_CALL OPreparedStatement::executeUpdate() Reference< XResultSet > SAL_CALL OPreparedStatement::executeQuery() throw(SQLException, RuntimeException) { - if (!execute()) - { - // execute succeeded but no results - throw SQLException(); // TODO: add message to exception - } - + execute(); return m_xResultSet; } commit fc118515eee34d7a00ce363149bf85737607fed0 Author: Andrzej J.R. Hunt <[email protected]> Date: Thu Sep 19 09:01:23 2013 +0100 Implement implicit type conversion in ResultSet. (firebird-sdbc) Change-Id: I9faf9752556b7e0769d3a353e393924f5a1edb63 diff --git a/connectivity/source/drivers/firebird/ResultSet.cxx b/connectivity/source/drivers/firebird/ResultSet.cxx index e31e39e..c5af439 100644 --- a/connectivity/source/drivers/firebird/ResultSet.cxx +++ b/connectivity/source/drivers/firebird/ResultSet.cxx @@ -368,22 +368,126 @@ bool OResultSet::isNull(const sal_Int32 nColumnIndex) return false; } +ORowSetValue OResultSet::retrieveConvertibleValue(const sal_Int32 nColumnIndex) +{ + // See http://wiki.openoffice.org/wiki/Documentation/DevGuide/Database/Using_the_getXXX_Methods + // (bottom of page) for a chart of possible conversions, we should allow all + // of these -- Blob/Clob will probably need some specialist handling especially + // w.r.t. to generating Strings for them. + // + // Basically we just have to map to the correct direct request and + // ORowSetValue does the rest for us here. + switch (m_pSqlda->sqlvar[nColumnIndex-1].sqltype & ~1) + { + case SQL_TEXT: + case SQL_VARYING: + return getString(nColumnIndex); + case SQL_SHORT: + return getShort(nColumnIndex); + case SQL_LONG: + return getInt(nColumnIndex); + case SQL_FLOAT: + return getFloat(nColumnIndex); + case SQL_DOUBLE: + return getDouble(nColumnIndex); + case SQL_D_FLOAT: + return getFloat(nColumnIndex); + case SQL_TIMESTAMP: + return getTimestamp(nColumnIndex); +// case SQL_BLOB: +// return DataType::BLOB; +// case SQL_ARRAY: +// return DataType::ARRAY; + case SQL_TYPE_TIME: + return getTime(nColumnIndex); + case SQL_TYPE_DATE: + return getTime(nColumnIndex); + case SQL_INT64: + return getLong(nColumnIndex); + case SQL_NULL: + assert(false); // We shouldn't really be returning this ever since + // detection is separate. +// case SQL_QUAD: // Is a "Blob ID" according to the docs +// return 0; // TODO: verify + default: + assert(false); + return ORowSetValue(); + } +} + template <typename T> T OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT nType) { - // TODO: check we have the right type. if ((m_bWasNull = isNull(nColumnIndex))) return T(); if ((m_pSqlda->sqlvar[nColumnIndex-1].sqltype & ~1) == nType) return *((T*) m_pSqlda->sqlvar[nColumnIndex-1].sqldata); else - return T(); - // TODO: fix + return retrieveConvertibleValue(nColumnIndex); +} + +template <> +Date OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT /*nType*/) +{ + if ((m_pSqlda->sqlvar[nColumnIndex-1].sqltype & ~1) == SQL_TYPE_DATE) + { + ISC_DATE aISCDate = *((ISC_DATE*) m_pSqlda->sqlvar[nColumnIndex-1].sqldata); + + struct tm aCTime; + isc_decode_sql_date(&aISCDate, &aCTime); + + return Date(aCTime.tm_mday, aCTime.tm_mon, aCTime.tm_year); + } + else + { + return retrieveConvertibleValue(nColumnIndex); + } } template <> -OUString OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT nType) +Time OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT /*nType*/) +{ + if ((m_pSqlda->sqlvar[nColumnIndex-1].sqltype & ~1) == SQL_TYPE_TIME) + { + ISC_TIME aISCTime = *((ISC_TIME*) m_pSqlda->sqlvar[nColumnIndex-1].sqldata); + + struct tm aCTime; + isc_decode_sql_time(&aISCTime, &aCTime); + + // first field is nanoseconds -- not supported in firebird or struct tm. + // last field denotes UTC (true) or unknown (false) + return Time(0, aCTime.tm_sec, aCTime.tm_min, aCTime.tm_hour, false); + } + else + { + return retrieveConvertibleValue(nColumnIndex); + } +} + +template <> +DateTime OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT /*nType*/) +{ + if ((m_pSqlda->sqlvar[nColumnIndex-1].sqltype & ~1) == SQL_TIMESTAMP) + { + ISC_TIMESTAMP aISCTimestamp = *((ISC_TIMESTAMP*) m_pSqlda->sqlvar[nColumnIndex-1].sqldata); + + struct tm aCTime; + isc_decode_timestamp(&aISCTimestamp, &aCTime); + + // first field is nanoseconds -- not supported in firebird or struct tm. + // last field denotes UTC (true) or unknown (false) + return DateTime(0, aCTime.tm_sec, aCTime.tm_min, aCTime.tm_hour, aCTime.tm_mday, + aCTime.tm_mon, aCTime.tm_year, false); + } + else + { + return retrieveConvertibleValue(nColumnIndex); + } +} + +template <> +OUString OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT /*nType*/) { if ((m_bWasNull = isNull(nColumnIndex))) return OUString(); @@ -407,9 +511,7 @@ OUString OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT } else { - (void) nType; - return OUString(); - // TODO: Possibly do some sort of type conversion? + return retrieveConvertibleValue(nColumnIndex); } } @@ -504,49 +606,29 @@ double SAL_CALL OResultSet::getDouble(sal_Int32 columnIndex) } // ---- XRow: More complex types ---------------------------------------------- -OUString SAL_CALL OResultSet::getString(sal_Int32 columnIndex) +OUString SAL_CALL OResultSet::getString(sal_Int32 nIndex) throw(SQLException, RuntimeException) { // TODO: special handling for char type? - return safelyRetrieveValue< OUString >(columnIndex, 0); + return safelyRetrieveValue< OUString >(nIndex, 0); } Date SAL_CALL OResultSet::getDate(sal_Int32 nIndex) throw(SQLException, RuntimeException) { - ISC_DATE aISCDate = safelyRetrieveValue< ISC_DATE >(nIndex, SQL_TYPE_DATE); - - struct tm aCTime; - isc_decode_sql_date(&aISCDate, &aCTime); - - return Date(aCTime.tm_mday, aCTime.tm_mon, aCTime.tm_year); + return safelyRetrieveValue< Date >(nIndex, SQL_TYPE_DATE); } Time SAL_CALL OResultSet::getTime(sal_Int32 nIndex) throw(SQLException, RuntimeException) { - ISC_TIME aISCTime = safelyRetrieveValue< ISC_TIME >(nIndex, SQL_TYPE_TIME); - - struct tm aCTime; - isc_decode_sql_time(&aISCTime, &aCTime); - - // first field is nanoseconds -- not supported in firebird or struct tm. - // last field denotes UTC (true) or unknown (false) - return Time(0, aCTime.tm_sec, aCTime.tm_min, aCTime.tm_hour, false); + return safelyRetrieveValue< Time >(nIndex, SQL_TYPE_TIME); } DateTime SAL_CALL OResultSet::getTimestamp(sal_Int32 nIndex) throw(SQLException, RuntimeException) { - ISC_TIMESTAMP aISCTimestamp = safelyRetrieveValue< ISC_TIMESTAMP >(nIndex, SQL_TIMESTAMP); - - struct tm aCTime; - isc_decode_timestamp(&aISCTimestamp, &aCTime); - - // first field is nanoseconds -- not supported in firebird or struct tm. - // last field denotes UTC (true) or unknown (false) - return DateTime(0, aCTime.tm_sec, aCTime.tm_min, aCTime.tm_hour, aCTime.tm_mday, - aCTime.tm_mon, aCTime.tm_year, false); + return safelyRetrieveValue< DateTime >(nIndex, SQL_TIMESTAMP); } // ------------------------------------------------------------------------- diff --git a/connectivity/source/drivers/firebird/ResultSet.hxx b/connectivity/source/drivers/firebird/ResultSet.hxx index c1dd904..fbaed5a 100644 --- a/connectivity/source/drivers/firebird/ResultSet.hxx +++ b/connectivity/source/drivers/firebird/ResultSet.hxx @@ -24,6 +24,7 @@ #include <ibase.h> +#include <connectivity/FValue.hxx> #include <connectivity/OSubComponent.hxx> #include <cppuhelper/compbase8.hxx> #include <comphelper/proparrhlp.hxx> @@ -92,6 +93,14 @@ namespace connectivity ISC_STATUS_ARRAY m_statusVector; bool isNull(const sal_Int32 nColumnIndex); + + /** + * Retrieves a value to an ORowSetValue allowing for conversion + * at will. Should only be used if conversion is needed to avoid + * any performance hit otherwise. + */ + ORowSetValue retrieveConvertibleValue(const sal_Int32 nColumnIndex); + template <typename T> T retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT nType); @@ -194,6 +203,22 @@ namespace connectivity }; // Specialisations have to be in the namespace and can't be within the class. + template <> ::com::sun::star::util::Date + OResultSet::retrieveValue( + const sal_Int32 nColumnIndex, + const ISC_SHORT nType); + template <> ::com::sun::star::util::Time + OResultSet::retrieveValue( + const sal_Int32 nColumnIndex, + const ISC_SHORT nType); + template <> ::com::sun::star::util::DateTime + OResultSet::retrieveValue( + const sal_Int32 nColumnIndex, + const ISC_SHORT nType); + template <> ISC_QUAD* + OResultSet::retrieveValue( + const sal_Int32 nColumnIndex, + const ISC_SHORT nType); template <> ::rtl::OUString OResultSet::retrieveValue( const sal_Int32 nColumnIndex, _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
