diff options
author | Javier Fernandez <jfernandez@igalia.com> | 2013-05-23 13:31:58 +0000 |
---|---|---|
committer | Andrzej J.R. Hunt <andrzej@ahunt.org> | 2013-07-10 14:08:43 +0100 |
commit | fa82a4cccaa85fc25a88485d6835fc2645e9f8b1 (patch) | |
tree | acb6f491b5d625ec2ae1200c5aefacc93be7dc9c | |
parent | 6aa52911ac04cd9f24efbfcf314f41961c8570e0 (diff) |
Implementing the ResultSet interface.
Change-Id: I755533c5cb5af713d453b8e6ba7b734870e358a2
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 *() |