1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_connectivity.hxx" 30 #include <limits> // included here to prevent problems if compiling with C52 31 32 #ifdef GCC 33 #include <iostream> 34 #endif 35 #include "connectivity/sdbcx/VColumn.hxx" 36 #include "file/FResultSet.hxx" 37 #include "file/FResultSetMetaData.hxx" 38 #include <com/sun/star/sdbc/DataType.hpp> 39 #include <com/sun/star/sdbc/ColumnValue.hpp> 40 #include <comphelper/property.hxx> 41 #include <com/sun/star/lang/DisposedException.hpp> 42 #include <com/sun/star/beans/PropertyAttribute.hpp> 43 #include <com/sun/star/container/XIndexAccess.hpp> 44 #include <comphelper/sequence.hxx> 45 #include <cppuhelper/typeprovider.hxx> 46 #include "connectivity/dbconversion.hxx" 47 #include "connectivity/dbtools.hxx" 48 #include <cppuhelper/propshlp.hxx> 49 #include <iterator> 50 #include <tools/debug.hxx> 51 #include <com/sun/star/sdbc/ResultSetType.hpp> 52 #include <com/sun/star/sdbc/FetchDirection.hpp> 53 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp> 54 #include <com/sun/star/sdbcx/XIndexesSupplier.hpp> 55 56 #include <algorithm> 57 #include <comphelper/extract.hxx> 58 #include "connectivity/dbexception.hxx" 59 #include <comphelper/types.hxx> 60 #include "resource/file_res.hrc" 61 #include "resource/sharedresources.hxx" 62 #include <rtl/logfile.hxx> 63 64 65 using namespace ::comphelper; 66 using namespace connectivity; 67 using namespace connectivity::file; 68 using namespace ::cppu; 69 using namespace dbtools; 70 using namespace com::sun::star::uno; 71 using namespace com::sun::star::lang; 72 using namespace com::sun::star::beans; 73 using namespace com::sun::star::sdbc; 74 using namespace com::sun::star::sdbcx; 75 using namespace com::sun::star::container; 76 77 // Maximale Anzahl von Rows, die mit ORDER BY sortiert durchlaufen werden koennen: 78 #define MAX_KEYSET_SIZE 0x40000 // 256K 79 80 namespace 81 { 82 void lcl_throwError(sal_uInt16 _nErrorId,const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>& _xContext) 83 { 84 ::connectivity::SharedResources aResources; 85 const ::rtl::OUString sMessage = aResources.getResourceString(_nErrorId); 86 ::dbtools::throwGenericSQLException(sMessage ,_xContext); 87 } 88 } 89 //------------------------------------------------------------------------------ 90 IMPLEMENT_SERVICE_INFO(OResultSet,"com.sun.star.sdbcx.drivers.file.ResultSet","com.sun.star.sdbc.ResultSet"); 91 DBG_NAME( file_OResultSet ) 92 // ------------------------------------------------------------------------- 93 OResultSet::OResultSet(OStatement_Base* pStmt,OSQLParseTreeIterator& _aSQLIterator) : OResultSet_BASE(m_aMutex) 94 ,::comphelper::OPropertyContainer(OResultSet_BASE::rBHelper) 95 ,m_aAssignValues(NULL) 96 ,m_pEvaluationKeySet(NULL) 97 ,m_aSkipDeletedSet(this) 98 ,m_pFileSet(NULL) 99 ,m_pSortIndex(NULL) 100 ,m_pTable(NULL) 101 ,m_pParseTree(pStmt->getParseTree()) 102 ,m_pSQLAnalyzer(NULL) 103 ,m_aSQLIterator(_aSQLIterator) 104 ,m_nFetchSize(0) 105 ,m_nResultSetType(ResultSetType::SCROLL_INSENSITIVE) 106 ,m_nFetchDirection(FetchDirection::FORWARD) 107 ,m_nResultSetConcurrency(ResultSetConcurrency::UPDATABLE) 108 ,m_xStatement(*pStmt) 109 ,m_xMetaData(NULL) 110 ,m_xDBMetaData(pStmt->getOwnConnection()->getMetaData()) 111 ,m_nTextEncoding(pStmt->getOwnConnection()->getTextEncoding()) 112 ,m_nRowPos(-1) 113 ,m_nFilePos(0) 114 ,m_nLastVisitedPos(-1) 115 ,m_nRowCountResult(-1) 116 ,m_nCurrentPosition(0) 117 ,m_nColumnCount(0) 118 ,m_bWasNull(sal_False) 119 ,m_bEOF(sal_False) 120 ,m_bLastRecord(sal_False) 121 ,m_bInserted(sal_False) 122 ,m_bRowUpdated(sal_False) 123 ,m_bRowInserted(sal_False) 124 ,m_bRowDeleted(sal_False) 125 ,m_bShowDeleted(pStmt->getOwnConnection()->showDeleted()) 126 ,m_bIsCount(sal_False) 127 { 128 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::OResultSet" ); 129 DBG_CTOR( file_OResultSet, NULL ); 130 osl_incrementInterlockedCount( &m_refCount ); 131 m_bIsCount = (m_pParseTree && 132 m_pParseTree->count() > 2 && 133 SQL_ISRULE(m_pParseTree->getChild(2),scalar_exp_commalist) && 134 SQL_ISRULE(m_pParseTree->getChild(2)->getChild(0),derived_column) && 135 SQL_ISRULE(m_pParseTree->getChild(2)->getChild(0)->getChild(0),general_set_fct) && 136 m_pParseTree->getChild(2)->getChild(0)->getChild(0)->count() == 4 137 ); 138 139 m_nResultSetConcurrency = isCount() ? ResultSetConcurrency::READ_ONLY : ResultSetConcurrency::UPDATABLE; 140 construct(); 141 m_aSkipDeletedSet.SetDeletedVisible(m_bShowDeleted); 142 osl_decrementInterlockedCount( &m_refCount ); 143 } 144 145 // ------------------------------------------------------------------------- 146 OResultSet::~OResultSet() 147 { 148 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::~OResultSet" ); 149 osl_incrementInterlockedCount( &m_refCount ); 150 disposing(); 151 DBG_DTOR( file_OResultSet, NULL ); 152 } 153 // ------------------------------------------------------------------------- 154 void OResultSet::construct() 155 { 156 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::construct" ); 157 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE), PROPERTY_ID_FETCHSIZE, 0,&m_nFetchSize, ::getCppuType(reinterpret_cast<sal_Int32*>(NULL))); 158 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE), PROPERTY_ID_RESULTSETTYPE, PropertyAttribute::READONLY,&m_nResultSetType, ::getCppuType(reinterpret_cast<sal_Int32*>(NULL))); 159 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION), PROPERTY_ID_FETCHDIRECTION, 0,&m_nFetchDirection, ::getCppuType(reinterpret_cast<sal_Int32*>(NULL))); 160 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY), PROPERTY_ID_RESULTSETCONCURRENCY,PropertyAttribute::READONLY,&m_nResultSetConcurrency, ::getCppuType(reinterpret_cast<sal_Int32*>(NULL))); 161 } 162 // ------------------------------------------------------------------------- 163 void OResultSet::disposing(void) 164 { 165 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::disposing" ); 166 OPropertySetHelper::disposing(); 167 168 ::osl::MutexGuard aGuard(m_aMutex); 169 m_xStatement.clear(); 170 m_xMetaData.clear(); 171 m_pParseTree = NULL; 172 m_xColNames.clear(); 173 m_xColumns = NULL; 174 m_xParamColumns = NULL; 175 m_xColsIdx.clear(); 176 177 Reference<XComponent> xComp = m_pTable; 178 if ( xComp.is() ) 179 xComp->removeEventListener(this); 180 if(m_pTable) 181 { 182 m_pTable->release(); 183 m_pTable = NULL; 184 } 185 clear(); 186 } 187 // ----------------------------------------------------------------------------- 188 void OResultSet::clear() 189 { 190 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::clear" ); 191 m_pFileSet = NULL; 192 DELETEZ(m_pSortIndex); 193 194 if(m_aInsertRow.isValid()) 195 m_aInsertRow->get().clear(); 196 197 m_aSkipDeletedSet.clear(); 198 } 199 // ------------------------------------------------------------------------- 200 Any SAL_CALL OResultSet::queryInterface( const Type & rType ) throw(RuntimeException) 201 { 202 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::queryInterface" ); 203 Any aRet = OPropertySetHelper::queryInterface(rType); 204 return aRet.hasValue() ? aRet : OResultSet_BASE::queryInterface(rType); 205 } 206 // ------------------------------------------------------------------------- 207 Sequence< Type > SAL_CALL OResultSet::getTypes( ) throw(RuntimeException) 208 { 209 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getTypes" ); 210 ::osl::MutexGuard aGuard( m_aMutex ); 211 212 OTypeCollection aTypes( ::getCppuType( (const Reference< ::com::sun::star::beans::XMultiPropertySet > *)0 ), 213 ::getCppuType( (const Reference< ::com::sun::star::beans::XPropertySet > *)0 ), 214 ::getCppuType( (const Reference< ::com::sun::star::beans::XPropertySet > *)0 )); 215 216 return ::comphelper::concatSequences(aTypes.getTypes(),OResultSet_BASE::getTypes()); 217 } 218 // ------------------------------------------------------------------------- 219 220 sal_Int32 SAL_CALL OResultSet::findColumn( const ::rtl::OUString& columnName ) throw(SQLException, RuntimeException) 221 { 222 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::findColumn" ); 223 ::osl::MutexGuard aGuard( m_aMutex ); 224 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 225 226 227 Reference< XResultSetMetaData > xMeta = getMetaData(); 228 sal_Int32 nLen = xMeta->getColumnCount(); 229 sal_Int32 i = 1; 230 for(;i<=nLen;++i) 231 if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) : 232 columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i))) 233 break; 234 return i; 235 } 236 // ----------------------------------------------------------------------------- 237 const ORowSetValue& OResultSet::getValue(sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException) 238 { 239 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getValue" ); 240 ::osl::MutexGuard aGuard( m_aMutex ); 241 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 242 243 //columnIndex = mapColumn(columnIndex); 244 checkIndex(columnIndex ); 245 246 247 m_bWasNull = (m_aSelectRow->get())[columnIndex]->getValue().isNull(); 248 return *(m_aSelectRow->get())[columnIndex]; 249 } 250 // ----------------------------------------------------------------------------- 251 void OResultSet::checkIndex(sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException) 252 { 253 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::checkIndex" ); 254 if ( columnIndex <= 0 255 // || columnIndex > (sal_Int32)m_xColumns->size() 256 || columnIndex >= m_nColumnCount ) 257 ::dbtools::throwInvalidIndexException(*this); 258 } 259 // ------------------------------------------------------------------------- 260 Reference< ::com::sun::star::io::XInputStream > SAL_CALL OResultSet::getBinaryStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 261 { 262 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getBinaryStream" ); 263 return NULL; 264 } 265 // ------------------------------------------------------------------------- 266 Reference< ::com::sun::star::io::XInputStream > SAL_CALL OResultSet::getCharacterStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 267 { 268 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getCharacterStream" ); 269 return NULL; 270 } 271 272 // ------------------------------------------------------------------------- 273 sal_Bool SAL_CALL OResultSet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 274 { 275 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getBoolean" ); 276 return getValue(columnIndex); 277 } 278 // ------------------------------------------------------------------------- 279 280 sal_Int8 SAL_CALL OResultSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 281 { 282 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getByte" ); 283 return getValue(columnIndex); 284 } 285 // ------------------------------------------------------------------------- 286 287 Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 288 { 289 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getBytes" ); 290 return getValue(columnIndex); 291 } 292 // ------------------------------------------------------------------------- 293 294 ::com::sun::star::util::Date SAL_CALL OResultSet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 295 { 296 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getDate" ); 297 return getValue(columnIndex); 298 } 299 // ------------------------------------------------------------------------- 300 301 double SAL_CALL OResultSet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 302 { 303 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getDouble" ); 304 return getValue(columnIndex); 305 } 306 // ------------------------------------------------------------------------- 307 308 float SAL_CALL OResultSet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 309 { 310 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getFloat" ); 311 return getValue(columnIndex); 312 } 313 // ------------------------------------------------------------------------- 314 315 sal_Int32 SAL_CALL OResultSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 316 { 317 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getInt" ); 318 return getValue(columnIndex); 319 } 320 // ------------------------------------------------------------------------- 321 322 sal_Int32 SAL_CALL OResultSet::getRow( ) throw(SQLException, RuntimeException) 323 { 324 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getRow" ); 325 ::osl::MutexGuard aGuard( m_aMutex ); 326 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 327 328 OSL_ENSURE((m_bShowDeleted || !m_aRow->isDeleted()),"getRow called for deleted row"); 329 330 return m_aSkipDeletedSet.getMappedPosition((m_aRow->get())[0]->getValue()); 331 } 332 // ------------------------------------------------------------------------- 333 334 sal_Int64 SAL_CALL OResultSet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 335 { 336 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getLong" ); 337 return getValue(columnIndex); 338 } 339 // ------------------------------------------------------------------------- 340 341 Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData( ) throw(SQLException, RuntimeException) 342 { 343 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getMetaData" ); 344 ::osl::MutexGuard aGuard( m_aMutex ); 345 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 346 347 348 if(!m_xMetaData.is()) 349 m_xMetaData = new OResultSetMetaData(m_xColumns,m_aSQLIterator.getTables().begin()->first,m_pTable); 350 return m_xMetaData; 351 } 352 // ------------------------------------------------------------------------- 353 Reference< XArray > SAL_CALL OResultSet::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 354 { 355 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getArray" ); 356 return NULL; 357 } 358 359 // ------------------------------------------------------------------------- 360 361 Reference< XClob > SAL_CALL OResultSet::getClob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 362 { 363 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getClob" ); 364 return NULL; 365 } 366 // ------------------------------------------------------------------------- 367 Reference< XBlob > SAL_CALL OResultSet::getBlob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 368 { 369 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getBlob" ); 370 return NULL; 371 } 372 // ------------------------------------------------------------------------- 373 374 Reference< XRef > SAL_CALL OResultSet::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 375 { 376 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getRef" ); 377 return NULL; 378 } 379 // ------------------------------------------------------------------------- 380 381 Any SAL_CALL OResultSet::getObject( sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException) 382 { 383 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getObject" ); 384 return getValue(columnIndex).makeAny(); 385 } 386 // ------------------------------------------------------------------------- 387 388 sal_Int16 SAL_CALL OResultSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 389 { 390 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getShort" ); 391 return getValue(columnIndex); 392 } 393 // ------------------------------------------------------------------------- 394 ::rtl::OUString SAL_CALL OResultSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 395 { 396 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getString" ); 397 return getValue(columnIndex); 398 } 399 // ------------------------------------------------------------------------- 400 ::com::sun::star::util::Time SAL_CALL OResultSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 401 { 402 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getTime" ); 403 return getValue(columnIndex); 404 } 405 // ------------------------------------------------------------------------- 406 ::com::sun::star::util::DateTime SAL_CALL OResultSet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 407 { 408 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getTimestamp" ); 409 return getValue(columnIndex); 410 } 411 // ------------------------------------------------------------------------- 412 413 sal_Bool SAL_CALL OResultSet::isAfterLast( ) throw(SQLException, RuntimeException) 414 { 415 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::isAfterLast" ); 416 ::osl::MutexGuard aGuard( m_aMutex ); 417 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 418 419 420 return m_nRowPos == sal_Int32(m_pFileSet->get().size()); 421 } 422 // ------------------------------------------------------------------------- 423 sal_Bool SAL_CALL OResultSet::isFirst( ) throw(SQLException, RuntimeException) 424 { 425 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::isFirst" ); 426 ::osl::MutexGuard aGuard( m_aMutex ); 427 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 428 429 430 return m_nRowPos == 0; 431 } 432 // ------------------------------------------------------------------------- 433 sal_Bool SAL_CALL OResultSet::isLast( ) throw(SQLException, RuntimeException) 434 { 435 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::isLast" ); 436 ::osl::MutexGuard aGuard( m_aMutex ); 437 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 438 439 440 return m_nRowPos == sal_Int32(m_pFileSet->get().size() - 1); 441 } 442 // ------------------------------------------------------------------------- 443 void SAL_CALL OResultSet::beforeFirst( ) throw(SQLException, RuntimeException) 444 { 445 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::beforeFirst" ); 446 ::osl::MutexGuard aGuard( m_aMutex ); 447 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 448 449 450 if(first()) 451 previous(); 452 } 453 // ------------------------------------------------------------------------- 454 void SAL_CALL OResultSet::afterLast( ) throw(SQLException, RuntimeException) 455 { 456 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::afterLast" ); 457 ::osl::MutexGuard aGuard( m_aMutex ); 458 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 459 460 461 if(last()) 462 next(); 463 m_bEOF = sal_True; 464 } 465 // ------------------------------------------------------------------------- 466 467 void SAL_CALL OResultSet::close( ) throw(SQLException, RuntimeException) 468 { 469 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::close" ); 470 dispose(); 471 } 472 // ------------------------------------------------------------------------- 473 474 sal_Bool SAL_CALL OResultSet::first( ) throw(SQLException, RuntimeException) 475 { 476 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::first" ); 477 ::osl::MutexGuard aGuard( m_aMutex ); 478 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 479 return m_pTable ? m_aSkipDeletedSet.skipDeleted(IResultSetHelper::FIRST,1,sal_True) : sal_False; 480 } 481 // ------------------------------------------------------------------------- 482 483 sal_Bool SAL_CALL OResultSet::last( ) throw(SQLException, RuntimeException) 484 { 485 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::last" ); 486 // here I know definitely that I stand on the last record 487 ::osl::MutexGuard aGuard( m_aMutex ); 488 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 489 return m_pTable ? m_aSkipDeletedSet.skipDeleted(IResultSetHelper::LAST,1,sal_True) : sal_False; 490 } 491 // ------------------------------------------------------------------------- 492 sal_Bool SAL_CALL OResultSet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException) 493 { 494 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::absolute" ); 495 ::osl::MutexGuard aGuard( m_aMutex ); 496 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 497 return m_pTable ? m_aSkipDeletedSet.skipDeleted(IResultSetHelper::ABSOLUTE,row,sal_True) : sal_False; 498 } 499 // ------------------------------------------------------------------------- 500 sal_Bool SAL_CALL OResultSet::relative( sal_Int32 row ) throw(SQLException, RuntimeException) 501 { 502 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::relative" ); 503 ::osl::MutexGuard aGuard( m_aMutex ); 504 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 505 return m_pTable ? m_aSkipDeletedSet.skipDeleted(IResultSetHelper::RELATIVE,row,sal_True) : sal_False; 506 } 507 // ------------------------------------------------------------------------- 508 sal_Bool SAL_CALL OResultSet::previous( ) throw(SQLException, RuntimeException) 509 { 510 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::previous" ); 511 ::osl::MutexGuard aGuard( m_aMutex ); 512 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 513 return m_pTable ? m_aSkipDeletedSet.skipDeleted(IResultSetHelper::PRIOR,0,sal_True) : sal_False; 514 } 515 // ------------------------------------------------------------------------- 516 Reference< XInterface > SAL_CALL OResultSet::getStatement( ) throw(SQLException, RuntimeException) 517 { 518 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getStatement" ); 519 ::osl::MutexGuard aGuard( m_aMutex ); 520 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 521 522 523 return m_xStatement; 524 } 525 // ------------------------------------------------------------------------- 526 527 sal_Bool SAL_CALL OResultSet::rowDeleted( ) throw(SQLException, RuntimeException) 528 { 529 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::rowDeleted" ); 530 ::osl::MutexGuard aGuard( m_aMutex ); 531 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 532 533 534 return m_bRowDeleted; 535 } 536 // ------------------------------------------------------------------------- 537 sal_Bool SAL_CALL OResultSet::rowInserted( ) throw(SQLException, RuntimeException) 538 { ::osl::MutexGuard aGuard( m_aMutex ); 539 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 540 541 542 return m_bRowInserted; 543 } 544 // ------------------------------------------------------------------------- 545 sal_Bool SAL_CALL OResultSet::rowUpdated( ) throw(SQLException, RuntimeException) 546 { 547 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::rowInserted" ); 548 ::osl::MutexGuard aGuard( m_aMutex ); 549 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 550 551 552 return m_bRowUpdated; 553 } 554 // ------------------------------------------------------------------------- 555 556 sal_Bool SAL_CALL OResultSet::isBeforeFirst( ) throw(SQLException, RuntimeException) 557 { 558 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::isBeforeFirst" ); 559 ::osl::MutexGuard aGuard( m_aMutex ); 560 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 561 562 563 return m_nRowPos == -1; 564 } 565 // ------------------------------------------------------------------------- 566 sal_Bool OResultSet::evaluate() 567 { 568 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::evaluate" ); 569 OSL_ENSURE(m_pSQLAnalyzer,"OResultSet::evaluate: Analyzer isn't set!"); 570 sal_Bool bRet = sal_True; 571 while(!m_pSQLAnalyzer->evaluateRestriction()) 572 { 573 if(m_pEvaluationKeySet) 574 { 575 if(m_aEvaluateIter == m_pEvaluationKeySet->end()) 576 return sal_False; 577 bRet = m_pTable->seekRow(IResultSetHelper::BOOKMARK,(*m_aEvaluateIter),m_nRowPos); 578 ++m_aEvaluateIter; 579 } 580 else 581 bRet = m_pTable->seekRow(IResultSetHelper::NEXT,1,m_nRowPos); 582 if(bRet) 583 { 584 if(m_pEvaluationKeySet) 585 { 586 bRet = m_pTable->fetchRow(m_aEvaluateRow,m_pTable->getTableColumns().getBody(),sal_True,sal_True); 587 evaluate(); 588 589 } 590 else 591 bRet = m_pTable->fetchRow(m_aRow,m_xColumns.getBody(),sal_False,sal_True); 592 } 593 } 594 595 return bRet; 596 } 597 // ------------------------------------------------------------------------- 598 599 sal_Bool SAL_CALL OResultSet::next( ) throw(SQLException, RuntimeException) 600 { 601 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::next" ); 602 ::osl::MutexGuard aGuard( m_aMutex ); 603 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 604 605 return m_pTable ? m_aSkipDeletedSet.skipDeleted(IResultSetHelper::NEXT,1,sal_True) : sal_False; 606 } 607 // ------------------------------------------------------------------------- 608 609 sal_Bool SAL_CALL OResultSet::wasNull( ) throw(SQLException, RuntimeException) 610 { 611 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::wasNull" ); 612 ::osl::MutexGuard aGuard( m_aMutex ); 613 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 614 615 return m_bWasNull; 616 } 617 // ------------------------------------------------------------------------- 618 619 void SAL_CALL OResultSet::cancel( ) throw(RuntimeException) 620 { 621 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::cancel" ); 622 } 623 // ------------------------------------------------------------------------- 624 void SAL_CALL OResultSet::clearWarnings( ) throw(SQLException, RuntimeException) 625 { 626 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::clearWarnings" ); 627 } 628 // ------------------------------------------------------------------------- 629 Any SAL_CALL OResultSet::getWarnings( ) throw(SQLException, RuntimeException) 630 { 631 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getWarnings" ); 632 return Any(); 633 } 634 // ------------------------------------------------------------------------- 635 void SAL_CALL OResultSet::insertRow( ) throw(SQLException, RuntimeException) 636 { 637 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::insertRow" ); 638 ::osl::MutexGuard aGuard( m_aMutex ); 639 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 640 641 642 if(!m_bInserted || !m_pTable) 643 throwFunctionSequenceException(*this); 644 645 // we know that we append new rows at the end 646 // so we have to know where the end is 647 m_aSkipDeletedSet.skipDeleted(IResultSetHelper::LAST,1,sal_False); 648 m_bRowInserted = m_pTable->InsertRow(m_aInsertRow.getBody(), sal_True,m_xColsIdx); 649 if(m_bRowInserted && m_pFileSet.isValid()) 650 { 651 sal_Int32 nPos = (m_aInsertRow->get())[0]->getValue(); 652 m_pFileSet->get().push_back(nPos); 653 *(m_aInsertRow->get())[0] = sal_Int32(m_pFileSet->get().size()); 654 clearInsertRow(); 655 656 m_aSkipDeletedSet.insertNewPosition((m_aRow->get())[0]->getValue()); 657 } 658 } 659 // ------------------------------------------------------------------------- 660 void SAL_CALL OResultSet::updateRow( ) throw(SQLException, RuntimeException) 661 { 662 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateRow" ); 663 ::osl::MutexGuard aGuard( m_aMutex ); 664 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 665 666 if(!m_pTable || m_pTable->isReadOnly()) 667 lcl_throwError(STR_TABLE_READONLY,*this); 668 669 m_bRowUpdated = m_pTable->UpdateRow(m_aInsertRow.getBody(), m_aRow,m_xColsIdx); 670 *(m_aInsertRow->get())[0] = (sal_Int32)(m_aRow->get())[0]->getValue(); 671 672 clearInsertRow(); 673 } 674 // ------------------------------------------------------------------------- 675 void SAL_CALL OResultSet::deleteRow() throw(SQLException, RuntimeException) 676 { 677 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::deleteRow" ); 678 ::osl::MutexGuard aGuard( m_aMutex ); 679 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 680 681 682 if(!m_pTable || m_pTable->isReadOnly()) 683 lcl_throwError(STR_TABLE_READONLY,*this); 684 if (m_bShowDeleted) 685 lcl_throwError(STR_DELETE_ROW,*this); 686 if(m_aRow->isDeleted()) 687 lcl_throwError(STR_ROW_ALREADY_DELETED,*this); 688 689 sal_Int32 nPos = (sal_Int32)(m_aRow->get())[0]->getValue(); 690 m_bRowDeleted = m_pTable->DeleteRow(m_xColumns.getBody()); 691 if(m_bRowDeleted && m_pFileSet.isValid()) 692 { 693 m_aRow->setDeleted(sal_True); 694 // don't touch the m_pFileSet member here 695 m_aSkipDeletedSet.deletePosition(nPos); 696 } 697 } 698 // ------------------------------------------------------------------------- 699 void SAL_CALL OResultSet::cancelRowUpdates( ) throw(SQLException, RuntimeException) 700 { 701 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::cancelRowUpdates" ); 702 ::osl::MutexGuard aGuard( m_aMutex ); 703 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 704 705 706 m_bInserted = sal_False; 707 m_bRowUpdated = sal_False; 708 m_bRowInserted = sal_False; 709 m_bRowDeleted = sal_False; 710 711 if(m_aInsertRow.isValid()) 712 { 713 OValueRefVector::Vector::iterator aIter = m_aInsertRow->get().begin()+1; 714 for(;aIter != m_aInsertRow->get().end();++aIter) 715 { 716 (*aIter)->setBound(sal_False); 717 (*aIter)->setNull(); 718 } 719 } 720 } 721 // ------------------------------------------------------------------------- 722 723 void SAL_CALL OResultSet::moveToInsertRow( ) throw(SQLException, RuntimeException) 724 { 725 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::moveToInsertRow" ); 726 ::osl::MutexGuard aGuard( m_aMutex ); 727 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 728 729 if(!m_pTable || m_pTable->isReadOnly()) 730 lcl_throwError(STR_TABLE_READONLY,*this); 731 732 m_bInserted = sal_True; 733 734 OValueRefVector::Vector::iterator aIter = m_aInsertRow->get().begin()+1; 735 for(;aIter != m_aInsertRow->get().end();++aIter) 736 { 737 (*aIter)->setBound(sal_False); 738 (*aIter)->setNull(); 739 } 740 } 741 // ------------------------------------------------------------------------- 742 743 void SAL_CALL OResultSet::moveToCurrentRow( ) throw(SQLException, RuntimeException) 744 { 745 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::moveToCurrentRow" ); 746 } 747 // ------------------------------------------------------------------------- 748 void OResultSet::updateValue(sal_Int32 columnIndex ,const ORowSetValue& x) throw(SQLException, RuntimeException) 749 { 750 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateValue" ); 751 ::osl::MutexGuard aGuard( m_aMutex ); 752 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 753 754 checkIndex(columnIndex ); 755 columnIndex = mapColumn(columnIndex); 756 757 (m_aInsertRow->get())[columnIndex]->setBound(sal_True); 758 *(m_aInsertRow->get())[columnIndex] = x; 759 } 760 // ----------------------------------------------------------------------------- 761 762 void SAL_CALL OResultSet::updateNull( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 763 { 764 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateNull" ); 765 ORowSetValue aEmpty; 766 updateValue(columnIndex,aEmpty); 767 } 768 // ------------------------------------------------------------------------- 769 770 void SAL_CALL OResultSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw(SQLException, RuntimeException) 771 { 772 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateBoolean" ); 773 updateValue(columnIndex,x); 774 } 775 // ------------------------------------------------------------------------- 776 void SAL_CALL OResultSet::updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw(SQLException, RuntimeException) 777 { 778 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateByte" ); 779 updateValue(columnIndex,x); 780 } 781 // ------------------------------------------------------------------------- 782 783 void SAL_CALL OResultSet::updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw(SQLException, RuntimeException) 784 { 785 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateShort" ); 786 updateValue(columnIndex,x); 787 } 788 // ------------------------------------------------------------------------- 789 void SAL_CALL OResultSet::updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw(SQLException, RuntimeException) 790 { 791 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateInt" ); 792 updateValue(columnIndex,x); 793 } 794 // ------------------------------------------------------------------------- 795 void SAL_CALL OResultSet::updateLong( sal_Int32 /*columnIndex*/, sal_Int64 /*x*/ ) throw(SQLException, RuntimeException) 796 { 797 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateLong" ); 798 ::dbtools::throwFeatureNotImplementedException( "XRowUpdate::updateLong", *this ); 799 } 800 // ----------------------------------------------------------------------- 801 void SAL_CALL OResultSet::updateFloat( sal_Int32 columnIndex, float x ) throw(SQLException, RuntimeException) 802 { 803 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateFloat" ); 804 updateValue(columnIndex,x); 805 } 806 // ------------------------------------------------------------------------- 807 808 void SAL_CALL OResultSet::updateDouble( sal_Int32 columnIndex, double x ) throw(SQLException, RuntimeException) 809 { 810 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateDouble" ); 811 updateValue(columnIndex,x); 812 } 813 // ------------------------------------------------------------------------- 814 void SAL_CALL OResultSet::updateString( sal_Int32 columnIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException) 815 { 816 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateString" ); 817 updateValue(columnIndex,x); 818 } 819 // ------------------------------------------------------------------------- 820 void SAL_CALL OResultSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException) 821 { 822 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateBytes" ); 823 updateValue(columnIndex,x); 824 } 825 // ------------------------------------------------------------------------- 826 void SAL_CALL OResultSet::updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x ) throw(SQLException, RuntimeException) 827 { 828 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateDate" ); 829 updateValue(columnIndex,x); 830 } 831 // ------------------------------------------------------------------------- 832 833 void SAL_CALL OResultSet::updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x ) throw(SQLException, RuntimeException) 834 { 835 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateTime" ); 836 updateValue(columnIndex,x); 837 } 838 // ------------------------------------------------------------------------- 839 840 void SAL_CALL OResultSet::updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x ) throw(SQLException, RuntimeException) 841 { 842 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateTimestamp" ); 843 updateValue(columnIndex,x); 844 } 845 // ------------------------------------------------------------------------- 846 847 void SAL_CALL OResultSet::updateBinaryStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) 848 { 849 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateBinaryStream" ); 850 ::osl::MutexGuard aGuard( m_aMutex ); 851 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 852 853 if(!x.is()) 854 ::dbtools::throwFunctionSequenceException(*this); 855 856 Sequence<sal_Int8> aSeq; 857 x->readBytes(aSeq,length); 858 updateValue(columnIndex,aSeq); 859 } 860 // ------------------------------------------------------------------------- 861 void SAL_CALL OResultSet::updateCharacterStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) 862 { 863 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateCharacterStream" ); 864 updateBinaryStream(columnIndex,x,length); 865 } 866 // ------------------------------------------------------------------------- 867 void SAL_CALL OResultSet::refreshRow( ) throw(SQLException, RuntimeException) 868 { 869 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::refreshRow" ); 870 ::osl::MutexGuard aGuard( m_aMutex ); 871 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 872 } 873 // ------------------------------------------------------------------------- 874 void SAL_CALL OResultSet::updateObject( sal_Int32 columnIndex, const Any& x ) throw(SQLException, RuntimeException) 875 { 876 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateObject" ); 877 if (!::dbtools::implUpdateObject(this, columnIndex, x)) 878 throw SQLException(); 879 } 880 // ------------------------------------------------------------------------- 881 882 void SAL_CALL OResultSet::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 /*scale*/ ) throw(SQLException, RuntimeException) 883 { 884 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::updateNumericObject" ); 885 if (!::dbtools::implUpdateObject(this, columnIndex, x)) 886 throw SQLException(); 887 } 888 // ------------------------------------------------------------------------- 889 IPropertyArrayHelper* OResultSet::createArrayHelper( ) const 890 { 891 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::createArrayHelper" ); 892 Sequence< Property > aProps; 893 describeProperties(aProps); 894 return new ::cppu::OPropertyArrayHelper(aProps); 895 } 896 // ------------------------------------------------------------------------- 897 IPropertyArrayHelper & OResultSet::getInfoHelper() 898 { 899 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getInfoHelper" ); 900 return *const_cast<OResultSet*>(this)->getArrayHelper(); 901 } 902 903 //------------------------------------------------------------------ 904 sal_Bool OResultSet::ExecuteRow(IResultSetHelper::Movement eFirstCursorPosition, 905 sal_Int32 nFirstOffset, 906 sal_Bool bEvaluate, 907 sal_Bool bRetrieveData) 908 { 909 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::ExecuteRow" ); 910 OSL_ENSURE(m_pSQLAnalyzer,"OResultSet::ExecuteRow: Analyzer isn't set!"); 911 912 // Fuer weitere Fetch-Operationen werden diese Angaben ggf. veraendert ... 913 IResultSetHelper::Movement eCursorPosition = eFirstCursorPosition; 914 sal_Int32 nOffset = nFirstOffset; 915 916 const OSQLColumns & rTableCols = m_pTable->getTableColumns().getBody(); 917 sal_Bool bHasRestriction = m_pSQLAnalyzer->hasRestriction(); 918 again: 919 920 // protect from reading over the end when someboby is inserting while we are reading 921 // this method works only for dBase at the moment !!!! 922 if (eCursorPosition == IResultSetHelper::NEXT && m_nFilePos == m_nLastVisitedPos) 923 { 924 return sal_False; 925 } 926 927 if (!m_pTable || !m_pTable->seekRow(eCursorPosition, nOffset, m_nFilePos)) 928 { 929 return sal_False; 930 } 931 932 if (!bEvaluate) // Laeuft keine Auswertung, dann nur Ergebniszeile fuellen 933 { 934 m_pTable->fetchRow(m_aRow,rTableCols, sal_True,bRetrieveData); 935 } 936 else 937 { 938 m_pTable->fetchRow(m_aEvaluateRow, rTableCols, sal_True,bRetrieveData || bHasRestriction); 939 940 if ( ( !m_bShowDeleted 941 && m_aEvaluateRow->isDeleted() 942 ) 943 || ( bHasRestriction 944 && !m_pSQLAnalyzer->evaluateRestriction() 945 ) 946 ) 947 { // naechsten Satz auswerten 948 // aktuelle Zeile loeschen im Keyset 949 if (m_pEvaluationKeySet) 950 { 951 ++m_aEvaluateIter; 952 if (m_pEvaluationKeySet->end() != m_aEvaluateIter) 953 nOffset = (*m_aEvaluateIter); 954 else 955 { 956 return sal_False; 957 } 958 } 959 else if (m_pFileSet.isValid()) 960 { 961 OSL_ENSURE(//!m_pFileSet->IsFrozen() && 962 eCursorPosition == IResultSetHelper::NEXT, "Falsche CursorPosition!"); 963 eCursorPosition = IResultSetHelper::NEXT; 964 nOffset = 1; 965 } 966 else if (eCursorPosition == IResultSetHelper::FIRST || 967 eCursorPosition == IResultSetHelper::NEXT || 968 eCursorPosition == IResultSetHelper::ABSOLUTE) 969 { 970 eCursorPosition = IResultSetHelper::NEXT; 971 nOffset = 1; 972 } 973 else if (eCursorPosition == IResultSetHelper::LAST || 974 eCursorPosition == IResultSetHelper::PRIOR) 975 { 976 eCursorPosition = IResultSetHelper::PRIOR; 977 nOffset = 1; 978 } 979 else if (eCursorPosition == IResultSetHelper::RELATIVE) 980 { 981 eCursorPosition = (nOffset >= 0) ? IResultSetHelper::NEXT : IResultSetHelper::PRIOR; 982 } 983 else 984 { 985 // aStatus.Set(SQL_STAT_NO_DATA_FOUND); 986 return sal_False; 987 } 988 // Nochmal probieren ... 989 goto again; 990 } 991 } 992 993 // Evaluate darf nur gesetzt sein, 994 // wenn der Keyset weiter aufgebaut werden soll 995 if ( ( m_aSQLIterator.getStatementType() == SQL_STATEMENT_SELECT ) 996 && !isCount() 997 && bEvaluate 998 ) 999 { 1000 if (m_pSortIndex) 1001 { 1002 OKeyValue* pKeyValue = GetOrderbyKeyValue( m_aSelectRow ); 1003 m_pSortIndex->AddKeyValue(pKeyValue); 1004 } 1005 else if (m_pFileSet.isValid()) 1006 { 1007 // OSL_ENSURE(!m_pFileSet->IsFrozen() , "Falsche CursorPosition!"); 1008 sal_uInt32 nBookmarkValue = Abs((sal_Int32)(m_aEvaluateRow->get())[0]->getValue()); 1009 m_pFileSet->get().push_back(nBookmarkValue); 1010 } 1011 } 1012 else if (m_aSQLIterator.getStatementType() == SQL_STATEMENT_UPDATE) 1013 { 1014 sal_Bool bOK = sal_True; 1015 if (bEvaluate) 1016 { 1017 // jetzt die eigentliche Ergebniszeile Lesen 1018 bOK = m_pTable->fetchRow(m_aEvaluateRow, m_pTable->getTableColumns().getBody(), sal_True,sal_True); 1019 } 1020 1021 if (bOK) 1022 { 1023 // Nur die zu aendernden Werte uebergeben: 1024 if(!m_pTable->UpdateRow(m_aAssignValues.getBody(),m_aEvaluateRow,m_xColsIdx)) 1025 return sal_False; 1026 } 1027 } 1028 else if (m_aSQLIterator.getStatementType() == SQL_STATEMENT_DELETE) 1029 { 1030 sal_Bool bOK = sal_True; 1031 if (bEvaluate) 1032 { 1033 bOK = m_pTable->fetchRow(m_aEvaluateRow, m_pTable->getTableColumns().getBody(), sal_True,sal_True); 1034 } 1035 if (bOK) 1036 { 1037 if(!m_pTable->DeleteRow(m_xColumns.getBody())) 1038 return sal_False; 1039 } 1040 } 1041 return sal_True; 1042 } 1043 1044 //------------------------------------------------------------------- 1045 sal_Bool OResultSet::Move(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Bool bRetrieveData) 1046 { 1047 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::Move" ); 1048 1049 //IgnoreDeletedRows: 1050 // 1051 sal_Int32 nTempPos = m_nRowPos; 1052 // exclusiver zugriff auf die Tabelle 1053 // vos::OGuard* pGuard = m_pTable->Lock(); 1054 1055 if (m_aSQLIterator.getStatementType() == SQL_STATEMENT_SELECT && 1056 !isCount()) 1057 { 1058 if (!m_pFileSet.isValid()) // kein Index verfuegbar 1059 { 1060 // Normales FETCH 1061 ExecuteRow(eCursorPosition,nOffset,sal_False,bRetrieveData); 1062 1063 // now set the bookmark for outside this is the logical pos and not the file pos 1064 *(*m_aRow->get().begin()) = sal_Int32(m_nRowPos + 1); 1065 } 1066 else 1067 { 1068 switch(eCursorPosition) 1069 { 1070 case IResultSetHelper::NEXT: 1071 ++m_nRowPos; 1072 break; 1073 case IResultSetHelper::PRIOR: 1074 if (m_nRowPos >= 0) 1075 --m_nRowPos; 1076 break; 1077 case IResultSetHelper::FIRST: 1078 m_nRowPos = 0; 1079 break; 1080 case IResultSetHelper::LAST: 1081 // OSL_ENSURE(IsRowCountFinal(), "Fehler im Keyset!"); // muss eingefroren sein, sonst Fehler beim SQLCursor 1082 m_nRowPos = m_pFileSet->get().size() - 1; 1083 break; 1084 case IResultSetHelper::RELATIVE: 1085 m_nRowPos += nOffset; 1086 break; 1087 case IResultSetHelper::ABSOLUTE: 1088 case IResultSetHelper::BOOKMARK: 1089 if ( m_nRowPos == (nOffset -1) ) 1090 return sal_True; 1091 m_nRowPos = nOffset -1; 1092 break; 1093 } 1094 1095 // OffRange? 1096 // Der FileCursor ist ausserhalb des gueltigen Bereichs, wenn 1097 // a.) m_nRowPos < 1 1098 // b.) Ein KeySet besteht und m_nRowPos > m_pFileSet->size() 1099 if (m_nRowPos < 0 || (m_pFileSet->isFrozen() && eCursorPosition != IResultSetHelper::BOOKMARK && m_nRowPos >= (sal_Int32)m_pFileSet->get().size() )) // && m_pFileSet->IsFrozen() 1100 { 1101 // aStatus.Set(SQL_STAT_NO_DATA_FOUND); 1102 goto Error; 1103 } 1104 else 1105 { 1106 if (m_nRowPos < (sal_Int32)m_pFileSet->get().size()) 1107 { 1108 // Fetch ueber Index 1109 ExecuteRow(IResultSetHelper::BOOKMARK,(m_pFileSet->get())[m_nRowPos],sal_False,bRetrieveData); 1110 1111 // now set the bookmark for outside 1112 *(*m_aRow->get().begin()) = sal_Int32(m_nRowPos + 1); 1113 if ( (bRetrieveData || m_pSQLAnalyzer->hasRestriction()) && m_pSQLAnalyzer->hasFunctions() ) 1114 { 1115 m_pSQLAnalyzer->setSelectionEvaluationResult(m_aSelectRow,m_aColMapping); 1116 } 1117 } 1118 else // Index muss weiter aufgebaut werden 1119 { 1120 // Zunaechst auf die letzte bekannte Zeile setzen 1121 if (!m_pFileSet->get().empty()) 1122 { 1123 m_aFileSetIter = m_pFileSet->get().end()-1; 1124 // m_pFileSet->SeekPos(m_pFileSet->size()-1); 1125 m_pTable->seekRow(IResultSetHelper::BOOKMARK, *m_aFileSetIter, m_nFilePos); 1126 } 1127 sal_Bool bOK = sal_True; 1128 // Ermitteln der Anzahl weiterer Fetches 1129 while (bOK && m_nRowPos >= (sal_Int32)m_pFileSet->get().size()) 1130 { 1131 if (m_pEvaluationKeySet) 1132 { 1133 if (m_nRowPos >= (sal_Int32)m_pEvaluationKeySet->size()) 1134 return sal_False; 1135 // aStatus.Set(SQL_STAT_NO_DATA_FOUND); 1136 else if (m_nRowPos == 0) 1137 { 1138 m_aEvaluateIter = m_pEvaluationKeySet->begin(); 1139 bOK = ExecuteRow(IResultSetHelper::BOOKMARK,*m_aEvaluateIter,sal_True, bRetrieveData); 1140 } 1141 else 1142 { 1143 ++m_aEvaluateIter; 1144 bOK = ExecuteRow(IResultSetHelper::BOOKMARK,*m_aEvaluateIter,sal_True, bRetrieveData); 1145 } 1146 } 1147 else 1148 bOK = ExecuteRow(IResultSetHelper::NEXT,1,sal_True, sal_False);//bRetrieveData); 1149 } 1150 1151 if (bOK) 1152 { 1153 // jetzt nochmal die Ergebnisse lesen 1154 m_pTable->fetchRow(m_aRow, m_pTable->getTableColumns().getBody(), sal_True,bRetrieveData); 1155 1156 // now set the bookmark for outside 1157 *(*m_aRow->get().begin()) = sal_Int32(m_nRowPos + 1); 1158 1159 if ( (bRetrieveData || m_pSQLAnalyzer->hasRestriction()) && m_pSQLAnalyzer->hasFunctions() ) 1160 { 1161 m_pSQLAnalyzer->setSelectionEvaluationResult(m_aSelectRow,m_aColMapping); 1162 } 1163 } 1164 else if (!m_pFileSet->isFrozen()) // keinen gueltigen Satz gefunden 1165 { 1166 //m_pFileSet->Freeze(); 1167 m_pFileSet->setFrozen(); 1168 1169 // DELETEZ(m_pEvaluationKeySet); 1170 m_pEvaluationKeySet = NULL; 1171 // aStatus.Set(SQL_STAT_NO_DATA_FOUND); 1172 goto Error; 1173 } 1174 } 1175 } 1176 } 1177 } 1178 else if (m_aSQLIterator.getStatementType() == SQL_STATEMENT_SELECT && isCount()) 1179 { 1180 // Fetch des COUNT(*) 1181 switch (eCursorPosition) 1182 { 1183 case IResultSetHelper::NEXT: 1184 ++m_nRowPos; 1185 break; 1186 case IResultSetHelper::PRIOR: 1187 --m_nRowPos; 1188 break; 1189 case IResultSetHelper::FIRST: 1190 m_nRowPos = 0; 1191 break; 1192 case IResultSetHelper::LAST: 1193 m_nRowPos = 0; 1194 break; 1195 case IResultSetHelper::RELATIVE: 1196 m_nRowPos += nOffset; 1197 break; 1198 case IResultSetHelper::ABSOLUTE: 1199 case IResultSetHelper::BOOKMARK: 1200 m_nRowPos = nOffset - 1; 1201 break; 1202 } 1203 1204 if ( m_nRowPos < 0 ) 1205 goto Error; 1206 else if (m_nRowPos == 0) 1207 { 1208 // COUNT(*) in Ergebnisrow packen 1209 // (muss die erste und einzige Variable in der Row sein) 1210 if (m_aRow->get().size() >= 2) 1211 { 1212 *(m_aRow->get())[1] = m_nRowCountResult; 1213 *(m_aRow->get())[0] = sal_Int32(1); 1214 (m_aRow->get())[1]->setBound(sal_True); 1215 (m_aSelectRow->get())[1] = (m_aRow->get())[1]; 1216 } 1217 } 1218 else 1219 { 1220 m_bEOF = sal_True; 1221 m_nRowPos = 1; 1222 return sal_False; 1223 } 1224 } 1225 else 1226 // Fetch nur bei SELECT moeglich! 1227 return sal_False; 1228 1229 return sal_True; 1230 1231 Error: 1232 // steht der Cursor vor dem ersten Satz 1233 // dann wird die position beibehalten 1234 if (nTempPos == -1) 1235 m_nRowPos = nTempPos; 1236 else 1237 { 1238 switch(eCursorPosition) 1239 { 1240 case IResultSetHelper::PRIOR: 1241 case IResultSetHelper::FIRST: 1242 m_nRowPos = -1; 1243 break; 1244 case IResultSetHelper::LAST: 1245 case IResultSetHelper::NEXT: 1246 case IResultSetHelper::ABSOLUTE: 1247 case IResultSetHelper::RELATIVE: 1248 if (nOffset > 0) 1249 m_nRowPos = m_pFileSet.isValid() ? (sal_Int32)m_pFileSet->get().size() : -1; 1250 else if (nOffset < 0) 1251 m_nRowPos = -1; 1252 break; 1253 case IResultSetHelper::BOOKMARK: 1254 m_nRowPos = nTempPos; // vorherige Position 1255 } 1256 } 1257 // delete pGuard; 1258 // rMode = (!bShowDeleted && aStatus.IsSuccessful() && m_aRow->isDeleted()) ? // keine Anzeige von geloeschten Saetzen 1259 // OCursor::SQL_MOD_INVALID : OCursor::SQL_MOD_NONE; 1260 return sal_False; 1261 } 1262 // ------------------------------------------------------------------------- 1263 void OResultSet::sortRows() 1264 { 1265 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::sortRows" ); 1266 if (!m_pSQLAnalyzer->hasRestriction() && m_aOrderbyColumnNumber.size() == 1) 1267 { 1268 // Ist nur ein Feld fuer die Sortierung angegeben 1269 // Und diese Feld ist indiziert, dann den Index ausnutzen 1270 Reference<XIndexesSupplier> xIndexSup; 1271 m_pTable->queryInterface(::getCppuType((const Reference<XIndexesSupplier>*)0)) >>= xIndexSup; 1272 // Reference<XIndexesSupplier> xIndexSup(m_pTable,UNO_QUERY); 1273 Reference<XIndexAccess> xIndexes; 1274 if(xIndexSup.is()) 1275 { 1276 xIndexes.set(xIndexSup->getIndexes(),UNO_QUERY); 1277 Reference<XPropertySet> xColProp; 1278 if(m_aOrderbyColumnNumber[0] < xIndexes->getCount()) 1279 { 1280 xColProp.set(xIndexes->getByIndex(m_aOrderbyColumnNumber[0]),UNO_QUERY); 1281 // iterate through the indexes to find the matching column 1282 const sal_Int32 nCount = xIndexes->getCount(); 1283 for(sal_Int32 i=0; i < nCount;++i) 1284 { 1285 Reference<XColumnsSupplier> xIndex(xIndexes->getByIndex(i),UNO_QUERY); 1286 Reference<XNameAccess> xIndexCols = xIndex->getColumns(); 1287 if(xIndexCols->hasByName(comphelper::getString(xColProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME))))) 1288 { 1289 m_pFileSet = new OKeySet(); 1290 1291 if(fillIndexValues(xIndex)) 1292 return; 1293 } 1294 } 1295 } 1296 } 1297 } 1298 1299 OSortIndex::TKeyTypeVector eKeyType(m_aOrderbyColumnNumber.size()); 1300 ::std::vector<sal_Int32>::iterator aOrderByIter = m_aOrderbyColumnNumber.begin(); 1301 for (::std::vector<sal_Int16>::size_type i=0;aOrderByIter != m_aOrderbyColumnNumber.end(); ++aOrderByIter,++i) 1302 { 1303 OSL_ENSURE((sal_Int32)m_aSelectRow->get().size() > *aOrderByIter,"Invalid Index"); 1304 switch ((*(m_aSelectRow->get().begin()+*aOrderByIter))->getValue().getTypeKind()) 1305 { 1306 case DataType::CHAR: 1307 case DataType::VARCHAR: 1308 case DataType::LONGVARCHAR: 1309 eKeyType[i] = SQL_ORDERBYKEY_STRING; 1310 break; 1311 1312 case DataType::OTHER: 1313 case DataType::TINYINT: 1314 case DataType::SMALLINT: 1315 case DataType::INTEGER: 1316 case DataType::DECIMAL: 1317 case DataType::NUMERIC: 1318 case DataType::REAL: 1319 case DataType::DOUBLE: 1320 case DataType::DATE: 1321 case DataType::TIME: 1322 case DataType::TIMESTAMP: 1323 case DataType::BIT: 1324 eKeyType[i] = SQL_ORDERBYKEY_DOUBLE; 1325 break; 1326 1327 // Andere Typen sind nicht implementiert (und damit immer sal_False) 1328 default: 1329 eKeyType[i] = SQL_ORDERBYKEY_NONE; 1330 OSL_ASSERT("OFILECursor::Execute: Datentyp nicht implementiert"); 1331 break; 1332 } 1333 (m_aSelectRow->get())[*aOrderByIter]->setBound(sal_True); 1334 } 1335 1336 m_pSortIndex = new OSortIndex(eKeyType,m_aOrderbyAscending); 1337 1338 if (m_pEvaluationKeySet) 1339 { 1340 m_aEvaluateIter = m_pEvaluationKeySet->begin(); 1341 1342 while (m_aEvaluateIter != m_pEvaluationKeySet->end()) 1343 { 1344 ExecuteRow(IResultSetHelper::BOOKMARK,(*m_aEvaluateIter),sal_True); 1345 ++m_aEvaluateIter; 1346 } 1347 } 1348 else 1349 { 1350 while ( ExecuteRow( IResultSetHelper::NEXT, 1, sal_False, sal_True ) ) 1351 { 1352 m_aSelectRow->get()[0]->setValue( m_aRow->get()[0]->getValue() ); 1353 if ( m_pSQLAnalyzer->hasFunctions() ) 1354 m_pSQLAnalyzer->setSelectionEvaluationResult( m_aSelectRow, m_aColMapping ); 1355 const sal_Int32 nBookmark = (*m_aRow->get().begin())->getValue(); 1356 ExecuteRow( IResultSetHelper::BOOKMARK, nBookmark, sal_True, sal_False ); 1357 } 1358 } 1359 1360 // Sortiertes Keyset erzeugen 1361 // DELETEZ(m_pEvaluationKeySet); 1362 m_pEvaluationKeySet = NULL; 1363 m_pFileSet = NULL; 1364 m_pFileSet = m_pSortIndex->CreateKeySet(); 1365 // if(!bDistinct) 1366 // SetRowCount(pFileSet->count()); 1367 DELETEZ(m_pSortIndex); 1368 // Nun kann ueber den Index sortiert zugegriffen werden. 1369 } 1370 1371 1372 // ------------------------------------------------------------------------- 1373 sal_Bool OResultSet::OpenImpl() 1374 { 1375 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::OpenImpl" ); 1376 OSL_ENSURE(m_pSQLAnalyzer,"No analyzer set with setSqlAnalyzer!"); 1377 if(!m_pTable) 1378 { 1379 const OSQLTables& xTabs = m_aSQLIterator.getTables(); 1380 if ((xTabs.begin() == xTabs.end()) || !xTabs.begin()->second.is()) 1381 lcl_throwError(STR_QUERY_TOO_COMPLEX,*this); 1382 1383 if ( xTabs.size() > 1 || m_aSQLIterator.hasErrors() ) 1384 lcl_throwError(STR_QUERY_MORE_TABLES,*this); 1385 1386 OSQLTable xTable = xTabs.begin()->second; 1387 m_xColumns = m_aSQLIterator.getSelectColumns(); 1388 1389 m_xColNames = xTable->getColumns(); 1390 m_xColsIdx.set(m_xColNames,UNO_QUERY); 1391 doTableSpecials(xTable); 1392 Reference<XComponent> xComp(xTable,UNO_QUERY); 1393 if(xComp.is()) 1394 xComp->addEventListener(this); 1395 } 1396 1397 m_pTable->refreshHeader(); 1398 1399 sal_Int32 nColumnCount = m_xColsIdx->getCount(); 1400 1401 initializeRow(m_aRow,nColumnCount); 1402 initializeRow(m_aEvaluateRow,nColumnCount); 1403 initializeRow(m_aInsertRow,nColumnCount); 1404 1405 1406 m_nResultSetConcurrency = (m_pTable->isReadOnly() || isCount()) ? ResultSetConcurrency::READ_ONLY : ResultSetConcurrency::UPDATABLE; 1407 1408 // Neuen Index aufbauen: 1409 m_pFileSet = NULL; 1410 // DELETEZ(m_pEvaluationKeySet); 1411 1412 // An den Anfang positionieren 1413 m_nRowPos = -1; 1414 m_nFilePos = 0; 1415 m_nRowCountResult = -1; 1416 1417 // exclusiver zugriff auf die Tabelle 1418 // vos::OGuard* pGuard = pTable->Lock(); 1419 m_nLastVisitedPos = m_pTable->getCurrentLastPos(); 1420 1421 switch(m_aSQLIterator.getStatementType()) 1422 { 1423 case SQL_STATEMENT_SELECT: 1424 { 1425 if(isCount()) 1426 { 1427 if(m_xColumns->get().size() > 1) 1428 lcl_throwError(STR_QUERY_COMPLEX_COUNT,*this); 1429 1430 m_nRowCountResult = 0; 1431 // Vorlaeufig einfach ueber alle Datensaetze iterieren und 1432 // dabei die Aktionen bearbeiten (bzw. einfach nur zaehlen): 1433 { 1434 sal_Bool bOK = sal_True; 1435 if (m_pEvaluationKeySet) 1436 { 1437 m_aEvaluateIter = m_pEvaluationKeySet->begin(); 1438 bOK = m_aEvaluateIter == m_pEvaluationKeySet->end(); 1439 1440 } 1441 while (bOK) 1442 { 1443 if (m_pEvaluationKeySet) 1444 ExecuteRow(IResultSetHelper::BOOKMARK,(*m_aEvaluateIter),sal_True); 1445 else 1446 bOK = ExecuteRow(IResultSetHelper::NEXT,1,sal_True); 1447 1448 if (bOK) 1449 { 1450 m_nRowCountResult++; 1451 if(m_pEvaluationKeySet) 1452 { 1453 ++m_aEvaluateIter; 1454 bOK = m_aEvaluateIter == m_pEvaluationKeySet->end(); 1455 } 1456 } 1457 } 1458 1459 // Ergebnis von COUNT(*) in m_nRowCountResult merken. 1460 // nRowCount, also die Anzahl der Rows in der Ergebnismenge, ist bei dieser 1461 // Anfrage = 1! 1462 m_pEvaluationKeySet = NULL; 1463 // DELETEZ(m_pEvaluationKeySet); 1464 } 1465 } 1466 else 1467 { 1468 sal_Bool bDistinct = sal_False; 1469 sal_Bool bWasSorted = sal_False; 1470 OSQLParseNode *pDistinct = m_pParseTree->getChild(1); 1471 ::std::vector<sal_Int32> aOrderbyColumnNumberSave; 1472 ::std::vector<TAscendingOrder> aOrderbyAscendingSave; 1473 1474 if (pDistinct && pDistinct->getTokenID() == SQL_TOKEN_DISTINCT ) 1475 { 1476 // Sort on all columns, saving original order for later 1477 if(IsSorted()) 1478 { 1479 aOrderbyColumnNumberSave = m_aOrderbyColumnNumber;// .assign(m_aOrderbyColumnNumber.begin(), m_aOrderbyColumnNumber.end()); 1480 m_aOrderbyColumnNumber.clear(); 1481 aOrderbyAscendingSave.assign(m_aOrderbyAscending.begin(), m_aOrderbyAscending.end()); 1482 bWasSorted = sal_True; 1483 } 1484 1485 // the first column is the bookmark column 1486 ::std::vector<sal_Int32>::iterator aColStart = (m_aColMapping.begin()+1); 1487 ::std::copy(aColStart, m_aColMapping.end(),::std::back_inserter(m_aOrderbyColumnNumber)); 1488 // m_aOrderbyColumnNumber.assign(aColStart, m_aColMapping.end()); 1489 m_aOrderbyAscending.assign(m_aColMapping.size()-1, SQL_ASC); 1490 bDistinct = sal_True; 1491 } 1492 1493 if (IsSorted()) 1494 sortRows(); 1495 1496 if (!m_pFileSet.isValid()) 1497 { 1498 m_pFileSet = new OKeySet(); 1499 1500 if (!m_pSQLAnalyzer->hasRestriction()) 1501 // jetzt kann das Keyset schon gefuellt werden! 1502 // Aber Achtung: es wird davon ausgegangen, das die FilePositionen als Folge 1..n 1503 // abgelegt werden! 1504 { 1505 if ( m_nLastVisitedPos > 0) 1506 m_pFileSet->get().reserve( m_nLastVisitedPos ); 1507 for (sal_Int32 i = 0; i < m_nLastVisitedPos; i++) 1508 m_pFileSet->get().push_back(i + 1); 1509 } 1510 } 1511 OSL_ENSURE(m_pFileSet.isValid(),"Kein KeySet vorhanden! :-("); 1512 1513 if(bDistinct && m_pFileSet.isValid()) // sicher ist sicher 1514 { 1515 OValueRow aSearchRow = new OValueVector(m_aRow->get().size()); 1516 OValueRefVector::Vector::iterator aRowIter = m_aRow->get().begin(); 1517 OValueVector::Vector::iterator aSearchIter = aSearchRow->get().begin(); 1518 for ( ++aRowIter,++aSearchIter; // the first column is the bookmark column 1519 aRowIter != m_aRow->get().end(); 1520 ++aRowIter,++aSearchIter) 1521 aSearchIter->setBound((*aRowIter)->isBound()); 1522 1523 size_t nMaxRow = m_pFileSet->get().size(); 1524 1525 if (nMaxRow) 1526 { 1527 #if OSL_DEBUG_LEVEL > 1 1528 sal_Int32 nFound=0; 1529 #endif 1530 sal_Int32 nPos; 1531 sal_Int32 nKey; 1532 1533 for( size_t j = nMaxRow-1; j > 0; --j) 1534 { 1535 nPos = (m_pFileSet->get())[j]; 1536 ExecuteRow(IResultSetHelper::BOOKMARK,nPos,sal_False); 1537 m_pSQLAnalyzer->setSelectionEvaluationResult(m_aSelectRow,m_aColMapping); 1538 { // copy row values 1539 OValueRefVector::Vector::iterator copyFrom = m_aSelectRow->get().begin(); 1540 OValueVector::Vector::iterator copyTo = aSearchRow->get().begin(); 1541 for ( ++copyFrom,++copyTo; // the first column is the bookmark column 1542 copyFrom != m_aSelectRow->get().end(); 1543 ++copyFrom,++copyTo) 1544 *copyTo = *(*copyFrom); 1545 // *aSearchRow = *m_aRow; 1546 } 1547 1548 // compare with next row 1549 nKey = (m_pFileSet->get())[j-1]; 1550 ExecuteRow(IResultSetHelper::BOOKMARK,nKey,sal_False); 1551 m_pSQLAnalyzer->setSelectionEvaluationResult(m_aSelectRow,m_aColMapping); 1552 OValueRefVector::Vector::iterator loopInRow = m_aSelectRow->get().begin(); 1553 OValueVector::Vector::iterator existentInSearchRow = aSearchRow->get().begin(); 1554 for ( ++loopInRow,++existentInSearchRow; // the first column is the bookmark column 1555 loopInRow != m_aSelectRow->get().end(); 1556 ++loopInRow,++existentInSearchRow) 1557 { 1558 if ( (*loopInRow)->isBound() && !( *(*loopInRow) == *existentInSearchRow) ) 1559 break; 1560 } 1561 1562 if(loopInRow == m_aSelectRow->get().end()) 1563 (m_pFileSet->get())[j] = 0; // Rows match -- Mark for deletion by setting key to 0 1564 #if OSL_DEBUG_LEVEL > 1 1565 else 1566 nFound++; 1567 #endif 1568 } 1569 1570 m_pFileSet->get().erase(::std::remove_if(m_pFileSet->get().begin(),m_pFileSet->get().end(), 1571 ::std::bind2nd(::std::equal_to<sal_Int32>(),0)) 1572 ,m_pFileSet->get().end()); 1573 1574 if (bWasSorted) 1575 { 1576 // Re-sort on original requested order 1577 m_aOrderbyColumnNumber = aOrderbyColumnNumberSave; 1578 m_aOrderbyAscending.assign(aOrderbyAscendingSave.begin(), aOrderbyAscendingSave.end()); 1579 1580 TIntVector aEvaluationKeySet(m_pFileSet->get()); 1581 m_pEvaluationKeySet = &aEvaluationKeySet; 1582 sortRows(); 1583 } 1584 else 1585 { 1586 m_aOrderbyColumnNumber.clear(); 1587 m_aOrderbyAscending.clear(); 1588 ::std::sort(m_pFileSet->get().begin(),m_pFileSet->get().end()); 1589 } 1590 } 1591 // SetRowCount(m_pFileSet->count()); 1592 } 1593 } 1594 } break; 1595 1596 case SQL_STATEMENT_UPDATE: 1597 case SQL_STATEMENT_DELETE: 1598 // waehrend der Bearbeitung die Anzahl der bearbeiteten Rows zaehlen: 1599 m_nRowCountResult = 0; 1600 // Vorlaeufig einfach ueber alle Datensaetze iterieren und 1601 // dabei die Aktionen bearbeiten (bzw. einfach nur zaehlen): 1602 { 1603 1604 sal_Bool bOK = sal_True; 1605 if (m_pEvaluationKeySet) 1606 { 1607 m_aEvaluateIter = m_pEvaluationKeySet->begin(); 1608 bOK = m_aEvaluateIter == m_pEvaluationKeySet->end(); 1609 1610 } 1611 while (bOK) 1612 { 1613 if (m_pEvaluationKeySet) 1614 ExecuteRow(IResultSetHelper::BOOKMARK,(*m_aEvaluateIter),sal_True); 1615 else 1616 bOK = ExecuteRow(IResultSetHelper::NEXT,1,sal_True); 1617 1618 if (bOK) 1619 { 1620 m_nRowCountResult++; 1621 if(m_pEvaluationKeySet) 1622 { 1623 ++m_aEvaluateIter; 1624 bOK = m_aEvaluateIter == m_pEvaluationKeySet->end(); 1625 } 1626 } 1627 } 1628 1629 // Ergebnis von COUNT(*) in nRowCountResult merken. 1630 // nRowCount, also die Anzahl der Rows in der Ergebnismenge, ist bei dieser 1631 // Anfrage = 1! 1632 // DELETEZ(m_pEvaluationKeySet); 1633 m_pEvaluationKeySet = NULL; 1634 } 1635 // SetRowCount(1); 1636 break; 1637 case SQL_STATEMENT_INSERT: 1638 m_nRowCountResult = 0; 1639 1640 OSL_ENSURE(m_aAssignValues.isValid(),"No assign values set!"); 1641 if(!m_pTable->InsertRow(m_aAssignValues.getBody(), sal_True,m_xColsIdx)) 1642 { 1643 m_nFilePos = 0; 1644 return sal_False; 1645 } 1646 1647 m_nRowCountResult = 1; 1648 break; 1649 default: 1650 OSL_ENSURE( false, "OResultSet::OpenImpl: unsupported statement type!" ); 1651 break; 1652 } 1653 1654 // FilePos zuruecksetzen 1655 m_nFilePos = 0; 1656 1657 return sal_True; 1658 } 1659 //-------------------------------------------------------------------------- 1660 Sequence< sal_Int8 > OResultSet::getUnoTunnelImplementationId() 1661 { 1662 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getUnoTunnelImplementationId" ); 1663 static ::cppu::OImplementationId * pId = 0; 1664 if (! pId) 1665 { 1666 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 1667 if (! pId) 1668 { 1669 static ::cppu::OImplementationId aId; 1670 pId = &aId; 1671 } 1672 } 1673 return pId->getImplementationId(); 1674 } 1675 1676 // com::sun::star::lang::XUnoTunnel 1677 //------------------------------------------------------------------ 1678 sal_Int64 OResultSet::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException) 1679 { 1680 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getSomething" ); 1681 return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) ) 1682 ? reinterpret_cast< sal_Int64 >( this ) 1683 : 0; 1684 } 1685 // ----------------------------------------------------------------------------- 1686 void OResultSet::setBoundedColumns(const OValueRefRow& _rRow, 1687 const OValueRefRow& _rSelectRow, 1688 const ::vos::ORef<connectivity::OSQLColumns>& _rxColumns, 1689 const Reference<XIndexAccess>& _xNames, 1690 sal_Bool _bSetColumnMapping, 1691 const Reference<XDatabaseMetaData>& _xMetaData, 1692 ::std::vector<sal_Int32>& _rColMapping) 1693 { 1694 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::setBoundedColumns" ); 1695 ::comphelper::UStringMixEqual aCase(_xMetaData->supportsMixedCaseQuotedIdentifiers()); 1696 1697 Reference<XPropertySet> xTableColumn; 1698 ::rtl::OUString sTableColumnName, sSelectColumnRealName; 1699 1700 const ::rtl::OUString sName = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME); 1701 const ::rtl::OUString sRealName = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME); 1702 const ::rtl::OUString sType = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE); 1703 1704 typedef ::std::map<OSQLColumns::Vector::iterator,sal_Bool> IterMap; 1705 IterMap aSelectIters; 1706 OValueRefVector::Vector::iterator aRowIter = _rRow->get().begin()+1; 1707 for (sal_Int32 i=0; // the first column is the bookmark column 1708 aRowIter != _rRow->get().end(); 1709 ++i, ++aRowIter 1710 ) 1711 { 1712 (*aRowIter)->setBound(sal_False); 1713 try 1714 { 1715 // get the table column and it's name 1716 _xNames->getByIndex(i) >>= xTableColumn; 1717 OSL_ENSURE(xTableColumn.is(), "OResultSet::setBoundedColumns: invalid table column!"); 1718 if (xTableColumn.is()) 1719 xTableColumn->getPropertyValue(sName) >>= sTableColumnName; 1720 else 1721 sTableColumnName = ::rtl::OUString(); 1722 1723 // look if we have such a select column 1724 // TODO: would like to have a O(log n) search here ... 1725 for ( OSQLColumns::Vector::iterator aIter = _rxColumns->get().begin(); 1726 aIter != _rxColumns->get().end(); 1727 ++aIter 1728 ) 1729 { 1730 if((*aIter)->getPropertySetInfo()->hasPropertyByName(sRealName)) 1731 (*aIter)->getPropertyValue(sRealName) >>= sSelectColumnRealName; 1732 else 1733 (*aIter)->getPropertyValue(sName) >>= sSelectColumnRealName; 1734 1735 if ( aCase(sTableColumnName, sSelectColumnRealName) && !(*aRowIter)->isBound() && aSelectIters.end() == aSelectIters.find(aIter) ) 1736 { 1737 aSelectIters.insert(IterMap::value_type(aIter,sal_True)); 1738 if(_bSetColumnMapping) 1739 { 1740 sal_Int32 nSelectColumnPos = aIter - _rxColumns->get().begin() + 1; 1741 // the getXXX methods are 1-based ... 1742 sal_Int32 nTableColumnPos = i + 1; 1743 // get first table column is the bookmark column ... 1744 _rColMapping[nSelectColumnPos] = nTableColumnPos; 1745 (_rSelectRow->get())[nSelectColumnPos] = *aRowIter; 1746 } 1747 1748 (*aRowIter)->setBound(sal_True); 1749 sal_Int32 nType = DataType::OTHER; 1750 if (xTableColumn.is()) 1751 xTableColumn->getPropertyValue(sType) >>= nType; 1752 (*aRowIter)->setTypeKind(nType); 1753 1754 break; 1755 } 1756 } 1757 } 1758 catch (Exception&) 1759 { 1760 OSL_ENSURE(sal_False, "OResultSet::setBoundedColumns: caught an Exception!"); 1761 } 1762 } 1763 // in this case we got more select columns as columns exist in the table 1764 if ( _bSetColumnMapping && aSelectIters.size() != _rColMapping.size() ) 1765 { 1766 Reference<XNameAccess> xNameAccess(_xNames,UNO_QUERY); 1767 Sequence< ::rtl::OUString > aSelectColumns = xNameAccess->getElementNames(); 1768 1769 for ( OSQLColumns::Vector::iterator aIter = _rxColumns->get().begin(); 1770 aIter != _rxColumns->get().end(); 1771 ++aIter 1772 ) 1773 { 1774 if ( aSelectIters.end() == aSelectIters.find(aIter) ) 1775 { 1776 if ( (*aIter)->getPropertySetInfo()->hasPropertyByName(sRealName) ) 1777 (*aIter)->getPropertyValue(sRealName) >>= sSelectColumnRealName; 1778 else 1779 (*aIter)->getPropertyValue(sName) >>= sSelectColumnRealName; 1780 1781 if ( xNameAccess->hasByName( sSelectColumnRealName ) ) 1782 { 1783 aSelectIters.insert(IterMap::value_type(aIter,sal_True)); 1784 sal_Int32 nSelectColumnPos = aIter - _rxColumns->get().begin() + 1; 1785 const ::rtl::OUString* pBegin = aSelectColumns.getConstArray(); 1786 const ::rtl::OUString* pEnd = pBegin + aSelectColumns.getLength(); 1787 for(sal_Int32 i=0;pBegin != pEnd;++pBegin,++i) 1788 { 1789 if ( aCase(*pBegin, sSelectColumnRealName) ) 1790 { 1791 // the getXXX methods are 1-based ... 1792 sal_Int32 nTableColumnPos = i + 1; 1793 // get first table column is the bookmark column ... 1794 _rColMapping[nSelectColumnPos] = nTableColumnPos; 1795 (_rSelectRow->get())[nSelectColumnPos] = (_rRow->get())[nTableColumnPos]; 1796 break; 1797 } 1798 } 1799 } 1800 } 1801 } 1802 } 1803 } 1804 // ----------------------------------------------------------------------------- 1805 void SAL_CALL OResultSet::acquire() throw() 1806 { 1807 OResultSet_BASE::acquire(); 1808 } 1809 // ----------------------------------------------------------------------------- 1810 void SAL_CALL OResultSet::release() throw() 1811 { 1812 OResultSet_BASE::release(); 1813 } 1814 // ----------------------------------------------------------------------------- 1815 Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OResultSet::getPropertySetInfo( ) throw(RuntimeException) 1816 { 1817 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getPropertySetInfo" ); 1818 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper()); 1819 } 1820 // ----------------------------------------------------------------------------- 1821 void OResultSet::doTableSpecials(const OSQLTable& _xTable) 1822 { 1823 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::doTableSpecials" ); 1824 Reference< ::com::sun::star::lang::XUnoTunnel> xTunnel(_xTable,UNO_QUERY); 1825 if(xTunnel.is()) 1826 { 1827 m_pTable = reinterpret_cast< OFileTable* >( xTunnel->getSomething(OFileTable::getUnoTunnelImplementationId()) ); 1828 if(m_pTable) 1829 m_pTable->acquire(); 1830 } 1831 } 1832 // ----------------------------------------------------------------------------- 1833 void OResultSet::clearInsertRow() 1834 { 1835 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::clearInsertRow" ); 1836 m_aRow->setDeleted(sal_False); // set to false here because this is the new row 1837 OValueRefVector::Vector::iterator aIter = m_aInsertRow->get().begin(); 1838 const OValueRefVector::Vector::iterator aEnd = m_aInsertRow->get().end(); 1839 for(sal_Int32 nPos = 0;aIter != aEnd;++aIter,++nPos) 1840 { 1841 ORowSetValueDecoratorRef& rValue = (*aIter); 1842 if ( rValue->isBound() ) 1843 { 1844 (m_aRow->get())[nPos]->setValue( (*aIter)->getValue() ); 1845 } 1846 rValue->setBound(nPos == 0); 1847 rValue->setModified(sal_False); 1848 rValue->setNull(); 1849 } 1850 } 1851 // ----------------------------------------------------------------------------- 1852 void OResultSet::initializeRow(OValueRefRow& _rRow,sal_Int32 _nColumnCount) 1853 { 1854 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::initializeRow" ); 1855 if(!_rRow.isValid()) 1856 { 1857 _rRow = new OValueRefVector(_nColumnCount); 1858 (_rRow->get())[0]->setBound(sal_True); 1859 ::std::for_each(_rRow->get().begin()+1,_rRow->get().end(),TSetRefBound(sal_False)); 1860 } 1861 } 1862 // ----------------------------------------------------------------------------- 1863 sal_Bool OResultSet::fillIndexValues(const Reference< XColumnsSupplier> &/*_xIndex*/) 1864 { 1865 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::fillIndexValues" ); 1866 return sal_False; 1867 } 1868 // ----------------------------------------------------------------------------- 1869 sal_Bool OResultSet::move(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool _bRetrieveData) 1870 { 1871 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::move" ); 1872 return Move(_eCursorPosition,_nOffset,_bRetrieveData); 1873 } 1874 // ----------------------------------------------------------------------------- 1875 sal_Int32 OResultSet::getDriverPos() const 1876 { 1877 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::getDriverPos" ); 1878 return (m_aRow->get())[0]->getValue(); 1879 } 1880 // ----------------------------------------------------------------------------- 1881 sal_Bool OResultSet::deletedVisible() const 1882 { 1883 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::deletedVisible" ); 1884 return m_bShowDeleted; 1885 } 1886 // ----------------------------------------------------------------------------- 1887 sal_Bool OResultSet::isRowDeleted() const 1888 { 1889 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::isRowDeleted" ); 1890 return m_aRow->isDeleted(); 1891 } 1892 // ----------------------------------------------------------------------------- 1893 void SAL_CALL OResultSet::disposing( const EventObject& Source ) throw (RuntimeException) 1894 { 1895 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OResultSet::disposing" ); 1896 // Reference<XInterface> xInt = m_pTable; 1897 Reference<XPropertySet> xProp = m_pTable; 1898 if(m_pTable && Source.Source == xProp) 1899 { 1900 m_pTable->release(); 1901 m_pTable = NULL; 1902 } 1903 } 1904 // ----------------------------------------------------------------------------- 1905