1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_connectivity.hxx" 26 #include "odbc/OResultSet.hxx" 27 #include "odbc/OTools.hxx" 28 #include "odbc/OResultSetMetaData.hxx" 29 #include <com/sun/star/sdbc/DataType.hpp> 30 #include <com/sun/star/beans/PropertyAttribute.hpp> 31 #include <com/sun/star/sdbcx/CompareBookmark.hpp> 32 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp> 33 #include <com/sun/star/sdbc/FetchDirection.hpp> 34 #include <com/sun/star/sdbc/ResultSetType.hpp> 35 #include <comphelper/property.hxx> 36 #include <comphelper/sequence.hxx> 37 #include <cppuhelper/typeprovider.hxx> 38 #include <comphelper/extract.hxx> 39 #include <com/sun/star/lang/DisposedException.hpp> 40 #include <comphelper/types.hxx> 41 #include "connectivity/dbtools.hxx" 42 #include "connectivity/dbexception.hxx" 43 #include "diagnose_ex.h" 44 #include <rtl/logfile.hxx> 45 46 using namespace ::comphelper; 47 using namespace connectivity; 48 using namespace connectivity::odbc; 49 using namespace cppu; 50 using namespace com::sun::star::uno; 51 using namespace com::sun::star::lang; 52 using namespace com::sun::star::beans; 53 using namespace com::sun::star::sdbc; 54 using namespace com::sun::star::sdbcx; 55 using namespace com::sun::star::container; 56 using namespace com::sun::star::io; 57 using namespace com::sun::star::util; 58 59 #define ODBC_SQL_NOT_DEFINED 99UL 60 61 //------------------------------------------------------------------------------ 62 // IMPLEMENT_SERVICE_INFO(OResultSet,"com.sun.star.sdbcx.OResultSet","com.sun.star.sdbc.ResultSet"); 63 ::rtl::OUString SAL_CALL OResultSet::getImplementationName( ) throw ( RuntimeException) 64 { 65 return ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.odbc.ResultSet"); 66 } 67 // ------------------------------------------------------------------------- 68 Sequence< ::rtl::OUString > SAL_CALL OResultSet::getSupportedServiceNames( ) throw( RuntimeException) 69 { 70 Sequence< ::rtl::OUString > aSupported(2); 71 aSupported[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbc.ResultSet"); 72 aSupported[1] = ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.ResultSet"); 73 return aSupported; 74 } 75 // ------------------------------------------------------------------------- 76 sal_Bool SAL_CALL OResultSet::supportsService( const ::rtl::OUString& _rServiceName ) throw( RuntimeException) 77 { 78 Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames()); 79 const ::rtl::OUString* pSupported = aSupported.getConstArray(); 80 const ::rtl::OUString* pEnd = pSupported + aSupported.getLength(); 81 for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported) 82 ; 83 84 return pSupported != pEnd; 85 } 86 87 // ------------------------------------------------------------------------- 88 OResultSet::OResultSet(SQLHANDLE _pStatementHandle ,OStatement_Base* pStmt) : OResultSet_BASE(m_aMutex) 89 ,OPropertySetHelper(OResultSet_BASE::rBHelper) 90 ,m_aStatementHandle(_pStatementHandle) 91 ,m_aConnectionHandle(pStmt->getConnectionHandle()) 92 ,m_pStatement(pStmt) 93 ,m_pSkipDeletedSet(NULL) 94 ,m_xStatement(*pStmt) 95 ,m_xMetaData(NULL) 96 ,m_pRowStatusArray( NULL ) 97 ,m_nTextEncoding(pStmt->getOwnConnection()->getTextEncoding()) 98 ,m_nRowPos(0) 99 ,m_nLastColumnPos(0) 100 ,m_nUseBookmarks(ODBC_SQL_NOT_DEFINED) 101 ,m_nCurrentFetchState(0) 102 ,m_bWasNull(sal_True) 103 ,m_bEOF(sal_True) 104 ,m_bLastRecord(sal_False) 105 ,m_bFreeHandle(sal_False) 106 ,m_bInserting(sal_False) 107 ,m_bFetchData(sal_True) 108 ,m_bRowInserted(sal_False) 109 ,m_bRowDeleted(sal_False) 110 ,m_bUseFetchScroll(sal_False) 111 { 112 osl_incrementInterlockedCount( &m_refCount ); 113 try 114 { 115 m_pRowStatusArray = new SQLUSMALLINT[1]; // the default value 116 N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_ROW_STATUS_PTR,m_pRowStatusArray,SQL_IS_POINTER); 117 } 118 catch(Exception&) 119 { // we don't want our result destroy here 120 } 121 SQLINTEGER nCurType = 0; 122 try 123 { 124 N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_CURSOR_TYPE,&nCurType,SQL_IS_UINTEGER,0); 125 SQLUINTEGER nValueLen = m_pStatement->getCursorProperties(nCurType,sal_False); 126 if( (nValueLen & SQL_CA2_SENSITIVITY_DELETIONS) != SQL_CA2_SENSITIVITY_DELETIONS || 127 (nValueLen & SQL_CA2_CRC_EXACT) != SQL_CA2_CRC_EXACT) 128 m_pSkipDeletedSet = new OSkipDeletedSet(this); 129 } 130 catch(Exception&) 131 { // we don't want our result destroy here 132 } 133 try 134 { 135 SQLUINTEGER nValueLen = 0; 136 OTools::GetInfo(m_pStatement->getOwnConnection(),m_aConnectionHandle,SQL_GETDATA_EXTENSIONS,nValueLen,NULL); 137 m_bFetchData = !((SQL_GD_ANY_ORDER & nValueLen) == SQL_GD_ANY_ORDER && nCurType != SQL_CURSOR_FORWARD_ONLY); 138 } 139 catch(Exception&) 140 { // we don't want our result destroy here 141 m_bFetchData = sal_True; 142 } 143 try 144 { 145 if ( getOdbcFunction(ODBC3SQLGetFunctions) ) 146 { 147 SQLUSMALLINT nSupported = 0; 148 m_bUseFetchScroll = ( N3SQLGetFunctions(m_aConnectionHandle,SQL_API_SQLFETCHSCROLL,&nSupported) == SQL_SUCCESS && nSupported == 1 ); 149 } 150 } 151 catch(Exception&) 152 { 153 m_bUseFetchScroll = sal_False; 154 } 155 156 osl_decrementInterlockedCount( &m_refCount ); 157 } 158 // ------------------------------------------------------------------------- 159 OResultSet::~OResultSet() 160 { 161 delete [] m_pRowStatusArray; 162 delete m_pSkipDeletedSet; 163 } 164 // ----------------------------------------------------------------------------- 165 void OResultSet::construct() 166 { 167 osl_incrementInterlockedCount( &m_refCount ); 168 allocBuffer(); 169 osl_decrementInterlockedCount( &m_refCount ); 170 } 171 // ------------------------------------------------------------------------- 172 void OResultSet::disposing(void) 173 { 174 SQLRETURN nRet = N3SQLCloseCursor(m_aStatementHandle); 175 OSL_UNUSED( nRet ); 176 OPropertySetHelper::disposing(); 177 178 ::osl::MutexGuard aGuard(m_aMutex); 179 if(!m_aBindVector.empty()) 180 releaseBuffer(); 181 if(m_bFreeHandle) 182 m_pStatement->getOwnConnection()->freeStatementHandle(m_aStatementHandle); 183 184 m_xStatement.clear(); 185 m_xMetaData.clear(); 186 } 187 // ------------------------------------------------------------------------- 188 SQLRETURN OResultSet::unbind(sal_Bool _bUnbindHandle) 189 { 190 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::unbind" ); 191 SQLRETURN nRet = 0; 192 if ( _bUnbindHandle ) 193 nRet = N3SQLFreeStmt(m_aStatementHandle,SQL_UNBIND); 194 195 if ( m_aBindVector.size() > 1 ) 196 { 197 TVoidVector::iterator pValue = m_aBindVector.begin() + 1; 198 TVoidVector::iterator pEnd = m_aBindVector.end(); 199 for(; pValue != pEnd; ++pValue) 200 { 201 switch (pValue->second) 202 { 203 case DataType::CHAR: 204 case DataType::VARCHAR: 205 delete static_cast< ::rtl::OString* >(reinterpret_cast< void * >(pValue->first)); 206 break; 207 case DataType::BIGINT: 208 delete static_cast< sal_Int64* >(reinterpret_cast< void * >(pValue->first)); 209 break; 210 case DataType::DECIMAL: 211 case DataType::NUMERIC: 212 delete static_cast< ::rtl::OString* >(reinterpret_cast< void * >(pValue->first)); 213 break; 214 case DataType::REAL: 215 case DataType::DOUBLE: 216 delete static_cast< double* >(reinterpret_cast< void * >(pValue->first)); 217 break; 218 case DataType::LONGVARCHAR: 219 case DataType::CLOB: 220 delete [] static_cast< char* >(reinterpret_cast< void * >(pValue->first)); 221 break; 222 case DataType::LONGVARBINARY: 223 case DataType::BLOB: 224 delete [] static_cast< char* >(reinterpret_cast< void * >(pValue->first)); 225 break; 226 case DataType::DATE: 227 delete static_cast< DATE_STRUCT* >(reinterpret_cast< void * >(pValue->first)); 228 break; 229 case DataType::TIME: 230 delete static_cast< TIME_STRUCT* >(reinterpret_cast< void * >(pValue->first)); 231 break; 232 case DataType::TIMESTAMP: 233 delete static_cast< TIMESTAMP_STRUCT* >(reinterpret_cast< void * >(pValue->first)); 234 break; 235 case DataType::BIT: 236 case DataType::TINYINT: 237 delete static_cast< sal_Int8* >(reinterpret_cast< void * >(pValue->first)); 238 break; 239 case DataType::SMALLINT: 240 delete static_cast< sal_Int16* >(reinterpret_cast< void * >(pValue->first)); 241 break; 242 case DataType::INTEGER: 243 delete static_cast< sal_Int32* >(reinterpret_cast< void * >(pValue->first)); 244 break; 245 case DataType::FLOAT: 246 delete static_cast< float* >(reinterpret_cast< void * >(pValue->first)); 247 break; 248 case DataType::BINARY: 249 case DataType::VARBINARY: 250 delete static_cast< sal_Int8* >(reinterpret_cast< void * >(pValue->first)); 251 break; 252 } 253 } 254 m_aBindVector.clear(); 255 m_aBindVector.push_back(TVoidPtr(0,0)); // the first is reserved for the bookmark 256 } 257 return nRet; 258 } 259 // ------------------------------------------------------------------------- 260 TVoidPtr OResultSet::allocBindColumn(sal_Int32 _nType,sal_Int32 _nColumnIndex) 261 { 262 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::allocBindColumn" ); 263 TVoidPtr aPair; 264 switch (_nType) 265 { 266 case DataType::CHAR: 267 case DataType::VARCHAR: 268 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new ::rtl::OString()),_nType); 269 break; 270 case DataType::BIGINT: 271 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int64(0)),_nType); 272 break; 273 case DataType::DECIMAL: 274 case DataType::NUMERIC: 275 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new ::rtl::OString()),_nType); 276 break; 277 case DataType::REAL: 278 case DataType::DOUBLE: 279 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new double(0.0)),_nType); 280 break; 281 case DataType::LONGVARCHAR: 282 case DataType::CLOB: 283 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new char[2]),_nType); // dient nur zum auffinden 284 break; 285 case DataType::LONGVARBINARY: 286 case DataType::BLOB: 287 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new char[2]),_nType); // dient nur zum auffinden 288 break; 289 case DataType::DATE: 290 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new DATE_STRUCT),_nType); 291 break; 292 case DataType::TIME: 293 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new TIME_STRUCT),_nType); 294 break; 295 case DataType::TIMESTAMP: 296 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new TIMESTAMP_STRUCT),_nType); 297 break; 298 case DataType::BIT: 299 case DataType::TINYINT: 300 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int8(0)),_nType); 301 break; 302 case DataType::SMALLINT: 303 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int16(0)),_nType); 304 break; 305 case DataType::INTEGER: 306 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int32(0)),_nType); 307 break; 308 case DataType::FLOAT: 309 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new float(0)),_nType); 310 break; 311 case DataType::BINARY: 312 case DataType::VARBINARY: 313 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int8[m_aRow[_nColumnIndex].getSequence().getLength()]),_nType); 314 break; 315 default: 316 OSL_ENSURE(0,"Unknown type"); 317 aPair = TVoidPtr(0,_nType); 318 } 319 return aPair; 320 } 321 // ------------------------------------------------------------------------- 322 void OResultSet::allocBuffer() 323 { 324 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::allocBuffer" ); 325 Reference< XResultSetMetaData > xMeta = getMetaData(); 326 sal_Int32 nLen = xMeta->getColumnCount(); 327 328 m_aBindVector.reserve(nLen+1); 329 m_aBindVector.push_back(TVoidPtr(0,0)); // the first is reserved for the bookmark 330 m_aRow.resize(nLen+1); 331 332 for(sal_Int32 i = 1;i<=nLen;++i) 333 { 334 sal_Int32 nType = xMeta->getColumnType(i); 335 m_aRow[i].setTypeKind( nType ); 336 } 337 m_aLengthVector.resize(nLen + 1); 338 } 339 // ------------------------------------------------------------------------- 340 void OResultSet::releaseBuffer() 341 { 342 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::releaseBuffer" ); 343 unbind(sal_False); 344 m_aLengthVector.clear(); 345 } 346 // ------------------------------------------------------------------------- 347 Any SAL_CALL OResultSet::queryInterface( const Type & rType ) throw(RuntimeException) 348 { 349 Any aRet = OPropertySetHelper::queryInterface(rType); 350 return aRet.hasValue() ? aRet : OResultSet_BASE::queryInterface(rType); 351 } 352 // ------------------------------------------------------------------------- 353 Sequence< Type > SAL_CALL OResultSet::getTypes( ) throw( RuntimeException) 354 { 355 OTypeCollection aTypes( ::getCppuType( (const Reference< ::com::sun::star::beans::XMultiPropertySet > *)0 ), 356 ::getCppuType( (const Reference< ::com::sun::star::beans::XFastPropertySet > *)0 ), 357 ::getCppuType( (const Reference< ::com::sun::star::beans::XPropertySet > *)0 )); 358 359 return ::comphelper::concatSequences(aTypes.getTypes(),OResultSet_BASE::getTypes()); 360 } 361 // ------------------------------------------------------------------------- 362 363 sal_Int32 SAL_CALL OResultSet::findColumn( const ::rtl::OUString& columnName ) throw(SQLException, RuntimeException) 364 { 365 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::findColumn" ); 366 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 367 368 369 ::osl::MutexGuard aGuard( m_aMutex ); 370 371 Reference< XResultSetMetaData > xMeta = getMetaData(); 372 sal_Int32 nLen = xMeta->getColumnCount(); 373 sal_Int32 i = 1; 374 for(;i<=nLen;++i) 375 if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) : 376 columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i))) 377 break; 378 return i; 379 } 380 // ------------------------------------------------------------------------- 381 Reference< XInputStream > SAL_CALL OResultSet::getBinaryStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 382 { 383 ::osl::MutexGuard aGuard( m_aMutex ); 384 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 385 386 387 // TODO use getBytes instead of 388 return NULL; 389 } 390 // ------------------------------------------------------------------------- 391 Reference< XInputStream > SAL_CALL OResultSet::getCharacterStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 392 { 393 ::osl::MutexGuard aGuard( m_aMutex ); 394 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 395 396 397 // TODO use getBytes instead of 398 return NULL; 399 } 400 // ----------------------------------------------------------------------------- 401 const ORowSetValue& OResultSet::getValue(sal_Int32 _nColumnIndex,SQLSMALLINT _nType,void* _pValue,SQLINTEGER _rSize) 402 { 403 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getValue" ); 404 ::osl::MutexGuard aGuard( m_aMutex ); 405 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 406 407 if(m_bFetchData) 408 { 409 if(_nColumnIndex > m_nLastColumnPos) 410 fillRow(_nColumnIndex); 411 return m_aRow[_nColumnIndex]; 412 } 413 else 414 OTools::getValue(m_pStatement->getOwnConnection(),m_aStatementHandle,_nColumnIndex,_nType,m_bWasNull,**this,_pValue,_rSize); 415 416 return m_aEmptyValue; 417 } 418 // ------------------------------------------------------------------------- 419 sal_Bool SAL_CALL OResultSet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 420 { 421 sal_Int8 nVal(0); 422 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_BIT,&nVal,sizeof nVal); 423 return (&aValue == &m_aEmptyValue) ? (sal_Bool)nVal : (sal_Bool)aValue; 424 } 425 // ------------------------------------------------------------------------- 426 427 sal_Int8 SAL_CALL OResultSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 428 { 429 sal_Int8 nRet(0); 430 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_TINYINT,&nRet,sizeof nRet); 431 return (&aValue == &m_aEmptyValue) ? nRet : (sal_Int8)aValue; 432 } 433 // ------------------------------------------------------------------------- 434 435 Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 436 { 437 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getBytes" ); 438 439 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 440 ::osl::MutexGuard aGuard( m_aMutex ); 441 442 443 if(m_bFetchData) 444 { 445 if(columnIndex > m_nLastColumnPos) 446 fillRow(columnIndex); 447 Sequence< sal_Int8 > nRet; 448 switch(m_aRow[columnIndex].getTypeKind()) 449 { 450 case DataType::BINARY: 451 case DataType::VARBINARY: 452 case DataType::LONGVARBINARY: 453 nRet = m_aRow[columnIndex]; 454 break; 455 default: 456 { 457 ::rtl::OUString sRet; 458 sRet = m_aRow[columnIndex].getString(); 459 nRet = Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(sRet.getStr()),sizeof(sal_Unicode)*sRet.getLength()); 460 } 461 } 462 return nRet; 463 } 464 465 const SWORD nColumnType = impl_getColumnType_nothrow(columnIndex); 466 467 switch(nColumnType) 468 { 469 case SQL_WVARCHAR: 470 case SQL_WCHAR: 471 case SQL_WLONGVARCHAR: 472 case SQL_VARCHAR: 473 case SQL_CHAR: 474 case SQL_LONGVARCHAR: 475 { 476 ::rtl::OUString aRet = OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,nColumnType,m_bWasNull,**this,m_nTextEncoding); 477 return Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(aRet.getStr()),sizeof(sal_Unicode)*aRet.getLength()); 478 } 479 default: 480 ; 481 } 482 return OTools::getBytesValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,SQL_C_BINARY,m_bWasNull,**this); 483 } 484 // ------------------------------------------------------------------------- 485 486 Date SAL_CALL OResultSet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 487 { 488 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getDate" ); 489 DATE_STRUCT aDate; 490 aDate.day = 0; 491 aDate.month = 0; 492 aDate.year = 0; 493 494 const ORowSetValue& aValue = getValue( columnIndex, 495 m_pStatement->getOwnConnection()->useOldDateFormat() ? SQL_C_DATE : SQL_C_TYPE_DATE, 496 &aDate,sizeof aDate); 497 return (&aValue == &m_aEmptyValue) ? Date(aDate.day,aDate.month,aDate.year) : (Date)aValue; 498 } 499 // ------------------------------------------------------------------------- 500 501 double SAL_CALL OResultSet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 502 { 503 double nRet(0); 504 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_DOUBLE,&nRet,sizeof nRet); 505 return (&aValue == &m_aEmptyValue) ? nRet : (double)aValue; 506 } 507 // ------------------------------------------------------------------------- 508 509 float SAL_CALL OResultSet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 510 { 511 float nRet(0); 512 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_FLOAT,&nRet,sizeof nRet); 513 return (&aValue == &m_aEmptyValue) ? nRet : (float)aValue; 514 } 515 // ------------------------------------------------------------------------- 516 517 sal_Int32 SAL_CALL OResultSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 518 { 519 sal_Int32 nRet(0); 520 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_LONG,&nRet,sizeof nRet); 521 return (&aValue == &m_aEmptyValue) ? nRet : (sal_Int32)aValue; 522 } 523 // ------------------------------------------------------------------------- 524 525 sal_Int32 SAL_CALL OResultSet::getRow( ) throw(SQLException, RuntimeException) 526 { 527 ::osl::MutexGuard aGuard( m_aMutex ); 528 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 529 530 return m_pSkipDeletedSet ? m_pSkipDeletedSet->getMappedPosition(getDriverPos()) : getDriverPos(); 531 } 532 // ------------------------------------------------------------------------- 533 534 sal_Int64 SAL_CALL OResultSet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 535 { 536 sal_Int64 nRet(0); 537 try 538 { 539 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_SBIGINT,&nRet,sizeof nRet); 540 return (&aValue == &m_aEmptyValue) ? nRet : (sal_Int64)aValue; 541 } 542 catch(SQLException&) 543 { 544 nRet = getString(columnIndex).toInt64(); 545 } 546 return nRet; 547 } 548 // ------------------------------------------------------------------------- 549 550 Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData( ) throw(SQLException, RuntimeException) 551 { 552 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getMetaData" ); 553 ::osl::MutexGuard aGuard( m_aMutex ); 554 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 555 556 557 if(!m_xMetaData.is()) 558 m_xMetaData = new OResultSetMetaData(m_pStatement->getOwnConnection(),m_aStatementHandle); 559 return m_xMetaData; 560 } 561 // ------------------------------------------------------------------------- 562 Reference< XArray > SAL_CALL OResultSet::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 563 { 564 ::dbtools::throwFunctionNotSupportedException( "XRow::getArray", *this ); 565 return NULL; 566 } 567 568 // ------------------------------------------------------------------------- 569 570 Reference< XClob > SAL_CALL OResultSet::getClob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 571 { 572 ::dbtools::throwFunctionNotSupportedException( "XRow::getClob", *this ); 573 return NULL; 574 } 575 // ------------------------------------------------------------------------- 576 Reference< XBlob > SAL_CALL OResultSet::getBlob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 577 { 578 ::dbtools::throwFunctionNotSupportedException( "XRow::getBlob", *this ); 579 return NULL; 580 } 581 // ------------------------------------------------------------------------- 582 583 Reference< XRef > SAL_CALL OResultSet::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 584 { 585 ::dbtools::throwFunctionNotSupportedException( "XRow::getRef", *this ); 586 return NULL; 587 } 588 // ------------------------------------------------------------------------- 589 590 Any SAL_CALL OResultSet::getObject( sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException) 591 { 592 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getObject" ); 593 ::osl::MutexGuard aGuard( m_aMutex ); 594 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 595 596 fillRow(columnIndex); 597 return m_aRow[columnIndex].makeAny(); 598 } 599 // ------------------------------------------------------------------------- 600 601 sal_Int16 SAL_CALL OResultSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 602 { 603 sal_Int16 nRet(0); 604 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_SHORT,&nRet,sizeof nRet); 605 return (&aValue == &m_aEmptyValue) ? nRet : (sal_Int16)aValue; 606 } 607 // ------------------------------------------------------------------------- 608 609 610 ::rtl::OUString SAL_CALL OResultSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 611 { 612 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getString" ); 613 ::osl::MutexGuard aGuard( m_aMutex ); 614 615 ::rtl::OUString nRet; 616 if ( m_bFetchData ) 617 nRet = getValue(columnIndex,0,NULL,0); 618 else 619 { 620 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 621 const SWORD nColumnType = impl_getColumnType_nothrow(columnIndex); 622 nRet = OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,nColumnType,m_bWasNull,**this,m_nTextEncoding); 623 } 624 return nRet; 625 } 626 // ------------------------------------------------------------------------- 627 628 Time SAL_CALL OResultSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 629 { 630 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getTime" ); 631 TIME_STRUCT aTime={0,0,0}; 632 const ORowSetValue& aValue = getValue(columnIndex, 633 m_pStatement->getOwnConnection()->useOldDateFormat() ? SQL_C_TIME : SQL_C_TYPE_TIME, 634 &aTime,sizeof aTime); 635 return (&aValue == &m_aEmptyValue) ? Time(0,aTime.second,aTime.minute,aTime.hour) : (Time)aValue; 636 } 637 // ------------------------------------------------------------------------- 638 639 640 DateTime SAL_CALL OResultSet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 641 { 642 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getTimestamp" ); 643 TIMESTAMP_STRUCT aTime={0,0,0,0,0,0,0}; 644 const ORowSetValue& aValue = getValue(columnIndex, 645 m_pStatement->getOwnConnection()->useOldDateFormat() ? SQL_C_TIMESTAMP : SQL_C_TYPE_TIMESTAMP, 646 &aTime,sizeof aTime); 647 return (&aValue == &m_aEmptyValue) 648 ? 649 DateTime(static_cast<sal_uInt16>(aTime.fraction*1000),aTime.second,aTime.minute,aTime.hour,aTime.day,aTime.month,aTime.year) 650 : 651 (DateTime)aValue; 652 } 653 // ------------------------------------------------------------------------- 654 655 sal_Bool SAL_CALL OResultSet::isBeforeFirst( ) throw(SQLException, RuntimeException) 656 { 657 ::osl::MutexGuard aGuard( m_aMutex ); 658 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 659 return m_nRowPos == 0; 660 } 661 // ------------------------------------------------------------------------- 662 sal_Bool SAL_CALL OResultSet::isAfterLast( ) throw(SQLException, RuntimeException) 663 { 664 ::osl::MutexGuard aGuard( m_aMutex ); 665 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 666 667 return m_nRowPos != 0 && m_nCurrentFetchState == SQL_NO_DATA; 668 } 669 // ------------------------------------------------------------------------- 670 sal_Bool SAL_CALL OResultSet::isFirst( ) throw(SQLException, RuntimeException) 671 { 672 ::osl::MutexGuard aGuard( m_aMutex ); 673 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 674 675 return m_nRowPos == 1; 676 } 677 // ------------------------------------------------------------------------- 678 sal_Bool SAL_CALL OResultSet::isLast( ) throw(SQLException, RuntimeException) 679 { 680 ::osl::MutexGuard aGuard( m_aMutex ); 681 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 682 683 684 return m_bEOF && m_nCurrentFetchState != SQL_NO_DATA; 685 } 686 // ------------------------------------------------------------------------- 687 void SAL_CALL OResultSet::beforeFirst( ) throw(SQLException, RuntimeException) 688 { 689 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::beforeFirst" ); 690 ::osl::MutexGuard aGuard( m_aMutex ); 691 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 692 693 694 if(first()) 695 previous(); 696 m_nCurrentFetchState = SQL_SUCCESS; 697 } 698 // ------------------------------------------------------------------------- 699 void SAL_CALL OResultSet::afterLast( ) throw(SQLException, RuntimeException) 700 { 701 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::afterLast" ); 702 ::osl::MutexGuard aGuard( m_aMutex ); 703 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 704 705 if(last()) 706 next(); 707 m_bEOF = sal_True; 708 } 709 // ------------------------------------------------------------------------- 710 711 void SAL_CALL OResultSet::close( ) throw(SQLException, RuntimeException) 712 { 713 { 714 ::osl::MutexGuard aGuard( m_aMutex ); 715 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 716 717 } 718 dispose(); 719 } 720 // ------------------------------------------------------------------------- 721 722 sal_Bool SAL_CALL OResultSet::first( ) throw(SQLException, RuntimeException) 723 { 724 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::first" ); 725 return moveImpl(IResultSetHelper::FIRST,0,sal_True); 726 } 727 // ------------------------------------------------------------------------- 728 729 sal_Bool SAL_CALL OResultSet::last( ) throw(SQLException, RuntimeException) 730 { 731 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::last" ); 732 return moveImpl(IResultSetHelper::LAST,0,sal_True); 733 } 734 // ------------------------------------------------------------------------- 735 sal_Bool SAL_CALL OResultSet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException) 736 { 737 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::absolute" ); 738 return moveImpl(IResultSetHelper::ABSOLUTE,row,sal_True); 739 } 740 // ------------------------------------------------------------------------- 741 sal_Bool SAL_CALL OResultSet::relative( sal_Int32 row ) throw(SQLException, RuntimeException) 742 { 743 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::relative" ); 744 return moveImpl(IResultSetHelper::RELATIVE,row,sal_True); 745 } 746 // ------------------------------------------------------------------------- 747 sal_Bool SAL_CALL OResultSet::previous( ) throw(SQLException, RuntimeException) 748 { 749 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::previous" ); 750 return moveImpl(IResultSetHelper::PRIOR,0,sal_True); 751 } 752 // ------------------------------------------------------------------------- 753 Reference< XInterface > SAL_CALL OResultSet::getStatement( ) throw(SQLException, RuntimeException) 754 { 755 ::osl::MutexGuard aGuard( m_aMutex ); 756 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 757 return m_xStatement; 758 } 759 // ------------------------------------------------------------------------- 760 761 sal_Bool SAL_CALL OResultSet::rowDeleted() throw(SQLException, RuntimeException) 762 { 763 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::rowDeleted" ); 764 ::osl::MutexGuard aGuard( m_aMutex ); 765 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 766 767 sal_Bool bRet = m_bRowDeleted; 768 m_bRowDeleted = sal_False; 769 770 return bRet; 771 } 772 // ------------------------------------------------------------------------- 773 sal_Bool SAL_CALL OResultSet::rowInserted( ) throw(SQLException, RuntimeException) 774 { 775 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::rowInserted" ); 776 ::osl::MutexGuard aGuard( m_aMutex ); 777 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 778 779 sal_Bool bInserted = m_bRowInserted; 780 m_bRowInserted = sal_False; 781 782 return bInserted; 783 } 784 // ------------------------------------------------------------------------- 785 sal_Bool SAL_CALL OResultSet::rowUpdated( ) throw(SQLException, RuntimeException) 786 { 787 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::rowUpdated" ); 788 ::osl::MutexGuard aGuard( m_aMutex ); 789 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 790 791 792 return m_pRowStatusArray[0] == SQL_ROW_UPDATED; 793 } 794 // ------------------------------------------------------------------------- 795 796 sal_Bool SAL_CALL OResultSet::next( ) throw(SQLException, RuntimeException) 797 { 798 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::next" ); 799 return moveImpl(IResultSetHelper::NEXT,1,sal_True); 800 } 801 // ------------------------------------------------------------------------- 802 803 sal_Bool SAL_CALL OResultSet::wasNull( ) throw(SQLException, RuntimeException) 804 { 805 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::wasNull" ); 806 ::osl::MutexGuard aGuard( m_aMutex ); 807 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 808 809 810 return m_bFetchData ? m_aRow[m_nLastColumnPos].isNull() : m_bWasNull; 811 } 812 // ------------------------------------------------------------------------- 813 814 void SAL_CALL OResultSet::cancel( ) throw(RuntimeException) 815 { 816 ::osl::MutexGuard aGuard( m_aMutex ); 817 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 818 819 820 OTools::ThrowException(m_pStatement->getOwnConnection(),N3SQLCancel(m_aStatementHandle),m_aStatementHandle,SQL_HANDLE_STMT,*this); 821 } 822 // ------------------------------------------------------------------------- 823 void SAL_CALL OResultSet::clearWarnings( ) throw(SQLException, RuntimeException) 824 { 825 } 826 // ------------------------------------------------------------------------- 827 Any SAL_CALL OResultSet::getWarnings( ) throw(SQLException, RuntimeException) 828 { 829 return Any(); 830 } 831 // ------------------------------------------------------------------------- 832 void SAL_CALL OResultSet::insertRow( ) throw(SQLException, RuntimeException) 833 { 834 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::insertRow" ); 835 ::osl::MutexGuard aGuard( m_aMutex ); 836 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 837 838 839 SQLLEN nMaxLen = 20; 840 SQLLEN nRealLen = 0; 841 Sequence<sal_Int8> aBookmark(nMaxLen); 842 843 SQLRETURN nRet = N3SQLBindCol(m_aStatementHandle, 844 0, 845 SQL_C_VARBOOKMARK, 846 aBookmark.getArray(), 847 nMaxLen, 848 &nRealLen 849 ); 850 // Sequence<sal_Int8> aRealBookmark(nMaxLen); 851 852 sal_Bool bPositionByBookmark = ( NULL != getOdbcFunction( ODBC3SQLBulkOperations ) ); 853 if ( bPositionByBookmark ) 854 { 855 nRet = N3SQLBulkOperations( m_aStatementHandle, SQL_ADD ); 856 fillNeededData( nRet ); 857 } 858 else 859 { 860 if(isBeforeFirst()) 861 next(); // must be done 862 nRet = N3SQLSetPos( m_aStatementHandle, 1, SQL_ADD, SQL_LOCK_NO_CHANGE ); 863 fillNeededData( nRet ); 864 } 865 try 866 { 867 OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this); 868 } 869 catch(SQLException e) 870 { 871 nRet = unbind(); 872 throw; 873 } 874 875 876 if ( bPositionByBookmark ) 877 { 878 nRet = N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_FETCH_BOOKMARK_PTR,aBookmark.getArray(),SQL_IS_POINTER); // SQL_LEN_BINARY_ATTR(aBookmark.getLength()) 879 880 nRet = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_BOOKMARK,0); 881 } 882 else 883 nRet = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_RELATIVE,0); // OJ 06.03.2004 884 // sometimes we got an error but we are not interested in anymore #106047# OJ 885 // OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this); 886 nRet = unbind(); 887 OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this); 888 889 if(m_pSkipDeletedSet) 890 { 891 aBookmark.realloc(nRealLen); 892 if(moveToBookmark(makeAny(aBookmark))) 893 { 894 sal_Int32 nRowPos = getDriverPos(); 895 if ( -1 == m_nRowPos ) 896 { 897 nRowPos = m_aPosToBookmarks.size() + 1; 898 } 899 if ( nRowPos == m_nRowPos ) 900 ++nRowPos; 901 m_nRowPos = nRowPos; 902 m_pSkipDeletedSet->insertNewPosition(nRowPos); 903 m_aPosToBookmarks[aBookmark] = nRowPos; 904 } 905 } 906 m_bRowInserted = sal_True; 907 908 } 909 // ------------------------------------------------------------------------- 910 void SAL_CALL OResultSet::updateRow( ) throw(SQLException, RuntimeException) 911 { 912 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::updateRow" ); 913 ::osl::MutexGuard aGuard( m_aMutex ); 914 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 915 916 SQLRETURN nRet; 917 918 sal_Bool bPositionByBookmark = ( NULL != getOdbcFunction( ODBC3SQLBulkOperations ) ); 919 if ( bPositionByBookmark ) 920 { 921 SQLLEN nRealLen = 0; 922 nRet = N3SQLBindCol(m_aStatementHandle, 923 0, 924 SQL_C_VARBOOKMARK, 925 m_aBookmark.getArray(), 926 m_aBookmark.getLength(), 927 &nRealLen 928 ); 929 fillNeededData(nRet = N3SQLBulkOperations(m_aStatementHandle, SQL_UPDATE_BY_BOOKMARK)); 930 } 931 else 932 fillNeededData(nRet = N3SQLSetPos(m_aStatementHandle,1,SQL_UPDATE,SQL_LOCK_NO_CHANGE)); 933 OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this); 934 // now unbind all columns so we can fetch all columns again with SQLGetData 935 nRet = unbind(); 936 OSL_ENSURE(nRet == SQL_SUCCESS,"Could not unbind the columns!"); 937 } 938 // ------------------------------------------------------------------------- 939 void SAL_CALL OResultSet::deleteRow( ) throw(SQLException, RuntimeException) 940 { 941 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::deleteRow" ); 942 SQLRETURN nRet = SQL_SUCCESS; 943 sal_Int32 nPos = getDriverPos(); 944 nRet = N3SQLSetPos(m_aStatementHandle,1,SQL_DELETE,SQL_LOCK_NO_CHANGE); 945 OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this); 946 947 m_bRowDeleted = ( m_pRowStatusArray[0] == SQL_ROW_DELETED ); 948 if ( m_bRowDeleted ) 949 { 950 TBookmarkPosMap::iterator aIter = m_aPosToBookmarks.begin(); 951 TBookmarkPosMap::iterator aEnd = m_aPosToBookmarks.end(); 952 for (; aIter != aEnd; ++aIter) 953 { 954 if ( aIter->second == nPos ) 955 { 956 m_aPosToBookmarks.erase(aIter); 957 break; 958 } 959 } 960 } 961 if ( m_pSkipDeletedSet ) 962 m_pSkipDeletedSet->deletePosition(nPos); 963 } 964 // ------------------------------------------------------------------------- 965 966 void SAL_CALL OResultSet::cancelRowUpdates( ) throw(SQLException, RuntimeException) 967 { 968 } 969 // ------------------------------------------------------------------------- 970 971 void SAL_CALL OResultSet::moveToInsertRow( ) throw(SQLException, RuntimeException) 972 { 973 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::moveToInsertRow" ); 974 ::osl::MutexGuard aGuard( m_aMutex ); 975 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 976 977 978 m_nLastColumnPos = 0; 979 // first unbound all columns 980 OSL_VERIFY_EQUALS( unbind(), SQL_SUCCESS, "Could not unbind columns!" ); 981 // SQLRETURN nRet = N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_ROW_ARRAY_SIZE ,(SQLPOINTER)1,SQL_IS_INTEGER); 982 m_bInserting = sal_True; 983 } 984 // ------------------------------------------------------------------------- 985 986 void SAL_CALL OResultSet::moveToCurrentRow( ) throw(SQLException, RuntimeException) 987 { 988 m_nLastColumnPos = 0; 989 } 990 // ------------------------------------------------------------------------- 991 void OResultSet::updateValue(sal_Int32 columnIndex,SQLSMALLINT _nType,void* _pValue) throw(SQLException, RuntimeException) 992 { 993 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::updateValue" ); 994 ::osl::MutexGuard aGuard( m_aMutex ); 995 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 996 997 m_aBindVector.push_back(allocBindColumn(OTools::MapOdbcType2Jdbc(_nType),columnIndex)); 998 void* pData = reinterpret_cast<void*>(m_aBindVector.rbegin()->first); 999 OSL_ENSURE(pData != NULL,"Data for update is NULL!"); 1000 OTools::bindValue( m_pStatement->getOwnConnection(), 1001 m_aStatementHandle, 1002 columnIndex, 1003 _nType, 1004 0, 1005 _pValue, 1006 pData, 1007 &m_aLengthVector[columnIndex], 1008 **this, 1009 m_nTextEncoding, 1010 m_pStatement->getOwnConnection()->useOldDateFormat()); 1011 } 1012 // ----------------------------------------------------------------------------- 1013 void SAL_CALL OResultSet::updateNull( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1014 { 1015 ::osl::MutexGuard aGuard( m_aMutex ); 1016 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 1017 1018 m_aBindVector.push_back(allocBindColumn(DataType::CHAR,columnIndex)); 1019 void* pData = reinterpret_cast<void*>(m_aBindVector.rbegin()->first); 1020 OTools::bindValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,SQL_CHAR,0,(sal_Int8*)NULL,pData,&m_aLengthVector[columnIndex],**this,m_nTextEncoding,m_pStatement->getOwnConnection()->useOldDateFormat()); 1021 } 1022 // ------------------------------------------------------------------------- 1023 1024 void SAL_CALL OResultSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw(SQLException, RuntimeException) 1025 { 1026 updateValue(columnIndex,SQL_BIT,&x); 1027 } 1028 // ------------------------------------------------------------------------- 1029 void SAL_CALL OResultSet::updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw(SQLException, RuntimeException) 1030 { 1031 updateValue(columnIndex,SQL_CHAR,&x); 1032 } 1033 // ------------------------------------------------------------------------- 1034 1035 void SAL_CALL OResultSet::updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw(SQLException, RuntimeException) 1036 { 1037 updateValue(columnIndex,SQL_TINYINT,&x); 1038 } 1039 // ------------------------------------------------------------------------- 1040 void SAL_CALL OResultSet::updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw(SQLException, RuntimeException) 1041 { 1042 updateValue(columnIndex,SQL_INTEGER,&x); 1043 } 1044 // ------------------------------------------------------------------------- 1045 void SAL_CALL OResultSet::updateLong( sal_Int32 /*columnIndex*/, sal_Int64 /*x*/ ) throw(SQLException, RuntimeException) 1046 { 1047 ::dbtools::throwFunctionNotSupportedException( "XRowUpdate::updateLong", *this ); 1048 } 1049 // ----------------------------------------------------------------------- 1050 void SAL_CALL OResultSet::updateFloat( sal_Int32 columnIndex, float x ) throw(SQLException, RuntimeException) 1051 { 1052 updateValue(columnIndex,SQL_REAL,&x); 1053 } 1054 // ------------------------------------------------------------------------- 1055 1056 void SAL_CALL OResultSet::updateDouble( sal_Int32 columnIndex, double x ) throw(SQLException, RuntimeException) 1057 { 1058 updateValue(columnIndex,SQL_DOUBLE,&x); 1059 } 1060 // ------------------------------------------------------------------------- 1061 void SAL_CALL OResultSet::updateString( sal_Int32 columnIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException) 1062 { 1063 sal_Int32 nType = m_aRow[columnIndex].getTypeKind(); 1064 SQLSMALLINT nOdbcType = static_cast<SQLSMALLINT>(OTools::jdbcTypeToOdbc(nType)); 1065 m_aRow[columnIndex] = x; 1066 m_aRow[columnIndex].setTypeKind(nType); // OJ: otherwise longvarchar will be recognized by fillNeededData 1067 updateValue(columnIndex,nOdbcType,(void*)&x); 1068 } 1069 // ------------------------------------------------------------------------- 1070 void SAL_CALL OResultSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException) 1071 { 1072 sal_Int32 nType = m_aRow[columnIndex].getTypeKind(); 1073 SQLSMALLINT nOdbcType = static_cast<SQLSMALLINT>(OTools::jdbcTypeToOdbc(nType)); 1074 m_aRow[columnIndex] = x; 1075 m_aRow[columnIndex].setTypeKind(nType); // OJ: otherwise longvarbinary will be recognized by fillNeededData 1076 updateValue(columnIndex,nOdbcType,(void*)&x); 1077 } 1078 // ------------------------------------------------------------------------- 1079 void SAL_CALL OResultSet::updateDate( sal_Int32 columnIndex, const Date& x ) throw(SQLException, RuntimeException) 1080 { 1081 DATE_STRUCT aVal = OTools::DateToOdbcDate(x); 1082 updateValue(columnIndex,SQL_DATE,&aVal); 1083 } 1084 // ------------------------------------------------------------------------- 1085 1086 void SAL_CALL OResultSet::updateTime( sal_Int32 columnIndex, const Time& x ) throw(SQLException, RuntimeException) 1087 { 1088 TIME_STRUCT aVal = OTools::TimeToOdbcTime(x); 1089 updateValue(columnIndex,SQL_TIME,&aVal); 1090 } 1091 // ------------------------------------------------------------------------- 1092 1093 void SAL_CALL OResultSet::updateTimestamp( sal_Int32 columnIndex, const DateTime& x ) throw(SQLException, RuntimeException) 1094 { 1095 TIMESTAMP_STRUCT aVal = OTools::DateTimeToTimestamp(x); 1096 updateValue(columnIndex,SQL_TIMESTAMP,&aVal); 1097 } 1098 // ------------------------------------------------------------------------- 1099 1100 void SAL_CALL OResultSet::updateBinaryStream( sal_Int32 columnIndex, const Reference< XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) 1101 { 1102 if(!x.is()) 1103 ::dbtools::throwFunctionSequenceException(*this); 1104 1105 Sequence<sal_Int8> aSeq; 1106 x->readBytes(aSeq,length); 1107 updateBytes(columnIndex,aSeq); 1108 } 1109 // ------------------------------------------------------------------------- 1110 void SAL_CALL OResultSet::updateCharacterStream( sal_Int32 columnIndex, const Reference< XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) 1111 { 1112 updateBinaryStream(columnIndex,x,length); 1113 } 1114 // ------------------------------------------------------------------------- 1115 void SAL_CALL OResultSet::refreshRow( ) throw(SQLException, RuntimeException) 1116 { 1117 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::refreshRow" ); 1118 ::osl::MutexGuard aGuard( m_aMutex ); 1119 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 1120 1121 1122 // SQLRETURN nRet = N3SQLSetPos(m_aStatementHandle,1,SQL_REFRESH,SQL_LOCK_NO_CHANGE); 1123 m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_RELATIVE,0); 1124 OTools::ThrowException(m_pStatement->getOwnConnection(),m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this); 1125 } 1126 // ------------------------------------------------------------------------- 1127 void SAL_CALL OResultSet::updateObject( sal_Int32 columnIndex, const Any& x ) throw(SQLException, RuntimeException) 1128 { 1129 if (!::dbtools::implUpdateObject(this, columnIndex, x)) 1130 throw SQLException(); 1131 } 1132 // ------------------------------------------------------------------------- 1133 1134 void SAL_CALL OResultSet::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 /*scale*/ ) throw(SQLException, RuntimeException) 1135 { 1136 if (!::dbtools::implUpdateObject(this, columnIndex, x)) 1137 throw SQLException(); 1138 } 1139 // ------------------------------------------------------------------------- 1140 // XRowLocate 1141 Any SAL_CALL OResultSet::getBookmark( ) throw( SQLException, RuntimeException) 1142 { 1143 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getBookmark" ); 1144 ::osl::MutexGuard aGuard( m_aMutex ); 1145 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 1146 1147 TBookmarkPosMap::iterator aFind = ::std::find_if(m_aPosToBookmarks.begin(),m_aPosToBookmarks.end(), 1148 ::std::compose1(::std::bind2nd(::std::equal_to<sal_Int32>(),m_nRowPos),::std::select2nd<TBookmarkPosMap::value_type>())); 1149 1150 if ( aFind == m_aPosToBookmarks.end() ) 1151 { 1152 if ( m_nUseBookmarks == ODBC_SQL_NOT_DEFINED ) 1153 { 1154 RTL_LOGFILE_CONTEXT_TRACE( aLogger, "SQLGetStmtAttr" ); 1155 m_nUseBookmarks = SQL_UB_OFF; 1156 SQLRETURN nRet = N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_USE_BOOKMARKS,&m_nUseBookmarks,SQL_IS_UINTEGER,NULL); 1157 OSL_UNUSED( nRet ); 1158 } 1159 if(m_nUseBookmarks == SQL_UB_OFF) 1160 throw SQLException(); 1161 1162 m_aBookmark = OTools::getBytesValue(m_pStatement->getOwnConnection(),m_aStatementHandle,0,SQL_C_VARBOOKMARK,m_bWasNull,**this); 1163 m_aPosToBookmarks[m_aBookmark] = m_nRowPos; 1164 OSL_ENSURE(m_aBookmark.getLength(),"Invalid bookmark from length 0!"); 1165 } 1166 else 1167 m_aBookmark = aFind->first; 1168 return makeAny(m_aBookmark); 1169 } 1170 // ------------------------------------------------------------------------- 1171 sal_Bool SAL_CALL OResultSet::moveToBookmark( const Any& bookmark ) throw( SQLException, RuntimeException) 1172 { 1173 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::moveToBookmark" ); 1174 ::osl::MutexGuard aGuard( m_aMutex ); 1175 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 1176 1177 m_nLastColumnPos = 0; 1178 bookmark >>= m_aBookmark; 1179 OSL_ENSURE(m_aBookmark.getLength(),"Invalid bookmark from length 0!"); 1180 if(m_aBookmark.getLength()) 1181 { 1182 SQLRETURN nReturn = N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_FETCH_BOOKMARK_PTR,m_aBookmark.getArray(),SQL_IS_POINTER); // SQL_LEN_BINARY_ATTR(aBookmark.getLength()) 1183 OSL_UNUSED( nReturn ); 1184 1185 if ( SQL_INVALID_HANDLE != nReturn && SQL_ERROR != nReturn ) 1186 { 1187 m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_BOOKMARK,0); 1188 OTools::ThrowException(m_pStatement->getOwnConnection(),m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this); 1189 TBookmarkPosMap::iterator aFind = m_aPosToBookmarks.find(m_aBookmark); 1190 if(aFind != m_aPosToBookmarks.end()) 1191 m_nRowPos = aFind->second; 1192 else 1193 m_nRowPos = -1; 1194 return m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO; 1195 } 1196 } 1197 return sal_False; 1198 } 1199 // ------------------------------------------------------------------------- 1200 sal_Bool SAL_CALL OResultSet::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) throw( SQLException, RuntimeException) 1201 { 1202 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::moveRelativeToBookmark" ); 1203 ::osl::MutexGuard aGuard( m_aMutex ); 1204 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 1205 1206 1207 m_nLastColumnPos = 0; 1208 bookmark >>= m_aBookmark; 1209 SQLRETURN nReturn = N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_FETCH_BOOKMARK_PTR,m_aBookmark.getArray(),SQL_IS_POINTER); 1210 OSL_UNUSED( nReturn ); 1211 1212 m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_BOOKMARK,rows); 1213 OTools::ThrowException(m_pStatement->getOwnConnection(),m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this); 1214 return m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO; 1215 } 1216 // ------------------------------------------------------------------------- 1217 sal_Int32 SAL_CALL OResultSet::compareBookmarks( const Any& lhs, const Any& rhs ) throw( SQLException, RuntimeException) 1218 { 1219 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::compareBookmarks" ); 1220 ::osl::MutexGuard aGuard( m_aMutex ); 1221 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 1222 1223 return (lhs == rhs) ? CompareBookmark::EQUAL : CompareBookmark::NOT_EQUAL; 1224 } 1225 // ------------------------------------------------------------------------- 1226 sal_Bool SAL_CALL OResultSet::hasOrderedBookmarks( ) throw( SQLException, RuntimeException) 1227 { 1228 return sal_False; 1229 } 1230 // ------------------------------------------------------------------------- 1231 sal_Int32 SAL_CALL OResultSet::hashBookmark( const Any& /*bookmark*/ ) throw( SQLException, RuntimeException) 1232 { 1233 ::dbtools::throwFunctionNotSupportedException( "XRowLocate::hashBookmark", *this ); 1234 return 0; 1235 } 1236 // ------------------------------------------------------------------------- 1237 // XDeleteRows 1238 Sequence< sal_Int32 > SAL_CALL OResultSet::deleteRows( const Sequence< Any >& rows ) throw( SQLException, RuntimeException) 1239 { 1240 Sequence< sal_Int32 > aRet(rows.getLength()); 1241 sal_Int32 *pRet = aRet.getArray(); 1242 1243 const Any *pBegin = rows.getConstArray(); 1244 const Any *pEnd = pBegin + rows.getLength(); 1245 1246 for(;pBegin != pEnd;++pBegin,++pRet) 1247 { 1248 try 1249 { 1250 if(moveToBookmark(*pBegin)) 1251 { 1252 deleteRow(); 1253 *pRet = 1; 1254 } 1255 } 1256 catch(SQLException&) 1257 { 1258 *pRet = 0; 1259 } 1260 } 1261 return aRet; 1262 } 1263 //------------------------------------------------------------------------------ 1264 sal_Int32 OResultSet::getResultSetConcurrency() const 1265 { 1266 sal_uInt32 nValue = 0; 1267 SQLRETURN nReturn = N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_CONCURRENCY,&nValue,SQL_IS_UINTEGER,0); 1268 OSL_UNUSED( nReturn ); 1269 if(SQL_CONCUR_READ_ONLY == nValue) 1270 nValue = ResultSetConcurrency::READ_ONLY; 1271 else 1272 nValue = ResultSetConcurrency::UPDATABLE; 1273 1274 return nValue; 1275 } 1276 //------------------------------------------------------------------------------ 1277 sal_Int32 OResultSet::getResultSetType() const 1278 { 1279 sal_uInt32 nValue = 0; 1280 N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_CURSOR_SENSITIVITY,&nValue,SQL_IS_UINTEGER,0); 1281 if(SQL_SENSITIVE == nValue) 1282 nValue = ResultSetType::SCROLL_SENSITIVE; 1283 else if(SQL_INSENSITIVE == nValue) 1284 nValue = ResultSetType::SCROLL_INSENSITIVE; 1285 else 1286 { 1287 SQLINTEGER nCurType = 0; 1288 N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_CURSOR_TYPE,&nCurType,SQL_IS_UINTEGER,0); 1289 if(SQL_CURSOR_KEYSET_DRIVEN == nCurType) 1290 nValue = ResultSetType::SCROLL_SENSITIVE; 1291 else if(SQL_CURSOR_STATIC == nCurType) 1292 nValue = ResultSetType::SCROLL_INSENSITIVE; 1293 else if(SQL_CURSOR_FORWARD_ONLY == nCurType) 1294 nValue = ResultSetType::FORWARD_ONLY; 1295 else if(SQL_CURSOR_DYNAMIC == nCurType) 1296 nValue = ResultSetType::SCROLL_SENSITIVE; 1297 } 1298 return nValue; 1299 } 1300 //------------------------------------------------------------------------------ 1301 sal_Int32 OResultSet::getFetchDirection() const 1302 { 1303 return FetchDirection::FORWARD; 1304 } 1305 //------------------------------------------------------------------------------ 1306 sal_Int32 OResultSet::getFetchSize() const 1307 { 1308 sal_uInt32 nValue = 0; 1309 N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_ROW_ARRAY_SIZE,&nValue,SQL_IS_UINTEGER,0); 1310 return nValue; 1311 } 1312 //------------------------------------------------------------------------------ 1313 ::rtl::OUString OResultSet::getCursorName() const 1314 { 1315 SQLCHAR pName[258]; 1316 SQLSMALLINT nRealLen = 0; 1317 N3SQLGetCursorName(m_aStatementHandle,(SQLCHAR*)pName,256,&nRealLen); 1318 return ::rtl::OUString::createFromAscii((const char*)pName); 1319 } 1320 // ------------------------------------------------------------------------- 1321 sal_Bool OResultSet::isBookmarkable() const 1322 { 1323 if(!m_aConnectionHandle) 1324 return sal_False; 1325 1326 sal_uInt32 nValue = 0; 1327 N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_CURSOR_TYPE,&nValue,SQL_IS_UINTEGER,0); 1328 1329 sal_Int32 nAttr = 0; 1330 try 1331 { 1332 switch(nValue) 1333 { 1334 case SQL_CURSOR_FORWARD_ONLY: 1335 return sal_False; 1336 case SQL_CURSOR_STATIC: 1337 OTools::GetInfo(m_pStatement->getOwnConnection(),m_aConnectionHandle,SQL_STATIC_CURSOR_ATTRIBUTES1,nAttr,NULL); 1338 break; 1339 case SQL_CURSOR_KEYSET_DRIVEN: 1340 OTools::GetInfo(m_pStatement->getOwnConnection(),m_aConnectionHandle,SQL_KEYSET_CURSOR_ATTRIBUTES1,nAttr,NULL); 1341 break; 1342 case SQL_CURSOR_DYNAMIC: 1343 OTools::GetInfo(m_pStatement->getOwnConnection(),m_aConnectionHandle,SQL_DYNAMIC_CURSOR_ATTRIBUTES1,nAttr,NULL); 1344 break; 1345 } 1346 } 1347 catch(Exception&) 1348 { 1349 return sal_False; 1350 } 1351 1352 if ( m_nUseBookmarks == ODBC_SQL_NOT_DEFINED ) 1353 { 1354 m_nUseBookmarks = SQL_UB_OFF; 1355 SQLRETURN nRet = N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_USE_BOOKMARKS,&m_nUseBookmarks,SQL_IS_UINTEGER,NULL); 1356 OSL_UNUSED( nRet ); 1357 } 1358 1359 return (m_nUseBookmarks != SQL_UB_OFF) && (nAttr & SQL_CA1_BOOKMARK) == SQL_CA1_BOOKMARK; 1360 } 1361 //------------------------------------------------------------------------------ 1362 void OResultSet::setFetchDirection(sal_Int32 _par0) 1363 { 1364 OSL_ENSURE(_par0>0,"Illegal fetch direction!"); 1365 if ( _par0 > 0 ) 1366 { 1367 N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_CURSOR_TYPE,(SQLPOINTER)_par0,SQL_IS_UINTEGER); 1368 } 1369 } 1370 //------------------------------------------------------------------------------ 1371 void OResultSet::setFetchSize(sal_Int32 _par0) 1372 { 1373 OSL_ENSURE(_par0>0,"Illegal fetch size!"); 1374 if ( _par0 > 0 ) 1375 { 1376 N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_ROW_ARRAY_SIZE,(SQLPOINTER)_par0,SQL_IS_UINTEGER); 1377 delete m_pRowStatusArray; 1378 1379 m_pRowStatusArray = new SQLUSMALLINT[_par0]; 1380 N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_ROW_STATUS_PTR,m_pRowStatusArray,SQL_IS_POINTER); 1381 } 1382 } 1383 // ------------------------------------------------------------------------- 1384 IPropertyArrayHelper* OResultSet::createArrayHelper( ) const 1385 { 1386 Sequence< Property > aProps(6); 1387 Property* pProperties = aProps.getArray(); 1388 sal_Int32 nPos = 0; 1389 DECL_PROP1IMPL(CURSORNAME, ::rtl::OUString) PropertyAttribute::READONLY); 1390 DECL_PROP0(FETCHDIRECTION, sal_Int32); 1391 DECL_PROP0(FETCHSIZE, sal_Int32); 1392 DECL_BOOL_PROP1IMPL(ISBOOKMARKABLE) PropertyAttribute::READONLY); 1393 DECL_PROP1IMPL(RESULTSETCONCURRENCY,sal_Int32) PropertyAttribute::READONLY); 1394 DECL_PROP1IMPL(RESULTSETTYPE, sal_Int32) PropertyAttribute::READONLY); 1395 1396 return new OPropertyArrayHelper(aProps); 1397 } 1398 // ------------------------------------------------------------------------- 1399 IPropertyArrayHelper & OResultSet::getInfoHelper() 1400 { 1401 return *const_cast<OResultSet*>(this)->getArrayHelper(); 1402 } 1403 // ------------------------------------------------------------------------- 1404 sal_Bool OResultSet::convertFastPropertyValue( 1405 Any & rConvertedValue, 1406 Any & rOldValue, 1407 sal_Int32 nHandle, 1408 const Any& rValue ) 1409 throw (::com::sun::star::lang::IllegalArgumentException) 1410 { 1411 switch(nHandle) 1412 { 1413 case PROPERTY_ID_ISBOOKMARKABLE: 1414 case PROPERTY_ID_CURSORNAME: 1415 case PROPERTY_ID_RESULTSETCONCURRENCY: 1416 case PROPERTY_ID_RESULTSETTYPE: 1417 throw ::com::sun::star::lang::IllegalArgumentException(); 1418 case PROPERTY_ID_FETCHDIRECTION: 1419 return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchDirection()); 1420 case PROPERTY_ID_FETCHSIZE: 1421 return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchSize()); 1422 default: 1423 ; 1424 } 1425 return sal_False; 1426 } 1427 // ------------------------------------------------------------------------- 1428 void OResultSet::setFastPropertyValue_NoBroadcast( 1429 sal_Int32 nHandle, 1430 const Any& rValue 1431 ) 1432 throw (Exception) 1433 { 1434 switch(nHandle) 1435 { 1436 case PROPERTY_ID_ISBOOKMARKABLE: 1437 case PROPERTY_ID_CURSORNAME: 1438 case PROPERTY_ID_RESULTSETCONCURRENCY: 1439 case PROPERTY_ID_RESULTSETTYPE: 1440 throw Exception(); 1441 case PROPERTY_ID_FETCHDIRECTION: 1442 setFetchDirection(getINT32(rValue)); 1443 break; 1444 case PROPERTY_ID_FETCHSIZE: 1445 setFetchSize(getINT32(rValue)); 1446 break; 1447 default: 1448 ; 1449 } 1450 } 1451 // ------------------------------------------------------------------------- 1452 void OResultSet::getFastPropertyValue( 1453 Any& rValue, 1454 sal_Int32 nHandle 1455 ) const 1456 { 1457 switch(nHandle) 1458 { 1459 case PROPERTY_ID_ISBOOKMARKABLE: 1460 rValue = bool2any(isBookmarkable()); 1461 break; 1462 case PROPERTY_ID_CURSORNAME: 1463 rValue <<= getCursorName(); 1464 break; 1465 case PROPERTY_ID_RESULTSETCONCURRENCY: 1466 rValue <<= getResultSetConcurrency(); 1467 break; 1468 case PROPERTY_ID_RESULTSETTYPE: 1469 rValue <<= getResultSetType(); 1470 break; 1471 case PROPERTY_ID_FETCHDIRECTION: 1472 rValue <<= getFetchDirection(); 1473 break; 1474 case PROPERTY_ID_FETCHSIZE: 1475 rValue <<= getFetchSize(); 1476 break; 1477 } 1478 } 1479 // ------------------------------------------------------------------------- 1480 void OResultSet::fillRow(sal_Int32 _nToColumn) 1481 { 1482 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::fillRow" ); 1483 if((sal_Int32)m_aRow.size() <= _nToColumn) 1484 { 1485 m_aRow.resize(_nToColumn+1); 1486 m_aRow[_nToColumn].setBound(sal_True); 1487 } 1488 m_bFetchData = sal_False; 1489 1490 sal_Int32 nColumn = m_nLastColumnPos + 1; 1491 TDataRow::iterator pColumn = m_aRow.begin() + nColumn; 1492 TDataRow::iterator pColumnEnd = m_aRow.begin() + _nToColumn + 1; 1493 1494 for (; pColumn < pColumnEnd; ++nColumn, ++pColumn) 1495 { 1496 const sal_Int32 nType = pColumn->getTypeKind(); 1497 switch (nType) 1498 { 1499 case DataType::CHAR: 1500 case DataType::VARCHAR: 1501 case DataType::DECIMAL: 1502 case DataType::NUMERIC: 1503 case DataType::LONGVARCHAR: 1504 case DataType::CLOB: 1505 { 1506 const SWORD nColumnType = impl_getColumnType_nothrow(nColumn); 1507 *pColumn = OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,nColumn,nColumnType,m_bWasNull,**this,m_nTextEncoding); 1508 } 1509 break; 1510 case DataType::BIGINT: 1511 *pColumn = getLong(nColumn); 1512 break; 1513 case DataType::REAL: 1514 case DataType::DOUBLE: 1515 *pColumn = getDouble(nColumn); 1516 break; 1517 case DataType::LONGVARBINARY: 1518 case DataType::BLOB: 1519 *pColumn = getBytes(nColumn); 1520 break; 1521 case DataType::DATE: 1522 *pColumn = getDate(nColumn); 1523 break; 1524 case DataType::TIME: 1525 *pColumn = getTime(nColumn); 1526 break; 1527 case DataType::TIMESTAMP: 1528 *pColumn = getTimestamp(nColumn); 1529 break; 1530 case DataType::BIT: 1531 *pColumn = getBoolean(nColumn); 1532 break; 1533 case DataType::TINYINT: 1534 *pColumn = getByte(nColumn); 1535 break; 1536 case DataType::SMALLINT: 1537 *pColumn = getShort(nColumn); 1538 break; 1539 case DataType::INTEGER: 1540 *pColumn = getInt(nColumn); 1541 break; 1542 case DataType::FLOAT: 1543 *pColumn = getFloat(nColumn); 1544 break; 1545 case DataType::BINARY: 1546 case DataType::VARBINARY: 1547 *pColumn = getBytes(nColumn); 1548 break; 1549 } 1550 1551 if ( m_bWasNull ) 1552 pColumn->setNull(); 1553 if(nType != pColumn->getTypeKind()) 1554 { 1555 pColumn->setTypeKind(nType); 1556 } 1557 } 1558 m_nLastColumnPos = _nToColumn; 1559 m_bFetchData = sal_True; 1560 } 1561 // ----------------------------------------------------------------------------- 1562 void SAL_CALL OResultSet::acquire() throw() 1563 { 1564 OResultSet_BASE::acquire(); 1565 } 1566 // ----------------------------------------------------------------------------- 1567 void SAL_CALL OResultSet::release() throw() 1568 { 1569 OResultSet_BASE::release(); 1570 } 1571 // ----------------------------------------------------------------------------- 1572 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OResultSet::getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException) 1573 { 1574 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper()); 1575 } 1576 // ----------------------------------------------------------------------------- 1577 sal_Bool OResultSet::move(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool /*_bRetrieveData*/) 1578 { 1579 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::move" ); 1580 SQLSMALLINT nFetchOrientation = SQL_FETCH_NEXT; 1581 switch(_eCursorPosition) 1582 { 1583 case IResultSetHelper::NEXT: 1584 nFetchOrientation = SQL_FETCH_NEXT; 1585 break; 1586 case IResultSetHelper::PRIOR: 1587 nFetchOrientation = SQL_FETCH_PRIOR; 1588 break; 1589 case IResultSetHelper::FIRST: 1590 nFetchOrientation = SQL_FETCH_FIRST; 1591 break; 1592 case IResultSetHelper::LAST: 1593 nFetchOrientation = SQL_FETCH_LAST; 1594 break; 1595 case IResultSetHelper::RELATIVE: 1596 nFetchOrientation = SQL_FETCH_RELATIVE; 1597 break; 1598 case IResultSetHelper::ABSOLUTE: 1599 nFetchOrientation = SQL_FETCH_ABSOLUTE; 1600 break; 1601 case IResultSetHelper::BOOKMARK: // special case here because we are only called with position numbers 1602 { 1603 TBookmarkPosMap::iterator aIter = m_aPosToBookmarks.begin(); 1604 TBookmarkPosMap::iterator aEnd = m_aPosToBookmarks.end(); 1605 for (; aIter != aEnd; ++aIter) 1606 { 1607 if ( aIter->second == _nOffset ) 1608 return moveToBookmark(makeAny(aIter->first)); 1609 } 1610 OSL_ENSURE(0,"Bookmark not found!"); 1611 } 1612 return sal_False; 1613 } 1614 1615 m_bEOF = sal_False; 1616 m_nLastColumnPos = 0; 1617 1618 SQLRETURN nOldFetchStatus = m_nCurrentFetchState; 1619 if ( !m_bUseFetchScroll && _eCursorPosition == IResultSetHelper::NEXT ) 1620 m_nCurrentFetchState = N3SQLFetch(m_aStatementHandle); 1621 else 1622 m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,nFetchOrientation,_nOffset); 1623 1624 OSL_TRACE( __FILE__": OSkipDeletedSet::OResultSet::move(%d,%d), FetchState = %d",nFetchOrientation,_nOffset,m_nCurrentFetchState); 1625 OTools::ThrowException(m_pStatement->getOwnConnection(),m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this); 1626 1627 const bool bSuccess = m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO; 1628 if ( bSuccess ) 1629 { 1630 switch(_eCursorPosition) 1631 { 1632 case IResultSetHelper::NEXT: 1633 ++m_nRowPos; 1634 break; 1635 case IResultSetHelper::PRIOR: 1636 --m_nRowPos; 1637 break; 1638 case IResultSetHelper::FIRST: 1639 m_nRowPos = 1; 1640 break; 1641 case IResultSetHelper::LAST: 1642 m_bEOF = sal_True; 1643 break; 1644 case IResultSetHelper::RELATIVE: 1645 m_nRowPos += _nOffset; 1646 break; 1647 case IResultSetHelper::ABSOLUTE: 1648 case IResultSetHelper::BOOKMARK: // special case here because we are only called with position numbers 1649 m_nRowPos = _nOffset; 1650 break; 1651 } // switch(_eCursorPosition) 1652 if ( m_nUseBookmarks == ODBC_SQL_NOT_DEFINED ) 1653 { 1654 RTL_LOGFILE_CONTEXT_TRACE( aLogger, "SQLGetStmtAttr" ); 1655 m_nUseBookmarks = SQL_UB_OFF; 1656 SQLRETURN nRet = N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_USE_BOOKMARKS,&m_nUseBookmarks,SQL_IS_UINTEGER,NULL); 1657 OSL_UNUSED( nRet ); 1658 } 1659 if ( m_nUseBookmarks != SQL_UB_OFF ) 1660 { 1661 RTL_LOGFILE_CONTEXT_TRACE( aLogger, "OTools::getBytesValue" ); 1662 m_aBookmark = OTools::getBytesValue(m_pStatement->getOwnConnection(),m_aStatementHandle,0,SQL_C_VARBOOKMARK,m_bWasNull,**this); 1663 m_aPosToBookmarks[m_aBookmark] = m_nRowPos; 1664 OSL_ENSURE(m_aBookmark.getLength(),"Invalid bookmark from length 0!"); 1665 } 1666 } 1667 else if ( IResultSetHelper::PRIOR == _eCursorPosition && m_nCurrentFetchState == SQL_NO_DATA ) 1668 m_nRowPos = 0; 1669 else if(IResultSetHelper::NEXT == _eCursorPosition && m_nCurrentFetchState == SQL_NO_DATA && nOldFetchStatus != SQL_NO_DATA) 1670 ++m_nRowPos; 1671 1672 return bSuccess; 1673 } 1674 // ----------------------------------------------------------------------------- 1675 sal_Int32 OResultSet::getDriverPos() const 1676 { 1677 sal_Int32 nValue = 0; 1678 SQLRETURN nRet = N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_ROW_NUMBER,&nValue,SQL_IS_UINTEGER,0); 1679 OSL_UNUSED( nRet ); 1680 OSL_TRACE( __FILE__": OResultSet::getDriverPos() = Ret = %d, RowNum = %d, RowPos = %d",nRet,nValue , m_nRowPos); 1681 return nValue ? nValue : m_nRowPos; 1682 } 1683 // ----------------------------------------------------------------------------- 1684 sal_Bool OResultSet::deletedVisible() const 1685 { 1686 return sal_False; 1687 } 1688 // ----------------------------------------------------------------------------- 1689 sal_Bool OResultSet::isRowDeleted() const 1690 { 1691 return m_pRowStatusArray[0] == SQL_ROW_DELETED; 1692 } 1693 // ----------------------------------------------------------------------------- 1694 sal_Bool OResultSet::moveImpl(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool _bRetrieveData) 1695 { 1696 ::osl::MutexGuard aGuard( m_aMutex ); 1697 checkDisposed(OResultSet_BASE::rBHelper.bDisposed); 1698 return (m_pSkipDeletedSet != NULL) 1699 ? m_pSkipDeletedSet->skipDeleted(_eCursorPosition,_nOffset,_bRetrieveData) 1700 : move(_eCursorPosition,_nOffset,_bRetrieveData); 1701 } 1702 // ----------------------------------------------------------------------------- 1703 void OResultSet::fillNeededData(SQLRETURN _nRet) 1704 { 1705 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::fillNeededData" ); 1706 SQLRETURN nRet = _nRet; 1707 if( nRet == SQL_NEED_DATA) 1708 { 1709 void* pColumnIndex = 0; 1710 nRet = N3SQLParamData(m_aStatementHandle,&pColumnIndex); 1711 1712 do 1713 { 1714 if (nRet != SQL_SUCCESS && nRet != SQL_SUCCESS_WITH_INFO && nRet != SQL_NEED_DATA) 1715 break; 1716 1717 sal_IntPtr nColumnIndex ( reinterpret_cast<sal_IntPtr>(pColumnIndex)); 1718 Sequence< sal_Int8 > aSeq; 1719 switch(m_aRow[nColumnIndex].getTypeKind()) 1720 { 1721 case DataType::BINARY: 1722 case DataType::VARBINARY: 1723 case DataType::LONGVARBINARY: 1724 case DataType::BLOB: 1725 aSeq = m_aRow[nColumnIndex]; 1726 N3SQLPutData (m_aStatementHandle, aSeq.getArray(), aSeq.getLength()); 1727 break; 1728 case SQL_WLONGVARCHAR: 1729 { 1730 ::rtl::OUString sRet; 1731 sRet = m_aRow[nColumnIndex].getString(); 1732 nRet = N3SQLPutData (m_aStatementHandle, (SQLPOINTER)sRet.getStr(), sizeof(sal_Unicode)*sRet.getLength()); 1733 break; 1734 } 1735 case DataType::LONGVARCHAR: 1736 case DataType::CLOB: 1737 { 1738 ::rtl::OUString sRet; 1739 sRet = m_aRow[nColumnIndex].getString(); 1740 ::rtl::OString aString(::rtl::OUStringToOString(sRet,m_nTextEncoding)); 1741 nRet = N3SQLPutData (m_aStatementHandle, (SQLPOINTER)aString.getStr(), aString.getLength()); 1742 break; 1743 } 1744 default: 1745 OSL_ENSURE(0,"Not supported at the moment!"); 1746 } 1747 nRet = N3SQLParamData(m_aStatementHandle,&pColumnIndex); 1748 } 1749 while (nRet == SQL_NEED_DATA); 1750 } 1751 } 1752 // ----------------------------------------------------------------------------- 1753 SWORD OResultSet::impl_getColumnType_nothrow(sal_Int32 columnIndex) 1754 { 1755 ::std::map<sal_Int32,SWORD>::iterator aFind = m_aODBCColumnTypes.find(columnIndex); 1756 if ( aFind == m_aODBCColumnTypes.end() ) 1757 aFind = m_aODBCColumnTypes.insert(::std::map<sal_Int32,SWORD>::value_type(columnIndex,OResultSetMetaData::getColumnODBCType(m_pStatement->getOwnConnection(),m_aStatementHandle,*this,columnIndex))).first; 1758 return aFind->second; 1759 } 1760 1761