[Libreoffice-commits] core.git: 8 commits - connectivity/source

Andrzej J.R. Hunt andrzej at ahunt.org
Thu Sep 19 12:38:43 PDT 2013


 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 <andrzej at ahunt.org>
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 <andrzej at ahunt.org>
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 <andrzej at ahunt.org>
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 <andrzej at ahunt.org>
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 <andrzej at ahunt.org>
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 <andrzej at ahunt.org>
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 <andrzej at ahunt.org>
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 <andrzej at ahunt.org>
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,


More information about the Libreoffice-commits mailing list