summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier Fernandez <jfernandez@igalia.com>2013-05-23 13:31:58 +0000
committerJavier Fernandez <jfernandez@igalia.com>2013-06-06 09:37:42 +0000
commit2be7f51d14a9c5c09ed310dea5058e72eadbd712 (patch)
tree36d8d0e5b258ee8c044094f1c895bc183a86f82d
parent358b46a56df542226021af2c347595354e457684 (diff)
Implementing the ResultSet interface.
Change-Id: I755533c5cb5af713d453b8e6ba7b734870e358a2
-rw-r--r--connectivity/source/drivers/firebird/FDatabaseMetaData.cxx2
-rw-r--r--connectivity/source/drivers/firebird/FPreparedStatement.cxx84
-rw-r--r--connectivity/source/drivers/firebird/FResultSet.cxx141
-rw-r--r--connectivity/source/drivers/firebird/FResultSet.hxx15
4 files changed, 196 insertions, 46 deletions
diff --git a/connectivity/source/drivers/firebird/FDatabaseMetaData.cxx b/connectivity/source/drivers/firebird/FDatabaseMetaData.cxx
index 0225f12b6b9f..fef10bed241e 100644
--- a/connectivity/source/drivers/firebird/FDatabaseMetaData.cxx
+++ b/connectivity/source/drivers/firebird/FDatabaseMetaData.cxx
@@ -876,7 +876,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTables(
*/
Reference< XPreparedStatement > statement = m_pConnection->prepareStatement(
"SELECT "
- "RDB$RELATION_NAME " // avoid duplicates
+ "'schema' as schema, RDB$RELATION_NAME, RDB$SYSTEM_FLAG, RDB$RELATION_TYPE, 'description' as description " // avoid duplicates
"FROM RDB$RELATIONS "
"WHERE (RDB$RELATION_TYPE = 0 OR RDB$RELATION_TYPE = 1) ");
diff --git a/connectivity/source/drivers/firebird/FPreparedStatement.cxx b/connectivity/source/drivers/firebird/FPreparedStatement.cxx
index 59bd67936752..a78ecb66f657 100644
--- a/connectivity/source/drivers/firebird/FPreparedStatement.cxx
+++ b/connectivity/source/drivers/firebird/FPreparedStatement.cxx
@@ -38,6 +38,7 @@
#include "FPreparedStatement.hxx"
#include <com/sun/star/sdbc/DataType.hpp>
#include "FResultSetMetaData.hxx"
+#include "FResultSet.hxx"
#include <cppuhelper/typeprovider.hxx>
#include <com/sun/star/lang/DisposedException.hpp>
#include "propertyids.hxx"
@@ -53,6 +54,11 @@ using namespace com::sun::star::container;
using namespace com::sun::star::io;
using namespace com::sun::star::util;
+typedef struct vary {
+ short vary_length;
+ char vary_string[1];
+} VARY;
+
IMPLEMENT_SERVICE_INFO(OPreparedStatement,"com.sun.star.sdbcx.firebird.PreparedStatement","com.sun.star.sdbc.PreparedStatement");
@@ -182,61 +188,97 @@ static int pr_error (long* status, char* operation)
Reference< XResultSet > SAL_CALL OPreparedStatement::executeQuery( ) throw(SQLException, RuntimeException)
{
- char sqlStr[128];
- strcpy(sqlStr, OUStringToOString( m_sSqlStatement, RTL_TEXTENCODING_ASCII_US ).getStr());
+ char *sqlStr = strdup(OUStringToOString( m_sSqlStatement, RTL_TEXTENCODING_ASCII_US ).getStr());
printf("DEBUG !!! connectivity.firebird => OPreparedStatement::executeQuery() got called with sql: %s \n", sqlStr);
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OStatement_BASE::rBHelper.bDisposed);
- Reference< XResultSet > xRS = NULL;
// create a resultset as result of executing the sql statement
// you have to here something :-)
- ISC_STATUS_ARRAY status; /* status vector */
- isc_db_handle db = NULL; /* database handle */
+ ISC_STATUS_ARRAY status; /* status vector */
+ ISC_STATUS retcode;
+ isc_db_handle db = NULL; /* database handle */
isc_tr_handle trans = NULL; /* transaction handle */
isc_stmt_handle stmt = NULL; /* prepared statement handle */
- XSQLDA * sel_sqlda;
- int CURRENLEN = 10;
- char orig_name[CURRENLEN + 1];
+ XSQLDA * sel_sqlda = NULL;
+ int CURRENLEN = 30;
if (isc_attach_database(status, 0, "/home/javi/Firebird/test/new.fdb", &db, 0, NULL))
if (pr_error(status, "attach database"))
- return xRS;
+ return NULL;
if (isc_start_transaction(status, &trans, 1, &db, 0, NULL))
if (pr_error(status, "start transaction"))
- return xRS;
+ return NULL;
- sel_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
- sel_sqlda->sqln = 1;
+ sel_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(5));
+ sel_sqlda->sqln = 5;
sel_sqlda->version = 1;
if (isc_dsql_allocate_statement(status, &db, &stmt))
if (pr_error(status, "allocate statement"))
- return xRS;
+ return NULL;
if (isc_dsql_prepare(status, &trans, &stmt, 0, sqlStr, 1, sel_sqlda))
if (pr_error(status, "prepare statement"))
- return xRS;
+ return NULL;
- sel_sqlda->sqlvar[0].sqldata = orig_name;
- sel_sqlda->sqlvar[0].sqltype = SQL_TEXT;
+ sel_sqlda->sqlvar[0].sqldata = (char *) malloc(sizeof(char)*CURRENLEN);
+ sel_sqlda->sqlvar[0].sqltype = SQL_VARYING;
sel_sqlda->sqlvar[0].sqllen = CURRENLEN;
+ sel_sqlda->sqlvar[1].sqldata = (char *) malloc(sizeof(char)*CURRENLEN);
+ sel_sqlda->sqlvar[1].sqltype = SQL_VARYING;
+ sel_sqlda->sqlvar[1].sqllen = CURRENLEN;
+ sel_sqlda->sqlvar[2].sqldata = (char *) malloc(sizeof(char)*CURRENLEN);
+ sel_sqlda->sqlvar[2].sqltype = SQL_VARYING;
+ sel_sqlda->sqlvar[2].sqllen = CURRENLEN;
+ sel_sqlda->sqlvar[3].sqldata = (char *) malloc(sizeof(char)*CURRENLEN);
+ sel_sqlda->sqlvar[3].sqltype = SQL_VARYING;
+ sel_sqlda->sqlvar[3].sqllen = CURRENLEN;
+ sel_sqlda->sqlvar[4].sqldata = (char *) malloc(sizeof(char)*CURRENLEN);
+ sel_sqlda->sqlvar[4].sqltype = SQL_VARYING;
+ sel_sqlda->sqlvar[4].sqllen = CURRENLEN;
if (isc_dsql_execute(status, &trans, &stmt, 1, NULL))
if (pr_error(status, "execute query"))
- return xRS;
- if (isc_dsql_fetch(status, &stmt, 1, sel_sqlda))
+ return NULL;
+
+ int i = 0,j = 0;
+ TTable table;
+ VARY *data = NULL;
+ while ((retcode = isc_dsql_fetch(status, &stmt, 1, sel_sqlda)) == 0)
+ {
+ i++;
+ if (i < 10)
+ printf("DEBUG !!! row %i : ", i);
+ else
+ printf("DEBUG !!! row %i: ", i);
+
+ TRow row(sel_sqlda->sqln);
+ for (j=0; j < sel_sqlda->sqln; j++)
+ {
+ data = (VARY *) sel_sqlda->sqlvar[j].sqldata;
+ printf("%-30.*s ", data->vary_length, data->vary_string);
+ row[j] = OUString(data->vary_string, data->vary_length, RTL_TEXTENCODING_UTF8);
+ }
+ printf("\n");
+ table.push_back(row);
+ }
+ if (retcode != 100L)
+ {
+ printf("DEBUG !!! retcode %i: ", retcode);
if (pr_error(status, "fetch data"))
- return xRS;
+ return NULL;
+ }
if (isc_commit_transaction (status, &trans))
isc_print_status(status);
printf("DEBuG !!! connectivity.firebird => OPreparedStatement::executeQuery() Changes committed.\n");
- orig_name[CURRENLEN] = '\0';
- printf("Modifying currency string: %s\n", orig_name);
+ Reference< OResultSet > pResult( new OResultSet( this, table, i, sel_sqlda->sqln ) );
+ //initializeResultSet( pResult.get() );
+ Reference< XResultSet > xRS = pResult.get();
return xRS;
}
diff --git a/connectivity/source/drivers/firebird/FResultSet.cxx b/connectivity/source/drivers/firebird/FResultSet.cxx
index bd314e03d356..2cce24a793f9 100644
--- a/connectivity/source/drivers/firebird/FResultSet.cxx
+++ b/connectivity/source/drivers/firebird/FResultSet.cxx
@@ -35,6 +35,7 @@
#include "FResultSet.hxx"
#include "FResultSetMetaData.hxx"
+#include <rtl/ustrbuf.hxx>
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/sdbcx/CompareBookmark.hpp>
@@ -53,6 +54,11 @@ using namespace com::sun::star::container;
using namespace com::sun::star::io;
using namespace com::sun::star::util;
+typedef struct vary {
+short vary_length;
+char vary_string[1];
+} VARY;
+
//------------------------------------------------------------------------------
// IMPLEMENT_SERVICE_INFO(OResultSet,"com.sun.star.sdbcx.OResultSet","com.sun.star.sdbc.ResultSet");
::rtl::OUString SAL_CALL OResultSet::getImplementationName( ) throw ( RuntimeException) \
@@ -80,7 +86,7 @@ sal_Bool SAL_CALL OResultSet::supportsService( const ::rtl::OUString& _rServiceN
}
// -------------------------------------------------------------------------
-OResultSet::OResultSet(OStatement_Base* pStmt)
+OResultSet::OResultSet(OStatement_Base* pStmt, TTable table, sal_Int32 rows, sal_Int32 fields)
: OResultSet_BASE(m_aMutex)
,OPropertySetHelper(OResultSet_BASE::rBHelper)
,m_aStatement((OWeakObject*)pStmt)
@@ -88,7 +94,12 @@ OResultSet::OResultSet(OStatement_Base* pStmt)
,m_nTextEncoding(pStmt->getOwnConnection()->getTextEncoding())
,m_pStatement(pStmt)
,m_bWasNull(sal_True)
+ ,m_row(-1)
+ ,m_rowCount(rows)
+ ,m_fieldCount(fields)
+ ,m_sqldata(table)
{
+
}
// -------------------------------------------------------------------------
OResultSet::~OResultSet()
@@ -240,8 +251,7 @@ sal_Int32 SAL_CALL OResultSet::getRow( ) throw(SQLException, RuntimeException)
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- sal_Int32 nValue = 0;
- return nValue;
+ return m_row +1;
}
// -------------------------------------------------------------------------
@@ -321,15 +331,35 @@ sal_Int16 SAL_CALL OResultSet::getShort( sal_Int32 columnIndex ) throw(SQLExcept
}
// -------------------------------------------------------------------------
+/*
+ * Print the status, the SQLCODE, and exit.
+ * Also, indicate which operation the error occured on.
+ */
+static int pr_error (long* status, char* operation)
+{
+ printf("[\n");
+ printf("PROBLEM ON \"%s\".\n", operation);
+
+ isc_print_status(status);
+
+ printf("SQLCODE:%d\n", isc_sqlcode(status));
+
+ printf("]\n");
+
+ return 1;
+}
+
::rtl::OUString SAL_CALL OResultSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex( columnIndex );
+ checkRowIndex( sal_True /* must be on row */ );
+ printf("DEBUG !!! OResultSet::getString => row: %i, column: %i \n", m_row, columnIndex);
- ::rtl::OUString nRet;
- return nRet;
+ return m_sqldata[m_row][columnIndex-1];
}
// -------------------------------------------------------------------------
@@ -362,10 +392,7 @@ sal_Bool SAL_CALL OResultSet::isBeforeFirst( ) throw(SQLException, RuntimeExcep
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-
- // here you have to implement your movements
- // return true means there is no data
- return sal_True;
+ return m_row == -1;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL OResultSet::isAfterLast( ) throw(SQLException, RuntimeException)
@@ -373,7 +400,7 @@ sal_Bool SAL_CALL OResultSet::isAfterLast( ) throw(SQLException, RuntimeExcepti
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- return sal_True;
+ return m_row >= m_rowCount;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL OResultSet::isFirst( ) throw(SQLException, RuntimeException)
@@ -381,8 +408,7 @@ sal_Bool SAL_CALL OResultSet::isFirst( ) throw(SQLException, RuntimeException)
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-
- return sal_False;
+ return m_row == 0 && m_rowCount;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL OResultSet::isLast( ) throw(SQLException, RuntimeException)
@@ -390,8 +416,7 @@ sal_Bool SAL_CALL OResultSet::isLast( ) throw(SQLException, RuntimeException)
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-
- return sal_False;
+ return m_row >= 0 && m_row + 1 == m_rowCount;
}
// -------------------------------------------------------------------------
void SAL_CALL OResultSet::beforeFirst( ) throw(SQLException, RuntimeException)
@@ -399,14 +424,15 @@ void SAL_CALL OResultSet::beforeFirst( ) throw(SQLException, RuntimeException)
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- // move before the first row so that isBeforeFirst returns false
- // the smae for other movement methods
+ m_row = -1;
}
// -------------------------------------------------------------------------
void SAL_CALL OResultSet::afterLast( ) throw(SQLException, RuntimeException)
{
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
+
+ m_row = m_rowCount;
}
// -------------------------------------------------------------------------
@@ -426,7 +452,10 @@ sal_Bool SAL_CALL OResultSet::first( ) throw(SQLException, RuntimeException)
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- return sal_False;
+ sal_Bool bRet = ( m_rowCount > 0 );
+ if( bRet )
+ m_row = 0;
+ return bRet;
}
// -------------------------------------------------------------------------
@@ -435,7 +464,10 @@ sal_Bool SAL_CALL OResultSet::last( ) throw(SQLException, RuntimeException)
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- return sal_False;
+ sal_Bool bRet = ( m_rowCount > 0 );
+ if( bRet )
+ m_row = m_rowCount -1;
+ return bRet;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL OResultSet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException)
@@ -443,7 +475,19 @@ sal_Bool SAL_CALL OResultSet::absolute( sal_Int32 row ) throw(SQLException, Runt
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- return sal_False;
+ if( row > 0 )
+ {
+ m_row = row -1;
+ if( m_row > m_rowCount )
+ m_row = m_rowCount;
+ }
+ else
+ {
+ m_row = m_rowCount + row;
+ if( m_row < -1 )
+ m_row = -1;
+ }
+ return sal_True;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL OResultSet::relative( sal_Int32 row ) throw(SQLException, RuntimeException)
@@ -451,7 +495,13 @@ sal_Bool SAL_CALL OResultSet::relative( sal_Int32 row ) throw(SQLException, Runt
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- return sal_False;
+ m_row += row;
+
+ if( m_row > m_rowCount )
+ m_row = m_rowCount;
+ else if ( m_row < -1 )
+ m_row = -1;
+ return sal_True;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL OResultSet::previous( ) throw(SQLException, RuntimeException)
@@ -459,7 +509,10 @@ sal_Bool SAL_CALL OResultSet::previous( ) throw(SQLException, RuntimeException)
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- return sal_False;
+ sal_Bool bRet = ( m_row != -1 );
+ if( bRet )
+ m_row --;
+ return bRet;
}
// -------------------------------------------------------------------------
Reference< XInterface > SAL_CALL OResultSet::getStatement( ) throw(SQLException, RuntimeException)
@@ -505,8 +558,8 @@ sal_Bool SAL_CALL OResultSet::next( ) throw(SQLException, RuntimeException)
::osl::MutexGuard aGuard( m_aMutex );
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-
- return sal_False;
+ m_row ++;
+ return m_row < m_rowCount;
}
// -------------------------------------------------------------------------
@@ -870,6 +923,48 @@ void SAL_CALL OResultSet::release() throw()
}
// -----------------------------------------------------------------------------
+void SAL_CALL OResultSet::checkColumnIndex(sal_Int32 index ) throw ( SQLException, RuntimeException )
+{
+ if( index < 1 || index > m_fieldCount )
+ {
+ OUStringBuffer buf(128);
+ buf.appendAscii( "pq_resultset: index out of range (" );
+ buf.append( index );
+ buf.appendAscii( ", allowed range is 1 to " );
+ buf.append( m_fieldCount );
+ buf.appendAscii( ")" );
+ throw SQLException( buf.makeStringAndClear(), *this, OUString(), 1, Any() );
+ }
+
+}
+
+void SAL_CALL OResultSet::checkRowIndex( sal_Bool mustBeOnValidRow )
+{
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( "pq_baseresultset: row index out of range, allowed is " );
+ if( mustBeOnValidRow )
+ {
+ if( m_row < 0 || m_row >= m_rowCount )
+ {
+ buf.appendAscii( "0 to " );
+ buf.append( ((sal_Int32)(m_rowCount -1)) );
+ buf.appendAscii( ", got " );
+ buf.append( m_row );
+ throw SQLException( buf.makeStringAndClear(), *this, OUString(),1, Any() );
+ }
+ }
+ else
+ {
+ if( m_row < -1 || m_row > m_rowCount )
+ {
+ buf.appendAscii( "-1 to " );
+ buf.append( m_rowCount );
+ buf.appendAscii( ", got " );
+ buf.append( m_row );
+ throw SQLException( buf.makeStringAndClear(), *this, OUString(),1, Any() );
+ }
+ }
+}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/firebird/FResultSet.hxx b/connectivity/source/drivers/firebird/FResultSet.hxx
index 36ebe8894d71..46f24457ef05 100644
--- a/connectivity/source/drivers/firebird/FResultSet.hxx
+++ b/connectivity/source/drivers/firebird/FResultSet.hxx
@@ -51,11 +51,16 @@
#include "FStatement.hxx"
#include "OSubComponent.hxx"
+#include <ibase.h>
+
namespace connectivity
{
namespace firebird
{
+ typedef std::vector< OUString> TRow;
+ typedef std::vector< TRow> TTable;
+
/*
** OResultSet
*/
@@ -83,6 +88,10 @@ namespace connectivity
::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData> m_xMetaData;
rtl_TextEncoding m_nTextEncoding;
sal_Bool m_bWasNull;
+ sal_Int32 m_row;
+ sal_Int32 m_rowCount;
+ sal_Int32 m_fieldCount;
+ TTable m_sqldata;
// OPropertyArrayUsageHelper
virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
@@ -105,12 +114,16 @@ namespace connectivity
sal_Int32 nHandle
) const;
+ virtual void checkColumnIndex( sal_Int32 index )
+ throw ( com::sun::star::sdbc::SQLException, com::sun::star::uno::RuntimeException );
+ virtual void checkRowIndex( sal_Bool mustBeOnValidRow );
+
// you can't delete objects of this type
virtual ~OResultSet();
public:
DECLARE_SERVICE_INFO();
- OResultSet( OStatement_Base* pStmt);
+ OResultSet( OStatement_Base* pStmt, TTable sqldata, sal_Int32 rows, sal_Int32 fields);
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > operator *()