Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #ifdef __GNUC__
22 : #include <iostream>
23 : #endif
24 : #include <connectivity/sdbcx/VColumn.hxx>
25 : #include "file/FResultSet.hxx"
26 : #include "sqlbison.hxx"
27 : #include "file/FResultSetMetaData.hxx"
28 : #include <com/sun/star/sdbc/DataType.hpp>
29 : #include <com/sun/star/sdbc/ColumnValue.hpp>
30 : #include <comphelper/property.hxx>
31 : #include <com/sun/star/lang/DisposedException.hpp>
32 : #include <com/sun/star/beans/PropertyAttribute.hpp>
33 : #include <com/sun/star/container/XIndexAccess.hpp>
34 : #include <comphelper/sequence.hxx>
35 : #include <cppuhelper/typeprovider.hxx>
36 : #include <connectivity/dbconversion.hxx>
37 : #include <connectivity/dbtools.hxx>
38 : #include <cppuhelper/propshlp.hxx>
39 : #include <iterator>
40 : #include <com/sun/star/sdbc/ResultSetType.hpp>
41 : #include <com/sun/star/sdbc/FetchDirection.hpp>
42 : #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
43 : #include <com/sun/star/sdbcx/XIndexesSupplier.hpp>
44 :
45 : #include <algorithm>
46 : #include <comphelper/extract.hxx>
47 : #include <connectivity/dbexception.hxx>
48 : #include <comphelper/types.hxx>
49 : #include "resource/file_res.hrc"
50 : #include "resource/sharedresources.hxx"
51 :
52 :
53 : using namespace ::comphelper;
54 : using namespace connectivity;
55 : using namespace connectivity::file;
56 : using namespace ::cppu;
57 : using namespace dbtools;
58 : using namespace com::sun::star::uno;
59 : using namespace com::sun::star::lang;
60 : using namespace com::sun::star::beans;
61 : using namespace com::sun::star::sdbc;
62 : using namespace com::sun::star::sdbcx;
63 : using namespace com::sun::star::container;
64 :
65 : namespace
66 : {
67 0 : void lcl_throwError(sal_uInt16 _nErrorId,const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>& _xContext)
68 : {
69 0 : ::connectivity::SharedResources aResources;
70 0 : const OUString sMessage = aResources.getResourceString(_nErrorId);
71 0 : ::dbtools::throwGenericSQLException(sMessage ,_xContext);
72 0 : }
73 : }
74 :
75 0 : IMPLEMENT_SERVICE_INFO(OResultSet,"com.sun.star.sdbcx.drivers.file.ResultSet","com.sun.star.sdbc.ResultSet");
76 :
77 29 : OResultSet::OResultSet(OStatement_Base* pStmt,OSQLParseTreeIterator& _aSQLIterator) : OResultSet_BASE(m_aMutex)
78 : ,::comphelper::OPropertyContainer(OResultSet_BASE::rBHelper)
79 : ,m_aAssignValues(NULL)
80 : ,m_pEvaluationKeySet(NULL)
81 : ,m_aSkipDeletedSet(this)
82 : ,m_pFileSet(NULL)
83 : ,m_pSortIndex(NULL)
84 : ,m_pTable(NULL)
85 29 : ,m_pParseTree(pStmt->getParseTree())
86 : ,m_pSQLAnalyzer(NULL)
87 : ,m_aSQLIterator(_aSQLIterator)
88 : ,m_nFetchSize(0)
89 : ,m_nResultSetType(ResultSetType::SCROLL_INSENSITIVE)
90 : ,m_nFetchDirection(FetchDirection::FORWARD)
91 : ,m_nResultSetConcurrency(ResultSetConcurrency::UPDATABLE)
92 : ,m_xStatement(*pStmt)
93 : ,m_xMetaData(NULL)
94 29 : ,m_xDBMetaData(pStmt->getOwnConnection()->getMetaData())
95 29 : ,m_nTextEncoding(pStmt->getOwnConnection()->getTextEncoding())
96 : ,m_nRowPos(-1)
97 : ,m_nFilePos(0)
98 : ,m_nLastVisitedPos(-1)
99 : ,m_nRowCountResult(-1)
100 : ,m_nColumnCount(0)
101 : ,m_bWasNull(false)
102 : ,m_bEOF(false)
103 : ,m_bLastRecord(false)
104 : ,m_bInserted(false)
105 : ,m_bRowUpdated(false)
106 : ,m_bRowInserted(false)
107 : ,m_bRowDeleted(false)
108 29 : ,m_bShowDeleted(pStmt->getOwnConnection()->showDeleted())
109 145 : ,m_bIsCount(false)
110 : {
111 29 : osl_atomic_increment( &m_refCount );
112 29 : m_bIsCount = (m_pParseTree &&
113 58 : m_pParseTree->count() > 2 &&
114 67 : SQL_ISRULE(m_pParseTree->getChild(2),scalar_exp_commalist) &&
115 27 : SQL_ISRULE(m_pParseTree->getChild(2)->getChild(0),derived_column) &&
116 47 : SQL_ISRULE(m_pParseTree->getChild(2)->getChild(0)->getChild(0),general_set_fct) &&
117 0 : m_pParseTree->getChild(2)->getChild(0)->getChild(0)->count() == 4
118 29 : );
119 :
120 29 : m_nResultSetConcurrency = isCount() ? ResultSetConcurrency::READ_ONLY : ResultSetConcurrency::UPDATABLE;
121 29 : construct();
122 29 : m_aSkipDeletedSet.SetDeletedVisible(m_bShowDeleted);
123 29 : osl_atomic_decrement( &m_refCount );
124 29 : }
125 :
126 :
127 58 : OResultSet::~OResultSet()
128 : {
129 29 : osl_atomic_increment( &m_refCount );
130 29 : disposing();
131 29 : }
132 :
133 29 : void OResultSet::construct()
134 : {
135 29 : registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE), PROPERTY_ID_FETCHSIZE, 0,&m_nFetchSize, ::cppu::UnoType<sal_Int32>::get());
136 29 : registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE), PROPERTY_ID_RESULTSETTYPE, PropertyAttribute::READONLY,&m_nResultSetType, ::cppu::UnoType<sal_Int32>::get());
137 29 : registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION), PROPERTY_ID_FETCHDIRECTION, 0,&m_nFetchDirection, ::cppu::UnoType<sal_Int32>::get());
138 29 : registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY), PROPERTY_ID_RESULTSETCONCURRENCY,PropertyAttribute::READONLY,&m_nResultSetConcurrency, ::cppu::UnoType<sal_Int32>::get());
139 29 : }
140 :
141 58 : void OResultSet::disposing()
142 : {
143 58 : OPropertySetHelper::disposing();
144 :
145 58 : ::osl::MutexGuard aGuard(m_aMutex);
146 58 : m_xStatement.clear();
147 58 : m_xMetaData.clear();
148 58 : m_pParseTree = NULL;
149 58 : m_xColNames.clear();
150 58 : m_xColumns = NULL;
151 58 : m_xParamColumns = NULL;
152 58 : m_xColsIdx.clear();
153 :
154 116 : Reference<XComponent> xComp = m_pTable;
155 58 : if ( xComp.is() )
156 29 : xComp->removeEventListener(this);
157 58 : if(m_pTable)
158 : {
159 29 : m_pTable->release();
160 29 : m_pTable = NULL;
161 : }
162 :
163 58 : m_pFileSet = NULL;
164 58 : DELETEZ(m_pSortIndex);
165 :
166 58 : if(m_aInsertRow.is())
167 58 : m_aInsertRow->get().clear();
168 :
169 116 : m_aSkipDeletedSet.clear();
170 58 : }
171 :
172 783 : Any SAL_CALL OResultSet::queryInterface( const Type & rType ) throw(RuntimeException, std::exception)
173 : {
174 783 : Any aRet = OPropertySetHelper::queryInterface(rType);
175 783 : return aRet.hasValue() ? aRet : OResultSet_BASE::queryInterface(rType);
176 : }
177 :
178 0 : Sequence< Type > SAL_CALL OResultSet::getTypes( ) throw(RuntimeException, std::exception)
179 : {
180 0 : ::osl::MutexGuard aGuard( m_aMutex );
181 :
182 0 : OTypeCollection aTypes( cppu::UnoType<com::sun::star::beans::XMultiPropertySet>::get(),
183 0 : cppu::UnoType<com::sun::star::beans::XPropertySet>::get(),
184 0 : cppu::UnoType<com::sun::star::beans::XPropertySet>::get());
185 :
186 0 : return ::comphelper::concatSequences(aTypes.getTypes(),OResultSet_BASE::getTypes());
187 : }
188 :
189 :
190 0 : sal_Int32 SAL_CALL OResultSet::findColumn( const OUString& columnName ) throw(SQLException, RuntimeException, std::exception)
191 : {
192 0 : ::osl::MutexGuard aGuard( m_aMutex );
193 0 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
194 :
195 :
196 0 : Reference< XResultSetMetaData > xMeta = getMetaData();
197 0 : sal_Int32 nLen = xMeta->getColumnCount();
198 0 : sal_Int32 i = 1;
199 0 : for(;i<=nLen;++i)
200 : {
201 0 : if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) :
202 0 : columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i)))
203 0 : return i;
204 : }
205 :
206 0 : ::dbtools::throwInvalidColumnException( columnName, *this );
207 : assert(false);
208 0 : return 0; // Never reached
209 : }
210 :
211 3792 : const ORowSetValue& OResultSet::getValue(sal_Int32 columnIndex)
212 : throw (css::sdbc::SQLException, css::uno::RuntimeException)
213 : {
214 3792 : ::osl::MutexGuard aGuard( m_aMutex );
215 3792 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
216 :
217 3792 : checkIndex(columnIndex );
218 :
219 :
220 3792 : m_bWasNull = (m_aSelectRow->get())[columnIndex]->getValue().isNull();
221 3792 : return *(m_aSelectRow->get())[columnIndex];
222 : }
223 :
224 3797 : void OResultSet::checkIndex(sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException)
225 : {
226 3797 : if ( columnIndex <= 0
227 3797 : || columnIndex >= m_nColumnCount )
228 0 : ::dbtools::throwInvalidIndexException(*this);
229 3797 : }
230 :
231 0 : Reference< ::com::sun::star::io::XInputStream > SAL_CALL OResultSet::getBinaryStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
232 : {
233 0 : return NULL;
234 : }
235 :
236 0 : Reference< ::com::sun::star::io::XInputStream > SAL_CALL OResultSet::getCharacterStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
237 : {
238 0 : return NULL;
239 : }
240 :
241 :
242 28 : sal_Bool SAL_CALL OResultSet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
243 : {
244 28 : return getValue(columnIndex);
245 : }
246 :
247 :
248 0 : sal_Int8 SAL_CALL OResultSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
249 : {
250 0 : return getValue(columnIndex);
251 : }
252 :
253 :
254 0 : Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
255 : {
256 0 : return getValue(columnIndex);
257 : }
258 :
259 :
260 56 : ::com::sun::star::util::Date SAL_CALL OResultSet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
261 : {
262 56 : return getValue(columnIndex);
263 : }
264 :
265 :
266 0 : double SAL_CALL OResultSet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
267 : {
268 0 : return getValue(columnIndex);
269 : }
270 :
271 :
272 0 : float SAL_CALL OResultSet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
273 : {
274 0 : return getValue(columnIndex);
275 : }
276 :
277 :
278 0 : sal_Int32 SAL_CALL OResultSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
279 : {
280 0 : return getValue(columnIndex);
281 : }
282 :
283 :
284 40 : sal_Int32 SAL_CALL OResultSet::getRow( ) throw(SQLException, RuntimeException, std::exception)
285 : {
286 40 : ::osl::MutexGuard aGuard( m_aMutex );
287 40 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
288 :
289 : OSL_ENSURE((m_bShowDeleted || !m_aRow->isDeleted()),"getRow called for deleted row");
290 :
291 40 : return m_aSkipDeletedSet.getMappedPosition((m_aRow->get())[0]->getValue());
292 : }
293 :
294 :
295 0 : sal_Int64 SAL_CALL OResultSet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
296 : {
297 0 : return getValue(columnIndex);
298 : }
299 :
300 :
301 58 : Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData( ) throw(SQLException, RuntimeException, std::exception)
302 : {
303 58 : ::osl::MutexGuard aGuard( m_aMutex );
304 58 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
305 :
306 :
307 58 : if(!m_xMetaData.is())
308 0 : m_xMetaData = new OResultSetMetaData(m_xColumns,m_aSQLIterator.getTables().begin()->first,m_pTable);
309 58 : return m_xMetaData;
310 : }
311 :
312 0 : Reference< XArray > SAL_CALL OResultSet::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
313 : {
314 0 : return NULL;
315 : }
316 :
317 :
318 :
319 0 : Reference< XClob > SAL_CALL OResultSet::getClob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
320 : {
321 0 : return NULL;
322 : }
323 :
324 0 : Reference< XBlob > SAL_CALL OResultSet::getBlob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
325 : {
326 0 : return NULL;
327 : }
328 :
329 :
330 0 : Reference< XRef > SAL_CALL OResultSet::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
331 : {
332 0 : return NULL;
333 : }
334 :
335 :
336 0 : Any SAL_CALL OResultSet::getObject( sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException, std::exception)
337 : {
338 0 : return getValue(columnIndex).makeAny();
339 : }
340 :
341 :
342 0 : sal_Int16 SAL_CALL OResultSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
343 : {
344 0 : return getValue(columnIndex);
345 : }
346 :
347 3708 : OUString SAL_CALL OResultSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
348 : {
349 3708 : return getValue(columnIndex);
350 : }
351 :
352 0 : ::com::sun::star::util::Time SAL_CALL OResultSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
353 : {
354 0 : return getValue(columnIndex);
355 : }
356 :
357 0 : ::com::sun::star::util::DateTime SAL_CALL OResultSet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
358 : {
359 0 : return getValue(columnIndex);
360 : }
361 :
362 :
363 0 : sal_Bool SAL_CALL OResultSet::isAfterLast( ) throw(SQLException, RuntimeException, std::exception)
364 : {
365 0 : ::osl::MutexGuard aGuard( m_aMutex );
366 0 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
367 :
368 :
369 0 : return m_nRowPos == sal_Int32(m_pFileSet->get().size());
370 : }
371 :
372 0 : sal_Bool SAL_CALL OResultSet::isFirst( ) throw(SQLException, RuntimeException, std::exception)
373 : {
374 0 : ::osl::MutexGuard aGuard( m_aMutex );
375 0 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
376 :
377 :
378 0 : return m_nRowPos == 0;
379 : }
380 :
381 0 : sal_Bool SAL_CALL OResultSet::isLast( ) throw(SQLException, RuntimeException, std::exception)
382 : {
383 0 : ::osl::MutexGuard aGuard( m_aMutex );
384 0 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
385 :
386 :
387 0 : return m_nRowPos == sal_Int32(m_pFileSet->get().size() - 1);
388 : }
389 :
390 42 : void SAL_CALL OResultSet::beforeFirst( ) throw(SQLException, RuntimeException, std::exception)
391 : {
392 42 : ::osl::MutexGuard aGuard( m_aMutex );
393 42 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
394 :
395 :
396 42 : if(first())
397 37 : previous();
398 42 : }
399 :
400 5 : void SAL_CALL OResultSet::afterLast( ) throw(SQLException, RuntimeException, std::exception)
401 : {
402 5 : ::osl::MutexGuard aGuard( m_aMutex );
403 5 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
404 :
405 :
406 5 : if(last())
407 5 : next();
408 5 : m_bEOF = true;
409 5 : }
410 :
411 :
412 32 : void SAL_CALL OResultSet::close( ) throw(SQLException, RuntimeException, std::exception)
413 : {
414 32 : dispose();
415 32 : }
416 :
417 :
418 77 : sal_Bool SAL_CALL OResultSet::first( ) throw(SQLException, RuntimeException, std::exception)
419 : {
420 77 : ::osl::MutexGuard aGuard( m_aMutex );
421 77 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
422 77 : return m_pTable ? m_aSkipDeletedSet.skipDeleted(IResultSetHelper::FIRST,1,true) : sal_False;
423 : }
424 :
425 :
426 9 : sal_Bool SAL_CALL OResultSet::last( ) throw(SQLException, RuntimeException, std::exception)
427 : {
428 : // here I know definitely that I stand on the last record
429 9 : ::osl::MutexGuard aGuard( m_aMutex );
430 9 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
431 9 : return m_pTable ? m_aSkipDeletedSet.skipDeleted(IResultSetHelper::LAST,1,true) : sal_False;
432 : }
433 :
434 82 : sal_Bool SAL_CALL OResultSet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException, std::exception)
435 : {
436 82 : ::osl::MutexGuard aGuard( m_aMutex );
437 82 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
438 82 : return m_pTable ? m_aSkipDeletedSet.skipDeleted(IResultSetHelper::ABSOLUTE1,row,true) : sal_False;
439 : }
440 :
441 0 : sal_Bool SAL_CALL OResultSet::relative( sal_Int32 row ) throw(SQLException, RuntimeException, std::exception)
442 : {
443 0 : ::osl::MutexGuard aGuard( m_aMutex );
444 0 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
445 0 : return m_pTable ? m_aSkipDeletedSet.skipDeleted(IResultSetHelper::RELATIVE1,row,true) : sal_False;
446 : }
447 :
448 66 : sal_Bool SAL_CALL OResultSet::previous( ) throw(SQLException, RuntimeException, std::exception)
449 : {
450 66 : ::osl::MutexGuard aGuard( m_aMutex );
451 66 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
452 66 : return m_pTable ? m_aSkipDeletedSet.skipDeleted(IResultSetHelper::PRIOR,0,true) : sal_False;
453 : }
454 :
455 0 : Reference< XInterface > SAL_CALL OResultSet::getStatement( ) throw(SQLException, RuntimeException, std::exception)
456 : {
457 0 : ::osl::MutexGuard aGuard( m_aMutex );
458 0 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
459 :
460 :
461 0 : return m_xStatement;
462 : }
463 :
464 :
465 1 : sal_Bool SAL_CALL OResultSet::rowDeleted( ) throw(SQLException, RuntimeException, std::exception)
466 : {
467 1 : ::osl::MutexGuard aGuard( m_aMutex );
468 1 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
469 :
470 :
471 1 : return m_bRowDeleted;
472 : }
473 :
474 2 : sal_Bool SAL_CALL OResultSet::rowInserted( ) throw(SQLException, RuntimeException, std::exception)
475 2 : { ::osl::MutexGuard aGuard( m_aMutex );
476 2 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
477 :
478 :
479 2 : return m_bRowInserted;
480 : }
481 :
482 1 : sal_Bool SAL_CALL OResultSet::rowUpdated( ) throw(SQLException, RuntimeException, std::exception)
483 : {
484 1 : ::osl::MutexGuard aGuard( m_aMutex );
485 1 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
486 :
487 :
488 1 : return m_bRowUpdated;
489 : }
490 :
491 :
492 0 : sal_Bool SAL_CALL OResultSet::isBeforeFirst( ) throw(SQLException, RuntimeException, std::exception)
493 : {
494 0 : ::osl::MutexGuard aGuard( m_aMutex );
495 0 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
496 :
497 :
498 0 : return m_nRowPos == -1;
499 : }
500 :
501 : // sal_Bool OResultSet::evaluate()
502 : // {
503 : // OSL_ENSURE(m_pSQLAnalyzer,"OResultSet::evaluate: Analyzer isn't set!");
504 : // sal_Bool bRet = sal_True;
505 : // while(!m_pSQLAnalyzer->evaluateRestriction())
506 : // {
507 : // if(m_pEvaluationKeySet)
508 : // {
509 : // if(m_aEvaluateIter == m_pEvaluationKeySet->end())
510 : // return sal_False;
511 : // bRet = m_pTable->seekRow(IResultSetHelper::BOOKMARK,(*m_aEvaluateIter),m_nRowPos);
512 : // ++m_aEvaluateIter;
513 : // }
514 : // else
515 : // bRet = m_pTable->seekRow(IResultSetHelper::NEXT,1,m_nRowPos);
516 : // if(bRet)
517 : // {
518 : // if(m_pEvaluationKeySet)
519 : // {
520 : // bRet = m_pTable->fetchRow(m_aEvaluateRow,*(m_pTable->getTableColumns()),sal_True,sal_True);
521 : // evaluate();
522 :
523 : // }
524 : // else
525 : // bRet = m_pTable->fetchRow(m_aRow,*m_xColumns,sal_False,sal_True);
526 : // }
527 : // }
528 :
529 : // return bRet;
530 : // }
531 :
532 :
533 238 : sal_Bool SAL_CALL OResultSet::next( ) throw(SQLException, RuntimeException, std::exception)
534 : {
535 238 : ::osl::MutexGuard aGuard( m_aMutex );
536 238 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
537 :
538 238 : return m_pTable ? m_aSkipDeletedSet.skipDeleted(IResultSetHelper::NEXT,1,true) : sal_False;
539 : }
540 :
541 :
542 3792 : sal_Bool SAL_CALL OResultSet::wasNull( ) throw(SQLException, RuntimeException, std::exception)
543 : {
544 3792 : ::osl::MutexGuard aGuard( m_aMutex );
545 3792 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
546 :
547 3792 : return m_bWasNull;
548 : }
549 :
550 :
551 0 : void SAL_CALL OResultSet::cancel( ) throw(RuntimeException, std::exception)
552 : {
553 0 : }
554 :
555 0 : void SAL_CALL OResultSet::clearWarnings( ) throw(SQLException, RuntimeException, std::exception)
556 : {
557 0 : }
558 :
559 1 : Any SAL_CALL OResultSet::getWarnings( ) throw(SQLException, RuntimeException, std::exception)
560 : {
561 1 : return Any();
562 : }
563 :
564 1 : void SAL_CALL OResultSet::insertRow( ) throw(SQLException, RuntimeException, std::exception)
565 : {
566 1 : ::osl::MutexGuard aGuard( m_aMutex );
567 1 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
568 :
569 :
570 1 : if(!m_bInserted || !m_pTable)
571 0 : throwFunctionSequenceException(*this);
572 :
573 : // we know that we append new rows at the end
574 : // so we have to know where the end is
575 1 : m_aSkipDeletedSet.skipDeleted(IResultSetHelper::LAST,1,false);
576 1 : m_bRowInserted = m_pTable->InsertRow(*m_aInsertRow, true, m_xColsIdx);
577 1 : if(m_bRowInserted && m_pFileSet.is())
578 : {
579 1 : sal_Int32 nPos = (m_aInsertRow->get())[0]->getValue();
580 1 : m_pFileSet->get().push_back(nPos);
581 1 : *(m_aInsertRow->get())[0] = sal_Int32(m_pFileSet->get().size());
582 1 : clearInsertRow();
583 :
584 1 : m_aSkipDeletedSet.insertNewPosition((m_aRow->get())[0]->getValue());
585 1 : }
586 1 : }
587 :
588 4 : void SAL_CALL OResultSet::updateRow( ) throw(SQLException, RuntimeException, std::exception)
589 : {
590 4 : ::osl::MutexGuard aGuard( m_aMutex );
591 4 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
592 :
593 4 : if(!m_pTable || m_pTable->isReadOnly())
594 0 : lcl_throwError(STR_TABLE_READONLY,*this);
595 :
596 4 : m_bRowUpdated = m_pTable->UpdateRow(*m_aInsertRow, m_aRow,m_xColsIdx);
597 4 : *(m_aInsertRow->get())[0] = (sal_Int32)(m_aRow->get())[0]->getValue();
598 :
599 4 : clearInsertRow();
600 4 : }
601 :
602 1 : void SAL_CALL OResultSet::deleteRow() throw(SQLException, RuntimeException, std::exception)
603 : {
604 1 : ::osl::MutexGuard aGuard( m_aMutex );
605 1 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
606 :
607 :
608 1 : if(!m_pTable || m_pTable->isReadOnly())
609 0 : lcl_throwError(STR_TABLE_READONLY,*this);
610 1 : if (m_bShowDeleted)
611 0 : lcl_throwError(STR_DELETE_ROW,*this);
612 1 : if(m_aRow->isDeleted())
613 0 : lcl_throwError(STR_ROW_ALREADY_DELETED,*this);
614 :
615 1 : sal_Int32 nPos = (sal_Int32)(m_aRow->get())[0]->getValue();
616 1 : m_bRowDeleted = m_pTable->DeleteRow(*m_xColumns);
617 1 : if(m_bRowDeleted && m_pFileSet.is())
618 : {
619 1 : m_aRow->setDeleted(true);
620 : // don't touch the m_pFileSet member here
621 1 : m_aSkipDeletedSet.deletePosition(nPos);
622 1 : }
623 1 : }
624 :
625 20 : void SAL_CALL OResultSet::cancelRowUpdates( ) throw(SQLException, RuntimeException, std::exception)
626 : {
627 20 : ::osl::MutexGuard aGuard( m_aMutex );
628 20 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
629 :
630 :
631 20 : m_bInserted = false;
632 20 : m_bRowUpdated = false;
633 20 : m_bRowInserted = false;
634 20 : m_bRowDeleted = false;
635 :
636 20 : if(m_aInsertRow.is())
637 : {
638 20 : OValueRefVector::Vector::iterator aIter = m_aInsertRow->get().begin()+1;
639 380 : for(;aIter != m_aInsertRow->get().end();++aIter)
640 : {
641 360 : (*aIter)->setBound(false);
642 360 : (*aIter)->setNull();
643 : }
644 20 : }
645 20 : }
646 :
647 :
648 21 : void SAL_CALL OResultSet::moveToInsertRow( ) throw(SQLException, RuntimeException, std::exception)
649 : {
650 21 : ::osl::MutexGuard aGuard( m_aMutex );
651 21 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
652 :
653 21 : if(!m_pTable || m_pTable->isReadOnly())
654 0 : lcl_throwError(STR_TABLE_READONLY,*this);
655 :
656 21 : m_bInserted = true;
657 :
658 21 : OValueRefVector::Vector::iterator aIter = m_aInsertRow->get().begin()+1;
659 412 : for(;aIter != m_aInsertRow->get().end();++aIter)
660 : {
661 391 : (*aIter)->setBound(false);
662 391 : (*aIter)->setNull();
663 21 : }
664 21 : }
665 :
666 :
667 0 : void SAL_CALL OResultSet::moveToCurrentRow( ) throw(SQLException, RuntimeException, std::exception)
668 : {
669 0 : }
670 :
671 5 : void OResultSet::updateValue(sal_Int32 columnIndex ,const ORowSetValue& x) throw(SQLException, RuntimeException)
672 : {
673 5 : ::osl::MutexGuard aGuard( m_aMutex );
674 5 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
675 :
676 5 : checkIndex(columnIndex );
677 5 : columnIndex = mapColumn(columnIndex);
678 :
679 5 : (m_aInsertRow->get())[columnIndex]->setBound(true);
680 5 : *(m_aInsertRow->get())[columnIndex] = x;
681 5 : }
682 :
683 :
684 0 : void SAL_CALL OResultSet::updateNull( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
685 : {
686 0 : ORowSetValue aEmpty;
687 0 : updateValue(columnIndex,aEmpty);
688 0 : }
689 :
690 :
691 0 : void SAL_CALL OResultSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw(SQLException, RuntimeException, std::exception)
692 : {
693 0 : updateValue(columnIndex, static_cast<bool>(x));
694 0 : }
695 :
696 0 : void SAL_CALL OResultSet::updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw(SQLException, RuntimeException, std::exception)
697 : {
698 0 : updateValue(columnIndex,x);
699 0 : }
700 :
701 :
702 0 : void SAL_CALL OResultSet::updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw(SQLException, RuntimeException, std::exception)
703 : {
704 0 : updateValue(columnIndex,x);
705 0 : }
706 :
707 0 : void SAL_CALL OResultSet::updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw(SQLException, RuntimeException, std::exception)
708 : {
709 0 : updateValue(columnIndex,x);
710 0 : }
711 :
712 0 : void SAL_CALL OResultSet::updateLong( sal_Int32 /*columnIndex*/, sal_Int64 /*x*/ ) throw(SQLException, RuntimeException, std::exception)
713 : {
714 0 : ::dbtools::throwFeatureNotImplementedSQLException( "XRowUpdate::updateLong", *this );
715 0 : }
716 :
717 0 : void SAL_CALL OResultSet::updateFloat( sal_Int32 columnIndex, float x ) throw(SQLException, RuntimeException, std::exception)
718 : {
719 0 : updateValue(columnIndex,x);
720 0 : }
721 :
722 :
723 0 : void SAL_CALL OResultSet::updateDouble( sal_Int32 columnIndex, double x ) throw(SQLException, RuntimeException, std::exception)
724 : {
725 0 : updateValue(columnIndex,x);
726 0 : }
727 :
728 5 : void SAL_CALL OResultSet::updateString( sal_Int32 columnIndex, const OUString& x ) throw(SQLException, RuntimeException, std::exception)
729 : {
730 5 : updateValue(columnIndex,x);
731 5 : }
732 :
733 0 : void SAL_CALL OResultSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException, std::exception)
734 : {
735 0 : updateValue(columnIndex,x);
736 0 : }
737 :
738 0 : void SAL_CALL OResultSet::updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x ) throw(SQLException, RuntimeException, std::exception)
739 : {
740 0 : updateValue(columnIndex,x);
741 0 : }
742 :
743 :
744 0 : void SAL_CALL OResultSet::updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x ) throw(SQLException, RuntimeException, std::exception)
745 : {
746 0 : updateValue(columnIndex,x);
747 0 : }
748 :
749 :
750 0 : void SAL_CALL OResultSet::updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x ) throw(SQLException, RuntimeException, std::exception)
751 : {
752 0 : updateValue(columnIndex,x);
753 0 : }
754 :
755 :
756 0 : void SAL_CALL OResultSet::updateBinaryStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException, std::exception)
757 : {
758 0 : ::osl::MutexGuard aGuard( m_aMutex );
759 0 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
760 :
761 0 : if(!x.is())
762 0 : ::dbtools::throwFunctionSequenceException(*this);
763 :
764 0 : Sequence<sal_Int8> aSeq;
765 0 : x->readBytes(aSeq,length);
766 0 : updateValue(columnIndex,aSeq);
767 0 : }
768 :
769 0 : void SAL_CALL OResultSet::updateCharacterStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException, std::exception)
770 : {
771 0 : updateBinaryStream(columnIndex,x,length);
772 0 : }
773 :
774 1 : void SAL_CALL OResultSet::refreshRow( ) throw(SQLException, RuntimeException, std::exception)
775 : {
776 1 : ::osl::MutexGuard aGuard( m_aMutex );
777 1 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
778 1 : }
779 :
780 0 : void SAL_CALL OResultSet::updateObject( sal_Int32 columnIndex, const Any& x ) throw(SQLException, RuntimeException, std::exception)
781 : {
782 0 : if (!::dbtools::implUpdateObject(this, columnIndex, x))
783 0 : throw SQLException();
784 0 : }
785 :
786 :
787 0 : void SAL_CALL OResultSet::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 /*scale*/ ) throw(SQLException, RuntimeException, std::exception)
788 : {
789 0 : if (!::dbtools::implUpdateObject(this, columnIndex, x))
790 0 : throw SQLException();
791 0 : }
792 :
793 0 : IPropertyArrayHelper* OResultSet::createArrayHelper( ) const
794 : {
795 0 : Sequence< Property > aProps;
796 0 : describeProperties(aProps);
797 0 : return new ::cppu::OPropertyArrayHelper(aProps);
798 : }
799 :
800 0 : IPropertyArrayHelper & OResultSet::getInfoHelper()
801 : {
802 0 : return *getArrayHelper();
803 : }
804 :
805 :
806 2347 : bool OResultSet::ExecuteRow(IResultSetHelper::Movement eFirstCursorPosition,
807 : sal_Int32 nFirstOffset,
808 : bool bEvaluate,
809 : bool bRetrieveData)
810 : {
811 : OSL_ENSURE(m_pSQLAnalyzer,"OResultSet::ExecuteRow: Analyzer isn't set!");
812 :
813 : // For further Fetch-Operations this information may possibly be changed ...
814 2347 : IResultSetHelper::Movement eCursorPosition = eFirstCursorPosition;
815 2347 : sal_Int32 nOffset = nFirstOffset;
816 :
817 2347 : if (!m_pTable)
818 0 : return false;
819 :
820 2347 : const OSQLColumns & rTableCols = *(m_pTable->getTableColumns());
821 2347 : bool bHasRestriction = m_pSQLAnalyzer->hasRestriction();
822 : again:
823 :
824 : // protect from reading over the end when someboby is inserting while we are reading
825 : // this method works only for dBase at the moment !!!!
826 2362 : if (eCursorPosition == IResultSetHelper::NEXT && m_nFilePos == m_nLastVisitedPos)
827 : {
828 29 : return false;
829 : }
830 :
831 2333 : if (!m_pTable || !m_pTable->seekRow(eCursorPosition, nOffset, m_nFilePos))
832 : {
833 0 : return false;
834 : }
835 :
836 2333 : if (!bEvaluate) // If no evaluation runs, then just fill the results-row
837 : {
838 2203 : m_pTable->fetchRow(m_aRow,rTableCols, true,bRetrieveData);
839 : }
840 : else
841 : {
842 130 : m_pTable->fetchRow(m_aEvaluateRow, rTableCols, true,bRetrieveData || bHasRestriction);
843 :
844 260 : if ( ( !m_bShowDeleted
845 130 : && m_aEvaluateRow->isDeleted()
846 : )
847 275 : || ( bHasRestriction
848 18 : && !m_pSQLAnalyzer->evaluateRestriction()
849 : )
850 : )
851 : { // Evaluate the next record
852 : // delete current row in Keyset
853 107 : if (m_pEvaluationKeySet)
854 : {
855 0 : ++m_aEvaluateIter;
856 0 : if (m_pEvaluationKeySet->end() != m_aEvaluateIter)
857 0 : nOffset = (*m_aEvaluateIter);
858 : else
859 : {
860 0 : return false;
861 : }
862 : }
863 107 : else if (m_pFileSet.is())
864 : {
865 : OSL_ENSURE(eCursorPosition == IResultSetHelper::NEXT, "Falsche CursorPosition!");
866 15 : eCursorPosition = IResultSetHelper::NEXT;
867 15 : nOffset = 1;
868 : }
869 92 : else if (eCursorPosition == IResultSetHelper::FIRST ||
870 92 : eCursorPosition == IResultSetHelper::NEXT ||
871 : eCursorPosition == IResultSetHelper::ABSOLUTE1)
872 : {
873 0 : eCursorPosition = IResultSetHelper::NEXT;
874 0 : nOffset = 1;
875 : }
876 92 : else if (eCursorPosition == IResultSetHelper::LAST ||
877 : eCursorPosition == IResultSetHelper::PRIOR)
878 : {
879 0 : eCursorPosition = IResultSetHelper::PRIOR;
880 0 : nOffset = 1;
881 : }
882 92 : else if (eCursorPosition == IResultSetHelper::RELATIVE1)
883 : {
884 0 : eCursorPosition = (nOffset >= 0) ? IResultSetHelper::NEXT : IResultSetHelper::PRIOR;
885 : }
886 : else
887 : {
888 92 : return false;
889 : }
890 : // Try again ...
891 15 : goto again;
892 : }
893 : }
894 :
895 : // Evaluate may only be set,
896 : // if the Keyset will be constructed further
897 4452 : if ( ( m_aSQLIterator.getStatementType() == SQL_STATEMENT_SELECT )
898 2226 : && !isCount()
899 4452 : && bEvaluate
900 : )
901 : {
902 23 : if (m_pSortIndex)
903 : {
904 20 : OKeyValue* pKeyValue = GetOrderbyKeyValue( m_aSelectRow );
905 20 : m_pSortIndex->AddKeyValue(pKeyValue);
906 : }
907 3 : else if (m_pFileSet.is())
908 : {
909 3 : sal_uInt32 nBookmarkValue = std::abs((sal_Int32)(m_aEvaluateRow->get())[0]->getValue());
910 3 : m_pFileSet->get().push_back(nBookmarkValue);
911 : }
912 : }
913 2203 : else if (m_aSQLIterator.getStatementType() == SQL_STATEMENT_UPDATE)
914 : {
915 0 : bool bOK = true;
916 0 : if (bEvaluate)
917 : {
918 : // read the actual result-row
919 0 : bOK = m_pTable->fetchRow(m_aEvaluateRow, *(m_pTable->getTableColumns()), true,true);
920 : }
921 :
922 0 : if (bOK)
923 : {
924 : // just give the values to be changed:
925 0 : if(!m_pTable->UpdateRow(*m_aAssignValues,m_aEvaluateRow, m_xColsIdx))
926 0 : return false;
927 : }
928 : }
929 2203 : else if (m_aSQLIterator.getStatementType() == SQL_STATEMENT_DELETE)
930 : {
931 0 : bool bOK = true;
932 0 : if (bEvaluate)
933 : {
934 0 : bOK = m_pTable->fetchRow(m_aEvaluateRow, *(m_pTable->getTableColumns()), true,true);
935 : }
936 0 : if (bOK)
937 : {
938 0 : if(!m_pTable->DeleteRow(*m_xColumns))
939 0 : return false;
940 : }
941 : }
942 2226 : return true;
943 : }
944 :
945 :
946 2230 : bool OResultSet::Move(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, bool bRetrieveData)
947 : {
948 2230 : sal_Int32 nTempPos = m_nRowPos;
949 :
950 4460 : if (m_aSQLIterator.getStatementType() == SQL_STATEMENT_SELECT &&
951 2230 : !isCount())
952 : {
953 2230 : if (!m_pFileSet.is()) //no Index available
954 : {
955 : // Normal FETCH
956 0 : ExecuteRow(eCursorPosition,nOffset,false,bRetrieveData);
957 :
958 : // now set the bookmark for outside this is the logical pos and not the file pos
959 0 : *(*m_aRow->get().begin()) = sal_Int32(m_nRowPos + 1);
960 : }
961 : else
962 : {
963 2230 : switch(eCursorPosition)
964 : {
965 : case IResultSetHelper::NEXT:
966 1261 : ++m_nRowPos;
967 1261 : break;
968 : case IResultSetHelper::PRIOR:
969 778 : if (m_nRowPos >= 0)
970 774 : --m_nRowPos;
971 778 : break;
972 : case IResultSetHelper::FIRST:
973 86 : m_nRowPos = 0;
974 86 : break;
975 : case IResultSetHelper::LAST:
976 0 : m_nRowPos = m_pFileSet->get().size() - 1;
977 0 : break;
978 : case IResultSetHelper::RELATIVE1:
979 0 : m_nRowPos += nOffset;
980 0 : break;
981 : case IResultSetHelper::ABSOLUTE1:
982 : case IResultSetHelper::BOOKMARK:
983 105 : if ( m_nRowPos == (nOffset -1) )
984 21 : return true;
985 84 : m_nRowPos = nOffset -1;
986 84 : break;
987 : }
988 :
989 : // OffRange?
990 : // The FileCursor is outside of the valid range, if:
991 : // a.) m_nRowPos < 1
992 : // b.) a KeySet exists and m_nRowPos > m_pFileSet->size()
993 2209 : if (m_nRowPos < 0 || (m_pFileSet->isFrozen() && eCursorPosition != IResultSetHelper::BOOKMARK && m_nRowPos >= (sal_Int32)m_pFileSet->get().size() )) // && m_pFileSet->IsFrozen()
994 : {
995 87 : goto Error;
996 : }
997 : else
998 : {
999 2122 : if (m_nRowPos < (sal_Int32)m_pFileSet->get().size())
1000 : {
1001 : // Fetch via Index
1002 2091 : bool bOK = ExecuteRow(IResultSetHelper::BOOKMARK,(m_pFileSet->get())[m_nRowPos],false,bRetrieveData);
1003 2091 : if (!bOK)
1004 0 : goto Error;
1005 :
1006 : // now set the bookmark for outside
1007 2091 : *(*m_aRow->get().begin()) = sal_Int32(m_nRowPos + 1);
1008 2091 : if ( (bRetrieveData || m_pSQLAnalyzer->hasRestriction()) && m_pSQLAnalyzer->hasFunctions() )
1009 : {
1010 0 : m_pSQLAnalyzer->setSelectionEvaluationResult(m_aSelectRow,m_aColMapping);
1011 : }
1012 : }
1013 : else // Index must be further constructed
1014 : {
1015 : // set first on the last known row
1016 31 : if (m_pFileSet->get().empty())
1017 : {
1018 7 : m_pTable->seekRow(IResultSetHelper::ABSOLUTE1, 0, m_nFilePos);
1019 : }
1020 : else
1021 : {
1022 24 : m_aFileSetIter = m_pFileSet->get().end()-1;
1023 24 : m_pTable->seekRow(IResultSetHelper::BOOKMARK, *m_aFileSetIter, m_nFilePos);
1024 : }
1025 31 : bool bOK = true;
1026 : // Determine the number of further Fetches
1027 93 : while (bOK && m_nRowPos >= (sal_Int32)m_pFileSet->get().size())
1028 : {
1029 31 : if (m_pEvaluationKeySet)
1030 : {
1031 0 : if (m_nRowPos >= (sal_Int32)m_pEvaluationKeySet->size())
1032 0 : return false;
1033 0 : else if (m_nRowPos == 0)
1034 : {
1035 0 : m_aEvaluateIter = m_pEvaluationKeySet->begin();
1036 0 : bOK = ExecuteRow(IResultSetHelper::BOOKMARK,*m_aEvaluateIter,true, bRetrieveData);
1037 : }
1038 : else
1039 : {
1040 0 : ++m_aEvaluateIter;
1041 0 : bOK = ExecuteRow(IResultSetHelper::BOOKMARK,*m_aEvaluateIter,true, bRetrieveData);
1042 : }
1043 : }
1044 : else
1045 31 : bOK = ExecuteRow(IResultSetHelper::NEXT,1,true, false);//bRetrieveData);
1046 : }
1047 :
1048 31 : if (bOK)
1049 : {
1050 : // read the results again
1051 3 : m_pTable->fetchRow(m_aRow, *(m_pTable->getTableColumns()), true,bRetrieveData);
1052 :
1053 : // now set the bookmark for outside
1054 3 : *(*m_aRow->get().begin()) = sal_Int32(m_nRowPos + 1);
1055 :
1056 3 : if ( (bRetrieveData || m_pSQLAnalyzer->hasRestriction()) && m_pSQLAnalyzer->hasFunctions() )
1057 : {
1058 0 : m_pSQLAnalyzer->setSelectionEvaluationResult(m_aSelectRow,m_aColMapping);
1059 : }
1060 : }
1061 28 : else if (!m_pFileSet->isFrozen()) // no valid record found
1062 : {
1063 28 : m_pFileSet->setFrozen();
1064 28 : m_pEvaluationKeySet = NULL;
1065 28 : goto Error;
1066 : }
1067 : }
1068 : }
1069 : }
1070 : }
1071 0 : else if (m_aSQLIterator.getStatementType() == SQL_STATEMENT_SELECT && isCount())
1072 : {
1073 : // Fetch the COUNT(*)
1074 0 : switch (eCursorPosition)
1075 : {
1076 : case IResultSetHelper::NEXT:
1077 0 : ++m_nRowPos;
1078 0 : break;
1079 : case IResultSetHelper::PRIOR:
1080 0 : --m_nRowPos;
1081 0 : break;
1082 : case IResultSetHelper::FIRST:
1083 0 : m_nRowPos = 0;
1084 0 : break;
1085 : case IResultSetHelper::LAST:
1086 0 : m_nRowPos = 0;
1087 0 : break;
1088 : case IResultSetHelper::RELATIVE1:
1089 0 : m_nRowPos += nOffset;
1090 0 : break;
1091 : case IResultSetHelper::ABSOLUTE1:
1092 : case IResultSetHelper::BOOKMARK:
1093 0 : m_nRowPos = nOffset - 1;
1094 0 : break;
1095 : }
1096 :
1097 0 : if ( m_nRowPos < 0 )
1098 0 : goto Error;
1099 0 : else if (m_nRowPos == 0)
1100 : {
1101 : // put COUNT(*) in result-row
1102 : // (must be the first and only variable in the row)
1103 0 : if (m_aRow->get().size() >= 2)
1104 : {
1105 0 : *(m_aRow->get())[1] = m_nRowCountResult;
1106 0 : *(m_aRow->get())[0] = sal_Int32(1);
1107 0 : (m_aRow->get())[1]->setBound(true);
1108 0 : (m_aSelectRow->get())[1] = (m_aRow->get())[1];
1109 : }
1110 : }
1111 : else
1112 : {
1113 0 : m_bEOF = true;
1114 0 : m_nRowPos = 1;
1115 0 : return false;
1116 : }
1117 : }
1118 : else
1119 : // Fetch only possible at SELECT!
1120 0 : return false;
1121 :
1122 2094 : return true;
1123 :
1124 : Error:
1125 : // is the Cursor positioned before the first row
1126 : // then the position will be maintained
1127 115 : if (nTempPos == -1)
1128 20 : m_nRowPos = nTempPos;
1129 : else
1130 : {
1131 95 : switch(eCursorPosition)
1132 : {
1133 : case IResultSetHelper::PRIOR:
1134 : case IResultSetHelper::FIRST:
1135 37 : m_nRowPos = -1;
1136 37 : break;
1137 : case IResultSetHelper::LAST:
1138 : case IResultSetHelper::NEXT:
1139 : case IResultSetHelper::ABSOLUTE1:
1140 : case IResultSetHelper::RELATIVE1:
1141 58 : if (nOffset > 0)
1142 58 : m_nRowPos = m_pFileSet.is() ? (sal_Int32)m_pFileSet->get().size() : -1;
1143 0 : else if (nOffset < 0)
1144 0 : m_nRowPos = -1;
1145 58 : break;
1146 : case IResultSetHelper::BOOKMARK:
1147 0 : m_nRowPos = nTempPos; // last Position
1148 : }
1149 : }
1150 115 : return false;
1151 : }
1152 :
1153 1 : void OResultSet::sortRows()
1154 : {
1155 1 : if (!m_pSQLAnalyzer->hasRestriction() && m_aOrderbyColumnNumber.size() == 1)
1156 : {
1157 : // is just one field given for sorting
1158 : // and this field is indexed, then the Index will be used
1159 1 : Reference<XIndexesSupplier> xIndexSup;
1160 1 : m_pTable->queryInterface(cppu::UnoType<XIndexesSupplier>::get()) >>= xIndexSup;
1161 :
1162 2 : Reference<XIndexAccess> xIndexes;
1163 1 : if(xIndexSup.is())
1164 : {
1165 1 : xIndexes.set(xIndexSup->getIndexes(),UNO_QUERY);
1166 1 : Reference<XPropertySet> xColProp;
1167 1 : if(m_aOrderbyColumnNumber[0] < xIndexes->getCount())
1168 : {
1169 0 : xColProp.set(xIndexes->getByIndex(m_aOrderbyColumnNumber[0]),UNO_QUERY);
1170 : // iterate through the indexes to find the matching column
1171 0 : const sal_Int32 nCount = xIndexes->getCount();
1172 0 : for(sal_Int32 i=0; i < nCount;++i)
1173 : {
1174 0 : Reference<XColumnsSupplier> xIndex(xIndexes->getByIndex(i),UNO_QUERY);
1175 0 : Reference<XNameAccess> xIndexCols = xIndex->getColumns();
1176 0 : if(xIndexCols->hasByName(comphelper::getString(xColProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)))))
1177 : {
1178 0 : m_pFileSet = new OKeySet();
1179 :
1180 0 : if(fillIndexValues(xIndex))
1181 1 : return;
1182 : }
1183 0 : }
1184 1 : }
1185 1 : }
1186 : }
1187 :
1188 1 : OSortIndex::TKeyTypeVector eKeyType(m_aOrderbyColumnNumber.size());
1189 1 : ::std::vector<sal_Int32>::iterator aOrderByIter = m_aOrderbyColumnNumber.begin();
1190 2 : for (::std::vector<sal_Int16>::size_type i=0;aOrderByIter != m_aOrderbyColumnNumber.end(); ++aOrderByIter,++i)
1191 : {
1192 : OSL_ENSURE((sal_Int32)m_aSelectRow->get().size() > *aOrderByIter,"Invalid Index");
1193 1 : switch ((*(m_aSelectRow->get().begin()+*aOrderByIter))->getValue().getTypeKind())
1194 : {
1195 : case DataType::CHAR:
1196 : case DataType::VARCHAR:
1197 : case DataType::LONGVARCHAR:
1198 1 : eKeyType[i] = SQL_ORDERBYKEY_STRING;
1199 1 : break;
1200 :
1201 : case DataType::OTHER:
1202 : case DataType::TINYINT:
1203 : case DataType::SMALLINT:
1204 : case DataType::INTEGER:
1205 : case DataType::DECIMAL:
1206 : case DataType::NUMERIC:
1207 : case DataType::REAL:
1208 : case DataType::DOUBLE:
1209 : case DataType::DATE:
1210 : case DataType::TIME:
1211 : case DataType::TIMESTAMP:
1212 : case DataType::BIT:
1213 0 : eKeyType[i] = SQL_ORDERBYKEY_DOUBLE;
1214 0 : break;
1215 :
1216 : // Other types aren't implemented (so they are always FALSE)
1217 : default:
1218 0 : eKeyType[i] = SQL_ORDERBYKEY_NONE;
1219 : SAL_WARN( "connectivity.drivers","OFILECursor::Execute: Datentyp nicht implementiert");
1220 0 : break;
1221 : }
1222 1 : (m_aSelectRow->get())[*aOrderByIter]->setBound(true);
1223 : }
1224 :
1225 1 : m_pSortIndex = new OSortIndex(eKeyType,m_aOrderbyAscending);
1226 :
1227 1 : if (m_pEvaluationKeySet)
1228 : {
1229 0 : m_aEvaluateIter = m_pEvaluationKeySet->begin();
1230 :
1231 0 : while (m_aEvaluateIter != m_pEvaluationKeySet->end())
1232 : {
1233 0 : ExecuteRow(IResultSetHelper::BOOKMARK,(*m_aEvaluateIter),true);
1234 0 : ++m_aEvaluateIter;
1235 : }
1236 : }
1237 : else
1238 : {
1239 114 : while ( ExecuteRow( IResultSetHelper::NEXT, 1, false, true ) )
1240 : {
1241 112 : m_aSelectRow->get()[0]->setValue( m_aRow->get()[0]->getValue() );
1242 112 : if ( m_pSQLAnalyzer->hasFunctions() )
1243 0 : m_pSQLAnalyzer->setSelectionEvaluationResult( m_aSelectRow, m_aColMapping );
1244 112 : const sal_Int32 nBookmark = (*m_aRow->get().begin())->getValue();
1245 112 : ExecuteRow( IResultSetHelper::BOOKMARK, nBookmark, true, false );
1246 : }
1247 : }
1248 :
1249 : // create sorted Keyset
1250 1 : m_pEvaluationKeySet = NULL;
1251 1 : m_pFileSet = NULL;
1252 1 : m_pFileSet = m_pSortIndex->CreateKeySet();
1253 1 : DELETEZ(m_pSortIndex);
1254 : // now access to a sorted set is possible via Index
1255 : }
1256 :
1257 :
1258 :
1259 29 : bool OResultSet::OpenImpl()
1260 : {
1261 : OSL_ENSURE(m_pSQLAnalyzer,"No analyzer set with setSqlAnalyzer!");
1262 29 : if(!m_pTable)
1263 : {
1264 29 : const OSQLTables& xTabs = m_aSQLIterator.getTables();
1265 29 : if ((xTabs.begin() == xTabs.end()) || !xTabs.begin()->second.is())
1266 0 : lcl_throwError(STR_QUERY_TOO_COMPLEX,*this);
1267 :
1268 29 : if ( xTabs.size() > 1 || m_aSQLIterator.hasErrors() )
1269 0 : lcl_throwError(STR_QUERY_MORE_TABLES,*this);
1270 :
1271 29 : OSQLTable xTable = xTabs.begin()->second;
1272 29 : m_xColumns = m_aSQLIterator.getSelectColumns();
1273 :
1274 29 : m_xColNames = xTable->getColumns();
1275 29 : m_xColsIdx.set(m_xColNames,UNO_QUERY);
1276 29 : doTableSpecials(xTable);
1277 58 : Reference<XComponent> xComp(xTable,UNO_QUERY);
1278 29 : if(xComp.is())
1279 58 : xComp->addEventListener(this);
1280 : }
1281 :
1282 29 : m_pTable->refreshHeader();
1283 :
1284 29 : sal_Int32 nColumnCount = m_xColsIdx->getCount();
1285 :
1286 29 : initializeRow(m_aRow,nColumnCount);
1287 29 : initializeRow(m_aEvaluateRow,nColumnCount);
1288 29 : initializeRow(m_aInsertRow,nColumnCount);
1289 :
1290 :
1291 29 : m_nResultSetConcurrency = (m_pTable->isReadOnly() || isCount()) ? ResultSetConcurrency::READ_ONLY : ResultSetConcurrency::UPDATABLE;
1292 :
1293 : // create new Index:
1294 29 : m_pFileSet = NULL;
1295 :
1296 : // position at the beginning
1297 29 : m_nRowPos = -1;
1298 29 : m_nFilePos = 0;
1299 29 : m_nRowCountResult = -1;
1300 29 : m_pTable->seekRow(IResultSetHelper::ABSOLUTE1, 0, m_nFilePos);
1301 :
1302 29 : m_nLastVisitedPos = m_pTable->getCurrentLastPos();
1303 :
1304 29 : switch(m_aSQLIterator.getStatementType())
1305 : {
1306 : case SQL_STATEMENT_SELECT:
1307 : {
1308 29 : if(isCount())
1309 : {
1310 0 : if(m_xColumns->get().size() > 1)
1311 0 : lcl_throwError(STR_QUERY_COMPLEX_COUNT,*this);
1312 :
1313 0 : m_nRowCountResult = 0;
1314 : // for now simply iterate over all rows and
1315 : // do all actions (or just count)
1316 : {
1317 0 : bool bOK = true;
1318 0 : if (m_pEvaluationKeySet)
1319 : {
1320 0 : m_aEvaluateIter = m_pEvaluationKeySet->begin();
1321 0 : bOK = m_aEvaluateIter == m_pEvaluationKeySet->end();
1322 :
1323 : }
1324 0 : while (bOK)
1325 : {
1326 0 : if (m_pEvaluationKeySet)
1327 0 : ExecuteRow(IResultSetHelper::BOOKMARK,(*m_aEvaluateIter),true);
1328 : else
1329 0 : bOK = ExecuteRow(IResultSetHelper::NEXT,1,true);
1330 :
1331 0 : if (bOK)
1332 : {
1333 0 : m_nRowCountResult++;
1334 0 : if(m_pEvaluationKeySet)
1335 : {
1336 0 : ++m_aEvaluateIter;
1337 0 : bOK = m_aEvaluateIter == m_pEvaluationKeySet->end();
1338 : }
1339 : }
1340 : }
1341 :
1342 : // save result of COUNT(*) in m_nRowCountResult.
1343 : // nRowCount (number of Rows in the result) = 1 for this request!
1344 0 : m_pEvaluationKeySet = NULL;
1345 : }
1346 : }
1347 : else
1348 : {
1349 29 : bool bDistinct = false;
1350 : assert(m_pParseTree != 0);
1351 29 : OSQLParseNode *pDistinct = m_pParseTree->getChild(1);
1352 :
1353 : assert(m_aOrderbyColumnNumber.size() ==
1354 : m_aOrderbyAscending.size());
1355 29 : if (pDistinct && pDistinct->getTokenID() == SQL_TOKEN_DISTINCT )
1356 : {
1357 : // To eliminate duplicates we need to sort on all columns.
1358 : // This is not a problem because the SQL spec says that the
1359 : // order of columns that are not specified in ORDER BY
1360 : // clause is undefined, so it doesn't hurt to sort on
1361 : // these; pad the vectors to include them.
1362 0 : for (size_t i = 1; // 0: bookmark (see setBoundedColumns)
1363 0 : i < m_aColMapping.size(); ++i)
1364 : {
1365 0 : if (::std::find(m_aOrderbyColumnNumber.begin(),
1366 0 : m_aOrderbyColumnNumber.end(), i)
1367 0 : == m_aOrderbyColumnNumber.end())
1368 : {
1369 0 : m_aOrderbyColumnNumber.push_back(i);
1370 : // ASC or DESC doesn't matter
1371 0 : m_aOrderbyAscending.push_back(SQL_ASC);
1372 : }
1373 : }
1374 0 : bDistinct = true;
1375 : }
1376 :
1377 29 : if (IsSorted())
1378 1 : sortRows();
1379 :
1380 29 : if (!m_pFileSet.is())
1381 : {
1382 28 : m_pFileSet = new OKeySet();
1383 :
1384 28 : if (!m_pSQLAnalyzer->hasRestriction())
1385 : // now the Keyset can be filled!
1386 : // But be careful: It is assumed, that the FilePositions will be stored as sequence 1..n
1387 : {
1388 22 : if ( m_nLastVisitedPos > 0)
1389 21 : m_pFileSet->get().reserve( m_nLastVisitedPos );
1390 782 : for (sal_Int32 i = 0; i < m_nLastVisitedPos; i++)
1391 760 : m_pFileSet->get().push_back(i + 1);
1392 : }
1393 : }
1394 : OSL_ENSURE(m_pFileSet.is(),"Kein KeySet vorhanden! :-(");
1395 :
1396 29 : if(bDistinct && m_pFileSet.is())
1397 : {
1398 0 : OValueRow aSearchRow = new OValueVector(m_aRow->get().size());
1399 0 : OValueRefVector::Vector::iterator aRowIter = m_aRow->get().begin();
1400 0 : OValueVector::Vector::iterator aSearchIter = aSearchRow->get().begin();
1401 0 : for ( ++aRowIter,++aSearchIter; // the first column is the bookmark column
1402 0 : aRowIter != m_aRow->get().end();
1403 : ++aRowIter,++aSearchIter)
1404 0 : aSearchIter->setBound((*aRowIter)->isBound());
1405 :
1406 0 : size_t nMaxRow = m_pFileSet->get().size();
1407 :
1408 0 : if (nMaxRow)
1409 : {
1410 : #if OSL_DEBUG_LEVEL > 1
1411 : sal_Int32 nFound=0;
1412 : #endif
1413 : sal_Int32 nPos;
1414 : sal_Int32 nKey;
1415 :
1416 0 : for( size_t j = nMaxRow-1; j > 0; --j)
1417 : {
1418 0 : nPos = (m_pFileSet->get())[j];
1419 0 : ExecuteRow(IResultSetHelper::BOOKMARK,nPos,false);
1420 0 : m_pSQLAnalyzer->setSelectionEvaluationResult(m_aSelectRow,m_aColMapping);
1421 : { // copy row values
1422 0 : OValueRefVector::Vector::iterator copyFrom = m_aSelectRow->get().begin();
1423 0 : OValueVector::Vector::iterator copyTo = aSearchRow->get().begin();
1424 0 : for ( ++copyFrom,++copyTo; // the first column is the bookmark column
1425 0 : copyFrom != m_aSelectRow->get().end();
1426 : ++copyFrom,++copyTo)
1427 0 : *copyTo = *(*copyFrom);
1428 : }
1429 :
1430 : // compare with next row
1431 0 : nKey = (m_pFileSet->get())[j-1];
1432 0 : ExecuteRow(IResultSetHelper::BOOKMARK,nKey,false);
1433 0 : m_pSQLAnalyzer->setSelectionEvaluationResult(m_aSelectRow,m_aColMapping);
1434 0 : OValueRefVector::Vector::iterator loopInRow = m_aSelectRow->get().begin();
1435 0 : OValueVector::Vector::iterator existentInSearchRow = aSearchRow->get().begin();
1436 0 : for ( ++loopInRow,++existentInSearchRow; // the first column is the bookmark column
1437 0 : loopInRow != m_aSelectRow->get().end();
1438 : ++loopInRow,++existentInSearchRow)
1439 : {
1440 0 : if ( (*loopInRow)->isBound() && !( *(*loopInRow) == *existentInSearchRow) )
1441 0 : break;
1442 : }
1443 :
1444 0 : if(loopInRow == m_aSelectRow->get().end())
1445 0 : (m_pFileSet->get())[j] = 0; // Rows match -- Mark for deletion by setting key to 0
1446 : #if OSL_DEBUG_LEVEL > 1
1447 : else
1448 : nFound++;
1449 : #endif
1450 : }
1451 :
1452 0 : m_pFileSet->get().erase(::std::remove_if(m_pFileSet->get().begin(),m_pFileSet->get().end(),
1453 : ::std::bind2nd(::std::equal_to<sal_Int32>(),0))
1454 0 : ,m_pFileSet->get().end());
1455 0 : }
1456 : }
1457 : }
1458 29 : } break;
1459 :
1460 : case SQL_STATEMENT_UPDATE:
1461 : case SQL_STATEMENT_DELETE:
1462 : // during processing count the number of processed Rows
1463 0 : m_nRowCountResult = 0;
1464 : // for now simply iterate over all rows and
1465 : // run the actions (or simply count):
1466 : {
1467 :
1468 0 : bool bOK = true;
1469 0 : if (m_pEvaluationKeySet)
1470 : {
1471 0 : m_aEvaluateIter = m_pEvaluationKeySet->begin();
1472 0 : bOK = m_aEvaluateIter == m_pEvaluationKeySet->end();
1473 :
1474 : }
1475 0 : while (bOK)
1476 : {
1477 0 : if (m_pEvaluationKeySet)
1478 0 : ExecuteRow(IResultSetHelper::BOOKMARK,(*m_aEvaluateIter),true);
1479 : else
1480 0 : bOK = ExecuteRow(IResultSetHelper::NEXT,1,true);
1481 :
1482 0 : if (bOK)
1483 : {
1484 0 : m_nRowCountResult++;
1485 0 : if(m_pEvaluationKeySet)
1486 : {
1487 0 : ++m_aEvaluateIter;
1488 0 : bOK = m_aEvaluateIter == m_pEvaluationKeySet->end();
1489 : }
1490 : }
1491 : }
1492 :
1493 : // save result of COUNT(*) in nRowCountResult.
1494 : // nRowCount (number of rows in the result-set) = 1 for this request!
1495 0 : m_pEvaluationKeySet = NULL;
1496 : }
1497 0 : break;
1498 : case SQL_STATEMENT_INSERT:
1499 0 : m_nRowCountResult = 0;
1500 :
1501 : OSL_ENSURE(m_aAssignValues.is(),"No assign values set!");
1502 0 : if(!m_pTable->InsertRow(*m_aAssignValues, true,m_xColsIdx))
1503 : {
1504 0 : m_nFilePos = 0;
1505 0 : return false;
1506 : }
1507 :
1508 0 : m_nRowCountResult = 1;
1509 0 : break;
1510 : default:
1511 : SAL_WARN( "connectivity.drivers", "OResultSet::OpenImpl: unsupported statement type!" );
1512 0 : break;
1513 : }
1514 :
1515 : // reset FilePos
1516 29 : m_nFilePos = 0;
1517 :
1518 29 : return true;
1519 : }
1520 :
1521 0 : Sequence< sal_Int8 > OResultSet::getUnoTunnelImplementationId()
1522 : {
1523 : static ::cppu::OImplementationId * pId = 0;
1524 0 : if (! pId)
1525 : {
1526 0 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
1527 0 : if (! pId)
1528 : {
1529 0 : static ::cppu::OImplementationId aId;
1530 0 : pId = &aId;
1531 0 : }
1532 : }
1533 0 : return pId->getImplementationId();
1534 : }
1535 :
1536 : // com::sun::star::lang::XUnoTunnel
1537 :
1538 0 : sal_Int64 OResultSet::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException, std::exception)
1539 : {
1540 0 : return (rId.getLength() == 16 && 0 == memcmp(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
1541 : ? reinterpret_cast< sal_Int64 >( this )
1542 0 : : 0;
1543 : }
1544 :
1545 116 : void OResultSet::setBoundedColumns(const OValueRefRow& _rRow,
1546 : const OValueRefRow& _rSelectRow,
1547 : const ::rtl::Reference<connectivity::OSQLColumns>& _rxColumns,
1548 : const Reference<XIndexAccess>& _xNames,
1549 : bool _bSetColumnMapping,
1550 : const Reference<XDatabaseMetaData>& _xMetaData,
1551 : ::std::vector<sal_Int32>& _rColMapping)
1552 : {
1553 116 : ::comphelper::UStringMixEqual aCase(_xMetaData->supportsMixedCaseQuotedIdentifiers());
1554 :
1555 116 : Reference<XPropertySet> xTableColumn;
1556 232 : OUString sTableColumnName, sSelectColumnRealName;
1557 :
1558 232 : const OUString sName = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME);
1559 232 : const OUString sRealName = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME);
1560 232 : const OUString sType = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE);
1561 :
1562 : typedef ::std::map<OSQLColumns::Vector::iterator,sal_Bool> IterMap;
1563 232 : IterMap aSelectIters;
1564 116 : OValueRefVector::Vector::iterator aRowIter = _rRow->get().begin()+1;
1565 6660 : for (sal_Int32 i=0; // the first column is the bookmark column
1566 4440 : aRowIter != _rRow->get().end();
1567 : ++i, ++aRowIter
1568 : )
1569 : {
1570 2104 : (*aRowIter)->setBound(false);
1571 : try
1572 : {
1573 : // get the table column and its name
1574 2104 : _xNames->getByIndex(i) >>= xTableColumn;
1575 : OSL_ENSURE(xTableColumn.is(), "OResultSet::setBoundedColumns: invalid table column!");
1576 2104 : if (xTableColumn.is())
1577 2104 : xTableColumn->getPropertyValue(sName) >>= sTableColumnName;
1578 : else
1579 0 : sTableColumnName.clear();
1580 :
1581 : // look if we have such a select column
1582 : // TODO: would like to have a O(log n) search here ...
1583 29082 : for ( OSQLColumns::Vector::iterator aIter = _rxColumns->get().begin();
1584 19388 : aIter != _rxColumns->get().end();
1585 : ++aIter
1586 : )
1587 : {
1588 8334 : if((*aIter)->getPropertySetInfo()->hasPropertyByName(sRealName))
1589 8334 : (*aIter)->getPropertyValue(sRealName) >>= sSelectColumnRealName;
1590 : else
1591 0 : (*aIter)->getPropertyValue(sName) >>= sSelectColumnRealName;
1592 :
1593 8334 : if ( aCase(sTableColumnName, sSelectColumnRealName) && !(*aRowIter)->isBound() && aSelectIters.end() == aSelectIters.find(aIter) )
1594 : {
1595 744 : aSelectIters.insert(IterMap::value_type(aIter,sal_True));
1596 744 : if(_bSetColumnMapping)
1597 : {
1598 736 : sal_Int32 nSelectColumnPos = aIter - _rxColumns->get().begin() + 1;
1599 : // the getXXX methods are 1-based ...
1600 736 : sal_Int32 nTableColumnPos = i + 1;
1601 : // get first table column is the bookmark column ...
1602 736 : _rColMapping[nSelectColumnPos] = nTableColumnPos;
1603 736 : (_rSelectRow->get())[nSelectColumnPos] = *aRowIter;
1604 : }
1605 :
1606 744 : (*aRowIter)->setBound(true);
1607 744 : sal_Int32 nType = DataType::OTHER;
1608 744 : if (xTableColumn.is())
1609 744 : xTableColumn->getPropertyValue(sType) >>= nType;
1610 744 : (*aRowIter)->setTypeKind(nType);
1611 :
1612 744 : break;
1613 : }
1614 : }
1615 : }
1616 0 : catch (Exception&)
1617 : {
1618 : SAL_WARN( "connectivity.drivers","OResultSet::setBoundedColumns: caught an Exception!");
1619 : }
1620 : }
1621 : // in this case we got more select columns as columns exist in the table
1622 116 : if ( _bSetColumnMapping && aSelectIters.size() != _rColMapping.size() )
1623 : {
1624 58 : Reference<XNameAccess> xNameAccess(_xNames,UNO_QUERY);
1625 116 : Sequence< OUString > aSelectColumns = xNameAccess->getElementNames();
1626 :
1627 2382 : for ( OSQLColumns::Vector::iterator aIter = _rxColumns->get().begin();
1628 1588 : aIter != _rxColumns->get().end();
1629 : ++aIter
1630 : )
1631 : {
1632 736 : if ( aSelectIters.end() == aSelectIters.find(aIter) )
1633 : {
1634 0 : if ( (*aIter)->getPropertySetInfo()->hasPropertyByName(sRealName) )
1635 0 : (*aIter)->getPropertyValue(sRealName) >>= sSelectColumnRealName;
1636 : else
1637 0 : (*aIter)->getPropertyValue(sName) >>= sSelectColumnRealName;
1638 :
1639 0 : if ( xNameAccess->hasByName( sSelectColumnRealName ) )
1640 : {
1641 0 : aSelectIters.insert(IterMap::value_type(aIter,sal_True));
1642 0 : sal_Int32 nSelectColumnPos = aIter - _rxColumns->get().begin() + 1;
1643 0 : const OUString* pBegin = aSelectColumns.getConstArray();
1644 0 : const OUString* pEnd = pBegin + aSelectColumns.getLength();
1645 0 : for(sal_Int32 i=0;pBegin != pEnd;++pBegin,++i)
1646 : {
1647 0 : if ( aCase(*pBegin, sSelectColumnRealName) )
1648 : {
1649 : // the getXXX methods are 1-based ...
1650 0 : sal_Int32 nTableColumnPos = i + 1;
1651 : // get first table column is the bookmark column ...
1652 0 : _rColMapping[nSelectColumnPos] = nTableColumnPos;
1653 0 : (_rSelectRow->get())[nSelectColumnPos] = (_rRow->get())[nTableColumnPos];
1654 0 : break;
1655 : }
1656 : }
1657 : }
1658 : }
1659 58 : }
1660 116 : }
1661 116 : }
1662 :
1663 2117 : void SAL_CALL OResultSet::acquire() throw()
1664 : {
1665 2117 : OResultSet_BASE::acquire();
1666 2117 : }
1667 :
1668 2117 : void SAL_CALL OResultSet::release() throw()
1669 : {
1670 2117 : OResultSet_BASE::release();
1671 2117 : }
1672 :
1673 0 : Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OResultSet::getPropertySetInfo( ) throw(RuntimeException, std::exception)
1674 : {
1675 0 : return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1676 : }
1677 :
1678 29 : void OResultSet::doTableSpecials(const OSQLTable& _xTable)
1679 : {
1680 29 : Reference<css::lang::XUnoTunnel> xTunnel(_xTable, UNO_QUERY_THROW);
1681 29 : m_pTable = reinterpret_cast< OFileTable* >(xTunnel->getSomething(OFileTable::getUnoTunnelImplementationId()));
1682 : assert(m_pTable);
1683 29 : m_pTable->acquire();
1684 29 : }
1685 :
1686 5 : void OResultSet::clearInsertRow()
1687 : {
1688 5 : m_aRow->setDeleted(false); // set to false here because this is the new row
1689 5 : OValueRefVector::Vector::iterator aIter = m_aInsertRow->get().begin();
1690 5 : const OValueRefVector::Vector::iterator aEnd = m_aInsertRow->get().end();
1691 85 : for(sal_Int32 nPos = 0;aIter != aEnd;++aIter,++nPos)
1692 : {
1693 80 : ORowSetValueDecoratorRef& rValue = (*aIter);
1694 80 : if ( rValue->isBound() )
1695 : {
1696 10 : (m_aRow->get())[nPos]->setValue( (*aIter)->getValue() );
1697 : }
1698 80 : rValue->setBound(nPos == 0);
1699 80 : rValue->setModified(false);
1700 80 : rValue->setNull();
1701 : }
1702 5 : }
1703 :
1704 87 : void OResultSet::initializeRow(OValueRefRow& _rRow,sal_Int32 _nColumnCount)
1705 : {
1706 87 : if(!_rRow.is())
1707 : {
1708 29 : _rRow = new OValueRefVector(_nColumnCount);
1709 29 : (_rRow->get())[0]->setBound(true);
1710 29 : ::std::for_each(_rRow->get().begin()+1,_rRow->get().end(),TSetRefBound(false));
1711 : }
1712 87 : }
1713 :
1714 0 : bool OResultSet::fillIndexValues(const Reference< XColumnsSupplier> &/*_xIndex*/)
1715 : {
1716 0 : return false;
1717 : }
1718 :
1719 2218 : bool OResultSet::move(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, bool _bRetrieveData)
1720 : {
1721 2218 : return Move(_eCursorPosition,_nOffset,_bRetrieveData);
1722 : }
1723 :
1724 301 : sal_Int32 OResultSet::getDriverPos() const
1725 : {
1726 301 : return (m_aRow->get())[0]->getValue();
1727 : }
1728 :
1729 0 : bool OResultSet::deletedVisible() const
1730 : {
1731 0 : return m_bShowDeleted;
1732 : }
1733 :
1734 1925 : bool OResultSet::isRowDeleted() const
1735 : {
1736 1925 : return m_aRow->isDeleted();
1737 : }
1738 :
1739 0 : void SAL_CALL OResultSet::disposing( const EventObject& Source ) throw (RuntimeException, std::exception)
1740 : {
1741 0 : Reference<XPropertySet> xProp = m_pTable;
1742 0 : if(m_pTable && Source.Source == xProp)
1743 : {
1744 0 : m_pTable->release();
1745 0 : m_pTable = NULL;
1746 0 : }
1747 36 : }
1748 :
1749 :
1750 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|