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 : #include <com/sun/star/sdbc/DataType.hpp>
21 : #include <com/sun/star/beans/PropertyAttribute.hpp>
22 : #include <comphelper/property.hxx>
23 : #include <comphelper/sequence.hxx>
24 : #include <cppuhelper/typeprovider.hxx>
25 : #include <cppuhelper/supportsservice.hxx>
26 : #include <comphelper/extract.hxx>
27 : #include <com/sun/star/lang/DisposedException.hpp>
28 : #include <com/sun/star/sdbc/ResultSetType.hpp>
29 : #include <com/sun/star/sdbc/FetchDirection.hpp>
30 : #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
31 : #include <com/sun/star/sdbcx/CompareBookmark.hpp>
32 : #include <comphelper/types.hxx>
33 : #include <connectivity/dbexception.hxx>
34 : #include <connectivity/dbtools.hxx>
35 :
36 : #include <TSortIndex.hxx>
37 : #include <rtl/string.hxx>
38 : #include <vector>
39 : #include <algorithm>
40 : #include "MResultSet.hxx"
41 : #include "sqlbison.hxx"
42 : #include "MResultSetMetaData.hxx"
43 : #include "FDatabaseMetaDataResultSet.hxx"
44 :
45 : #include "resource/mork_res.hrc"
46 : #include "resource/common_res.hrc"
47 :
48 : #if OSL_DEBUG_LEVEL > 0
49 : # define OUtoCStr( x ) ( OUStringToOString ( (x), RTL_TEXTENCODING_ASCII_US).getStr())
50 : #else /* OSL_DEBUG_LEVEL */
51 : # define OUtoCStr( x ) ("dummy")
52 : #endif /* OSL_DEBUG_LEVEL */
53 :
54 : using namespace ::comphelper;
55 : using namespace connectivity;
56 : using namespace connectivity::mork;
57 : using namespace ::cppu;
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 : using namespace com::sun::star::io;
65 : using namespace com::sun::star::util;
66 :
67 :
68 : // IMPLEMENT_SERVICE_INFO(OResultSet,"com.sun.star.sdbcx.OResultSet","com.sun.star.sdbc.ResultSet");
69 0 : OUString SAL_CALL OResultSet::getImplementationName( ) throw ( RuntimeException, std::exception) \
70 : {
71 0 : return OUString("com.sun.star.sdbcx.mork.ResultSet");
72 : }
73 :
74 0 : Sequence< OUString > SAL_CALL OResultSet::getSupportedServiceNames( ) throw( RuntimeException, std::exception)
75 : {
76 0 : ::com::sun::star::uno::Sequence< OUString > aSupported(2);
77 0 : aSupported[0] = "com.sun.star.sdbc.ResultSet";
78 0 : aSupported[1] = "com.sun.star.sdbcx.ResultSet";
79 0 : return aSupported;
80 : }
81 :
82 0 : sal_Bool SAL_CALL OResultSet::supportsService( const OUString& _rServiceName ) throw( RuntimeException, std::exception)
83 : {
84 0 : return cppu::supportsService(this, _rServiceName);
85 : }
86 :
87 :
88 2 : OResultSet::OResultSet(OCommonStatement* pStmt, const ::boost::shared_ptr< connectivity::OSQLParseTreeIterator >& _pSQLIterator )
89 : : OResultSet_BASE(m_aMutex)
90 : ,OPropertySetHelper(OResultSet_BASE::rBHelper)
91 : ,m_pStatement(pStmt)
92 : ,m_xStatement(*pStmt)
93 : ,m_xMetaData(NULL)
94 : ,m_nRowPos(0)
95 : ,m_nOldRowPos(0)
96 : ,m_bWasNull(false)
97 : ,m_nFetchSize(0)
98 : ,m_nResultSetType(ResultSetType::SCROLL_INSENSITIVE)
99 : ,m_nFetchDirection(FetchDirection::FORWARD)
100 : ,m_nResultSetConcurrency(ResultSetConcurrency::UPDATABLE)
101 : ,m_pSQLIterator( _pSQLIterator )
102 2 : ,m_pParseTree( _pSQLIterator->getParseTree() )
103 2 : ,m_aQueryHelper(pStmt->getOwnConnection()->getColumnAlias())
104 : ,m_pTable(NULL)
105 : ,m_CurrentRowCount(0)
106 : ,m_nParamIndex(0)
107 : ,m_bIsAlwaysFalseQuery(false)
108 : ,m_pKeySet(NULL)
109 : ,m_nNewRow(0)
110 : ,m_nUpdatedRow(0)
111 : ,m_RowStates(0)
112 6 : ,m_bIsReadOnly(TRISTATE_INDET)
113 : {
114 : //m_aQuery.setMaxNrOfReturns(pStmt->getOwnConnection()->getMaxResultRecords());
115 2 : }
116 :
117 4 : OResultSet::~OResultSet()
118 : {
119 4 : }
120 :
121 :
122 2 : void OResultSet::disposing()
123 : {
124 2 : OPropertySetHelper::disposing();
125 :
126 2 : ::osl::MutexGuard aGuard(m_aMutex);
127 :
128 2 : m_xStatement.clear();
129 2 : m_xMetaData.clear();
130 2 : m_pParseTree = NULL;
131 2 : m_xColumns = NULL;
132 2 : m_xParamColumns = NULL;
133 2 : m_pKeySet = NULL;
134 2 : if(m_pTable)
135 : {
136 2 : m_pTable->release();
137 2 : m_pTable = NULL;
138 2 : }
139 2 : }
140 :
141 10 : Any SAL_CALL OResultSet::queryInterface( const Type & rType ) throw(RuntimeException, std::exception)
142 : {
143 10 : Any aRet = OPropertySetHelper::queryInterface(rType);
144 10 : if(!aRet.hasValue())
145 8 : aRet = OResultSet_BASE::queryInterface(rType);
146 10 : return aRet;
147 : }
148 :
149 0 : Sequence< Type > SAL_CALL OResultSet::getTypes( ) throw( RuntimeException, std::exception)
150 : {
151 0 : OTypeCollection aTypes( cppu::UnoType<com::sun::star::beans::XMultiPropertySet>::get(),
152 0 : cppu::UnoType<com::sun::star::beans::XFastPropertySet>::get(),
153 0 : cppu::UnoType<com::sun::star::beans::XPropertySet>::get());
154 :
155 0 : return ::comphelper::concatSequences(aTypes.getTypes(),OResultSet_BASE::getTypes());
156 : }
157 :
158 14 : void OResultSet::methodEntry()
159 : {
160 14 : checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
161 14 : if ( !m_pTable )
162 : {
163 : OSL_FAIL( "OResultSet::methodEntry: looks like we're disposed, but how is this possible?" );
164 0 : throw DisposedException( OUString(), *this );
165 : }
166 14 : }
167 :
168 :
169 0 : sal_Int32 SAL_CALL OResultSet::findColumn( const OUString& columnName ) throw(SQLException, RuntimeException, std::exception)
170 : {
171 0 : ResultSetEntryGuard aGuard( *this );
172 :
173 : // find the first column with the name columnName
174 0 : Reference< XResultSetMetaData > xMeta = getMetaData();
175 0 : sal_Int32 nLen = xMeta->getColumnCount();
176 0 : sal_Int32 i = 1;
177 0 : for(;i<=nLen;++i)
178 : {
179 0 : if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) :
180 0 : columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i)))
181 0 : return i;
182 : }
183 :
184 0 : ::dbtools::throwInvalidColumnException( columnName, *this );
185 : assert(false);
186 0 : return 0; // Never reached
187 : }
188 :
189 0 : Reference< XInputStream > SAL_CALL OResultSet::getBinaryStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
190 : {
191 0 : return NULL;
192 : }
193 :
194 0 : Reference< XInputStream > SAL_CALL OResultSet::getCharacterStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
195 : {
196 0 : return NULL;
197 : }
198 :
199 :
200 0 : sal_Bool SAL_CALL OResultSet::getBoolean( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
201 : {
202 0 : ResultSetEntryGuard aGuard( *this );
203 0 : m_bWasNull = true;
204 0 : return sal_False;
205 : }
206 :
207 :
208 0 : sal_Int8 SAL_CALL OResultSet::getByte( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
209 : {
210 0 : ResultSetEntryGuard aGuard( *this );
211 0 : return 0;
212 : }
213 :
214 :
215 0 : Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
216 : {
217 0 : ResultSetEntryGuard aGuard( *this );
218 0 : return Sequence< sal_Int8 >();
219 : }
220 :
221 :
222 0 : Date SAL_CALL OResultSet::getDate( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
223 : {
224 0 : ResultSetEntryGuard aGuard( *this );
225 0 : return Date();
226 : }
227 :
228 :
229 0 : double SAL_CALL OResultSet::getDouble( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
230 : {
231 0 : ResultSetEntryGuard aGuard( *this );
232 0 : return 0.0;
233 : }
234 :
235 :
236 0 : float SAL_CALL OResultSet::getFloat( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
237 : {
238 0 : ResultSetEntryGuard aGuard( *this );
239 0 : return 0;
240 : }
241 :
242 :
243 0 : sal_Int32 SAL_CALL OResultSet::getInt( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
244 : {
245 0 : ResultSetEntryGuard aGuard( *this );
246 0 : return 0;
247 : }
248 :
249 :
250 0 : sal_Int32 SAL_CALL OResultSet::getRow( ) throw(SQLException, RuntimeException, std::exception)
251 : {
252 0 : ResultSetEntryGuard aGuard( *this );
253 :
254 : SAL_INFO("connectivity.mork", "return = " << m_nRowPos);
255 0 : return m_nRowPos;
256 : }
257 :
258 :
259 0 : sal_Int64 SAL_CALL OResultSet::getLong( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
260 : {
261 0 : ResultSetEntryGuard aGuard( *this );
262 0 : return sal_Int64();
263 : }
264 :
265 :
266 0 : Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData( ) throw(SQLException, RuntimeException, std::exception)
267 : {
268 0 : ResultSetEntryGuard aGuard( *this );
269 :
270 0 : if(!m_xMetaData.is())
271 0 : m_xMetaData = new OResultSetMetaData(
272 0 : m_pSQLIterator->getSelectColumns(), m_pSQLIterator->getTables().begin()->first ,m_pTable,determineReadOnly());
273 0 : return m_xMetaData;
274 : }
275 :
276 0 : Reference< XArray > SAL_CALL OResultSet::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
277 : {
278 0 : return NULL;
279 : }
280 :
281 :
282 :
283 0 : Reference< XClob > SAL_CALL OResultSet::getClob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
284 : {
285 0 : return NULL;
286 : }
287 :
288 0 : Reference< XBlob > SAL_CALL OResultSet::getBlob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
289 : {
290 0 : return NULL;
291 : }
292 :
293 :
294 0 : Reference< XRef > SAL_CALL OResultSet::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
295 : {
296 0 : return NULL;
297 : }
298 :
299 :
300 0 : Any SAL_CALL OResultSet::getObject( sal_Int32 /*columnIndex*/, const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException, std::exception)
301 : {
302 0 : return Any();
303 : }
304 :
305 :
306 0 : sal_Int16 SAL_CALL OResultSet::getShort( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
307 : {
308 0 : return 0;
309 : }
310 :
311 :
312 4 : void OResultSet::checkIndex(sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException)
313 : {
314 4 : if(columnIndex <= 0 || columnIndex > (sal_Int32)m_xColumns->get().size())
315 0 : ::dbtools::throwInvalidIndexException(*this);
316 4 : }
317 :
318 6 : sal_uInt32 OResultSet::currentRowCount()
319 : {
320 6 : if ( m_bIsAlwaysFalseQuery )
321 0 : return 0;
322 : //return 0;//m_aQuery.getRealRowCount() - deletedCount();
323 : // new implementation
324 6 : return m_aQueryHelper.getResultCount();
325 : }
326 :
327 :
328 :
329 5 : bool OResultSet::fetchCurrentRow( ) throw(SQLException, RuntimeException)
330 : {
331 : SAL_INFO("connectivity.mork", "m_nRowPos = " << m_nRowPos);
332 5 : return fetchRow(getCurrentCardNumber());
333 : }
334 :
335 :
336 19 : bool OResultSet::fetchRow(sal_Int32 cardNumber,bool bForceReload) throw(SQLException, RuntimeException)
337 : {
338 : SAL_INFO("connectivity.mork", "cardNumber = " << cardNumber);
339 19 : if (!bForceReload)
340 : {
341 : // Check whether we've already fetched the row...
342 19 : if ( !(m_aRow->get())[0].isNull() && (sal_Int32)(m_aRow->get())[0] == (sal_Int32)cardNumber )
343 5 : return true;
344 : //Check whether the old row has been changed
345 14 : if (cardNumber == m_nUpdatedRow)
346 : {
347 : //write back the changes first
348 0 : if (!pushCard(cardNumber)) //error write back the changes
349 0 : throw SQLException();
350 : }
351 : }
352 : // else
353 : // m_aQuery.resyncRow(cardNumber);
354 :
355 14 : if ( !validRow( cardNumber ) )
356 0 : return false;
357 :
358 14 : (m_aRow->get())[0] = (sal_Int32)cardNumber;
359 14 : sal_Int32 nCount = m_aColumnNames.getLength();
360 : //m_RowStates = m_aQuery.getRowStates(cardNumber);
361 532 : for( sal_Int32 i = 1; i <= nCount; i++ )
362 : {
363 518 : if ( (m_aRow->get())[i].isBound() )
364 : {
365 :
366 : // Everything in the addressbook is a string!
367 :
368 14 : if ( !m_aQueryHelper.getRowValue( (m_aRow->get())[i], cardNumber, m_aColumnNames[i-1], DataType::VARCHAR ))
369 : {
370 0 : m_pStatement->getOwnConnection()->throwSQLException( m_aQueryHelper.getError(), *this );
371 : }
372 : }
373 : }
374 14 : return true;
375 :
376 : }
377 :
378 :
379 14 : const ORowSetValue& OResultSet::getValue(sal_Int32 cardNumber, sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
380 : {
381 14 : if ( !fetchRow( cardNumber ) )
382 : {
383 : OSL_FAIL("fetchRow() returned False" );
384 0 : m_bWasNull = true;
385 0 : return *ODatabaseMetaDataResultSet::getEmptyValue();
386 : }
387 :
388 14 : m_bWasNull = (m_aRow->get())[columnIndex].isNull();
389 14 : return (m_aRow->get())[columnIndex];
390 :
391 : }
392 :
393 :
394 :
395 4 : OUString SAL_CALL OResultSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
396 : {
397 4 : ResultSetEntryGuard aGuard( *this );
398 :
399 : OSL_ENSURE(m_xColumns.is(), "Need the Columns!!");
400 : OSL_ENSURE(columnIndex <= (sal_Int32)m_xColumns->get().size(), "Trying to access invalid columns number");
401 4 : checkIndex( columnIndex );
402 :
403 : // If this query was sorted then we should have a valid KeySet, so use it
404 4 : return getValue(getCurrentCardNumber(), mapColumn( columnIndex ) );
405 :
406 : }
407 :
408 :
409 0 : Time SAL_CALL OResultSet::getTime( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
410 : {
411 0 : ResultSetEntryGuard aGuard( *this );
412 0 : return Time();
413 : }
414 :
415 :
416 :
417 0 : DateTime SAL_CALL OResultSet::getTimestamp( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
418 : {
419 0 : ResultSetEntryGuard aGuard( *this );
420 0 : return DateTime();
421 : }
422 :
423 :
424 0 : sal_Bool SAL_CALL OResultSet::isBeforeFirst( ) throw(SQLException, RuntimeException, std::exception)
425 : {
426 0 : ResultSetEntryGuard aGuard( *this );
427 :
428 : // here you have to implement your movements
429 : // return true means there is no data
430 : OSL_TRACE("In/Out: OResultSet::isBeforeFirst" );
431 0 : return( m_nRowPos < 1 );
432 : }
433 :
434 0 : sal_Bool SAL_CALL OResultSet::isAfterLast( ) throw(SQLException, RuntimeException, std::exception)
435 : {
436 : SAL_WARN("connectivity.mork", "OResultSet::isAfterLast() NOT IMPLEMENTED!");
437 0 : ResultSetEntryGuard aGuard( *this );
438 :
439 : OSL_TRACE("In/Out: OResultSet::isAfterLast" );
440 : // return sal_True;
441 0 : return m_nRowPos > currentRowCount() && MQueryHelper::queryComplete();
442 : }
443 :
444 0 : sal_Bool SAL_CALL OResultSet::isFirst( ) throw(SQLException, RuntimeException, std::exception)
445 : {
446 0 : ResultSetEntryGuard aGuard( *this );
447 :
448 : OSL_TRACE("In/Out: OResultSet::isFirst" );
449 0 : return m_nRowPos == 1;
450 : }
451 :
452 0 : sal_Bool SAL_CALL OResultSet::isLast( ) throw(SQLException, RuntimeException, std::exception)
453 : {
454 : SAL_WARN("connectivity.mork", "OResultSet::isLast() NOT IMPLEMENTED!");
455 0 : ResultSetEntryGuard aGuard( *this );
456 :
457 : OSL_TRACE("In/Out: OResultSet::isLast" );
458 : // return sal_True;
459 0 : return m_nRowPos == currentRowCount() && MQueryHelper::queryComplete();
460 : }
461 :
462 1 : void SAL_CALL OResultSet::beforeFirst( ) throw(SQLException, RuntimeException, std::exception)
463 : {
464 1 : ResultSetEntryGuard aGuard( *this );
465 :
466 : // move before the first row so that isBeforeFirst returns false
467 : OSL_TRACE("In/Out: OResultSet::beforeFirst" );
468 1 : if ( first() )
469 1 : previous();
470 1 : }
471 :
472 0 : void SAL_CALL OResultSet::afterLast( ) throw(SQLException, RuntimeException, std::exception)
473 : {
474 0 : ResultSetEntryGuard aGuard( *this );
475 : OSL_TRACE("In/Out: OResultSet::afterLast" );
476 :
477 0 : if(last())
478 0 : next();
479 0 : }
480 :
481 :
482 2 : void SAL_CALL OResultSet::close() throw(SQLException, RuntimeException, std::exception)
483 : {
484 : OSL_TRACE("In/Out: OResultSet::close" );
485 2 : dispose();
486 2 : }
487 :
488 :
489 3 : sal_Bool SAL_CALL OResultSet::first( ) throw(SQLException, RuntimeException, std::exception)
490 : {
491 : OSL_TRACE("In/Out: OResultSet::first" );
492 3 : return seekRow( FIRST_POS );
493 : }
494 :
495 :
496 1 : sal_Bool SAL_CALL OResultSet::last( ) throw(SQLException, RuntimeException, std::exception)
497 : {
498 : OSL_TRACE("In/Out: OResultSet::last" );
499 1 : return seekRow( LAST_POS );
500 : }
501 :
502 0 : sal_Bool SAL_CALL OResultSet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException, std::exception)
503 : {
504 : OSL_TRACE("In/Out: OResultSet::absolute" );
505 0 : return seekRow( ABSOLUTE_POS, row );
506 : }
507 :
508 0 : sal_Bool SAL_CALL OResultSet::relative( sal_Int32 row ) throw(SQLException, RuntimeException, std::exception)
509 : {
510 : OSL_TRACE("In/Out: OResultSet::relative" );
511 0 : return seekRow( RELATIVE_POS, row );
512 : }
513 :
514 1 : sal_Bool SAL_CALL OResultSet::previous( ) throw(SQLException, RuntimeException, std::exception)
515 : {
516 1 : ResultSetEntryGuard aGuard( *this );
517 : OSL_TRACE("In/Out: OResultSet::previous" );
518 1 : return seekRow( PRIOR_POS );
519 : }
520 :
521 0 : Reference< XInterface > SAL_CALL OResultSet::getStatement( ) throw(SQLException, RuntimeException, std::exception)
522 : {
523 0 : ResultSetEntryGuard aGuard( *this );
524 :
525 : OSL_TRACE("In/Out: OResultSet::getStatement" );
526 0 : return m_xStatement;
527 : }
528 :
529 :
530 0 : sal_Bool SAL_CALL OResultSet::rowDeleted( ) throw(SQLException, RuntimeException, std::exception)
531 : {
532 : SAL_WARN("connectivity.mork", "OResultSet::rowDeleted() NOT IMPLEMENTED!");
533 0 : ResultSetEntryGuard aGuard( *this );
534 0 : return sal_True;//return ((m_RowStates & RowStates_Deleted) == RowStates_Deleted) ;
535 : }
536 :
537 0 : sal_Bool SAL_CALL OResultSet::rowInserted( ) throw(SQLException, RuntimeException, std::exception)
538 : {
539 : SAL_WARN("connectivity.mork", "OResultSet::rowInserted() NOT IMPLEMENTED!");
540 0 : ResultSetEntryGuard aGuard( *this );
541 0 : return sal_True;//return ((m_RowStates & RowStates_Inserted) == RowStates_Inserted);
542 : }
543 :
544 0 : sal_Bool SAL_CALL OResultSet::rowUpdated( ) throw(SQLException, RuntimeException, std::exception)
545 : {
546 : SAL_WARN("connectivity.mork", "OResultSet::rowUpdated() NOT IMPLEMENTED!");
547 0 : ResultSetEntryGuard aGuard( *this );
548 0 : return sal_True;// return ((m_RowStates & RowStates_Updated) == RowStates_Updated) ;
549 : }
550 :
551 :
552 1 : sal_Bool SAL_CALL OResultSet::next( ) throw(SQLException, RuntimeException, std::exception)
553 : {
554 1 : return seekRow( NEXT_POS );
555 : }
556 :
557 :
558 0 : sal_Bool SAL_CALL OResultSet::wasNull( ) throw(SQLException, RuntimeException, std::exception)
559 : {
560 0 : ResultSetEntryGuard aGuard( *this );
561 :
562 0 : return m_bWasNull;
563 : }
564 :
565 :
566 0 : void SAL_CALL OResultSet::cancel( ) throw(RuntimeException, std::exception)
567 : {
568 0 : ResultSetEntryGuard aGuard( *this );
569 0 : OSL_TRACE("In/Out: OResultSet::cancel" );
570 :
571 0 : }
572 :
573 0 : void SAL_CALL OResultSet::clearWarnings( ) throw(SQLException, RuntimeException, std::exception)
574 : {
575 : OSL_TRACE("In/Out: OResultSet::clearWarnings" );
576 0 : }
577 :
578 0 : Any SAL_CALL OResultSet::getWarnings( ) throw(SQLException, RuntimeException, std::exception)
579 : {
580 : OSL_TRACE("In/Out: OResultSet::getWarnings" );
581 0 : return Any();
582 : }
583 :
584 0 : void SAL_CALL OResultSet::refreshRow( ) throw(SQLException, RuntimeException, std::exception)
585 : {
586 : OSL_TRACE("In/Out: OResultSet::refreshRow" );
587 0 : if (fetchRow(getCurrentCardNumber(),true)) {
588 : //force fetch current row will cause we lose all change to the current row
589 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_ERROR_REFRESH_ROW, *this );
590 : }
591 0 : }
592 :
593 0 : IPropertyArrayHelper* OResultSet::createArrayHelper( ) const
594 : {
595 0 : Sequence< Property > aProps(5);
596 0 : Property* pProperties = aProps.getArray();
597 0 : sal_Int32 nPos = 0;
598 0 : pProperties[nPos++] = ::com::sun::star::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION),
599 0 : PROPERTY_ID_FETCHDIRECTION, cppu::UnoType<sal_Int32>::get(), 0);
600 :
601 0 : pProperties[nPos++] = ::com::sun::star::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE),
602 0 : PROPERTY_ID_FETCHSIZE, cppu::UnoType<sal_Int32>::get(), 0);
603 :
604 0 : pProperties[nPos++] = ::com::sun::star::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISBOOKMARKABLE),
605 0 : PROPERTY_ID_ISBOOKMARKABLE, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY);
606 :
607 0 : pProperties[nPos++] = ::com::sun::star::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY),
608 0 : PROPERTY_ID_RESULTSETCONCURRENCY, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY);
609 :
610 0 : pProperties[nPos++] = ::com::sun::star::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE),
611 0 : PROPERTY_ID_RESULTSETTYPE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY);
612 :
613 0 : return new OPropertyArrayHelper(aProps);
614 : }
615 :
616 0 : IPropertyArrayHelper & OResultSet::getInfoHelper()
617 : {
618 0 : return *getArrayHelper();
619 : }
620 :
621 0 : sal_Bool OResultSet::convertFastPropertyValue(
622 : Any & /*rConvertedValue*/,
623 : Any & /*rOldValue*/,
624 : sal_Int32 nHandle,
625 : const Any& /*rValue*/ )
626 : throw (::com::sun::star::lang::IllegalArgumentException)
627 : {
628 : OSL_FAIL( "OResultSet::convertFastPropertyValue: not implemented!" );
629 0 : switch(nHandle)
630 : {
631 : case PROPERTY_ID_ISBOOKMARKABLE:
632 : case PROPERTY_ID_RESULTSETCONCURRENCY:
633 : case PROPERTY_ID_RESULTSETTYPE:
634 0 : throw ::com::sun::star::lang::IllegalArgumentException();
635 : case PROPERTY_ID_FETCHDIRECTION:
636 : case PROPERTY_ID_FETCHSIZE:
637 : default:
638 : ;
639 : }
640 0 : return sal_False;
641 : }
642 :
643 0 : void OResultSet::setFastPropertyValue_NoBroadcast(
644 : sal_Int32 nHandle,
645 : const Any& /*rValue*/
646 : )
647 : throw (Exception, std::exception)
648 : {
649 : OSL_FAIL( "OResultSet::setFastPropertyValue_NoBroadcast: not implemented!" );
650 0 : switch(nHandle)
651 : {
652 : case PROPERTY_ID_ISBOOKMARKABLE:
653 : case PROPERTY_ID_RESULTSETCONCURRENCY:
654 : case PROPERTY_ID_RESULTSETTYPE:
655 0 : throw Exception();
656 : case PROPERTY_ID_FETCHDIRECTION:
657 0 : break;
658 : case PROPERTY_ID_FETCHSIZE:
659 0 : break;
660 : default:
661 : ;
662 : }
663 0 : }
664 :
665 0 : void OResultSet::getFastPropertyValue(
666 : Any& rValue,
667 : sal_Int32 nHandle
668 : ) const
669 : {
670 0 : switch(nHandle)
671 : {
672 : case PROPERTY_ID_RESULTSETCONCURRENCY:
673 0 : rValue <<= (sal_Int32)m_nResultSetConcurrency;
674 0 : break;
675 : case PROPERTY_ID_RESULTSETTYPE:
676 0 : rValue <<= m_nResultSetType;
677 0 : break;
678 : case PROPERTY_ID_FETCHDIRECTION:
679 0 : rValue <<= m_nFetchDirection;
680 0 : break;
681 : case PROPERTY_ID_FETCHSIZE:
682 0 : rValue <<= m_nFetchSize;
683 0 : break;
684 : case PROPERTY_ID_ISBOOKMARKABLE:
685 0 : const_cast< OResultSet* >( this )->determineReadOnly();
686 0 : rValue <<= (m_bIsReadOnly == TRISTATE_FALSE);
687 0 : break;
688 : }
689 0 : }
690 :
691 36 : void SAL_CALL OResultSet::acquire() throw()
692 : {
693 36 : OResultSet_BASE::acquire();
694 36 : }
695 :
696 36 : void SAL_CALL OResultSet::release() throw()
697 : {
698 36 : OResultSet_BASE::release();
699 36 : }
700 :
701 0 : ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OResultSet::getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException, std::exception)
702 : {
703 0 : return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
704 : }
705 :
706 :
707 0 : void OResultSet::parseParameter( const OSQLParseNode* pNode, OUString& rMatchString )
708 : {
709 : OSL_ENSURE(pNode->count() > 0,"Error parsing parameter in Parse Tree");
710 0 : OSQLParseNode *pMark = pNode->getChild(0);
711 :
712 : // Initialize to empty string
713 0 : rMatchString.clear();
714 :
715 0 : OUString aParameterName;
716 0 : if (SQL_ISPUNCTUATION(pMark,"?")) {
717 0 : aParameterName = "?";
718 : }
719 0 : else if (SQL_ISPUNCTUATION(pMark,":")) {
720 0 : aParameterName = pNode->getChild(1)->getTokenValue();
721 : }
722 : // XXX - Now we know name, what's value????
723 0 : m_nParamIndex ++;
724 : SAL_INFO(
725 : "connectivity.mork",
726 : "Parameter name [" << m_nParamIndex << "]: " << aParameterName);
727 :
728 0 : if ( m_aParameterRow.is() ) {
729 : OSL_ENSURE( m_nParamIndex < (sal_Int32)m_aParameterRow->get().size() + 1, "More parameters than values found" );
730 0 : rMatchString = (m_aParameterRow->get())[(sal_uInt16)m_nParamIndex];
731 : #if OSL_DEBUG_LEVEL > 0
732 : OSL_TRACE("Prop Value : %s", OUtoCStr( rMatchString ) );
733 : #endif
734 0 : }
735 : #if OSL_DEBUG_LEVEL > 0
736 : else {
737 : OSL_TRACE("Prop Value : Invalid ParameterRow!" );
738 : }
739 : #endif
740 0 : }
741 :
742 : #define WILDCARD "%"
743 : #define ALT_WILDCARD "*"
744 : static const sal_Unicode MATCHCHAR = '_';
745 :
746 2 : void OResultSet::analyseWhereClause( const OSQLParseNode* parseTree,
747 : MQueryExpression &queryExpression)
748 : {
749 2 : OUString columnName;
750 2 : MQueryOp::cond_type op( MQueryOp::Is );
751 4 : OUString matchString;
752 :
753 2 : if ( parseTree == NULL )
754 2 : return;
755 :
756 2 : if ( m_pSQLIterator->getParseTree() != NULL ) {
757 2 : ::rtl::Reference<OSQLColumns> xColumns = m_pSQLIterator->getParameters();
758 2 : if(xColumns.is())
759 : {
760 4 : OUString aColName, aParameterValue;
761 2 : OSQLColumns::Vector::iterator aIter = xColumns->get().begin();
762 2 : sal_Int32 i = 1;
763 2 : for(;aIter != xColumns->get().end();++aIter)
764 : {
765 0 : (*aIter)->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= aColName;
766 : OSL_TRACE("Prop Column Name : %s", OUtoCStr( aColName ) );
767 0 : if ( m_aParameterRow.is() ) {
768 0 : aParameterValue = (m_aParameterRow->get())[(sal_uInt16)i];
769 : #if OSL_DEBUG_LEVEL > 0
770 : OSL_TRACE("Prop Value : %s", OUtoCStr( aParameterValue ) );
771 : #endif
772 : }
773 : #if OSL_DEBUG_LEVEL > 0
774 : else {
775 : OSL_TRACE("Prop Value : Invalid ParameterRow!" );
776 : }
777 : #endif
778 0 : i++;
779 2 : }
780 2 : }
781 :
782 : }
783 :
784 2 : if ( SQL_ISRULE(parseTree,where_clause) )
785 : {
786 : OSL_TRACE("analyseSQL : Got WHERE clause");
787 : // Reset Parameter Counter
788 1 : resetParameters();
789 1 : analyseWhereClause( parseTree->getChild( 1 ), queryExpression );
790 : }
791 2 : else if ( parseTree->count() == 3 && // Handle ()'s
792 1 : SQL_ISPUNCTUATION(parseTree->getChild(0),"(") &&
793 0 : SQL_ISPUNCTUATION(parseTree->getChild(2),")"))
794 : {
795 :
796 : OSL_TRACE("analyseSQL : Got Punctuation ()");
797 0 : MQueryExpression *subExpression = new MQueryExpression();
798 0 : analyseWhereClause( parseTree->getChild( 1 ), *subExpression );
799 0 : queryExpression.addExpression( subExpression );
800 : }
801 3 : else if ((SQL_ISRULE(parseTree,search_condition) || (SQL_ISRULE(parseTree,boolean_term)))
802 1 : && parseTree->count() == 3) // Handle AND/OR
803 : {
804 :
805 : OSL_TRACE("analyseSQL : Got AND/OR clause");
806 :
807 : // TODO - Need to take care or AND, for now match is always OR
808 0 : analyseWhereClause( parseTree->getChild( 0 ), queryExpression );
809 0 : analyseWhereClause( parseTree->getChild( 2 ), queryExpression );
810 :
811 0 : if (SQL_ISTOKEN(parseTree->getChild(1),OR)) { // OR-Operator
812 0 : queryExpression.setExpressionCondition( MQueryExpression::OR );
813 : }
814 0 : else if (SQL_ISTOKEN(parseTree->getChild(1),AND)) { // AND-Operator
815 0 : queryExpression.setExpressionCondition( MQueryExpression::AND );
816 : }
817 : else {
818 : OSL_FAIL("analyseSQL: Error in Parse Tree");
819 : }
820 : }
821 1 : else if (SQL_ISRULE(parseTree,comparison_predicate))
822 : {
823 : OSL_ENSURE(parseTree->count() == 3, "Error parsing COMPARE predicate");
824 0 : if (!(SQL_ISRULE(parseTree->getChild(0),column_ref) ||
825 0 : parseTree->getChild(2)->getNodeType() == SQL_NODE_STRING ||
826 0 : parseTree->getChild(2)->getNodeType() == SQL_NODE_INTNUM ||
827 0 : parseTree->getChild(2)->getNodeType() == SQL_NODE_APPROXNUM ||
828 0 : SQL_ISTOKEN(parseTree->getChild(2),TRUE) ||
829 0 : SQL_ISTOKEN(parseTree->getChild(2),FALSE) ||
830 0 : SQL_ISRULE(parseTree->getChild(2),parameter) ||
831 : // odbc date
832 0 : (SQL_ISRULE(parseTree->getChild(2),set_fct_spec) && SQL_ISPUNCTUATION(parseTree->getChild(2)->getChild(0),"{"))))
833 : {
834 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_QUERY_TOO_COMPLEX, *this );
835 : }
836 :
837 0 : OSQLParseNode *pPrec = parseTree->getChild(1);
838 0 : if (pPrec->getNodeType() == SQL_NODE_EQUAL)
839 0 : op = MQueryOp::Is;
840 0 : else if (pPrec->getNodeType() == SQL_NODE_NOTEQUAL)
841 0 : op = MQueryOp::IsNot;
842 :
843 0 : OUString sTableRange;
844 0 : if(SQL_ISRULE(parseTree->getChild(0),column_ref))
845 0 : m_pSQLIterator->getColumnRange(parseTree->getChild(0),columnName,sTableRange);
846 0 : else if(parseTree->getChild(0)->isToken())
847 0 : columnName = parseTree->getChild(0)->getTokenValue();
848 :
849 0 : if ( SQL_ISRULE(parseTree->getChild(2),parameter) ) {
850 0 : parseParameter( parseTree->getChild(2), matchString );
851 : }
852 : else {
853 0 : matchString = parseTree->getChild(2)->getTokenValue();
854 : }
855 :
856 0 : if ( columnName == "0" && op == MQueryOp::Is && matchString == "1" ) {
857 : OSL_TRACE("Query always evaluates to FALSE");
858 0 : m_bIsAlwaysFalseQuery = true;
859 : }
860 0 : queryExpression.addExpression( new MQueryExpressionString( columnName, op, matchString ));
861 : }
862 1 : else if (SQL_ISRULE(parseTree,like_predicate))
863 : {
864 : OSL_ENSURE(parseTree->count() == 2, "Error parsing LIKE predicate");
865 :
866 : OSL_TRACE("analyseSQL : Got LIKE rule");
867 :
868 1 : if ( !(SQL_ISRULE(parseTree->getChild(0), column_ref)) )
869 : {
870 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_QUERY_INVALID_LIKE_COLUMN, *this );
871 : }
872 :
873 :
874 : OSQLParseNode *pColumn;
875 : OSQLParseNode *pAtom;
876 : OSQLParseNode *pOptEscape;
877 1 : const OSQLParseNode* pPart2 = parseTree->getChild(1);
878 1 : pColumn = parseTree->getChild(0); // Match Item
879 1 : pAtom = pPart2->getChild(static_cast<sal_uInt32>(pPart2->count()-2)); // Match String
880 1 : pOptEscape = pPart2->getChild(static_cast<sal_uInt32>(pPart2->count()-1)); // Opt Escape Rule
881 : (void)pOptEscape;
882 1 : const bool bNot = SQL_ISTOKEN(pPart2->getChild(0), NOT);
883 :
884 2 : if (!(pAtom->getNodeType() == SQL_NODE_STRING ||
885 0 : pAtom->getNodeType() == SQL_NODE_NAME ||
886 0 : SQL_ISRULE(pAtom,parameter) ||
887 0 : ( pAtom->getChild(0) && pAtom->getChild(0)->getNodeType() == SQL_NODE_NAME ) ||
888 0 : ( pAtom->getChild(0) && pAtom->getChild(0)->getNodeType() == SQL_NODE_STRING )
889 1 : ) )
890 : {
891 : OSL_TRACE("analyseSQL : pAtom->count() = %zu", pAtom->count() );
892 :
893 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_QUERY_INVALID_LIKE_STRING, *this );
894 : }
895 :
896 1 : OUString sTableRange;
897 1 : if(SQL_ISRULE(pColumn,column_ref))
898 1 : m_pSQLIterator->getColumnRange(pColumn,columnName,sTableRange);
899 :
900 : OSL_TRACE("ColumnName = %s", OUtoCStr( columnName ) );
901 :
902 1 : if ( SQL_ISRULE(pAtom,parameter) ) {
903 0 : parseParameter( pAtom, matchString );
904 : // Replace all '*' with '%' : UI Usually does this but not with
905 : // Parameters for some reason.
906 0 : matchString = matchString.replaceAll( ALT_WILDCARD, WILDCARD );
907 : }
908 : else
909 : {
910 1 : matchString = pAtom->getTokenValue();
911 : }
912 :
913 : // Determine where '%' character is...
914 :
915 1 : if ( matchString == WILDCARD )
916 : {
917 : // String containing only a '%' and nothing else
918 0 : op = MQueryOp::Exists;
919 : // Will be ignored for Exists case, but clear anyway.
920 0 : matchString.clear();
921 : }
922 1 : else if ( matchString.indexOf ( WILDCARD ) == -1 &&
923 0 : matchString.indexOf ( MATCHCHAR ) == -1 )
924 : {
925 : // Simple string , eg. "to match"
926 0 : if ( bNot )
927 0 : op = MQueryOp::DoesNotContain;
928 : else
929 0 : op = MQueryOp::Contains;
930 : }
931 2 : else if ( matchString.startsWith( WILDCARD )
932 1 : && matchString.endsWith( WILDCARD )
933 0 : && matchString.indexOf ( WILDCARD, 1 ) == matchString.lastIndexOf ( WILDCARD )
934 1 : && matchString.indexOf( MATCHCHAR ) == -1
935 : )
936 : {
937 : // Relatively simple "%string%" - ie, contains...
938 : // Cut '%' from front and rear
939 0 : matchString = matchString.replaceAt( 0, 1, OUString() );
940 0 : matchString = matchString.replaceAt( matchString.getLength() -1 , 1, OUString() );
941 :
942 0 : if (bNot)
943 0 : op = MQueryOp::DoesNotContain;
944 : else
945 0 : op = MQueryOp::Contains;
946 : }
947 1 : else if ( bNot )
948 : {
949 : // We currently can't handle a 'NOT LIKE' when there are '%' or
950 : // '_' dispersed throughout
951 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_QUERY_NOT_LIKE_TOO_COMPLEX, *this );
952 : }
953 : else
954 : {
955 2 : if ( (matchString.indexOf ( WILDCARD ) == matchString.lastIndexOf ( WILDCARD ))
956 1 : && matchString.indexOf( MATCHCHAR ) == -1
957 : )
958 : {
959 : // One occurrence of '%' - no '_' matches...
960 1 : if ( matchString.startsWith( WILDCARD ) )
961 : {
962 1 : op = MQueryOp::EndsWith;
963 1 : matchString = matchString.replaceAt( 0, 1, OUString());
964 : }
965 0 : else if ( matchString.indexOf ( WILDCARD ) == matchString.getLength() -1 )
966 : {
967 0 : op = MQueryOp::BeginsWith;
968 0 : matchString = matchString.replaceAt( matchString.getLength() -1 , 1, OUString() );
969 : }
970 : else
971 : {
972 0 : sal_Int32 pos = matchString.indexOf ( WILDCARD );
973 0 : matchString = matchString.replaceAt( pos, 1, ".*" );
974 0 : op = MQueryOp::RegExp;
975 : }
976 :
977 : }
978 : else
979 : {
980 : // Most Complex, need to use an RE
981 : sal_Int32 pos;
982 0 : while ( (pos = matchString.indexOf ( WILDCARD )) != -1 )
983 : {
984 0 : matchString = matchString.replaceAt( pos, 1, OUString(".*") );
985 : }
986 :
987 0 : while ( (pos = matchString.indexOf( MATCHCHAR )) != -1 )
988 : {
989 0 : matchString = matchString.replaceAt( pos, 1, OUString(".") );
990 : }
991 :
992 0 : op = MQueryOp::RegExp;
993 : }
994 : }
995 :
996 1 : queryExpression.addExpression( new MQueryExpressionString( columnName, op, matchString ));
997 : }
998 0 : else if (SQL_ISRULE(parseTree,test_for_null))
999 : {
1000 : OSL_ENSURE(parseTree->count() == 2,"Error in ParseTree");
1001 0 : const OSQLParseNode* pPart2 = parseTree->getChild(1);
1002 : OSL_ENSURE(SQL_ISTOKEN(pPart2->getChild(0),IS),"Error in ParseTree");
1003 :
1004 0 : if (!SQL_ISRULE(parseTree->getChild(0),column_ref))
1005 : {
1006 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_QUERY_INVALID_IS_NULL_COLUMN, *this );
1007 : }
1008 :
1009 0 : if (SQL_ISTOKEN(pPart2->getChild(1),NOT))
1010 : {
1011 0 : op = MQueryOp::Exists;
1012 : }
1013 : else
1014 : {
1015 0 : op = MQueryOp::DoesNotExist;
1016 : }
1017 :
1018 0 : OUString sTableRange;
1019 0 : m_pSQLIterator->getColumnRange(parseTree->getChild(0),columnName,sTableRange);
1020 :
1021 0 : queryExpression.addExpression( new MQueryExpressionString( columnName, op ));
1022 : }
1023 : else
1024 : {
1025 : OSL_TRACE( "Unexpected statement!!!" );
1026 :
1027 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_QUERY_TOO_COMPLEX, *this );
1028 2 : }
1029 : }
1030 :
1031 :
1032 :
1033 2 : void OResultSet::fillRowData()
1034 : throw (css::sdbc::SQLException, css::uno::RuntimeException)
1035 : {
1036 : OSL_ENSURE( m_pStatement, "Require a statement" );
1037 :
1038 2 : MQueryExpression queryExpression;
1039 :
1040 2 : OConnection* xConnection = static_cast<OConnection*>(m_pStatement->getConnection().get());
1041 2 : m_xColumns = m_pSQLIterator->getSelectColumns();
1042 :
1043 : OSL_ENSURE(m_xColumns.is(), "Need the Columns!!");
1044 :
1045 2 : OSQLColumns::Vector::const_iterator aIter = m_xColumns->get().begin();
1046 4 : const OUString sProprtyName = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME);
1047 4 : OUString sName;
1048 2 : m_aAttributeStrings.clear();
1049 2 : m_aAttributeStrings.reserve(m_xColumns->get().size());
1050 4 : for (sal_Int32 i = 1; aIter != m_xColumns->get().end();++aIter, i++)
1051 : {
1052 2 : (*aIter)->getPropertyValue(sProprtyName) >>= sName;
1053 : SAL_INFO(
1054 : "connectivity.mork", "Query Columns : (" << i << ") " << sName);
1055 2 : m_aAttributeStrings.push_back( sName );
1056 : }
1057 :
1058 : // Generate Match Conditions for Query
1059 2 : const OSQLParseNode* pParseTree = m_pSQLIterator->getWhereTree();
1060 :
1061 2 : m_bIsAlwaysFalseQuery = false;
1062 2 : if ( pParseTree != NULL )
1063 : {
1064 : // Extract required info
1065 :
1066 : OSL_TRACE("\tHave a Where Clause");
1067 :
1068 1 : analyseWhereClause( pParseTree, queryExpression );
1069 : }
1070 : // If the query is a 0=1 then set Row count to 0 and return
1071 2 : if ( m_bIsAlwaysFalseQuery )
1072 : {
1073 0 : m_bIsReadOnly = TRISTATE_TRUE;
1074 2 : return;
1075 : }
1076 :
1077 4 : OUString aStr( m_pTable->getName() );
1078 2 : m_aQueryHelper.setAddressbook( aStr );
1079 :
1080 2 : sal_Int32 rv = m_aQueryHelper.executeQuery(xConnection, queryExpression);
1081 2 : if ( rv == -1 ) {
1082 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_ERR_EXECUTING_QUERY, *this );
1083 : }
1084 :
1085 2 : if (m_aQueryHelper.hadError())
1086 : {
1087 0 : m_pStatement->getOwnConnection()->throwSQLException( m_aQueryHelper.getError(), *this );
1088 : }
1089 :
1090 : //determine whether the address book is readonly
1091 2 : determineReadOnly();
1092 :
1093 : SAL_INFO("connectivity.mork", "executeQuery returned " << rv);
1094 :
1095 2 : OSL_TRACE( "\tOUT OResultSet::fillRowData()" );
1096 : }
1097 :
1098 :
1099 0 : static bool matchRow( OValueRow& row1, OValueRow& row2 )
1100 : {
1101 0 : OValueVector::Vector::iterator row1Iter = row1->get().begin();
1102 0 : OValueVector::Vector::iterator row2Iter = row2->get().begin();
1103 0 : for ( ++row1Iter,++row2Iter; // the first column is the bookmark column
1104 0 : row1Iter != row1->get().end(); ++row1Iter,++row2Iter)
1105 : {
1106 0 : if ( row1Iter->isBound())
1107 : {
1108 : // Compare values, if at anytime there's a mismatch return false
1109 0 : if ( !( (*row1Iter) == (*row2Iter) ) )
1110 0 : return false;
1111 : }
1112 : }
1113 :
1114 : // If we get to here the rows match
1115 0 : return true;
1116 : }
1117 :
1118 0 : sal_Int32 OResultSet::getRowForCardNumber(sal_Int32 nCardNum)
1119 : {
1120 : SAL_INFO("connectivity.mork", "nCardNum = " << nCardNum);
1121 :
1122 0 : if ( m_pKeySet.is() )
1123 : {
1124 : sal_Int32 nPos;
1125 0 : for(nPos=0;nPos < (sal_Int32)m_pKeySet->get().size();nPos++)
1126 : {
1127 0 : if (nCardNum == (m_pKeySet->get())[nPos])
1128 : {
1129 : SAL_INFO("connectivity.mork", "return = " << nPos+1);
1130 0 : return nPos+1;
1131 : }
1132 : }
1133 : }
1134 :
1135 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_INVALID_BOOKMARK, *this );
1136 :
1137 0 : return 0;
1138 : }
1139 :
1140 :
1141 2 : void SAL_CALL OResultSet::executeQuery() throw( ::com::sun::star::sdbc::SQLException,
1142 : ::com::sun::star::uno::RuntimeException)
1143 : {
1144 2 : ResultSetEntryGuard aGuard( *this );
1145 :
1146 : OSL_ENSURE( m_pTable, "Need a Table object");
1147 2 : if(!m_pTable)
1148 : {
1149 0 : const OSQLTables& xTabs = m_pSQLIterator->getTables();
1150 0 : if ((xTabs.begin() == xTabs.end()) || !xTabs.begin()->second.is())
1151 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_QUERY_TOO_COMPLEX, *this );
1152 :
1153 0 : m_pTable = static_cast< OTable* > ((xTabs.begin()->second).get());
1154 :
1155 : }
1156 :
1157 2 : m_nRowPos = 0;
1158 :
1159 2 : fillRowData();
1160 :
1161 : OSL_ENSURE(m_xColumns.is(), "Need the Columns!!");
1162 :
1163 2 : switch( m_pSQLIterator->getStatementType() )
1164 : {
1165 : case SQL_STATEMENT_SELECT:
1166 : {
1167 2 : if(m_bIsAlwaysFalseQuery) {
1168 0 : break;
1169 : }
1170 2 : else if(isCount())
1171 : {
1172 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_NO_COUNT_SUPPORT, *this );
1173 : }
1174 : else
1175 : {
1176 2 : bool bDistinct = false;
1177 2 : OSQLParseNode *pDistinct = m_pParseTree->getChild(1);
1178 2 : if (pDistinct && pDistinct->getTokenID() == SQL_TOKEN_DISTINCT)
1179 : {
1180 0 : if(!IsSorted())
1181 : {
1182 0 : m_aOrderbyColumnNumber.push_back(m_aColMapping[1]);
1183 0 : m_aOrderbyAscending.push_back(SQL_DESC);
1184 : }
1185 0 : bDistinct = true;
1186 : }
1187 :
1188 2 : OSortIndex::TKeyTypeVector eKeyType(m_aOrderbyColumnNumber.size());
1189 2 : ::std::vector<sal_Int32>::iterator aOrderByIter = m_aOrderbyColumnNumber.begin();
1190 3 : for ( ::std::vector<sal_Int16>::size_type i = 0; aOrderByIter != m_aOrderbyColumnNumber.end(); ++aOrderByIter,++i)
1191 : {
1192 : OSL_ENSURE((sal_Int32)m_aRow->get().size() > *aOrderByIter,"Invalid Index");
1193 1 : switch ((m_aRow->get().begin()+*aOrderByIter)->getTypeKind())
1194 : {
1195 : case DataType::CHAR:
1196 : case DataType::VARCHAR:
1197 1 : eKeyType[i] = SQL_ORDERBYKEY_STRING;
1198 1 : 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 : OSL_FAIL("MResultSet::executeQuery: Order By Data Type not implemented");
1219 0 : break;
1220 : }
1221 : }
1222 :
1223 2 : if (IsSorted())
1224 : {
1225 : // Implement Sorting
1226 :
1227 : // So that we can sort we need to wait until the executed
1228 : // query to the mozilla addressbooks has returned all
1229 : // values.
1230 :
1231 : OSL_TRACE("Query is to be sorted");
1232 :
1233 : OSL_ENSURE( MQueryHelper::queryComplete(), "Query not complete!!");
1234 :
1235 1 : OSortIndex aSortIndex(eKeyType,m_aOrderbyAscending);
1236 :
1237 : OSL_TRACE("OrderbyColumnNumber->size() = %zu",m_aOrderbyColumnNumber.size());
1238 : #if OSL_DEBUG_LEVEL > 0
1239 : for ( ::std::vector<sal_Int32>::size_type i = 0; i < m_aColMapping.size(); i++ )
1240 : SAL_INFO(
1241 : "connectivity.mork",
1242 : "Mapped: " << i << " -> " << m_aColMapping[i]);
1243 : #endif
1244 11 : for ( sal_Int32 nRow = 1; nRow <= m_aQueryHelper.getResultCount(); nRow++ ) {
1245 :
1246 10 : OKeyValue* pKeyValue = OKeyValue::createKeyValue((nRow));
1247 :
1248 10 : ::std::vector<sal_Int32>::iterator aIter = m_aOrderbyColumnNumber.begin();
1249 20 : for (;aIter != m_aOrderbyColumnNumber.end(); ++aIter)
1250 : {
1251 10 : const ORowSetValue& value = getValue(nRow, *aIter);
1252 :
1253 : SAL_INFO(
1254 : "connectivity.mork",
1255 : "Adding Value: (" << nRow << "," << *aIter
1256 : << ") : " << value.getString());
1257 :
1258 10 : pKeyValue->pushKey(new ORowSetValueDecorator(value));
1259 : }
1260 :
1261 10 : aSortIndex.AddKeyValue( pKeyValue );
1262 : }
1263 :
1264 1 : m_pKeySet = aSortIndex.CreateKeySet();
1265 1 : m_CurrentRowCount = static_cast<sal_Int32>(m_pKeySet->get().size());
1266 : #if OSL_DEBUG_LEVEL > 0
1267 : for( OKeySet::Vector::size_type i = 0; i < m_pKeySet->get().size(); i++ )
1268 : SAL_INFO(
1269 : "connectivity.mork",
1270 : "Sorted: " << i << " -> " << (m_pKeySet->get())[i]);
1271 : #endif
1272 :
1273 1 : beforeFirst(); // Go back to start
1274 : }
1275 : else //we always need m_pKeySet now
1276 1 : m_pKeySet = new OKeySet();
1277 :
1278 : // Handle the DISTINCT case
1279 2 : if ( bDistinct && m_pKeySet.is() )
1280 : {
1281 0 : OValueRow aSearchRow = new OValueVector( m_aRow->get().size() );
1282 :
1283 0 : for( OKeySet::Vector::size_type i = 0; i < m_pKeySet->get().size(); i++ )
1284 : {
1285 0 : fetchRow( (m_pKeySet->get())[i] ); // Fills m_aRow
1286 0 : if ( matchRow( m_aRow, aSearchRow ) )
1287 : {
1288 0 : (m_pKeySet->get())[i] = 0; // Marker for later to be removed
1289 : }
1290 : else
1291 : {
1292 : // They don't match, so it's not a duplicate.
1293 : // Use the current Row as the next one to match against
1294 0 : *aSearchRow = *m_aRow;
1295 : }
1296 : }
1297 : // Now remove any keys marked with a 0
1298 0 : m_pKeySet->get().erase(::std::remove_if(m_pKeySet->get().begin(),m_pKeySet->get().end()
1299 : ,::std::bind2nd(::std::equal_to<sal_Int32>(),0))
1300 0 : ,m_pKeySet->get().end());
1301 :
1302 2 : }
1303 : }
1304 2 : } break;
1305 :
1306 : case SQL_STATEMENT_UPDATE:
1307 : case SQL_STATEMENT_DELETE:
1308 : case SQL_STATEMENT_INSERT:
1309 0 : break;
1310 : default:
1311 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_STMT_TYPE_NOT_SUPPORTED, *this );
1312 0 : break;
1313 2 : }
1314 2 : }
1315 :
1316 :
1317 :
1318 :
1319 4 : void OResultSet::setBoundedColumns(const OValueRow& _rRow,
1320 : const ::rtl::Reference<connectivity::OSQLColumns>& _rxColumns,
1321 : const Reference<XIndexAccess>& _xNames,
1322 : bool _bSetColumnMapping,
1323 : const Reference<XDatabaseMetaData>& _xMetaData,
1324 : ::std::vector<sal_Int32>& _rColMapping)
1325 : {
1326 4 : ::comphelper::UStringMixEqual aCase(_xMetaData->supportsMixedCaseQuotedIdentifiers());
1327 :
1328 4 : Reference<XPropertySet> xTableColumn;
1329 8 : OUString sTableColumnName, sSelectColumnRealName;
1330 :
1331 8 : const OUString sName = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME);
1332 8 : const OUString sRealName = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME);
1333 :
1334 8 : ::std::vector< OUString> aColumnNames;
1335 4 : aColumnNames.reserve(_rxColumns->get().size());
1336 4 : OValueVector::Vector::iterator aRowIter = _rRow->get().begin()+1;
1337 456 : for (sal_Int32 i=0; // the first column is the bookmark column
1338 304 : aRowIter != _rRow->get().end();
1339 : ++i, ++aRowIter
1340 : )
1341 : {
1342 : try
1343 : {
1344 : // get the table column and its name
1345 148 : _xNames->getByIndex(i) >>= xTableColumn;
1346 : OSL_ENSURE(xTableColumn.is(), "OResultSet::setBoundedColumns: invalid table column!");
1347 148 : if (xTableColumn.is())
1348 148 : xTableColumn->getPropertyValue(sName) >>= sTableColumnName;
1349 : else
1350 0 : sTableColumnName.clear();
1351 :
1352 : // look if we have such a select column
1353 : // TODO: would like to have a O(log n) search here ...
1354 148 : sal_Int32 nColumnPos = 0;
1355 666 : for ( OSQLColumns::Vector::iterator aIter = _rxColumns->get().begin();
1356 444 : aIter != _rxColumns->get().end();
1357 : ++aIter,++nColumnPos
1358 : )
1359 : {
1360 74 : if ( nColumnPos < (sal_Int32)aColumnNames.size() )
1361 72 : sSelectColumnRealName = aColumnNames[nColumnPos];
1362 : else
1363 : {
1364 2 : if((*aIter)->getPropertySetInfo()->hasPropertyByName(sRealName))
1365 2 : (*aIter)->getPropertyValue(sRealName) >>= sSelectColumnRealName;
1366 : else
1367 0 : (*aIter)->getPropertyValue(sName) >>= sSelectColumnRealName;
1368 2 : aColumnNames.push_back(sSelectColumnRealName);
1369 : }
1370 :
1371 74 : if (aCase(sTableColumnName, sSelectColumnRealName))
1372 : {
1373 2 : if(_bSetColumnMapping)
1374 : {
1375 2 : sal_Int32 nSelectColumnPos = static_cast<sal_Int32>(aIter - _rxColumns->get().begin() + 1);
1376 : // the getXXX methods are 1-based ...
1377 2 : sal_Int32 nTableColumnPos = i + 1;
1378 : // get first table column is the bookmark column
1379 :
1380 : SAL_INFO(
1381 : "connectivity.mork",
1382 : "Set Col Mapping: " << nSelectColumnPos << " -> "
1383 : << nTableColumnPos);
1384 2 : _rColMapping[nSelectColumnPos] = nTableColumnPos;
1385 : }
1386 :
1387 2 : aRowIter->setBound(true);
1388 2 : aRowIter->setTypeKind(DataType::VARCHAR);
1389 : }
1390 : }
1391 : }
1392 0 : catch (Exception&)
1393 : {
1394 : OSL_FAIL("OResultSet::setBoundedColumns: caught an Exception!");
1395 : }
1396 4 : }
1397 4 : }
1398 :
1399 :
1400 :
1401 2 : bool OResultSet::isCount() const
1402 : {
1403 2 : return (m_pParseTree &&
1404 4 : m_pParseTree->count() > 2 &&
1405 6 : SQL_ISRULE(m_pParseTree->getChild(2),scalar_exp_commalist) &&
1406 6 : SQL_ISRULE(m_pParseTree->getChild(2)->getChild(0),derived_column) &&
1407 6 : SQL_ISRULE(m_pParseTree->getChild(2)->getChild(0)->getChild(0),general_set_fct) &&
1408 0 : m_pParseTree->getChild(2)->getChild(0)->getChild(0)->count() == 4
1409 2 : );
1410 : }
1411 :
1412 :
1413 :
1414 : // Check for valid row in m_aQuery
1415 :
1416 14 : bool OResultSet::validRow( sal_uInt32 nRow)
1417 : {
1418 14 : sal_Int32 nNumberOfRecords = m_aQueryHelper.getResultCount();
1419 :
1420 28 : while ( nRow > (sal_uInt32)nNumberOfRecords && !MQueryHelper::queryComplete() ) {
1421 : #if OSL_DEBUG_LEVEL > 0
1422 : OSL_TRACE("validRow: waiting...");
1423 : #endif
1424 0 : if (!m_aQueryHelper.checkRowAvailable( nRow ))
1425 : {
1426 : SAL_INFO(
1427 : "connectivity.mork",
1428 : "validRow(" << nRow << "): return False");
1429 0 : return false;
1430 : }
1431 :
1432 0 : if ( m_aQueryHelper.hadError() )
1433 : {
1434 0 : m_pStatement->getOwnConnection()->throwSQLException( m_aQueryHelper.getError(), *this );
1435 : }
1436 :
1437 0 : nNumberOfRecords = m_aQueryHelper.getResultCount();
1438 : }
1439 :
1440 28 : if (( nRow == 0 ) ||
1441 14 : ( nRow > (sal_uInt32)nNumberOfRecords && MQueryHelper::queryComplete()) ){
1442 : SAL_INFO("connectivity.mork", "validRow(" << nRow << "): return False");
1443 0 : return false;
1444 : }
1445 : SAL_INFO("connectivity.mork", "validRow(" << nRow << "): return True");
1446 :
1447 14 : return true;
1448 : }
1449 5 : bool OResultSet::fillKeySet(sal_Int32 nMaxCardNumber)
1450 : {
1451 5 : impl_ensureKeySet();
1452 5 : if (m_CurrentRowCount < nMaxCardNumber)
1453 : {
1454 : sal_Int32 nKeyValue;
1455 1 : if ( (sal_Int32)m_pKeySet->get().capacity() < nMaxCardNumber )
1456 1 : m_pKeySet->get().reserve(nMaxCardNumber + 20 );
1457 :
1458 2 : for (nKeyValue = m_CurrentRowCount+1; nKeyValue <= nMaxCardNumber; nKeyValue ++)
1459 1 : m_pKeySet->get().push_back( nKeyValue );
1460 1 : m_CurrentRowCount = nMaxCardNumber;
1461 : }
1462 5 : return true;
1463 : }
1464 :
1465 2 : sal_Int32 OResultSet::deletedCount()
1466 : {
1467 2 : impl_ensureKeySet();
1468 2 : return m_CurrentRowCount - static_cast<sal_Int32>(m_pKeySet->get().size());
1469 :
1470 : }
1471 :
1472 6 : bool OResultSet::seekRow( eRowPosition pos, sal_Int32 nOffset )
1473 : {
1474 6 : ResultSetEntryGuard aGuard( *this );
1475 6 : if ( !m_pKeySet.is() )
1476 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_ILLEGAL_MOVEMENT, *this );
1477 :
1478 6 : sal_Int32 nNumberOfRecords = m_aQueryHelper.getResultCount();
1479 6 : sal_Int32 nRetrievedRows = currentRowCount();
1480 6 : sal_Int32 nCurPos = m_nRowPos;
1481 :
1482 : SAL_INFO("connectivity.mork", "nCurPos = " << nCurPos);
1483 6 : switch( pos ) {
1484 : case NEXT_POS:
1485 : OSL_TRACE("seekRow: NEXT");
1486 1 : nCurPos++;
1487 1 : break;
1488 : case PRIOR_POS:
1489 : OSL_TRACE("seekRow: PRIOR");
1490 1 : if ( nCurPos > 0 )
1491 1 : nCurPos--;
1492 1 : break;
1493 :
1494 : case FIRST_POS:
1495 : OSL_TRACE("seekRow: FIRST");
1496 3 : nCurPos = 1;
1497 3 : break;
1498 :
1499 : case LAST_POS:
1500 : OSL_TRACE("seekRow: LAST");
1501 1 : nCurPos = nRetrievedRows;
1502 1 : break;
1503 : case ABSOLUTE_POS:
1504 : SAL_INFO("connectivity.mork", "ABSOLUTE : " << nOffset);
1505 0 : nCurPos = nOffset;
1506 0 : break;
1507 : case RELATIVE_POS:
1508 : SAL_INFO("connectivity.mork", "RELATIVE : " << nOffset);
1509 0 : nCurPos += sal_uInt32( nOffset );
1510 0 : break;
1511 : }
1512 :
1513 6 : if ( nCurPos <= 0 ) {
1514 1 : m_nRowPos = 0;
1515 : SAL_INFO(
1516 : "connectivity.mork", "return False, m_nRowPos = " << m_nRowPos);
1517 1 : return false;
1518 : }
1519 5 : sal_Int32 nCurCard = nCurPos;
1520 5 : if ( nCurPos < (sal_Int32)m_pKeySet->get().size() ) //The requested row is exist in m_pKeySet, so we just use it
1521 : {
1522 3 : nCurCard = (m_pKeySet->get())[nCurPos-1];
1523 : }
1524 : else //The requested row has not been retrieved until now. We should get the right card for it.
1525 2 : nCurCard = nCurPos + deletedCount();
1526 :
1527 5 : if ( nCurCard > nNumberOfRecords) {
1528 0 : fillKeySet(nNumberOfRecords);
1529 0 : m_nRowPos = static_cast<sal_uInt32>(m_pKeySet->get().size() + 1);
1530 : SAL_INFO(
1531 : "connectivity.mork", "return False, m_nRowPos = " << m_nRowPos);
1532 0 : return false;
1533 : }
1534 : //Insert new retrieved items for later use
1535 5 : fillKeySet(nNumberOfRecords);
1536 5 : m_nRowPos = (sal_uInt32)nCurPos;
1537 : SAL_INFO("connectivity.mork", "return True, m_nRowPos = " << m_nRowPos);
1538 5 : fetchCurrentRow();
1539 5 : return true;
1540 : }
1541 :
1542 2 : void OResultSet::setColumnMapping(const ::std::vector<sal_Int32>& _aColumnMapping)
1543 : {
1544 2 : m_aColMapping = _aColumnMapping;
1545 : #if OSL_DEBUG_LEVEL > 0
1546 : for ( size_t i = 0; i < m_aColMapping.size(); i++ )
1547 : SAL_INFO(
1548 : "connectivity.mork",
1549 : "Set Mapped: " << i << " -> " << m_aColMapping[i]);
1550 : #endif
1551 2 : }
1552 :
1553 :
1554 0 : ::com::sun::star::uno::Any OResultSet::getBookmark( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
1555 : {
1556 : SAL_INFO("connectivity.mork", "m_nRowPos = " << m_nRowPos);
1557 0 : ResultSetEntryGuard aGuard( *this );
1558 0 : if ( !fetchCurrentRow() ) {
1559 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_ERROR_GET_ROW, *this );
1560 : }
1561 :
1562 : OSL_ENSURE((!m_aRow->isDeleted()),"getBookmark called for deleted row");
1563 0 : return makeAny((sal_Int32)(m_aRow->get())[0]);
1564 : }
1565 0 : sal_Bool OResultSet::moveToBookmark( const ::com::sun::star::uno::Any& bookmark ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
1566 : {
1567 0 : ResultSetEntryGuard aGuard( *this );
1568 : SAL_INFO(
1569 : "connectivity.mork", "bookmark = " << comphelper::getINT32(bookmark));
1570 0 : sal_Int32 nCardNum = comphelper::getINT32(bookmark);
1571 0 : m_nRowPos = getRowForCardNumber(nCardNum);
1572 0 : fetchCurrentRow();
1573 0 : return sal_True;
1574 : }
1575 0 : sal_Bool OResultSet::moveRelativeToBookmark( const ::com::sun::star::uno::Any& bookmark, sal_Int32 rows ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
1576 : {
1577 0 : ResultSetEntryGuard aGuard( *this );
1578 : SAL_INFO(
1579 : "connectivity.mork",
1580 : "bookmark = " << comphelper::getINT32(bookmark) << " rows= " << rows);
1581 0 : sal_Int32 nCardNum = comphelper::getINT32(bookmark);
1582 0 : m_nRowPos = getRowForCardNumber(nCardNum);
1583 0 : return seekRow(RELATIVE_POS,rows );
1584 : }
1585 0 : sal_Int32 OResultSet::compareBookmarks( const ::com::sun::star::uno::Any& lhs, const ::com::sun::star::uno::Any& rhs ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
1586 : {
1587 0 : ResultSetEntryGuard aGuard( *this );
1588 : SAL_INFO("connectivity.mork", "m_nRowPos = " << m_nRowPos);
1589 0 : sal_Int32 nFirst=0;
1590 0 : sal_Int32 nSecond=0;
1591 0 : sal_Int32 nResult=0;
1592 :
1593 0 : if ( !( lhs >>= nFirst ) || !( rhs >>= nSecond ) ) {
1594 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_INVALID_BOOKMARK, *this );
1595 : }
1596 :
1597 0 : if(nFirst < nSecond)
1598 0 : nResult = CompareBookmark::LESS;
1599 0 : else if(nFirst > nSecond)
1600 0 : nResult = CompareBookmark::GREATER;
1601 : else
1602 0 : nResult = CompareBookmark::EQUAL;
1603 :
1604 0 : return nResult;
1605 : }
1606 0 : sal_Bool OResultSet::hasOrderedBookmarks( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
1607 : {
1608 0 : ResultSetEntryGuard aGuard( *this );
1609 : SAL_INFO("connectivity.mork", "m_nRowPos = " << m_nRowPos);
1610 0 : return sal_True;
1611 : }
1612 0 : sal_Int32 OResultSet::hashBookmark( const ::com::sun::star::uno::Any& bookmark ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
1613 : {
1614 0 : ResultSetEntryGuard aGuard( *this );
1615 : SAL_INFO("connectivity.mork", "m_nRowPos = " << m_nRowPos);
1616 0 : return comphelper::getINT32(bookmark);
1617 : }
1618 :
1619 9 : sal_Int32 OResultSet::getCurrentCardNumber()
1620 : {
1621 9 : if ( ( m_nRowPos == 0 ) || !m_pKeySet.is() )
1622 0 : return 0;
1623 9 : if (m_pKeySet->get().size() < m_nRowPos)
1624 0 : return 0;
1625 9 : return (m_pKeySet->get())[m_nRowPos-1];
1626 : }
1627 0 : void OResultSet::checkPendingUpdate() throw(SQLException, RuntimeException)
1628 : {
1629 : OSL_FAIL( "OResultSet::checkPendingUpdate() not implemented" );
1630 : /*
1631 : OSL_TRACE("checkPendingUpdate, m_nRowPos = %u", m_nRowPos );
1632 : const sal_Int32 nCurrentRow = getCurrentCardNumber();
1633 :
1634 : if ((m_nNewRow && nCurrentRow != m_nNewRow)
1635 : || ( m_nUpdatedRow && m_nUpdatedRow != nCurrentRow))
1636 : {
1637 : const OUString sError( m_pStatement->getOwnConnection()->getResources().getResourceStringWithSubstitution(
1638 : STR_COMMIT_ROW,
1639 : "$position$", OUString::valueOf(nCurrentRow)
1640 : ) );
1641 : ::dbtools::throwGenericSQLException(sError,*this);
1642 : }
1643 : */
1644 :
1645 0 : }
1646 0 : void OResultSet::updateValue(sal_Int32 columnIndex ,const ORowSetValue& x) throw(SQLException, RuntimeException)
1647 : {
1648 : SAL_INFO("connectivity.mork", "m_nRowPos = " << m_nRowPos);
1649 0 : ResultSetEntryGuard aGuard( *this );
1650 0 : if ( !fetchCurrentRow() ) {
1651 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_ERROR_GET_ROW, *this );
1652 : }
1653 :
1654 0 : checkPendingUpdate();
1655 :
1656 0 : checkIndex(columnIndex );
1657 0 : columnIndex = mapColumn(columnIndex);
1658 :
1659 0 : (m_aRow->get())[columnIndex].setBound(true);
1660 0 : (m_aRow->get())[columnIndex] = x;
1661 0 : m_nUpdatedRow = getCurrentCardNumber();
1662 : // m_RowStates = m_RowStates | RowStates_Updated;
1663 0 : }
1664 :
1665 :
1666 0 : void SAL_CALL OResultSet::updateNull( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1667 : {
1668 : SAL_INFO("connectivity.mork", "m_nRowPos = " << m_nRowPos);
1669 0 : ResultSetEntryGuard aGuard( *this );
1670 0 : if ( !fetchCurrentRow() )
1671 0 : m_pStatement->getOwnConnection()->throwSQLException( STR_ERROR_GET_ROW, *this );
1672 :
1673 0 : checkPendingUpdate();
1674 0 : checkIndex(columnIndex );
1675 0 : columnIndex = mapColumn(columnIndex);
1676 :
1677 0 : (m_aRow->get())[columnIndex].setBound(true);
1678 0 : (m_aRow->get())[columnIndex].setNull();
1679 0 : m_nUpdatedRow = getCurrentCardNumber();
1680 : // m_RowStates = m_RowStates | RowStates_Updated;
1681 0 : }
1682 :
1683 :
1684 0 : void SAL_CALL OResultSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw(SQLException, RuntimeException, std::exception)
1685 : {
1686 0 : updateValue(columnIndex, static_cast<bool>(x));
1687 0 : }
1688 :
1689 0 : void SAL_CALL OResultSet::updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw(SQLException, RuntimeException, std::exception)
1690 : {
1691 0 : updateValue(columnIndex,x);
1692 0 : }
1693 :
1694 :
1695 0 : void SAL_CALL OResultSet::updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw(SQLException, RuntimeException, std::exception)
1696 : {
1697 0 : updateValue(columnIndex,x);
1698 0 : }
1699 :
1700 0 : void SAL_CALL OResultSet::updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw(SQLException, RuntimeException, std::exception)
1701 : {
1702 0 : updateValue(columnIndex,x);
1703 0 : }
1704 :
1705 0 : void SAL_CALL OResultSet::updateLong( sal_Int32 /*columnIndex*/, sal_Int64 /*x*/ ) throw(SQLException, RuntimeException, std::exception)
1706 : {
1707 0 : ::dbtools::throwFeatureNotImplementedSQLException( "XRowUpdate::updateLong", *this );
1708 0 : }
1709 :
1710 0 : void SAL_CALL OResultSet::updateFloat( sal_Int32 columnIndex, float x ) throw(SQLException, RuntimeException, std::exception)
1711 : {
1712 0 : updateValue(columnIndex,x);
1713 0 : }
1714 :
1715 :
1716 0 : void SAL_CALL OResultSet::updateDouble( sal_Int32 columnIndex, double x ) throw(SQLException, RuntimeException, std::exception)
1717 : {
1718 0 : updateValue(columnIndex,x);
1719 0 : }
1720 :
1721 0 : void SAL_CALL OResultSet::updateString( sal_Int32 columnIndex, const OUString& x ) throw(SQLException, RuntimeException, std::exception)
1722 : {
1723 0 : updateValue(columnIndex,x);
1724 0 : }
1725 :
1726 0 : void SAL_CALL OResultSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException, std::exception)
1727 : {
1728 0 : updateValue(columnIndex,x);
1729 0 : }
1730 :
1731 0 : void SAL_CALL OResultSet::updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x ) throw(SQLException, RuntimeException, std::exception)
1732 : {
1733 0 : updateValue(columnIndex,x);
1734 0 : }
1735 :
1736 :
1737 0 : void SAL_CALL OResultSet::updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x ) throw(SQLException, RuntimeException, std::exception)
1738 : {
1739 0 : updateValue(columnIndex,x);
1740 0 : }
1741 :
1742 :
1743 0 : void SAL_CALL OResultSet::updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x ) throw(SQLException, RuntimeException, std::exception)
1744 : {
1745 0 : updateValue(columnIndex,x);
1746 0 : }
1747 :
1748 :
1749 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)
1750 : {
1751 0 : ResultSetEntryGuard aGuard( *this );
1752 :
1753 0 : if(!x.is())
1754 0 : ::dbtools::throwFunctionSequenceException(*this);
1755 :
1756 0 : Sequence<sal_Int8> aSeq;
1757 0 : x->readBytes(aSeq,length);
1758 0 : updateValue(columnIndex,aSeq);
1759 0 : }
1760 :
1761 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)
1762 : {
1763 0 : updateBinaryStream(columnIndex,x,length);
1764 0 : }
1765 :
1766 0 : void SAL_CALL OResultSet::updateObject( sal_Int32 columnIndex, const Any& x ) throw(SQLException, RuntimeException, std::exception)
1767 : {
1768 0 : if (!::dbtools::implUpdateObject(this, columnIndex, x))
1769 : {
1770 0 : const OUString sError( m_pStatement->getOwnConnection()->getResources().getResourceStringWithSubstitution(
1771 : STR_COLUMN_NOT_UPDATEABLE,
1772 : "$position$", OUString::number(columnIndex)
1773 0 : ) );
1774 0 : ::dbtools::throwGenericSQLException(sError,*this);
1775 : } // if (!::dbtools::implUpdateObject(this, columnIndex, x))
1776 0 : }
1777 :
1778 :
1779 0 : void SAL_CALL OResultSet::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 /*scale*/ ) throw(SQLException, RuntimeException, std::exception)
1780 : {
1781 0 : if (!::dbtools::implUpdateObject(this, columnIndex, x))
1782 : {
1783 0 : const OUString sError( m_pStatement->getOwnConnection()->getResources().getResourceStringWithSubstitution(
1784 : STR_COLUMN_NOT_UPDATEABLE,
1785 : "$position$", OUString::number(columnIndex)
1786 0 : ) );
1787 0 : ::dbtools::throwGenericSQLException(sError,*this);
1788 : }
1789 0 : }
1790 :
1791 : // XResultSetUpdate
1792 :
1793 0 : void SAL_CALL OResultSet::insertRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
1794 : {
1795 0 : ResultSetEntryGuard aGuard( *this );
1796 : SAL_INFO("connectivity.mork", "in, m_nRowPos = " << m_nRowPos);
1797 : // m_RowStates = RowStates_Inserted;
1798 0 : updateRow();
1799 0 : m_nOldRowPos = 0;
1800 0 : m_nNewRow = 0;
1801 : //m_aQueryHelper.setRowStates(getCurrentCardNumber(),m_RowStates);
1802 0 : SAL_INFO("connectivity.mork", "out, m_nRowPos = " << m_nRowPos);
1803 0 : }
1804 :
1805 0 : void SAL_CALL OResultSet::updateRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
1806 : {
1807 : OSL_FAIL( "OResultSet::updateRow( ) not implemented" );
1808 0 : }
1809 :
1810 0 : void SAL_CALL OResultSet::deleteRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
1811 : {
1812 : OSL_FAIL( "OResultSet::deleteRow( ) not implemented" );
1813 0 : }
1814 :
1815 0 : void SAL_CALL OResultSet::cancelRowUpdates( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
1816 : {
1817 : OSL_FAIL( "OResultSet::cancelRowUpdates( ) not implemented" );
1818 0 : }
1819 :
1820 0 : void SAL_CALL OResultSet::moveToInsertRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
1821 : {
1822 : OSL_FAIL( "OResultSet::moveToInsertRow( ) not implemented" );
1823 0 : }
1824 :
1825 0 : void SAL_CALL OResultSet::moveToCurrentRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
1826 : {
1827 0 : ResultSetEntryGuard aGuard( *this );
1828 : SAL_INFO("connectivity.mork", "m_nRowPos = " << m_nRowPos);
1829 0 : if (rowInserted())
1830 : {
1831 0 : m_nRowPos = m_nOldRowPos;
1832 0 : fetchCurrentRow();
1833 0 : }
1834 0 : }
1835 :
1836 2 : bool OResultSet::determineReadOnly()
1837 : {
1838 : // OSL_FAIL( "OResultSet::determineReadOnly( ) not implemented" );
1839 :
1840 2 : if (m_bIsReadOnly == TRISTATE_INDET)
1841 : {
1842 2 : m_bIsReadOnly = TRISTATE_TRUE;
1843 : // OConnection* xConnection = static_cast<OConnection*>(m_pStatement->getConnection().get());
1844 : // m_bIsReadOnly = !m_aQueryHelper.isWritable(xConnection) || m_bIsAlwaysFalseQuery;
1845 : }
1846 :
1847 2 : return m_bIsReadOnly != TRISTATE_FALSE;
1848 : }
1849 :
1850 2 : void OResultSet::setTable(OTable* _rTable)
1851 : {
1852 : OSL_TRACE("In : setTable");
1853 2 : m_pTable = _rTable;
1854 2 : m_pTable->acquire();
1855 2 : m_xTableColumns = m_pTable->getColumns();
1856 2 : if(m_xTableColumns.is())
1857 2 : m_aColumnNames = m_xTableColumns->getElementNames();
1858 : OSL_TRACE("Out : setTable");
1859 2 : }
1860 :
1861 2 : void OResultSet::setOrderByColumns(const ::std::vector<sal_Int32>& _aColumnOrderBy)
1862 : {
1863 2 : m_aOrderbyColumnNumber = _aColumnOrderBy;
1864 2 : }
1865 :
1866 2 : void OResultSet::setOrderByAscending(const ::std::vector<TAscendingOrder>& _aOrderbyAsc)
1867 : {
1868 2 : m_aOrderbyAscending = _aOrderbyAsc;
1869 2 : }
1870 0 : Sequence< sal_Int32 > SAL_CALL OResultSet::deleteRows( const Sequence< Any >& /*rows*/ ) throw(SQLException, RuntimeException, std::exception)
1871 : {
1872 0 : ::dbtools::throwFeatureNotImplementedSQLException( "XDeleteRows::deleteRows", *this );
1873 0 : return Sequence< sal_Int32 >();
1874 : };
1875 :
1876 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|