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