xref: /trunk/main/connectivity/source/drivers/ado/AResultSet.cxx (revision 45c5a00162811bd03b87fcb4fe9996782f2b59ec) !
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_ado.hxx"
26 #include "ado/AResultSet.hxx"
27 #include "ado/AResultSetMetaData.hxx"
28 #include <com/sun/star/sdbc/DataType.hpp>
29 #include <com/sun/star/sdbc/KeyRule.hpp>
30 #include <com/sun/star/sdbc/IndexType.hpp>
31 #include <comphelper/property.hxx>
32 #include <com/sun/star/lang/DisposedException.hpp>
33 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
34 #include <com/sun/star/sdbc/ResultSetType.hpp>
35 #include <com/sun/star/sdbc/FetchDirection.hpp>
36 #include <cppuhelper/typeprovider.hxx>
37 #include <comphelper/sequence.hxx>
38 #include <com/sun/star/beans/PropertyAttribute.hpp>
39 #include <comphelper/seqstream.hxx>
40 #include "connectivity/dbexception.hxx"
41 #include "connectivity/dbtools.hxx"
42 #include <comphelper/types.hxx>
43 
44 using namespace ::comphelper;
45 
46 
47 #include <oledb.h>
48 
49 #define CHECK_RETURN(x)                                                 \
50     if(!SUCCEEDED(x))                                                               \
51         ADOS::ThrowException(*m_pStmt->m_pConnection->getConnection(),*this);
52 
53 using namespace connectivity::ado;
54 using namespace com::sun::star::uno;
55 using namespace com::sun::star::lang;
56 using namespace com::sun::star::beans;
57 using namespace com::sun::star::sdbc;
58 
59 //------------------------------------------------------------------------------
60 //  IMPLEMENT_SERVICE_INFO(OResultSet,"com.sun.star.sdbcx.AResultSet","com.sun.star.sdbc.ResultSet");
61 ::rtl::OUString SAL_CALL OResultSet::getImplementationName(  )  \
62 {
63     return ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.ado.ResultSet");
64 }
65 // -------------------------------------------------------------------------
66 ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL OResultSet::getSupportedServiceNames(  )
67 {
68     ::com::sun::star::uno::Sequence< ::rtl::OUString > aSupported(2);
69     aSupported[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbc.ResultSet");
70     aSupported[1] = ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.ResultSet");
71     return aSupported;
72 }
73 // -------------------------------------------------------------------------
74 sal_Bool SAL_CALL OResultSet::supportsService( const ::rtl::OUString& _rServiceName )
75 {
76     Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
77     const ::rtl::OUString* pSupported = aSupported.getConstArray();
78     const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
79     for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
80         ;
81 
82     return pSupported != pEnd;
83 }
84 // -------------------------------------------------------------------------
85 OResultSet::OResultSet(ADORecordset* _pRecordSet,OStatement_Base* pStmt) :  OResultSet_BASE(m_aMutex)
86                         ,OPropertySetHelper(OResultSet_BASE::rBHelper)
87                         ,m_xStatement(*pStmt)
88                         ,m_pStmt(pStmt)
89                         ,m_nRowPos(0)
90                         ,m_xMetaData(NULL)
91                         ,m_pRecordSet(_pRecordSet)
92                         ,m_bEOF(sal_False)
93 {
94 }
95 // -------------------------------------------------------------------------
96 OResultSet::OResultSet(ADORecordset* _pRecordSet) : OResultSet_BASE(m_aMutex)
97                         ,OPropertySetHelper(OResultSet_BASE::rBHelper)
98                         ,m_xStatement(NULL)
99                         ,m_xMetaData(NULL)
100                         ,m_pRecordSet(_pRecordSet)
101                         ,m_bEOF(sal_False)
102 {
103 }
104 // -----------------------------------------------------------------------------
105 void OResultSet::construct()
106 {
107     osl_incrementInterlockedCount( &m_refCount );
108     if (!m_pRecordSet)
109     {
110         OSL_ENSURE( sal_False, "OResultSet::construct: no RecordSet!" );
111         Reference< XInterface > xInt( *this );
112         osl_decrementInterlockedCount( &m_refCount );
113         ::dbtools::throwFunctionSequenceException( xInt );
114     }
115     m_pRecordSet->AddRef();
116     VARIANT_BOOL bIsAtBOF;
117     CHECK_RETURN(m_pRecordSet->get_BOF(&bIsAtBOF))
118     m_bOnFirstAfterOpen = bIsAtBOF != VARIANT_TRUE;
119     osl_decrementInterlockedCount( &m_refCount );
120 }
121 // -------------------------------------------------------------------------
122 OResultSet::~OResultSet()
123 {
124     if(m_pRecordSet)
125         m_pRecordSet->Release();
126 }
127 // -------------------------------------------------------------------------
128 void OResultSet::disposing(void)
129 {
130     OPropertySetHelper::disposing();
131 
132     ::osl::MutexGuard aGuard(m_aMutex);
133     if(m_pRecordSet)
134         m_pRecordSet->Close();
135 m_xStatement.clear();
136 m_xMetaData.clear();
137 }
138 // -------------------------------------------------------------------------
139 Any SAL_CALL OResultSet::queryInterface( const Type & rType )
140 {
141     Any aRet = OPropertySetHelper::queryInterface(rType);
142     return aRet.hasValue() ? aRet : OResultSet_BASE::queryInterface(rType);
143 }
144 // -------------------------------------------------------------------------
145 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL OResultSet::getTypes(  )
146 {
147     ::cppu::OTypeCollection aTypes( ::getCppuType( (const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet > *)0 ),
148                                     ::getCppuType( (const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XFastPropertySet > *)0 ),
149                                     ::getCppuType( (const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > *)0 ));
150 
151     return ::comphelper::concatSequences(aTypes.getTypes(),OResultSet_BASE::getTypes());
152 }
153 
154 // -------------------------------------------------------------------------
155 
156 sal_Int32 SAL_CALL OResultSet::findColumn( const ::rtl::OUString& columnName )
157 {
158     ::osl::MutexGuard aGuard( m_aMutex );
159     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
160 
161 
162     Reference< XResultSetMetaData > xMeta = getMetaData();
163     sal_Int32 nLen = xMeta->getColumnCount();
164     sal_Int32 i = 1;
165     for(;i<=nLen;++i)
166         if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) :
167             columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i)))
168             break;
169     return i;
170 }
171 #define BLOCK_SIZE 256
172 // -------------------------------------------------------------------------
173 Reference< ::com::sun::star::io::XInputStream > SAL_CALL OResultSet::getBinaryStream( sal_Int32 columnIndex )
174 {
175     ::osl::MutexGuard aGuard( m_aMutex );
176     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
177 
178     WpADOField aField = ADOS::getField(m_pRecordSet,columnIndex);
179 
180     if((aField.GetAttributes() & adFldLong) == adFldLong)
181     {
182         //Copy the data only up to the Actual Size of Field.
183         sal_Int32 nSize = aField.GetActualSize();
184         Sequence<sal_Int8> aData(nSize);
185         long index = 0;
186         while(index < nSize)
187         {
188             m_aValue = aField.GetChunk(BLOCK_SIZE);
189             if(m_aValue.isNull())
190                 break;
191             UCHAR chData;
192             for(long index2 = 0;index2 < BLOCK_SIZE;++index2)
193             {
194                 HRESULT hr = ::SafeArrayGetElement(m_aValue.parray,&index2,&chData);
195                 if(SUCCEEDED(hr))
196                 {
197                     //Take BYTE by BYTE and advance Memory Location
198                     aData.getArray()[index++] = chData;
199                 }
200                 else
201                     break;
202             }
203         }
204 
205         return new ::comphelper::SequenceInputStream(aData);
206     }
207     // else we ask for a bytesequence
208     aField.get_Value(m_aValue);
209 
210     return m_aValue.isNull() ? NULL : new ::comphelper::SequenceInputStream(m_aValue);
211 }
212 // -------------------------------------------------------------------------
213 Reference< ::com::sun::star::io::XInputStream > SAL_CALL OResultSet::getCharacterStream( sal_Int32 /*columnIndex*/ )
214 {
215     ::dbtools::throwFeatureNotImplementedException( "XRow::getCharacterStream", *this );
216     return NULL;
217 }
218 // -----------------------------------------------------------------------------
219 OLEVariant OResultSet::getValue(sal_Int32 columnIndex )
220 {
221     ::osl::MutexGuard aGuard( m_aMutex );
222     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
223 
224     WpADOField aField = ADOS::getField(m_pRecordSet,columnIndex);
225     aField.get_Value(m_aValue);
226     return m_aValue;
227 }
228 // -------------------------------------------------------------------------
229 sal_Bool SAL_CALL OResultSet::getBoolean( sal_Int32 columnIndex )
230 {
231     return getValue(columnIndex);
232 }
233 // -------------------------------------------------------------------------
234 
235 sal_Int8 SAL_CALL OResultSet::getByte( sal_Int32 columnIndex )
236 {
237     return getValue(columnIndex);
238 }
239 // -------------------------------------------------------------------------
240 
241 Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes( sal_Int32 columnIndex )
242 {
243     return getValue(columnIndex);
244 }
245 // -------------------------------------------------------------------------
246 
247 ::com::sun::star::util::Date SAL_CALL OResultSet::getDate( sal_Int32 columnIndex )
248 {
249     return getValue(columnIndex);
250 }
251 // -------------------------------------------------------------------------
252 
253 double SAL_CALL OResultSet::getDouble( sal_Int32 columnIndex )
254 {
255     return getValue(columnIndex);
256 }
257 // -------------------------------------------------------------------------
258 
259 float SAL_CALL OResultSet::getFloat( sal_Int32 columnIndex )
260 {
261     return getValue(columnIndex);
262 }
263 // -------------------------------------------------------------------------
264 
265 sal_Int32 SAL_CALL OResultSet::getInt( sal_Int32 columnIndex )
266 {
267     return getValue(columnIndex);
268 }
269 // -------------------------------------------------------------------------
270 
271 sal_Int32 SAL_CALL OResultSet::getRow(  )
272 {
273     ::osl::MutexGuard aGuard( m_aMutex );
274     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
275 
276 
277     PositionEnum_Param aPos;
278     m_pRecordSet->get_AbsolutePosition(&aPos);
279     return  (aPos > 0) ? aPos : m_nRowPos;
280     // return the rowcount from driver if the driver doesn't support this return our count
281 }
282 // -------------------------------------------------------------------------
283 
284 sal_Int64 SAL_CALL OResultSet::getLong( sal_Int32 /*columnIndex*/ )
285 {
286     ::dbtools::throwFeatureNotImplementedException( "XRow::getLong", *this );
287     return sal_Int64(0);
288 }
289 // -------------------------------------------------------------------------
290 
291 Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData(  )
292 {
293     ::osl::MutexGuard aGuard( m_aMutex );
294     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
295 
296 
297     if(!m_xMetaData.is())
298         m_xMetaData = new OResultSetMetaData(m_pRecordSet);
299     return m_xMetaData;
300 }
301 // -------------------------------------------------------------------------
302 Reference< XArray > SAL_CALL OResultSet::getArray( sal_Int32 /*columnIndex*/ )
303 {
304     ::dbtools::throwFeatureNotImplementedException( "XRow::getArray", *this );
305     return NULL;
306 }
307 
308 // -------------------------------------------------------------------------
309 
310 Reference< XClob > SAL_CALL OResultSet::getClob( sal_Int32 /*columnIndex*/ )
311 {
312     ::dbtools::throwFeatureNotImplementedException( "XRow::getClob", *this );
313     return NULL;
314 }
315 // -------------------------------------------------------------------------
316 Reference< XBlob > SAL_CALL OResultSet::getBlob( sal_Int32 /*columnIndex*/ )
317 {
318     ::dbtools::throwFeatureNotImplementedException( "XRow::getBlob", *this );
319     return NULL;
320 }
321 // -------------------------------------------------------------------------
322 
323 Reference< XRef > SAL_CALL OResultSet::getRef( sal_Int32 /*columnIndex*/ )
324 {
325     ::dbtools::throwFeatureNotImplementedException( "XRow::getRef", *this );
326     return NULL;
327 }
328 // -------------------------------------------------------------------------
329 
330 Any SAL_CALL OResultSet::getObject( sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ )
331 {
332     return getValue(columnIndex).makeAny();
333 }
334 // -------------------------------------------------------------------------
335 
336 sal_Int16 SAL_CALL OResultSet::getShort( sal_Int32 columnIndex )
337 {
338     return getValue(columnIndex);
339 }
340 // -------------------------------------------------------------------------
341 
342 ::rtl::OUString SAL_CALL OResultSet::getString( sal_Int32 columnIndex )
343 {
344     return getValue(columnIndex);
345 }
346 
347 // -------------------------------------------------------------------------
348 
349 
350 ::com::sun::star::util::Time SAL_CALL OResultSet::getTime( sal_Int32 columnIndex )
351 {
352     return getValue(columnIndex);
353 }
354 // -------------------------------------------------------------------------
355 
356 
357 ::com::sun::star::util::DateTime SAL_CALL OResultSet::getTimestamp( sal_Int32 columnIndex )
358 {
359     return getValue(columnIndex);
360 }
361 // -------------------------------------------------------------------------
362 
363 sal_Bool SAL_CALL OResultSet::isAfterLast(  )
364 {
365     ::osl::MutexGuard aGuard( m_aMutex );
366     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
367 
368 
369     VARIANT_BOOL bIsAtEOF;
370     CHECK_RETURN(m_pRecordSet->get_EOF(&bIsAtEOF))
371     return bIsAtEOF == VARIANT_TRUE;
372 }
373 // -------------------------------------------------------------------------
374 sal_Bool SAL_CALL OResultSet::isFirst(  )
375 {
376     ::osl::MutexGuard aGuard( m_aMutex );
377     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
378 
379 
380     return m_nRowPos == 1;
381 }
382 // -------------------------------------------------------------------------
383 sal_Bool SAL_CALL OResultSet::isLast(  )
384 {
385     ::osl::MutexGuard aGuard( m_aMutex );
386     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
387 
388 
389     return sal_True;
390 }
391 // -------------------------------------------------------------------------
392 void SAL_CALL OResultSet::beforeFirst(  )
393 {
394     ::osl::MutexGuard aGuard( m_aMutex );
395     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
396 
397 
398     if(first())
399         m_bOnFirstAfterOpen = !previous();
400 }
401 // -------------------------------------------------------------------------
402 void SAL_CALL OResultSet::afterLast(  )
403 {
404     ::osl::MutexGuard aGuard( m_aMutex );
405     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
406 
407 
408     if(last())
409         next();
410     m_bEOF = sal_True;
411 }
412 // -------------------------------------------------------------------------
413 
414 void SAL_CALL OResultSet::close(  )
415 {
416     {
417         ::osl::MutexGuard aGuard( m_aMutex );
418         checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
419 
420     }
421     dispose();
422 }
423 // -------------------------------------------------------------------------
424 
425 sal_Bool SAL_CALL OResultSet::first(  )
426 {
427     ::osl::MutexGuard aGuard( m_aMutex );
428     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
429 
430 
431     if(SUCCEEDED(m_pRecordSet->MoveFirst()))
432     {
433         m_nRowPos = 1;
434         m_bOnFirstAfterOpen = sal_False;
435         return sal_True;
436     }
437     return sal_False;
438 }
439 // -------------------------------------------------------------------------
440 
441 sal_Bool SAL_CALL OResultSet::last(  )
442 {
443     ::osl::MutexGuard aGuard( m_aMutex );
444     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
445 
446 
447     sal_Bool bRet = SUCCEEDED(m_pRecordSet->MoveLast());
448     if(bRet)
449     {
450         sal_IntPtr rowPos;
451         m_pRecordSet->get_RecordCount(&rowPos);
452         m_nRowPos = rowPos;
453         m_bOnFirstAfterOpen = sal_False;
454     }
455     return bRet;
456 }
457 // -------------------------------------------------------------------------
458 sal_Bool SAL_CALL OResultSet::absolute( sal_Int32 row )
459 {
460     ::osl::MutexGuard aGuard( m_aMutex );
461     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
462 
463 
464     if(!row)                 // absolute with zero not allowed
465         ::dbtools::throwFunctionSequenceException(*this);
466 
467     sal_Bool bCheck = sal_True;
468     if(row < 0)
469     {
470         bCheck = SUCCEEDED(m_pRecordSet->MoveLast());
471         if ( bCheck )
472         {
473             while(++row < 0 && bCheck)
474                 bCheck = SUCCEEDED(m_pRecordSet->MovePrevious());
475         }
476     }
477     else
478     {
479         first();
480         OLEVariant aEmpty;
481         aEmpty.setNoArg();
482         bCheck = SUCCEEDED(m_pRecordSet->Move(row-1,aEmpty)); // move to row -1 because we stand already on the first
483         if(bCheck)
484             m_nRowPos = row;
485     }
486     if(bCheck)
487         m_bOnFirstAfterOpen = sal_False;
488     return bCheck;
489 }
490 // -------------------------------------------------------------------------
491 sal_Bool SAL_CALL OResultSet::relative( sal_Int32 row )
492 {
493     ::osl::MutexGuard aGuard( m_aMutex );
494     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
495 
496 
497     OLEVariant aEmpty;
498     aEmpty.setNoArg();
499     sal_Int32 nNewPos = row;
500     if ( m_bOnFirstAfterOpen && nNewPos > 0 )
501         --nNewPos;
502     sal_Bool bRet = SUCCEEDED(m_pRecordSet->Move(row,aEmpty));
503     if(bRet)
504     {
505         m_nRowPos += row;
506         m_bOnFirstAfterOpen = sal_False;
507     }
508     return bRet;
509 }
510 // -------------------------------------------------------------------------
511 sal_Bool SAL_CALL OResultSet::previous(  )
512 {
513     ::osl::MutexGuard aGuard( m_aMutex );
514     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
515 
516     sal_Bool bRet = SUCCEEDED(m_pRecordSet->MovePrevious());
517     if(bRet)
518     {
519         --m_nRowPos;
520         m_bOnFirstAfterOpen = sal_False;
521     }
522     return bRet;
523 }
524 // -------------------------------------------------------------------------
525 Reference< XInterface > SAL_CALL OResultSet::getStatement(  )
526 {
527     ::osl::MutexGuard aGuard( m_aMutex );
528     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
529     return m_xStatement;
530 }
531 // -------------------------------------------------------------------------
532 
533 sal_Bool SAL_CALL OResultSet::rowDeleted(  )
534 {
535     ::osl::MutexGuard aGuard( m_aMutex );
536     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
537 
538 
539     RecordStatusEnum eRec;
540     m_pRecordSet->get_Status((sal_Int32*)&eRec);
541     sal_Bool  bRet = (eRec & adRecDeleted) == adRecDeleted;
542     if(bRet)
543         --m_nRowPos;
544     return bRet;
545 }
546 // -------------------------------------------------------------------------
547 sal_Bool SAL_CALL OResultSet::rowInserted(  )
548 {   ::osl::MutexGuard aGuard( m_aMutex );
549     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
550 
551 
552     RecordStatusEnum eRec;
553     m_pRecordSet->get_Status((sal_Int32*)&eRec);
554     sal_Bool  bRet = (eRec & adRecNew) == adRecNew;
555     if(bRet)
556         ++m_nRowPos;
557     return bRet;
558 }
559 // -------------------------------------------------------------------------
560 sal_Bool SAL_CALL OResultSet::rowUpdated(  )
561 {
562     ::osl::MutexGuard aGuard( m_aMutex );
563     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
564 
565 
566     RecordStatusEnum eRec;
567     m_pRecordSet->get_Status((sal_Int32*)&eRec);
568     return (eRec & adRecModified) == adRecModified;
569 }
570 // -------------------------------------------------------------------------
571 
572 sal_Bool SAL_CALL OResultSet::isBeforeFirst(  )
573 {
574     ::osl::MutexGuard aGuard( m_aMutex );
575     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
576 
577 
578     OSL_ENSURE(!m_nRowPos,"OResultSet::isBeforeFirst: Error in setting m_nRowPos!");
579     VARIANT_BOOL bIsAtBOF = VARIANT_TRUE;
580     if(!m_bOnFirstAfterOpen)
581     {
582         OSL_ENSURE(!m_nRowPos,"OResultSet::isBeforeFirst: Error in setting m_nRowPos!");
583         m_pRecordSet->get_BOF(&bIsAtBOF);
584     }
585     return bIsAtBOF == VARIANT_TRUE;
586 }
587 // -------------------------------------------------------------------------
588 
589 sal_Bool SAL_CALL OResultSet::next(  )
590 {
591     ::osl::MutexGuard aGuard( m_aMutex );
592     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
593 
594 
595     sal_Bool bRet = sal_True;
596     if(m_bOnFirstAfterOpen)
597     {
598         m_bOnFirstAfterOpen = sal_False;
599         ++m_nRowPos;
600     }
601     else
602     {
603         bRet = SUCCEEDED(m_pRecordSet->MoveNext());
604 
605         if(bRet)
606         {
607             VARIANT_BOOL bIsAtEOF;
608             CHECK_RETURN(m_pRecordSet->get_EOF(&bIsAtEOF))
609             bRet = bIsAtEOF != VARIANT_TRUE;
610             ++m_nRowPos;
611         }
612         else
613             ADOS::ThrowException(*m_pStmt->m_pConnection->getConnection(),*this);
614     }
615 
616     return bRet;
617 }
618 // -------------------------------------------------------------------------
619 
620 sal_Bool SAL_CALL OResultSet::wasNull(  )
621 {
622     ::osl::MutexGuard aGuard( m_aMutex );
623     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
624 
625 
626     return m_aValue.isNull();
627 }
628 // -------------------------------------------------------------------------
629 
630 void SAL_CALL OResultSet::cancel(  )
631 {
632     ::osl::MutexGuard aGuard( m_aMutex );
633     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
634 
635 
636     m_pRecordSet->Cancel();
637 }
638 // -------------------------------------------------------------------------
639 void SAL_CALL OResultSet::clearWarnings(  )
640 {
641 }
642 // -------------------------------------------------------------------------
643 Any SAL_CALL OResultSet::getWarnings(  )
644 {
645     return Any();
646 }
647 // -------------------------------------------------------------------------
648 void SAL_CALL OResultSet::insertRow(  )
649 {
650     ::osl::MutexGuard aGuard( m_aMutex );
651     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
652 
653 
654     OLEVariant aEmpty;
655     aEmpty.setNoArg();
656     m_pRecordSet->AddNew(aEmpty,aEmpty);
657 }
658 // -------------------------------------------------------------------------
659 void SAL_CALL OResultSet::updateRow(  )
660 {
661     ::osl::MutexGuard aGuard( m_aMutex );
662     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
663 
664 
665     OLEVariant aEmpty;
666     aEmpty.setNoArg();
667     m_pRecordSet->Update(aEmpty,aEmpty);
668 }
669 // -------------------------------------------------------------------------
670 void SAL_CALL OResultSet::deleteRow(  )
671 {
672     ::osl::MutexGuard aGuard( m_aMutex );
673     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
674 
675 
676     m_pRecordSet->Delete(adAffectCurrent);
677     m_pRecordSet->UpdateBatch(adAffectCurrent);
678 }
679 // -------------------------------------------------------------------------
680 
681 void SAL_CALL OResultSet::cancelRowUpdates(  )
682 {
683     ::osl::MutexGuard aGuard( m_aMutex );
684     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
685 
686 
687     m_pRecordSet->CancelUpdate();
688 }
689 // -------------------------------------------------------------------------
690 
691 void SAL_CALL OResultSet::moveToInsertRow(  )
692 {
693  //   ::osl::MutexGuard aGuard( m_aMutex );
694     //checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
695  //   if ( getResultSetConcurrency() == ResultSetConcurrency::READ_ONLY )
696  //       throw SQLException();
697 }
698 // -------------------------------------------------------------------------
699 
700 void SAL_CALL OResultSet::moveToCurrentRow(  )
701 {
702 }
703 // -----------------------------------------------------------------------------
704 void OResultSet::updateValue(sal_Int32 columnIndex,const OLEVariant& x)
705 {
706     ::osl::MutexGuard aGuard( m_aMutex );
707     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
708 
709     WpADOField aField = ADOS::getField(m_pRecordSet,columnIndex);
710     aField.PutValue(x);
711 }
712 // -------------------------------------------------------------------------
713 void SAL_CALL OResultSet::updateNull( sal_Int32 columnIndex )
714 {
715     OLEVariant x;
716     x.setNull();
717     updateValue(columnIndex,x);
718 }
719 // -------------------------------------------------------------------------
720 
721 void SAL_CALL OResultSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x )
722 {
723     updateValue(columnIndex,x);
724 }
725 // -------------------------------------------------------------------------
726 void SAL_CALL OResultSet::updateByte( sal_Int32 columnIndex, sal_Int8 x )
727 {
728     updateValue(columnIndex,x);
729 }
730 // -------------------------------------------------------------------------
731 
732 void SAL_CALL OResultSet::updateShort( sal_Int32 columnIndex, sal_Int16 x )
733 {
734     updateValue(columnIndex,x);
735 }
736 // -------------------------------------------------------------------------
737 void SAL_CALL OResultSet::updateInt( sal_Int32 columnIndex, sal_Int32 x )
738 {
739     updateValue(columnIndex,x);
740 }
741 // -------------------------------------------------------------------------
742 void SAL_CALL OResultSet::updateLong( sal_Int32 columnIndex, sal_Int64 x )
743 {
744     updateValue(columnIndex,x);
745 }
746 // -----------------------------------------------------------------------
747 void SAL_CALL OResultSet::updateFloat( sal_Int32 columnIndex, float x )
748 {
749     updateValue(columnIndex,x);
750 }
751 // -------------------------------------------------------------------------
752 
753 void SAL_CALL OResultSet::updateDouble( sal_Int32 columnIndex, double x )
754 {
755     updateValue(columnIndex,x);
756 }
757 // -------------------------------------------------------------------------
758 void SAL_CALL OResultSet::updateString( sal_Int32 columnIndex, const ::rtl::OUString& x )
759 {
760     updateValue(columnIndex,x);
761 }
762 // -------------------------------------------------------------------------
763 void SAL_CALL OResultSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x )
764 {
765     updateValue(columnIndex,x);
766 }
767 // -------------------------------------------------------------------------
768 void SAL_CALL OResultSet::updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x )
769 {
770     updateValue(columnIndex,x);
771 }
772 // -------------------------------------------------------------------------
773 
774 void SAL_CALL OResultSet::updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x )
775 {
776     updateValue(columnIndex,x);
777 }
778 // -------------------------------------------------------------------------
779 
780 void SAL_CALL OResultSet::updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x )
781 {
782     updateValue(columnIndex,x);
783 }
784 // -------------------------------------------------------------------------
785 
786 void SAL_CALL OResultSet::updateBinaryStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length )
787 {
788     if(!x.is())
789         ::dbtools::throwFunctionSequenceException(*this);
790 
791     Sequence<sal_Int8> aSeq;
792     x->readBytes(aSeq,length);
793     updateBytes(columnIndex,aSeq);
794 }
795 // -------------------------------------------------------------------------
796 void SAL_CALL OResultSet::updateCharacterStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length )
797 {
798     if(!x.is())
799         ::dbtools::throwFunctionSequenceException(*this);
800 
801     Sequence<sal_Int8> aSeq;
802     x->readBytes(aSeq,length);
803     updateBytes(columnIndex,aSeq);
804 }
805 // -------------------------------------------------------------------------
806 void SAL_CALL OResultSet::refreshRow(  )
807 {
808     ::osl::MutexGuard aGuard( m_aMutex );
809     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
810 
811 
812     m_pRecordSet->Resync(adAffectCurrent,adResyncAllValues);
813 }
814 // -------------------------------------------------------------------------
815 void SAL_CALL OResultSet::updateObject( sal_Int32 columnIndex, const Any& x )
816 {
817     if (!::dbtools::implUpdateObject(this, columnIndex, x))
818         throw SQLException();
819 }
820 // -------------------------------------------------------------------------
821 
822 void SAL_CALL OResultSet::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 /*scale*/ )
823 {
824     if (!::dbtools::implUpdateObject(this, columnIndex, x))
825         throw SQLException();
826 }
827 //------------------------------------------------------------------------------
828 // XRowLocate
829 Any SAL_CALL OResultSet::getBookmark(  )
830 {
831     ::osl::MutexGuard aGuard( m_aMutex );
832     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
833 
834     if(m_nRowPos < (sal_Int32)m_aBookmarks.size()) // this bookmark was already fetched
835         return makeAny(sal_Int32(m_nRowPos-1));
836 
837     OLEVariant aVar;
838     m_pRecordSet->get_Bookmark(&aVar);
839     m_aBookmarks.push_back(aVar);
840     return makeAny((sal_Int32)(m_aBookmarks.size()-1));
841 
842 }
843 //------------------------------------------------------------------------------
844 sal_Bool SAL_CALL OResultSet::moveToBookmark( const Any& bookmark )
845 {
846     ::osl::MutexGuard aGuard( m_aMutex );
847     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
848 
849 
850     sal_Int32 nPos;
851     bookmark >>= nPos;
852     OSL_ENSURE(nPos >= 0 && nPos < (sal_Int32)m_aBookmarks.size(),"Invalid Index for vector");
853     if(nPos < 0 || nPos >= (sal_Int32)m_aBookmarks.size())
854         ::dbtools::throwFunctionSequenceException(*this);
855 
856     return SUCCEEDED(m_pRecordSet->Move(0,m_aBookmarks[nPos]));
857 }
858 //------------------------------------------------------------------------------
859 sal_Bool SAL_CALL OResultSet::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows )
860 {
861     ::osl::MutexGuard aGuard( m_aMutex );
862     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
863 
864 
865     sal_Int32 nPos;
866     bookmark >>= nPos;
867     nPos += rows;
868     OSL_ENSURE(nPos >= 0 && nPos < (sal_Int32)m_aBookmarks.size(),"Invalid Index for vector");
869     if(nPos < 0 || nPos >= (sal_Int32)m_aBookmarks.size())
870         ::dbtools::throwFunctionSequenceException(*this);
871     return SUCCEEDED(m_pRecordSet->Move(rows,m_aBookmarks[nPos]));
872 }
873 //------------------------------------------------------------------------------
874 sal_Int32 SAL_CALL OResultSet::compareBookmarks( const Any& first, const Any& second )
875 {
876     ::osl::MutexGuard aGuard( m_aMutex );
877     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
878 
879     sal_Int32 nPos1;
880     first >>= nPos1;
881     sal_Int32 nPos2;
882     second >>= nPos2;
883     if(nPos1 == nPos2)  // they should be equal
884         return sal_True;
885 
886     OSL_ENSURE((nPos1 >= 0 && nPos1 < (sal_Int32)m_aBookmarks.size()) || (nPos1 >= 0 && nPos2 < (sal_Int32)m_aBookmarks.size()),"Invalid Index for vector");
887 
888     CompareEnum eNum;
889     m_pRecordSet->CompareBookmarks(m_aBookmarks[nPos1],m_aBookmarks[nPos2],&eNum);
890     return ((sal_Int32)eNum) +1;
891 }
892 //------------------------------------------------------------------------------
893 sal_Bool SAL_CALL OResultSet::hasOrderedBookmarks(  )
894 {
895     ::osl::MutexGuard aGuard( m_aMutex );
896     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
897 
898 
899     ADOProperties* pProps = NULL;
900     m_pRecordSet->get_Properties(&pProps);
901     WpADOProperties aProps;
902     aProps.setWithOutAddRef(pProps);
903     ADOS::ThrowException(*((OConnection*)m_pStmt->getConnection().get())->getConnection(),*this);
904     OSL_ENSURE(aProps.IsValid(),"There are no properties at the connection");
905 
906     WpADOProperty aProp(aProps.GetItem(::rtl::OUString::createFromAscii("Bookmarks Ordered")));
907     OLEVariant aVar;
908     if(aProp.IsValid())
909         aVar = aProp.GetValue();
910     else
911         ADOS::ThrowException(*((OConnection*)m_pStmt->getConnection().get())->getConnection(),*this);
912 
913     sal_Bool bValue(sal_False);
914     if(!aVar.isNull() && !aVar.isEmpty())
915         bValue = aVar;
916     return bValue;
917 }
918 //------------------------------------------------------------------------------
919 sal_Int32 SAL_CALL OResultSet::hashBookmark( const Any& bookmark )
920 {
921     ::osl::MutexGuard aGuard( m_aMutex );
922     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
923 
924 
925     sal_Int32 nPos;
926     bookmark >>= nPos;
927     return nPos;
928 }
929 //------------------------------------------------------------------------------
930 // XDeleteRows
931 Sequence< sal_Int32 > SAL_CALL OResultSet::deleteRows( const Sequence< Any >& rows )
932 {
933     ::osl::MutexGuard aGuard( m_aMutex );
934     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
935 
936 
937     OLEVariant aVar;
938     sal_Int32 nPos;
939 
940     // Create SafeArray Bounds and initialize the array
941     SAFEARRAYBOUND rgsabound[1];
942     rgsabound[0].lLbound   = 0;
943     rgsabound[0].cElements = rows.getLength();
944     SAFEARRAY *psa         = SafeArrayCreate( VT_VARIANT, 1, rgsabound );
945 
946     const Any* pBegin = rows.getConstArray();
947     const Any* pEnd = pBegin + rows.getLength();
948     for(sal_Int32 i=0;pBegin != pEnd ;++pBegin,++i)
949     {
950         *pBegin >>= nPos;
951         SafeArrayPutElement(psa,&i,&m_aBookmarks[nPos]);
952     }
953 
954     // Initialize and fill the SafeArray
955     OLEVariant vsa;
956     vsa.setArray(psa,VT_VARIANT);
957 
958     m_pRecordSet->put_Filter(vsa);
959     m_pRecordSet->Delete(adAffectGroup);
960     m_pRecordSet->UpdateBatch(adAffectGroup);
961 
962     Sequence< sal_Int32 > aSeq(rows.getLength());
963     if(first())
964     {
965         sal_Int32* pSeq = aSeq.getArray();
966         sal_Int32 i=0;
967         do
968         {
969             OSL_ENSURE(i<aSeq.getLength(),"Index greater than length of sequence");
970             m_pRecordSet->get_Status(&pSeq[i]);
971             if(pSeq[i++] == adRecDeleted)
972                 --m_nRowPos;
973         }
974         while(next());
975     }
976     return aSeq;
977 }
978 //------------------------------------------------------------------------------
979 sal_Int32 OResultSet::getResultSetConcurrency() const
980 {
981     sal_Int32 nValue=ResultSetConcurrency::READ_ONLY;
982     LockTypeEnum eRet;
983     if(!SUCCEEDED(m_pRecordSet->get_LockType(&eRet)))
984     {
985         switch(eRet)
986         {
987             case adLockReadOnly:
988                 nValue = ResultSetConcurrency::READ_ONLY;
989                 break;
990             default:
991                 nValue = ResultSetConcurrency::UPDATABLE;
992                 break;
993         }
994     }
995     return nValue;
996 }
997 //------------------------------------------------------------------------------
998 sal_Int32 OResultSet::getResultSetType() const
999 {
1000     sal_Int32 nValue=0;
1001     CursorTypeEnum eRet;
1002     if(!SUCCEEDED(m_pRecordSet->get_CursorType(&eRet)))
1003     {
1004         switch(eRet)
1005         {
1006             case adOpenUnspecified:
1007             case adOpenForwardOnly:
1008                 nValue = ResultSetType::FORWARD_ONLY;
1009                 break;
1010             case adOpenStatic:
1011             case adOpenKeyset:
1012                 nValue = ResultSetType::SCROLL_INSENSITIVE;
1013                 break;
1014             case adOpenDynamic:
1015                 nValue = ResultSetType::SCROLL_SENSITIVE;
1016                 break;
1017         }
1018     }
1019     return nValue;
1020 }
1021 //------------------------------------------------------------------------------
1022 sal_Int32 OResultSet::getFetchDirection() const
1023 {
1024     return FetchDirection::FORWARD;
1025 }
1026 //------------------------------------------------------------------------------
1027 sal_Int32 OResultSet::getFetchSize() const
1028 {
1029     sal_Int32 nValue=-1;
1030     m_pRecordSet->get_CacheSize(&nValue);
1031     return nValue;
1032 }
1033 //------------------------------------------------------------------------------
1034 ::rtl::OUString OResultSet::getCursorName() const
1035 {
1036     return ::rtl::OUString();
1037 }
1038 
1039 //------------------------------------------------------------------------------
1040 void OResultSet::setFetchDirection(sal_Int32 /*_par0*/)
1041 {
1042     ::dbtools::throwFeatureNotImplementedException( "ResultSet::FetchDirection", *this );
1043 }
1044 //------------------------------------------------------------------------------
1045 void OResultSet::setFetchSize(sal_Int32 _par0)
1046 {
1047     m_pRecordSet->put_CacheSize(_par0);
1048 }
1049 // -------------------------------------------------------------------------
1050 ::cppu::IPropertyArrayHelper* OResultSet::createArrayHelper( ) const
1051 {
1052     Sequence< com::sun::star::beans::Property > aProps(5);
1053     com::sun::star::beans::Property* pProperties = aProps.getArray();
1054     sal_Int32 nPos = 0;
1055 
1056     //  DECL_PROP1IMPL(CURSORNAME,          ::rtl::OUString) PropertyAttribute::READONLY);
1057     DECL_PROP0(FETCHDIRECTION,          sal_Int32);
1058     DECL_PROP0(FETCHSIZE,               sal_Int32);
1059     DECL_BOOL_PROP1IMPL(ISBOOKMARKABLE) PropertyAttribute::READONLY);
1060     DECL_PROP1IMPL(RESULTSETCONCURRENCY,sal_Int32) PropertyAttribute::READONLY);
1061     DECL_PROP1IMPL(RESULTSETTYPE,       sal_Int32) PropertyAttribute::READONLY);
1062 
1063     return new ::cppu::OPropertyArrayHelper(aProps);
1064 }
1065 // -------------------------------------------------------------------------
1066 ::cppu::IPropertyArrayHelper & OResultSet::getInfoHelper()
1067 {
1068     return *const_cast<OResultSet*>(this)->getArrayHelper();
1069 }
1070 // -------------------------------------------------------------------------
1071 sal_Bool OResultSet::convertFastPropertyValue(
1072                             Any & rConvertedValue,
1073                             Any & rOldValue,
1074                             sal_Int32 nHandle,
1075                             const Any& rValue )
1076 {
1077     switch(nHandle)
1078     {
1079         case PROPERTY_ID_ISBOOKMARKABLE:
1080         case PROPERTY_ID_CURSORNAME:
1081         case PROPERTY_ID_RESULTSETCONCURRENCY:
1082         case PROPERTY_ID_RESULTSETTYPE:
1083             throw ::com::sun::star::lang::IllegalArgumentException();
1084             break;
1085         case PROPERTY_ID_FETCHDIRECTION:
1086             return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchDirection());
1087         case PROPERTY_ID_FETCHSIZE:
1088             return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchSize());
1089         default:
1090             ;
1091     }
1092     return sal_False;
1093 }
1094 // -------------------------------------------------------------------------
1095 void OResultSet::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue)
1096 {
1097     switch(nHandle)
1098     {
1099         case PROPERTY_ID_ISBOOKMARKABLE:
1100         case PROPERTY_ID_CURSORNAME:
1101         case PROPERTY_ID_RESULTSETCONCURRENCY:
1102         case PROPERTY_ID_RESULTSETTYPE:
1103             throw Exception();
1104             break;
1105         case PROPERTY_ID_FETCHDIRECTION:
1106             setFetchDirection(getINT32(rValue));
1107             break;
1108         case PROPERTY_ID_FETCHSIZE:
1109             setFetchSize(getINT32(rValue));
1110             break;
1111         default:
1112             ;
1113     }
1114 }
1115 // -------------------------------------------------------------------------
1116 void OResultSet::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
1117 {
1118     switch(nHandle)
1119     {
1120         case PROPERTY_ID_ISBOOKMARKABLE:
1121             {
1122                 VARIANT_BOOL bBool;
1123                 m_pRecordSet->Supports(adBookmark,&bBool);
1124                 sal_Bool bRet = bBool == VARIANT_TRUE;
1125                 rValue.setValue(&bRet, ::getCppuBooleanType() );
1126             }
1127             break;
1128         case PROPERTY_ID_CURSORNAME:
1129             rValue <<= getCursorName();
1130             break;
1131         case PROPERTY_ID_RESULTSETCONCURRENCY:
1132             rValue <<= getResultSetConcurrency();
1133             break;
1134         case PROPERTY_ID_RESULTSETTYPE:
1135             rValue <<= getResultSetType();
1136             break;
1137         case PROPERTY_ID_FETCHDIRECTION:
1138             rValue <<= getFetchDirection();
1139             break;
1140         case PROPERTY_ID_FETCHSIZE:
1141             rValue <<= getFetchSize();
1142             break;
1143     }
1144 }
1145 // -----------------------------------------------------------------------------
1146 void SAL_CALL OResultSet::acquire() throw()
1147 {
1148     OResultSet_BASE::acquire();
1149 }
1150 // -----------------------------------------------------------------------------
1151 void SAL_CALL OResultSet::release() throw()
1152 {
1153     OResultSet_BASE::release();
1154 }
1155 // -----------------------------------------------------------------------------
1156 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OResultSet::getPropertySetInfo(  )
1157 {
1158     return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1159 }
1160 // -----------------------------------------------------------------------------
1161