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

Andrzej J.R. Hunt andrzej at ahunt.org
Fri Jul 19 06:29:17 PDT 2013


 connectivity/source/drivers/firebird/FPreparedStatement.cxx |    5 
 connectivity/source/drivers/firebird/FResultSet.cxx         |  402 +++++-------
 connectivity/source/drivers/firebird/FResultSet.hxx         |   26 
 connectivity/source/drivers/firebird/FResultSetMetaData.cxx |  247 +++++--
 connectivity/source/drivers/firebird/FResultSetMetaData.hxx |   90 +-
 5 files changed, 443 insertions(+), 327 deletions(-)

New commits:
commit 2fcef1b2e302668d1c8fc4cc13c9851eb04e22be
Author: Andrzej J.R. Hunt <andrzej at ahunt.org>
Date:   Fri Jul 19 14:57:12 2013 +0200

    Implement FResultSetMetaData.
    
    Change-Id: I5a3ff140b68139d5b34c1d146a0e0d6544dc9548

diff --git a/connectivity/source/drivers/firebird/FPreparedStatement.cxx b/connectivity/source/drivers/firebird/FPreparedStatement.cxx
index c516b6fa..babde41 100644
--- a/connectivity/source/drivers/firebird/FPreparedStatement.cxx
+++ b/connectivity/source/drivers/firebird/FPreparedStatement.cxx
@@ -112,8 +112,9 @@ Reference< XResultSetMetaData > SAL_CALL OPreparedStatement::getMetaData(  ) thr
     ::osl::MutexGuard aGuard( m_pConnection->getMutex() );
     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
 
-    if(!m_xMetaData.is())
-        m_xMetaData = new OResultSetMetaData(getOwnConnection());
+//     if(!m_xMetaData.is())
+//         m_xMetaData = new OResultSetMetaData(m_pConnection, m_pSqlda);
+    // TODO: uncomment once PreparedStatement reimplemented with SQLDA
     return m_xMetaData;
 }
 // -------------------------------------------------------------------------
diff --git a/connectivity/source/drivers/firebird/FResultSet.cxx b/connectivity/source/drivers/firebird/FResultSet.cxx
index f2f0a78..b19ec4b 100644
--- a/connectivity/source/drivers/firebird/FResultSet.cxx
+++ b/connectivity/source/drivers/firebird/FResultSet.cxx
@@ -73,7 +73,7 @@ OResultSet::OResultSet(OConnection* pConnection,
     , OPropertySetHelper(OResultSet_BASE::rBHelper)
     , m_pConnection(pConnection)
     , m_xStatement(xStatement)
-    , m_xMetaData(NULL)
+    , m_xMetaData(0)
     , m_pSqlda(pSqlda)
     , m_statementHandle(aStatementHandle)
     , m_bWasNull(false)
@@ -434,6 +434,8 @@ T OResultSet::retrieveValue(sal_Int32 columnIndex)
 template <>
 OUString OResultSet::retrieveValue<OUString>(sal_Int32 columnIndex)
 {
+    // TODO: check we don't have SQL_VARYING (first 2 bytes = short with length
+    // of string.
     if ((m_bWasNull = isNull(columnIndex)))
         return OUString();
 
@@ -544,7 +546,7 @@ uno::Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData(  ) throw(
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
 
     if(!m_xMetaData.is())
-        m_xMetaData = new OResultSetMetaData(m_xStatement->getConnection());
+        m_xMetaData = new OResultSetMetaData(m_pConnection, m_pSqlda);
     return m_xMetaData;
 }
 // -------------------------------------------------------------------------
diff --git a/connectivity/source/drivers/firebird/FResultSet.hxx b/connectivity/source/drivers/firebird/FResultSet.hxx
index d83be38..011f9ff 100644
--- a/connectivity/source/drivers/firebird/FResultSet.hxx
+++ b/connectivity/source/drivers/firebird/FResultSet.hxx
@@ -40,7 +40,6 @@
 
 #include <ibase.h>
 
-#include <connectivity/FValue.hxx>
 #include <connectivity/OSubComponent.hxx>
 #include <cppuhelper/compbase12.hxx>
 
diff --git a/connectivity/source/drivers/firebird/FResultSetMetaData.cxx b/connectivity/source/drivers/firebird/FResultSetMetaData.cxx
index c25ddd0..06829d2 100644
--- a/connectivity/source/drivers/firebird/FResultSetMetaData.cxx
+++ b/connectivity/source/drivers/firebird/FResultSetMetaData.cxx
@@ -35,158 +35,259 @@
 
 #include "FResultSetMetaData.hxx"
 
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+
 using namespace connectivity::firebird;
-using namespace com::sun::star::uno;
+
+using namespace ::rtl;
+
 using namespace com::sun::star::lang;
 using namespace com::sun::star::sdbc;
+using namespace com::sun::star::uno;
 
-
-// -------------------------------------------------------------------------
 OResultSetMetaData::~OResultSetMetaData()
 {
-    (void) m_xConnection; // To remove warning until the rest of the class is implemented..
 }
-// -------------------------------------------------------------------------
-// -------------------------------------------------------------------------
-sal_Int32 SAL_CALL OResultSetMetaData::getColumnDisplaySize( sal_Int32 column ) throw(SQLException, RuntimeException)
+
+void OResultSetMetaData::verifyValidColumn(sal_Int32 column)
+    throw(SQLException)
 {
-    (void) column;
-    return 50;
+    if (column>getColumnCount() || column < 1)
+        throw SQLException("Invalid column specified", *this, OUString(), 0, Any());
 }
-// -------------------------------------------------------------------------
 
-sal_Int32 SAL_CALL OResultSetMetaData::getColumnType( sal_Int32 column ) throw(SQLException, RuntimeException)
+sal_Int32 SAL_CALL OResultSetMetaData::getColumnCount() throw(SQLException, RuntimeException)
 {
-    (void) column;
-    sal_Int32 nType = 0;
-    return nType;
+    return m_pSqlda->sqld;
 }
-// -------------------------------------------------------------------------
 
-sal_Int32 SAL_CALL OResultSetMetaData::getColumnCount(  ) throw(SQLException, RuntimeException)
+sal_Int32 SAL_CALL OResultSetMetaData::getColumnDisplaySize( sal_Int32 column ) throw(SQLException, RuntimeException)
 {
-    // this make no sense here so you have to change this
-    return 0;
+    verifyValidColumn(column);
+    return 32; // Hard limit for firebird
 }
-// -------------------------------------------------------------------------
 
-sal_Bool SAL_CALL OResultSetMetaData::isCaseSensitive( sal_Int32 column ) throw(SQLException, RuntimeException)
+sal_Int32 SAL_CALL OResultSetMetaData::getColumnType(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
-    (void) column;
-    return sal_True;
+    verifyValidColumn(column);
+
+    int aType = m_pSqlda->sqlvar[column-1].sqltype;
+
+    aType &= ~1; // Remove last bit -- it is used to denote whether column
+                // can store Null, not needed for type determination
+    switch (aType)
+    {
+        case SQL_TEXT:
+            return DataType::CHAR;
+        case SQL_VARYING:
+            return DataType::VARCHAR;
+        case SQL_SHORT:
+            return DataType::SMALLINT;
+        case SQL_LONG:
+            return DataType::INTEGER;
+        case SQL_FLOAT:
+            return DataType::REAL;
+        case SQL_DOUBLE:
+            return DataType::DOUBLE;
+        case SQL_D_FLOAT:
+            return DataType::FLOAT;
+        case SQL_TIMESTAMP:
+            return DataType::TIMESTAMP;
+        case SQL_BLOB:
+            return DataType::BLOB;
+        case SQL_ARRAY:
+            return DataType::ARRAY;
+        case SQL_TYPE_TIME:
+            return DataType::TIME;
+        case SQL_TYPE_DATE:
+            return DataType::DATE;
+        case SQL_INT64:
+            return DataType::BIGINT;
+        case SQL_NULL:
+            return DataType::SQLNULL;
+        case SQL_QUAD:      // Is a "Blob ID" according to the docs
+            return 0;       // TODO: verify
+        default:
+            assert(false); // Should never happen
+    }
 }
-// -------------------------------------------------------------------------
 
-::rtl::OUString SAL_CALL OResultSetMetaData::getSchemaName( sal_Int32 column ) throw(SQLException, RuntimeException)
+sal_Bool SAL_CALL OResultSetMetaData::isCaseSensitive(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
     (void) column;
-    return ::rtl::OUString();
+    return sal_False;
 }
-// -------------------------------------------------------------------------
 
-::rtl::OUString SAL_CALL OResultSetMetaData::getColumnName( sal_Int32 column ) throw(SQLException, RuntimeException)
+OUString SAL_CALL OResultSetMetaData::getSchemaName(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
     (void) column;
-    return ::rtl::OUString("Column") + ::rtl::OUString::valueOf(column);
+    return OUString(); // Schemas supported by firebird
 }
-// -------------------------------------------------------------------------
-::rtl::OUString SAL_CALL OResultSetMetaData::getTableName( sal_Int32 column ) throw(SQLException, RuntimeException)
+
+OUString SAL_CALL OResultSetMetaData::getColumnName(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
-    (void) column;
-    return ::rtl::OUString();
+    verifyValidColumn(column);
+    return OUString(m_pSqlda->sqlvar[column-1].sqlname,
+                    m_pSqlda->sqlvar[column-1].sqlname_length,
+                    RTL_TEXTENCODING_UTF8);
 }
-// -------------------------------------------------------------------------
-::rtl::OUString SAL_CALL OResultSetMetaData::getCatalogName( sal_Int32 column ) throw(SQLException, RuntimeException)
+
+OUString SAL_CALL OResultSetMetaData::getTableName(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
-    (void) column;
-    return ::rtl::OUString();
+    verifyValidColumn(column);
+    return OUString(m_pSqlda->sqlvar[column-1].relname,
+                    m_pSqlda->sqlvar[column-1].relname_length,
+                    RTL_TEXTENCODING_UTF8);
 }
-// -------------------------------------------------------------------------
-::rtl::OUString SAL_CALL OResultSetMetaData::getColumnTypeName( sal_Int32 column ) throw(SQLException, RuntimeException)
+
+OUString SAL_CALL OResultSetMetaData::getCatalogName(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
     (void) column;
-    return ::rtl::OUString();
+    return OUString(); // Catalogs not supported by firebird
 }
-// -------------------------------------------------------------------------
-::rtl::OUString SAL_CALL OResultSetMetaData::getColumnLabel( sal_Int32 column ) throw(SQLException, RuntimeException)
+
+OUString SAL_CALL OResultSetMetaData::getColumnTypeName(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
+    verifyValidColumn(column);
+
+    int aType = m_pSqlda->sqlvar[column-1].sqltype;
+
+    aType &= ~1; // Remove last bit -- it is used to denote whether column
+                // can store Null, not needed for type determination
+    switch (aType)
+    {
+        case SQL_TEXT:
+            return OUString("SQL_TEXT");
+        case SQL_VARYING:
+            return OUString("SQL_VARYING");
+        case SQL_SHORT:
+            return OUString("SQL_SHORT");
+        case SQL_LONG:
+            return OUString("SQL_LONG");
+        case SQL_FLOAT:
+            return OUString("SQL_FLOAT");
+        case SQL_DOUBLE:
+            return OUString("SQL_DOUBLE");
+        case SQL_D_FLOAT:
+            return OUString("SQL_D_FLOAT");
+        case SQL_TIMESTAMP:
+            return OUString("SQL_TIMESTAMP");
+        case SQL_BLOB:
+            return OUString("SQL_BLOB");
+        case SQL_ARRAY:
+            return OUString("SQL_ARRAY");
+        case SQL_TYPE_TIME:
+            return OUString("SQL_TYPE_TIME");
+        case SQL_TYPE_DATE:
+            return OUString("SQL_TYPE_DATE");
+        case SQL_INT64:
+            return OUString("SQL_INT64");
+        case SQL_NULL:
+            return OUString("SQL_NULL");
+        case SQL_QUAD:
+            return OUString("SQL_QUAD");
+        default:
+            assert(false); // Should never happen
+    }
+}
+
+OUString SAL_CALL OResultSetMetaData::getColumnLabel(sal_Int32 column)
+    throw(SQLException, RuntimeException)
+{
+    // TODO: clarify what this is -- probably not the alias
     (void) column;
-    return ::rtl::OUString();
+    return OUString();
 }
-// -------------------------------------------------------------------------
-::rtl::OUString SAL_CALL OResultSetMetaData::getColumnServiceName( sal_Int32 column ) throw(SQLException, RuntimeException)
+
+OUString SAL_CALL OResultSetMetaData::getColumnServiceName(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
+    // TODO: implement
     (void) column;
-    return ::rtl::OUString();
+    return OUString();
 }
-// -------------------------------------------------------------------------
 
-sal_Bool SAL_CALL OResultSetMetaData::isCurrency( sal_Int32 column ) throw(SQLException, RuntimeException)
+sal_Bool SAL_CALL OResultSetMetaData::isCurrency(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
     (void) column;
     return sal_False;
 }
-// -------------------------------------------------------------------------
 
-sal_Bool SAL_CALL OResultSetMetaData::isAutoIncrement( sal_Int32 column ) throw(SQLException, RuntimeException)
+sal_Bool SAL_CALL OResultSetMetaData::isAutoIncrement(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
+    // Supported internally but no way of determining this here.
     (void) column;
     return sal_False;
 }
-// -------------------------------------------------------------------------
 
 
-sal_Bool SAL_CALL OResultSetMetaData::isSigned( sal_Int32 column ) throw(SQLException, RuntimeException)
+sal_Bool SAL_CALL OResultSetMetaData::isSigned(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
+    // Unsigned values aren't supported in firebird.
     (void) column;
-    return sal_False;
+    return sal_True;
 }
-// -------------------------------------------------------------------------
-sal_Int32 SAL_CALL OResultSetMetaData::getPrecision( sal_Int32 column ) throw(SQLException, RuntimeException)
+
+sal_Int32 SAL_CALL OResultSetMetaData::getPrecision(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
+    // TODO: implement
     (void) column;
     return 0;
 }
-// -----------------------------------------------------------------------------
-sal_Int32 SAL_CALL OResultSetMetaData::getScale( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+
+sal_Int32 SAL_CALL OResultSetMetaData::getScale(sal_Int32 column)
+    throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
 {
-    (void) column;
-    return 0;
+    return m_pSqlda->sqlvar[column-1].sqlscale;
 }
-// -------------------------------------------------------------------------
 
-sal_Int32 SAL_CALL OResultSetMetaData::isNullable( sal_Int32 column ) throw(SQLException, RuntimeException)
+sal_Int32 SAL_CALL OResultSetMetaData::isNullable(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
-    (void) column;
-    return 0;
+    if (*m_pSqlda->sqlvar[column-1].sqlind & 1)
+        return ColumnValue::NULLABLE;
+    else
+        return ColumnValue::NO_NULLS;
 }
-// -------------------------------------------------------------------------
 
-sal_Bool SAL_CALL OResultSetMetaData::isSearchable( sal_Int32 column ) throw(SQLException, RuntimeException)
+sal_Bool SAL_CALL OResultSetMetaData::isSearchable(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
+    // TODO: Can the column be used as part of a where clause? Assume yes
     (void) column;
     return sal_True;
 }
-// -------------------------------------------------------------------------
 
-sal_Bool SAL_CALL OResultSetMetaData::isReadOnly( sal_Int32 column ) throw(SQLException, RuntimeException)
+sal_Bool SAL_CALL OResultSetMetaData::isReadOnly(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
     (void) column;
-    return sal_True;
+    return m_pConnection->isReadOnly(); // Readonly only available on db level
 }
-// -------------------------------------------------------------------------
 
-sal_Bool SAL_CALL OResultSetMetaData::isDefinitelyWritable( sal_Int32 column ) throw(SQLException, RuntimeException)
+sal_Bool SAL_CALL OResultSetMetaData::isDefinitelyWritable(sal_Int32 column)
+    throw(SQLException, RuntimeException)
 {
     (void) column;
-    return sal_False;
+    return !m_pConnection->isReadOnly();
 }
-// -------------------------------------------------------------------------
+
 sal_Bool SAL_CALL OResultSetMetaData::isWritable( sal_Int32 column ) throw(SQLException, RuntimeException)
 {
     (void) column;
-    return sal_False;
+    return !m_pConnection->isReadOnly();
 }
-// -------------------------------------------------------------------------
+
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/firebird/FResultSetMetaData.hxx b/connectivity/source/drivers/firebird/FResultSetMetaData.hxx
index 868b8b3..be6bb8b 100644
--- a/connectivity/source/drivers/firebird/FResultSetMetaData.hxx
+++ b/connectivity/source/drivers/firebird/FResultSetMetaData.hxx
@@ -36,56 +36,84 @@
 #ifndef CONNECTIVITY_SRESULSETMETADATA_HXX
 #define CONNECTIVITY_SRESULSETMETADATA_HXX
 
-#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
-#include <cppuhelper/implbase1.hxx>
 #include "FConnection.hxx"
 
+#include <ibase.h>
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
+
 namespace connectivity
 {
     namespace firebird
     {
-        //**************************************************************
-        //************ Class: ResultSetMetaData
-        //**************************************************************
-        typedef ::cppu::WeakImplHelper1< ::com::sun::star::sdbc::XResultSetMetaData>   OResultSetMetaData_BASE;
+        typedef ::cppu::WeakImplHelper1< ::com::sun::star::sdbc::XResultSetMetaData>
+                OResultSetMetaData_BASE;
 
         class OResultSetMetaData :  public  OResultSetMetaData_BASE
         {
-            const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& m_xConnection;
-
         protected:
+            OConnection*    m_pConnection;
+            XSQLDA*         m_pSqlda;
+
             virtual ~OResultSetMetaData();
+
+            void verifyValidColumn(sal_Int32 column) throw(::com::sun::star::sdbc::SQLException);
         public:
             // a constructor, which is required for returning objects:
-            OResultSetMetaData(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& xConnection)
-            : m_xConnection( xConnection )
+            OResultSetMetaData(OConnection* pConnection,
+                               XSQLDA* pSqlda)
+                : m_pConnection(pConnection)
+                , m_pSqlda(pSqlda)
             {}
 
             /// Avoid ambigous cast error from the compiler.
             inline operator ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > () throw()
             { return this; }
 
-            virtual sal_Int32 SAL_CALL getColumnCount(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual sal_Bool SAL_CALL isAutoIncrement( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual sal_Bool SAL_CALL isCaseSensitive( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual sal_Bool SAL_CALL isSearchable( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual sal_Bool SAL_CALL isCurrency( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual sal_Int32 SAL_CALL isNullable( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual sal_Bool SAL_CALL isSigned( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual sal_Int32 SAL_CALL getColumnDisplaySize( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual ::rtl::OUString SAL_CALL getColumnLabel( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual ::rtl::OUString SAL_CALL getColumnName( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual ::rtl::OUString SAL_CALL getSchemaName( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual sal_Int32 SAL_CALL getPrecision( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual sal_Int32 SAL_CALL getScale( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual ::rtl::OUString SAL_CALL getTableName( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual ::rtl::OUString SAL_CALL getCatalogName( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual sal_Int32 SAL_CALL getColumnType( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual ::rtl::OUString SAL_CALL getColumnTypeName( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual sal_Bool SAL_CALL isReadOnly( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual sal_Bool SAL_CALL isWritable( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual sal_Bool SAL_CALL isDefinitelyWritable( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-            virtual ::rtl::OUString SAL_CALL getColumnServiceName( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Int32 SAL_CALL getColumnCount()
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Bool SAL_CALL isAutoIncrement(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Bool SAL_CALL isCaseSensitive(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Bool SAL_CALL isSearchable(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Bool SAL_CALL isCurrency(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Int32 SAL_CALL isNullable(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Bool SAL_CALL isSigned(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Int32 SAL_CALL getColumnDisplaySize(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual ::rtl::OUString SAL_CALL getColumnLabel(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual ::rtl::OUString SAL_CALL getColumnName(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual ::rtl::OUString SAL_CALL getSchemaName(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Int32 SAL_CALL getPrecision(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Int32 SAL_CALL getScale(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual ::rtl::OUString SAL_CALL getTableName(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual ::rtl::OUString SAL_CALL getCatalogName(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Int32 SAL_CALL getColumnType(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual ::rtl::OUString SAL_CALL getColumnTypeName(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Bool SAL_CALL isReadOnly(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Bool SAL_CALL isWritable(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual sal_Bool SAL_CALL isDefinitelyWritable(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+            virtual ::rtl::OUString SAL_CALL getColumnServiceName(sal_Int32 column)
+                throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
         };
     }
 }
commit c277e307692af4b1aa33d1e3d358a60f62230ff8
Author: Andrzej J.R. Hunt <andrzej at ahunt.org>
Date:   Fri Jul 19 12:16:01 2013 +0200

    Implement String retrieval (firebird-sdbc).
    
    Change-Id: I85ed3a0c7cd473d89a48f4b35a94f3ca5fd72a11

diff --git a/connectivity/source/drivers/firebird/FResultSet.cxx b/connectivity/source/drivers/firebird/FResultSet.cxx
index 60fac62..f2f0a78 100644
--- a/connectivity/source/drivers/firebird/FResultSet.cxx
+++ b/connectivity/source/drivers/firebird/FResultSet.cxx
@@ -431,16 +431,16 @@ T OResultSet::retrieveValue(sal_Int32 columnIndex)
     return *m_pSqlda->sqlvar[columnIndex-1].sqldata;
 }
 
-// template <>
-// OUString OResultSet::retrieveValue< OUString >(sal_Int32 columnIndex)
-// {
-//     if ((m_bWasNull = isNull(columnIndex)))
-//         return "";
-//
-//     return OUString(m_pSqlda->pVar[columnIndex-1].sqldata,
-//                     m_pSqlda->pVar[columnIndex-1].sqllen,
-//                     RTL_TEXTENCODING_UTF8)
-// }
+template <>
+OUString OResultSet::retrieveValue<OUString>(sal_Int32 columnIndex)
+{
+    if ((m_bWasNull = isNull(columnIndex)))
+        return OUString();
+
+    return OUString(m_pSqlda->sqlvar[columnIndex-1].sqldata,
+                    m_pSqlda->sqlvar[columnIndex-1].sqllen,
+                    RTL_TEXTENCODING_UTF8);
+}
 
 template <typename T>
 T OResultSet::safelyRetrieveValue(sal_Int32 columnIndex)
@@ -514,9 +514,7 @@ double SAL_CALL OResultSet::getDouble(sal_Int32 columnIndex)
 OUString SAL_CALL OResultSet::getString(sal_Int32 columnIndex)
     throw(SQLException, RuntimeException)
 {
-    (void) columnIndex;
-    return OUString();
-//     return safelyRetrieveValue< OUString >(columnIndex);
+    return safelyRetrieveValue< OUString >(columnIndex);
 }
 
 Time SAL_CALL OResultSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
diff --git a/connectivity/source/drivers/firebird/FResultSet.hxx b/connectivity/source/drivers/firebird/FResultSet.hxx
index 88e02e2..d83be38 100644
--- a/connectivity/source/drivers/firebird/FResultSet.hxx
+++ b/connectivity/source/drivers/firebird/FResultSet.hxx
@@ -98,14 +98,8 @@ namespace connectivity
             const sal_Int32                             m_fieldCount;
             ISC_STATUS_ARRAY                            m_statusVector;
 
-//             void ensureDataAvailable()
-//                 throw (::com::sun::star::sdbc::SQLException);
-//             const ::connectivity::ORowSetValue& getSqlData(sal_Int32 aRow, sal_Int32 aColumn)
-//                 throw (::com::sun::star::sdbc::SQLException);
-
             bool isNull(sal_Int32 columnIndex);
             template <typename T> T     retrieveValue(sal_Int32 columnIndex);
-//             template <> ::rtl::OUString retrieveValue< ::rtl::OUString > (sal_Int32 columnIndex);
 
             template <typename T> T safelyRetrieveValue(sal_Int32 columnIndex)
                 throw(::com::sun::star::sdbc::SQLException);
@@ -248,6 +242,9 @@ namespace connectivity
             // XDeleteRows
             virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL deleteRows( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rows ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
         };
+
+        // Specialisations have to be in the namespace and can't be within the class.
+        template <> ::rtl::OUString OResultSet::retrieveValue< ::rtl::OUString >(sal_Int32 columnIndex);
     }
 }
 #endif // CONNECTIVITY_SRESULTSET_HXX
commit 6f0a454c0405cb1593aa97a0df7971d520a61e90
Author: Andrzej J.R. Hunt <andrzej at ahunt.org>
Date:   Fri Jul 19 11:51:26 2013 +0200

    Templateised retrieval for integer types (firebird-sdbc).
    
    Change-Id: Idef6a6bcf30d2c334c0809ea3d72b3650d4e3563

diff --git a/connectivity/source/drivers/firebird/FResultSet.cxx b/connectivity/source/drivers/firebird/FResultSet.cxx
index 26f0371..60fac62 100644
--- a/connectivity/source/drivers/firebird/FResultSet.cxx
+++ b/connectivity/source/drivers/firebird/FResultSet.cxx
@@ -408,85 +408,136 @@ uno::Reference< XInputStream > SAL_CALL OResultSet::getCharacterStream( sal_Int3
     return NULL;
 }
 
-// ---- Simple Numerical types -----------------------------------------------
-const ORowSetValue& OResultSet::safelyRetrieveValue(sal_Int32 columnIndex)
-    throw(SQLException)
+// ---- Internal Utilities ---------------------------------------------------
+bool OResultSet::isNull(sal_Int32 columnIndex)
+{
+    assert(columnIndex <= m_fieldCount);
+    XSQLVAR* pVar = m_pSqlda->sqlvar;
+
+    if (pVar[columnIndex-1].sqltype & 1) // Indicates column may contain null
+    {
+        if (*pVar[columnIndex-1].sqlind == -1)
+            return true;
+    }
+    return false;
+}
+
+template <typename T>
+T OResultSet::retrieveValue(sal_Int32 columnIndex)
+{
+    if ((m_bWasNull = isNull(columnIndex)))
+        return 0;
+
+    return *m_pSqlda->sqlvar[columnIndex-1].sqldata;
+}
+
+// template <>
+// OUString OResultSet::retrieveValue< OUString >(sal_Int32 columnIndex)
+// {
+//     if ((m_bWasNull = isNull(columnIndex)))
+//         return "";
+//
+//     return OUString(m_pSqlda->pVar[columnIndex-1].sqldata,
+//                     m_pSqlda->pVar[columnIndex-1].sqllen,
+//                     RTL_TEXTENCODING_UTF8)
+// }
+
+template <typename T>
+T OResultSet::safelyRetrieveValue(sal_Int32 columnIndex)
+    throw (SQLException)
 {
-    (void) columnIndex;
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    throw SQLException(); // Temporary until we've reimplemented everythign
-//     return getSqlData(m_currentRow,columnIndex);
-}
 
+    checkColumnIndex(columnIndex);
+    checkRowIndex();
+
+    return retrieveValue< T >(columnIndex);
+}
+// ---- Simple Numerical types -----------------------------------------------
 sal_Bool SAL_CALL OResultSet::getBoolean(sal_Int32 columnIndex)
     throw(SQLException, RuntimeException)
 {
-    return safelyRetrieveValue(columnIndex);
+    // TODO: maybe retrieve as string and test for "true", "t", "1" etc. instead?
+    return safelyRetrieveValue< bool >(columnIndex);
 }
 
 sal_Int8 SAL_CALL OResultSet::getByte( sal_Int32 columnIndex )
     throw(SQLException, RuntimeException)
 {
-    return safelyRetrieveValue(columnIndex);
+    return safelyRetrieveValue< sal_Int8 >(columnIndex);
 }
 
 Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes(sal_Int32 columnIndex)
     throw(SQLException, RuntimeException)
 {
-    return safelyRetrieveValue(columnIndex);
+    (void) columnIndex;
+    return Sequence< sal_Int8 >(); // TODO: implement
+    //return safelyRetrieveValue(columnIndex);
 }
 
 sal_Int16 SAL_CALL OResultSet::getShort(sal_Int32 columnIndex)
     throw(SQLException, RuntimeException)
 {
-    return safelyRetrieveValue(columnIndex);
+    return safelyRetrieveValue< sal_Int16 >(columnIndex);
 }
 
 sal_Int32 SAL_CALL OResultSet::getInt(sal_Int32 columnIndex)
     throw(SQLException, RuntimeException)
 {
-    return safelyRetrieveValue(columnIndex);
+    return safelyRetrieveValue< sal_Int32 >(columnIndex);
 }
 
 sal_Int64 SAL_CALL OResultSet::getLong(sal_Int32 columnIndex)
     throw(SQLException, RuntimeException)
 {
-    return safelyRetrieveValue(columnIndex);
+    return safelyRetrieveValue< sal_Int64 >(columnIndex);
 }
 
 float SAL_CALL OResultSet::getFloat(sal_Int32 columnIndex)
     throw(SQLException, RuntimeException)
 {
-    return safelyRetrieveValue(columnIndex);
+    (void) columnIndex;
+    return 0.0f; // TODO: implement
+//     return safelyRetrieveValue(columnIndex);
 }
 
 double SAL_CALL OResultSet::getDouble(sal_Int32 columnIndex)
     throw(SQLException, RuntimeException)
 {
-    return safelyRetrieveValue(columnIndex);
+    (void) columnIndex;
+    return 0.0; // TODO: implement
+//     return safelyRetrieveValue(columnIndex);
 }
 
 // ---- More complex types ---------------------------------------------------
 OUString SAL_CALL OResultSet::getString(sal_Int32 columnIndex)
     throw(SQLException, RuntimeException)
 {
-    return safelyRetrieveValue(columnIndex);
+    (void) columnIndex;
+    return OUString();
+//     return safelyRetrieveValue< OUString >(columnIndex);
 }
 
 Time SAL_CALL OResultSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
 {
-    return safelyRetrieveValue(columnIndex);
+    (void) columnIndex;
+    return Time();
+//     return safelyRetrieveValue(columnIndex);
 }
 
 DateTime SAL_CALL OResultSet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
 {
-    return safelyRetrieveValue(columnIndex);
+    (void) columnIndex;
+    return DateTime(); // TODO: implement
+//     return safelyRetrieveValue(columnIndex);
 }
 
 Date SAL_CALL OResultSet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
 {
-    return safelyRetrieveValue(columnIndex);
+    (void) columnIndex;
+    return Date(); // TODO: implement
+//     return safelyRetrieveValue(columnIndex);
 }
 // -------------------------------------------------------------------------
 uno::Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData(  ) throw(SQLException, RuntimeException)
diff --git a/connectivity/source/drivers/firebird/FResultSet.hxx b/connectivity/source/drivers/firebird/FResultSet.hxx
index b98b4ba..88e02e2 100644
--- a/connectivity/source/drivers/firebird/FResultSet.hxx
+++ b/connectivity/source/drivers/firebird/FResultSet.hxx
@@ -103,7 +103,11 @@ namespace connectivity
 //             const ::connectivity::ORowSetValue& getSqlData(sal_Int32 aRow, sal_Int32 aColumn)
 //                 throw (::com::sun::star::sdbc::SQLException);
 
-            const ::connectivity::ORowSetValue& safelyRetrieveValue(sal_Int32 columnIndex)
+            bool isNull(sal_Int32 columnIndex);
+            template <typename T> T     retrieveValue(sal_Int32 columnIndex);
+//             template <> ::rtl::OUString retrieveValue< ::rtl::OUString > (sal_Int32 columnIndex);
+
+            template <typename T> T safelyRetrieveValue(sal_Int32 columnIndex)
                 throw(::com::sun::star::sdbc::SQLException);
 
             // OPropertyArrayUsageHelper
commit 00d533e34c25eb5699fb19aba6b16007c1cc07c1
Author: Andrzej J.R. Hunt <andrzej at ahunt.org>
Date:   Fri Jul 19 10:55:14 2013 +0200

    Remove internal caching in FResultSet. (Breaks firebird-sdbc for now.)
    
    Change-Id: I99d764b1464c264d70c777ff212eaa4e8eba7c71

diff --git a/connectivity/source/drivers/firebird/FResultSet.cxx b/connectivity/source/drivers/firebird/FResultSet.cxx
index d587c85..26f0371 100644
--- a/connectivity/source/drivers/firebird/FResultSet.cxx
+++ b/connectivity/source/drivers/firebird/FResultSet.cxx
@@ -76,10 +76,9 @@ OResultSet::OResultSet(OConnection* pConnection,
     , m_xMetaData(NULL)
     , m_pSqlda(pSqlda)
     , m_statementHandle(aStatementHandle)
-    , m_bIsPopulated(sal_False)
-    , m_bWasNull(sal_True)
+    , m_bWasNull(false)
     , m_currentRow(0)
-    , m_rowCount(0)
+    , m_bIsAfterLastRow(false)
     , m_fieldCount(pSqlda? pSqlda->sqld : 0)
 {
     SAL_INFO("connectivity.firebird", "OResultSet().");
@@ -93,89 +92,33 @@ OResultSet::~OResultSet()
 {
 }
 
-void OResultSet::ensureDataAvailable() throw (SQLException)
-{
-    MutexGuard aGuard(m_pConnection->getMutex());
-    checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-
-    if (!m_bIsPopulated)
-    {
-        SAL_INFO("connectivity.firebird", "Iterating over data cursor");
-        ISC_STATUS fetchStat;
-
-        // Firebird doesn't support scrollable cursors so we have to load everything
-        // into memory. Can't really be done on demand as we need to determine the
-        // number of rows which can only be done by iterating over the XSQLDA
-        while ( 0 == (fetchStat = isc_dsql_fetch(m_statusVector,
-                                                 &m_statementHandle,
-                                                 1,
-                                                 m_pSqlda)))
-        {
-            m_rowCount++;
-
-            TRow aRow(m_fieldCount);
-            m_sqlData.push_back(aRow);
-            TRow& rRow = m_sqlData.back();
-
-            XSQLVAR* pVar = m_pSqlda->sqlvar;
-            for (int i = 0; i < m_fieldCount; pVar++, i++)
-            {
-                if ((pVar->sqltype & 1) == 0) // Means: Cannot contain NULL
-                {
-                    // TODO: test for null here and set as appropriate
-                }
-                else // Means: Can contain NULL
-                {
-                    // otherwise we need to test for SQL_TYPE and SQL_TYPE+1 below
-                    pVar->sqltype--;
-                }
-                switch (pVar->sqltype)
-                {
-                    case SQL_SHORT:
-                        rRow[i] = (sal_Int16) *pVar->sqldata;
-                        break;
-                    case SQL_LONG:
-                        rRow[i] = (sal_Int32) *pVar->sqldata;
-                        break;
-                    case SQL_INT64:
-                        rRow[i] = (sal_Int64) *pVar->sqldata;
-                        break;
-                    // TODO: remember sqlscale for decimal types
-                    default:
-                        rRow[i] = OUString(pVar->sqldata, pVar->sqllen, RTL_TEXTENCODING_UTF8);
-                        break;
-                }
-            }
-        }
-
-        ISC_STATUS aErr = isc_dsql_free_statement(m_statusVector,
-                                                  &m_statementHandle,
-                                                  DSQL_drop);
-        // TODO: cleanup the XSQLDA, probably in the destructor?
-
-        // fetchstat == 100L if fetching of data completed successfully.
-        if ((fetchStat != 100L) || aErr)
-        {
-            SAL_WARN("connectivity.firebird", "Error when populating data");
-            OConnection::evaluateStatusVector(m_statusVector,
-                                              "isc_dsql_free_statement",
-                                              *this);
-        }
-
-        SAL_INFO("connectivity.firebird", "Populated dataset with " << m_rowCount << " rows.");
-        m_bIsPopulated = true;
-    }
-}
-
-const ORowSetValue& OResultSet::getSqlData(sal_Int32 aRow, sal_Int32 aColumn)
-    throw(SQLException)
-{
-    // Validate input (throws Exceptions as appropriate)
-    checkRowIndex(aRow);
-    checkColumnIndex(aColumn);
+// void OResultSet::ensureDataAvailable() throw (SQLException)
+// {
+//     MutexGuard aGuard(m_pConnection->getMutex());
+//     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
+//
+//     if (!m_bIsPopulated)
+//     {
+//
+//         ISC_STATUS aErr = isc_dsql_free_statement(m_statusVector,
+//                                                   &m_statementHandle,
+//                                                   DSQL_drop);
+//         // TODO: cleanup the XSQLDA, probably in the destructor?
+//
+//         // fetchstat == 100L if fetching of data completed successfully.
+//         if ((fetchStat != 100L) || aErr)
+//         {
+//             SAL_WARN("connectivity.firebird", "Error when populating data");
+//             OConnection::evaluateStatusVector(m_statusVector,
+//                                               "isc_dsql_free_statement",
+//                                               *this);
+//         }
+//
+//         SAL_INFO("connectivity.firebird", "Populated dataset with " << m_rowCount << " rows.");
+//         m_bIsPopulated = true;
+//     }
+// }
 
-    return m_sqlData[aRow-1][aColumn-1];
-}
 
 // ---- XResultSet -- Row retrieval methods ------------------------------------
 sal_Int32 SAL_CALL OResultSet::getRow() throw(SQLException, RuntimeException)
@@ -190,34 +133,81 @@ sal_Bool SAL_CALL OResultSet::next() throw(SQLException, RuntimeException)
 {
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
 
-    if (m_currentRow < m_rowCount)
+    SAL_INFO("connectivity.firebird", "Fetching row from cursor");
+
+    m_currentRow++;
+
+    ISC_STATUS fetchStat = isc_dsql_fetch(m_statusVector,
+                               &m_statementHandle,
+                               1,
+                               m_pSqlda);
+    if (fetchStat == 0)         // SUCCESSFUL
     {
-        m_currentRow++;
         return sal_True;
     }
+    else if (fetchStat == 100L) // END OF DATASET
+    {
+        // TODO: shut the statement
+        return sal_False;
+    }
     else
     {
+        SAL_WARN("connectivity.firebird", "Error when populating data");
+        // Throws sql exception as appropriate
+        OConnection::evaluateStatusVector(m_statusVector,
+                                          "isc_dsql_fetch",
+                                          *this);
         return sal_False;
     }
+
+            //         {
+//             m_rowCount++;
+//
+//             TRow aRow(m_fieldCount);
+//             m_sqlData.push_back(aRow);
+//             TRow& rRow = m_sqlData.back();
+//
+//             XSQLVAR* pVar = m_pSqlda->sqlvar;
+//             for (int i = 0; i < m_fieldCount; pVar++, i++)
+//             {
+//                 if ((pVar->sqltype & 1) == 0) // Means: Cannot contain NULL
+//                 {
+//                     // TODO: test for null here and set as appropriate
+//                 }
+//                 else // Means: Can contain NULL
+//                 {
+//                     // otherwise we need to test for SQL_TYPE and SQL_TYPE+1 below
+//                     pVar->sqltype--;
+//                 }
+//                 switch (pVar->sqltype)
+//                 {
+//                     case SQL_SHORT:
+//                         rRow[i] = (sal_Int16) *pVar->sqldata;
+//                         break;
+//                     case SQL_LONG:
+//                         rRow[i] = (sal_Int32) *pVar->sqldata;
+//                         break;
+//                     case SQL_INT64:
+//                         rRow[i] = (sal_Int64) *pVar->sqldata;
+//                         break;
+//                     // TODO: remember sqlscale for decimal types
+//                     default:
+//                         rRow[i] = OUString(pVar->sqldata, pVar->sqllen, RTL_TEXTENCODING_UTF8);
+//                         break;
+//                 }
+//             }
+//         }
 }
 
 sal_Bool SAL_CALL OResultSet::previous() throw(SQLException, RuntimeException)
 {
-    MutexGuard aGuard(m_pConnection->getMutex());
-    checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
+    throw SQLException("Firebird doesn't support previous()", *this, OUString(), 0, Any());
+}
 
-    if (m_currentRow > 0)
-    {
-        m_currentRow--;
-        return sal_True;
-    }
-    else
-    {
-        return sal_False;
-    }
+sal_Bool SAL_CALL OResultSet::isLast() throw(SQLException, RuntimeException)
+{
+    throw SQLException("Firebird doesn't support isLast()", *this, OUString(), 0, Any());
 }
 
 sal_Bool SAL_CALL OResultSet::isBeforeFirst() throw(SQLException, RuntimeException)
@@ -232,27 +222,16 @@ sal_Bool SAL_CALL OResultSet::isAfterLast() throw(SQLException, RuntimeException
 {
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
 
-    return m_currentRow > m_rowCount;
+    return m_bIsAfterLastRow;
 }
 
 sal_Bool SAL_CALL OResultSet::isFirst() throw(SQLException, RuntimeException)
 {
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
 
-    return m_currentRow == 1 && m_rowCount;
-}
-
-sal_Bool SAL_CALL OResultSet::isLast() throw(SQLException, RuntimeException)
-{
-    MutexGuard aGuard(m_pConnection->getMutex());
-    checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
-
-    return (m_currentRow > 0) && (m_currentRow == m_rowCount);
+    return m_currentRow == 1 && !m_bIsAfterLastRow;
 }
 
 // Move to front
@@ -261,77 +240,59 @@ void SAL_CALL OResultSet::beforeFirst() throw(SQLException, RuntimeException)
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
 
-    m_currentRow = 0;
+    if (m_currentRow != 0)
+        throw SQLException("Firebird doesn't support beforeFirst()", *this, OUString(), 0, Any());
 }
 // Move to back
 void SAL_CALL OResultSet::afterLast() throw(SQLException, RuntimeException)
 {
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
 
-    m_currentRow = m_rowCount + 1;
+    if (!m_bIsAfterLastRow)
+        throw SQLException("Firebird doesn't support afterLast()", *this, OUString(), 0, Any());
 }
 
 sal_Bool SAL_CALL OResultSet::first() throw(SQLException, RuntimeException)
 {
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
 
-    if (m_rowCount > 0)
+    if (m_currentRow == 0)
     {
-        m_currentRow = 1;
-        return sal_True;
+        return next();
+    }
+    else if (m_currentRow == 1 && !m_bIsAfterLastRow)
+    {
+        return true;
     }
     else
     {
-        return sal_False;
+           throw SQLException("Firebird doesn't support first()", *this, OUString(), 0, Any());
     }
 }
 
 sal_Bool SAL_CALL OResultSet::last() throw(SQLException, RuntimeException)
 {
-    MutexGuard aGuard(m_pConnection->getMutex());
-    checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
-
-    if (m_rowCount > 0)
-    {
-        m_currentRow = m_rowCount;
-        return sal_True;
-    }
-    else
-    {
-        return sal_False;
-    }
+    // We need to iterate past the last row to know when we've passed the last
+    // row, so we can't actually move to last.
+        throw SQLException("Firebird doesn't support last()", *this, OUString(), 0, Any());
 }
 
 sal_Bool SAL_CALL OResultSet::absolute(sal_Int32 aRow) throw(SQLException, RuntimeException)
 {
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
 
-    if (m_rowCount > 0)
+    if (aRow > m_currentRow)
     {
-        if( aRow > 0 )
-        {
-            m_currentRow = aRow;
-            if( m_currentRow > m_rowCount )
-                m_currentRow = m_rowCount + 1;
-        }
-        else
-        {
-            m_currentRow = m_rowCount + 1 + aRow;
-            if( m_currentRow < 0 )
-                m_currentRow = 0;
-        }
-        return sal_True;
+        sal_Int32 aIterations = aRow - m_currentRow;
+        return relative(aIterations);
     }
     else
     {
-        return sal_False;
+        throw SQLException("Firebird doesn't support retrieval of rows before the current row",
+                            *this, OUString(), 0, Any());
     }
 }
 
@@ -339,26 +300,25 @@ sal_Bool SAL_CALL OResultSet::relative(sal_Int32 row) throw(SQLException, Runtim
 {
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
 
-    if (m_rowCount > 0)
+    if (row > 0)
     {
-        m_currentRow += row;
-
-        if( m_currentRow > m_rowCount )
-            m_currentRow = m_rowCount + 1;
-        else if ( m_currentRow < -1 )
-            m_currentRow = -1;
-
+        while (row--)
+        {
+            if (!next())
+                return sal_False;
+        }
         return sal_True;
     }
     else
     {
-        return false;
+        throw SQLException("Firebird doesn't support relative() for a negative offset",
+                           *this, OUString(), 0, Any());
     }
 }
 
-void SAL_CALL OResultSet::checkColumnIndex(sal_Int32 index ) throw ( SQLException, RuntimeException )
+void SAL_CALL OResultSet::checkColumnIndex(sal_Int32 index)
+    throw (SQLException, RuntimeException)
 {
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
@@ -369,25 +329,15 @@ void SAL_CALL OResultSet::checkColumnIndex(sal_Int32 index ) throw ( SQLExceptio
     }
 }
 
-void SAL_CALL OResultSet::checkRowIndex(sal_Bool mustBeOnValidRow)
+void SAL_CALL OResultSet::checkRowIndex()
+    throw (SQLException)
 {
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
 
-    if(mustBeOnValidRow)
+    if((m_currentRow < 1) || m_bIsAfterLastRow)
     {
-        if((m_currentRow < 1) || (m_currentRow > m_rowCount))
-        {
-            throw SQLException( "Row index is out of valid range.", *this, OUString(),1, Any() );
-        }
-    }
-    else
-    {
-        if((m_currentRow < 0) || (m_currentRow > 1 + m_rowCount))
-        {
-            throw SQLException( "Row index is invalid", *this, OUString(),1, Any() );
-        }
+        throw SQLException( "Row index is out of valid range.", *this, OUString(),1, Any() );
     }
 }
 // -------------------------------------------------------------------------
@@ -445,8 +395,6 @@ uno::Reference< XInputStream > SAL_CALL OResultSet::getBinaryStream( sal_Int32 c
     (void) columnIndex;
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
-
 
     return NULL;
 }
@@ -456,8 +404,6 @@ uno::Reference< XInputStream > SAL_CALL OResultSet::getCharacterStream( sal_Int3
     (void) columnIndex;
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
-
 
     return NULL;
 }
@@ -466,11 +412,11 @@ uno::Reference< XInputStream > SAL_CALL OResultSet::getCharacterStream( sal_Int3
 const ORowSetValue& OResultSet::safelyRetrieveValue(sal_Int32 columnIndex)
     throw(SQLException)
 {
+    (void) columnIndex;
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
-
-    return getSqlData(m_currentRow,columnIndex);
+    throw SQLException(); // Temporary until we've reimplemented everythign
+//     return getSqlData(m_currentRow,columnIndex);
 }
 
 sal_Bool SAL_CALL OResultSet::getBoolean(sal_Int32 columnIndex)
@@ -547,8 +493,6 @@ uno::Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData(  ) throw(
 {
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
-
 
     if(!m_xMetaData.is())
         m_xMetaData = new OResultSetMetaData(m_xStatement->getConnection());
@@ -560,7 +504,6 @@ uno::Reference< XArray > SAL_CALL OResultSet::getArray( sal_Int32 columnIndex )
     (void) columnIndex;
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
 
     return NULL;
 }
@@ -572,7 +515,6 @@ uno::Reference< XClob > SAL_CALL OResultSet::getClob( sal_Int32 columnIndex ) th
     (void) columnIndex;
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
 
     return NULL;
 }
@@ -582,7 +524,6 @@ uno::Reference< XBlob > SAL_CALL OResultSet::getBlob( sal_Int32 columnIndex ) th
     (void) columnIndex;
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
 
     return NULL;
 }
@@ -593,7 +534,6 @@ uno::Reference< XRef > SAL_CALL OResultSet::getRef( sal_Int32 columnIndex ) thro
     (void) columnIndex;
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
 
     return NULL;
 }
@@ -605,7 +545,6 @@ Any SAL_CALL OResultSet::getObject( sal_Int32 columnIndex, const uno::Reference<
     (void) typeMap;
     MutexGuard aGuard(m_pConnection->getMutex());
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-    ensureDataAvailable();
 
     return Any();
 }
diff --git a/connectivity/source/drivers/firebird/FResultSet.hxx b/connectivity/source/drivers/firebird/FResultSet.hxx
index b79b6c7..b98b4ba 100644
--- a/connectivity/source/drivers/firebird/FResultSet.hxx
+++ b/connectivity/source/drivers/firebird/FResultSet.hxx
@@ -61,10 +61,6 @@ namespace connectivity
 {
     namespace firebird
     {
-
-        typedef ::std::vector< ::connectivity::ORowSetValue > TRow;
-        typedef ::std::vector< TRow >                  TTable;
-
         /*
         **  OResultSet
         */
@@ -93,20 +89,19 @@ namespace connectivity
 
             XSQLDA*                                     m_pSqlda;
             isc_stmt_handle                             m_statementHandle;
-            sal_Bool                                    m_bIsPopulated;
 
-            sal_Bool                                    m_bWasNull;
+            bool                                        m_bWasNull;
             // Row numbering starts with 0 for "in front of first row"
             sal_Int32                                   m_currentRow;
-            sal_Int32                                   m_rowCount;
+            bool                                        m_bIsAfterLastRow;
+
             const sal_Int32                             m_fieldCount;
-            TTable                                      m_sqlData;
             ISC_STATUS_ARRAY                            m_statusVector;
 
-            void ensureDataAvailable()
-                throw (::com::sun::star::sdbc::SQLException);
-            const ::connectivity::ORowSetValue& getSqlData(sal_Int32 aRow, sal_Int32 aColumn)
-                throw (::com::sun::star::sdbc::SQLException);
+//             void ensureDataAvailable()
+//                 throw (::com::sun::star::sdbc::SQLException);
+//             const ::connectivity::ORowSetValue& getSqlData(sal_Int32 aRow, sal_Int32 aColumn)
+//                 throw (::com::sun::star::sdbc::SQLException);
 
             const ::connectivity::ORowSetValue& safelyRetrieveValue(sal_Int32 columnIndex)
                 throw(::com::sun::star::sdbc::SQLException);
@@ -135,7 +130,8 @@ namespace connectivity
 
             virtual void SAL_CALL checkColumnIndex( sal_Int32 index )
                 throw ( com::sun::star::sdbc::SQLException, com::sun::star::uno::RuntimeException );
-            virtual void SAL_CALL checkRowIndex( sal_Bool mustBeOnValidRow );
+            virtual void SAL_CALL checkRowIndex()
+                throw ( com::sun::star::sdbc::SQLException);
 
             // you can't delete objects of this type
             virtual ~OResultSet();


More information about the Libreoffice-commits mailing list