LibreOffice Module connectivity (master) 1
pq_baseresultset.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*************************************************************************
3 *
4 * Effective License of whole file:
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License version 2.1, as published by the Free Software Foundation.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
19 *
20 * Parts "Copyright by Sun Microsystems, Inc" prior to August 2011:
21 *
22 * The Contents of this file are made available subject to the terms of
23 * the GNU Lesser General Public License Version 2.1
24 *
25 * Copyright: 2000 by Sun Microsystems, Inc.
26 *
27 * Contributor(s): Joerg Budischewski
28 *
29 * All parts contributed on or after August 2011:
30 *
31 * This Source Code Form is subject to the terms of the Mozilla Public
32 * License, v. 2.0. If a copy of the MPL was not distributed with this
33 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
34 *
35 ************************************************************************/
36
38
39#include "pq_tools.hxx"
40#include "pq_array.hxx"
41#include "pq_baseresultset.hxx"
42
43#include <com/sun/star/script/CannotConvertException.hpp>
44#include <com/sun/star/sdbc/SQLException.hpp>
46
47using osl::MutexGuard;
48
49
50using com::sun::star::beans::XPropertySetInfo;
51
52using com::sun::star::uno::Any;
53using com::sun::star::uno::Type;
56using com::sun::star::uno::XInterface;
57
58using com::sun::star::lang::IllegalArgumentException;
59
60using com::sun::star::sdbc::SQLException;
61
62
63using com::sun::star::beans::Property;
64
65using namespace dbtools;
66
67namespace pq_sdbc_driver
68{
69static ::cppu::IPropertyArrayHelper & getResultSetPropertyArrayHelper()
70{
71 // LEM TODO: this needs to be kept in sync with other, e.g. pq_statics.css:508
72 // Should really share!
73 // At least use for the handles the #define'd values in .hxx file...
74 static ::cppu::OPropertyArrayHelper arrayHelper(
77 "CursorName", 0,
80 "EscapeProcessing", 1,
83 "FetchDirection", 2,
86 "FetchSize", 3,
89 "IsBookmarkable", 4,
92 "ResultSetConcurrency", 5,
95 "ResultSetType", 6,
97 true );
98 return arrayHelper;
99}
100
102 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
103 const Reference< XInterface > & owner,
104 sal_Int32 rowCount,
105 sal_Int32 colCount,
107 : BaseResultSet_BASE( refMutex->GetMutex() )
109 , m_owner( owner )
110 , m_tc( tc )
111 , m_xMutex( refMutex )
112 , m_row( -1 )
113 , m_rowCount( rowCount )
114 , m_fieldCount( colCount )
115 , m_wasNull(false)
116{
117}
118
119// LEM TODO: refMutex->GetMutex() should live longer than OComponentHelper,
120// but calling OComponentHelper::dispose explicitly here calls
121// BaseResultSet::~BaseResultSet in an infinite loop :(
123{
124}
125
127{
128 Any aRet = BaseResultSet_BASE::queryInterface(rType);
129 return aRet.hasValue() ? aRet : OPropertySetHelper::queryInterface(rType);
130}
131
132// void BaseResultSet::close( ) throw (SQLException, RuntimeException)
133// {
134// Reference< XInterface > owner;
135// {
136// ResultSetGuard guard(*this);
137// if( m_result )
138// {
139// PQclear(m_result );
140// m_result = 0;
141// m_row = -1;
142// }
143// owner = m_owner;
144// m_owner.clear();
145// }
146// }
147
149{
150 static Sequence< Type > collection(
151 ::comphelper::concatSequences(
152 OPropertySetHelper::getTypes(),
153 BaseResultSet_BASE::getTypes()));
154 return collection;
155}
156
158{
159 return css::uno::Sequence<sal_Int8>();
160}
161
162// Reference< XResultSetMetaData > BaseResultSet::getMetaData( ) throw (SQLException, RuntimeException)
163// {
164// ResultSetGuard guard(*this);
165// checkClosed();
166// return new ResultSetMetaData( m_xMutex, this, &m_result );
167// }
168
170{
171 MutexGuard guard( m_xMutex->GetMutex() );
172 checkClosed();
173 m_row ++;
174 return m_row < m_rowCount;
175}
176
178{
179 MutexGuard guard( m_xMutex->GetMutex() );
180 checkClosed();
181 return m_row == -1;
182}
183
185{
186 MutexGuard guard( m_xMutex->GetMutex() );
187 checkClosed();
188 return m_row >= m_rowCount;
189}
190
192{
193 MutexGuard guard( m_xMutex->GetMutex() );
194 checkClosed();
195 return m_row == 0 && m_rowCount;
196}
197
199{
200 MutexGuard guard( m_xMutex->GetMutex() );
201 checkClosed();
202 return m_row >= 0 && m_row + 1 == m_rowCount;
203}
204
206{
207 MutexGuard guard( m_xMutex->GetMutex() );
208 checkClosed();
209 m_row = -1;
210}
211
213{
214 MutexGuard guard( m_xMutex->GetMutex() );
215 checkClosed();
217}
218
220{
221 MutexGuard guard( m_xMutex->GetMutex() );
222 checkClosed();
223 bool bRet = ( m_rowCount > 0 );
224 if( bRet )
225 m_row = 0;
226 return bRet;
227}
228
230{
231 MutexGuard guard( m_xMutex->GetMutex() );
232 checkClosed();
233 bool bRet = ( m_rowCount > 0 );
234 if( bRet )
235 m_row = m_rowCount -1;
236 return bRet;
237}
238
240{
241 MutexGuard guard( m_xMutex->GetMutex() );
242 checkClosed();
243 return m_row +1;
244}
245
247{
248 MutexGuard guard( m_xMutex->GetMutex() );
249 checkClosed();
250 if( row > 0 )
251 {
252 m_row = row -1;
253 if( m_row > m_rowCount )
255 }
256 else
257 {
258 m_row = m_rowCount + row;
259 if( m_row < -1 )
260 m_row = -1;
261 }
262 return true;
263}
264
266{
267 MutexGuard guard( m_xMutex->GetMutex() );
268 checkClosed();
269 m_row += rows;
270
271 if( m_row > m_rowCount )
273 else if ( m_row < -1 )
274 m_row = -1;
275 return true;
276}
277
279{
280 MutexGuard guard( m_xMutex->GetMutex() );
281 checkClosed();
282 bool bRet = ( m_row != -1 );
283 if( bRet )
284 m_row --;
285 return bRet;
286}
287
289{
290 // TODO: not supported for now
291}
292
294{
295 return false;
296}
297
299{
300 return false;
301}
302
304{
305 return false;
306}
307
309{
310 MutexGuard guard( m_xMutex->GetMutex() );
311 checkClosed();
312 return m_owner;
313}
314
315
316//----------------- XRow interface ----------------------------------------------------
317
319{
320 return m_wasNull;
321}
322
323Any BaseResultSet::convertTo( const Any & val , const Type & type )
324{
325 Any aRet;
326 try
327 {
328 aRet = m_tc->convertTo( val , type );
329 }
330 catch( css::lang::IllegalArgumentException & )
331 {}
332 catch( css::script::CannotConvertException & )
333 {}
334 return aRet;
335}
336
337sal_Bool BaseResultSet::getBoolean( sal_Int32 columnIndex )
338{
339 MutexGuard guard( m_xMutex->GetMutex() );
340 checkClosed();
341 checkColumnIndex( columnIndex );
343
344 OUString str = getString( columnIndex );
345
346 if( str.getLength() > 0 )
347 {
348 switch(str[0])
349 {
350 case '1':
351 case 't':
352 case 'T':
353 case 'y':
354 case 'Y':
355
356 return true;
357 }
358 }
359 return false;
360}
361
362sal_Int8 BaseResultSet::getByte( sal_Int32 columnIndex )
363{
364 MutexGuard guard( m_xMutex->GetMutex() );
365 checkClosed();
366 checkColumnIndex( columnIndex );
368 sal_Int8 b = 0;
369 convertTo( getValue( columnIndex ), cppu::UnoType<decltype(b)>::get()) >>= b;
370 return b;
371}
372
373sal_Int16 BaseResultSet::getShort( sal_Int32 columnIndex )
374{
375 MutexGuard guard( m_xMutex->GetMutex() );
376 checkClosed();
377 checkColumnIndex( columnIndex );
379 sal_Int16 i = 0;
380 convertTo( getValue( columnIndex ), cppu::UnoType<decltype(i)>::get()) >>= i;
381 return i;
382}
383
384OUString BaseResultSet::getString( sal_Int32 columnIndex )
385{
386 MutexGuard guard(m_xMutex->GetMutex());
387 checkClosed();
388 checkColumnIndex( columnIndex );
390 OUString ret;
391 convertTo( getValue( columnIndex ), cppu::UnoType<decltype(ret)>::get() ) >>= ret;
392// printf( "BaseResultSet::getString() %s\n" , OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ).getStr() );
393 return ret;
394}
395
396sal_Int32 BaseResultSet::getInt( sal_Int32 columnIndex )
397{
398 MutexGuard guard( m_xMutex->GetMutex() );
399 checkClosed();
400 checkColumnIndex( columnIndex );
402 sal_Int32 i = 0;
403 convertTo( getValue( columnIndex ), cppu::UnoType<decltype(i)>::get()) >>= i;
404 return i;
405}
406
407sal_Int64 BaseResultSet::getLong( sal_Int32 columnIndex )
408{
409 MutexGuard guard( m_xMutex->GetMutex() );
410 checkClosed();
411 checkColumnIndex( columnIndex );
413 sal_Int64 i = 0;
414 convertTo( getValue( columnIndex ), cppu::UnoType<decltype(i)>::get()) >>= i;
415 return i;
416}
417
418float BaseResultSet::getFloat( sal_Int32 columnIndex )
419{
420 MutexGuard guard( m_xMutex->GetMutex() );
421 checkClosed();
422 checkColumnIndex( columnIndex );
424 float f = 0.;
425 convertTo( getValue( columnIndex ), cppu::UnoType<decltype(f)>::get()) >>= f;
426 return f;
427}
428
429double BaseResultSet::getDouble( sal_Int32 columnIndex )
430{
431 MutexGuard guard( m_xMutex->GetMutex() );
432 checkClosed();
433 checkColumnIndex( columnIndex );
434 double d = 0.;
435 convertTo( getValue( columnIndex ), cppu::UnoType<decltype(d)>::get()) >>= d;
436 return d;
437}
438
440{
441 MutexGuard guard( m_xMutex->GetMutex() );
442 checkClosed();
443 checkColumnIndex( columnIndex );
445
447 OUString ustr;
448 if( ! (getValue( columnIndex ) >>= ustr) )
449 m_wasNull = true;
450 else
451 {
452 // if this is a binary, it must contain escaped data !
453 OString val = OUStringToOString( ustr, RTL_TEXTENCODING_ASCII_US );
454
455 size_t length;
456 char * res = reinterpret_cast<char*>(PQunescapeBytea( reinterpret_cast<unsigned char const *>(val.getStr()), &length));
457 ret = Sequence< sal_Int8 > ( reinterpret_cast<sal_Int8*>(res), length );
458 if( res )
459 PQfreemem( res );
460 }
461 return ret;
462}
463
464
465css::util::Date BaseResultSet::getDate( sal_Int32 columnIndex )
466{
467 return DBTypeConversion::toDate( getString( columnIndex ) );
468}
469
470css::util::Time BaseResultSet::getTime( sal_Int32 columnIndex )
471{
472 return DBTypeConversion::toTime( getString( columnIndex ) );
473}
474
475css::util::DateTime BaseResultSet::getTimestamp( sal_Int32 columnIndex )
476{
477 return DBTypeConversion::toDateTime( getString( columnIndex ) );
478}
479
480 // LEM TODO: these look like they are missing an actual implementation
482{
483 return nullptr;
484}
485
487{
488 return nullptr;
489}
490
492 sal_Int32 /* columnIndex */,
493 const Reference< css::container::XNameAccess >& /* typeMap */ )
494{
495 return Any();
496}
497
499{
501}
502
504{
506}
507
509{
511}
512
514{
515 return new Array( m_xMutex, parseArray( getString( columnIndex ) ), *this, m_tc );
516}
517
519{
521}
522
524 Any & /* rConvertedValue */, Any & /* rOldValue */, sal_Int32 nHandle, const Any& rValue )
525{
526 bool bRet;
527 switch( nHandle )
528 {
530 {
531 OUString val;
532 bRet = ( rValue >>= val );
533 m_props[nHandle] <<= val;
534 break;
535 }
538 {
539 bool val(false);
540 bRet = ( rValue >>= val );
541 m_props[nHandle] <<= val;
542 break;
543 }
548 {
549 sal_Int32 val;
550 bRet = ( rValue >>= val );
551 m_props[nHandle] <<= val;
552 break;
553 }
554 default:
555 {
556 throw IllegalArgumentException(
557 "pq_resultset: Invalid property handle (" + OUString::number( nHandle ) + ")",
558 *this, 2 );
559 }
560 }
561 return bRet;
562}
563
564
566 sal_Int32 nHandle,const Any& rValue )
567{
568 m_props[nHandle] = rValue;
569}
570
571void BaseResultSet::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
572{
573 rValue = m_props[nHandle];
574}
575
577{
578 return OPropertySetHelper::createPropertySetInfo( getResultSetPropertyArrayHelper() );
579}
580
582{
583 close();
584}
585
587{
588 if( index < 1 || index > m_fieldCount )
589 {
590 throw SQLException(
591 "pq_resultset: index out of range ("
592 + OUString::number( index )
593 + ", allowed range is 1 to " + OUString::number( m_fieldCount )
594 + ")",
595 *this, OUString(), 1, Any() );
596 }
597
598}
599
601{
602 if( m_row < 0 || m_row >= m_rowCount )
603 {
604 throw SQLException(
605 "pq_baseresultset: row index out of range, allowed is 0 to " + OUString::number( m_rowCount -1 )
606 + ", got " + OUString::number( m_row ),
607 *this, OUString(),1, Any() );
608 }
609}
610
611}
612
613/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
double d
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getCharacterStream(sal_Int32 columnIndex) override
virtual sal_Bool SAL_CALL relative(sal_Int32 rows) override
css::uno::Reference< css::uno::XInterface > m_owner
virtual sal_Bool SAL_CALL getBoolean(sal_Int32 columnIndex) override
BaseResultSet(const ::rtl::Reference< comphelper::RefCountedMutex > &mutex, const css::uno::Reference< css::uno::XInterface > &owner, sal_Int32 rowCount, sal_Int32 columnCount, const css::uno::Reference< css::script::XTypeConverter > &tc)
virtual sal_Bool SAL_CALL rowUpdated() override
virtual sal_Int64 SAL_CALL getLong(sal_Int32 columnIndex) override
virtual sal_Bool SAL_CALL rowInserted() override
virtual css::util::Date SAL_CALL getDate(sal_Int32 columnIndex) override
virtual void checkClosed()=0
mutex should be locked before called
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getStatement() override
virtual sal_Int16 SAL_CALL getShort(sal_Int32 columnIndex) override
virtual sal_Bool SAL_CALL previous() override
virtual void SAL_CALL beforeFirst() override
virtual sal_Int32 SAL_CALL getRow() override
virtual css::uno::Reference< css::sdbc::XClob > SAL_CALL getClob(sal_Int32 columnIndex) override
css::uno::Reference< css::script::XTypeConverter > m_tc
virtual css::uno::Reference< css::sdbc::XRef > SAL_CALL getRef(sal_Int32 columnIndex) override
virtual sal_Int8 SAL_CALL getByte(sal_Int32 columnIndex) override
virtual sal_Bool SAL_CALL isAfterLast() override
virtual sal_Int32 SAL_CALL getInt(sal_Int32 columnIndex) override
::rtl::Reference< comphelper::RefCountedMutex > m_xMutex
void checkColumnIndex(sal_Int32 index)
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const css::uno::Any &rValue) override
virtual sal_Bool SAL_CALL rowDeleted() override
virtual css::uno::Any SAL_CALL getObject(sal_Int32 columnIndex, const css::uno::Reference< css::container::XNameAccess > &typeMap) override
virtual void SAL_CALL disposing() override
virtual double SAL_CALL getDouble(sal_Int32 columnIndex) override
virtual sal_Bool SAL_CALL last() override
virtual sal_Bool SAL_CALL convertFastPropertyValue(css::uno::Any &rConvertedValue, css::uno::Any &rOldValue, sal_Int32 nHandle, const css::uno::Any &rValue) override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getBytes(sal_Int32 columnIndex) override
virtual sal_Bool SAL_CALL wasNull() override
virtual css::util::DateTime SAL_CALL getTimestamp(sal_Int32 columnIndex) override
css::uno::Any convertTo(const css::uno::Any &str, const css::uno::Type &type)
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
virtual css::util::Time SAL_CALL getTime(sal_Int32 columnIndex) override
virtual sal_Bool SAL_CALL isLast() override
virtual sal_Bool SAL_CALL next() override
virtual css::uno::Reference< css::sdbc::XBlob > SAL_CALL getBlob(sal_Int32 columnIndex) override
virtual cppu::IPropertyArrayHelper &SAL_CALL getInfoHelper() override
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getBinaryStream(sal_Int32 columnIndex) override
virtual sal_Bool SAL_CALL absolute(sal_Int32 row) override
virtual float SAL_CALL getFloat(sal_Int32 columnIndex) override
virtual css::uno::Reference< css::sdbc::XArray > SAL_CALL getArray(sal_Int32 columnIndex) override
css::uno::Any m_props[BASERESULTSET_SIZE]
virtual void SAL_CALL refreshRow() override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &reqType) override
void SAL_CALL getFastPropertyValue(css::uno::Any &rValue, sal_Int32 nHandle) const override
virtual css::uno::Any getValue(sal_Int32 columnIndex)=0
virtual sal_Bool SAL_CALL first() override
virtual void SAL_CALL afterLast() override
virtual sal_Bool SAL_CALL isFirst() override
virtual sal_Bool SAL_CALL isBeforeFirst() override
virtual OUString SAL_CALL getString(sal_Int32 columnIndex) override
bool close
Type
OOO_DLLPUBLIC_DBTOOLS css::util::Date toDate(double dVal, const css::util::Date &_rNullDate=getStandardDate())
OOO_DLLPUBLIC_DBTOOLS css::util::Time toTime(double dVal, short nDigits=9)
OOO_DLLPUBLIC_DBTOOLS css::util::DateTime toDateTime(double dVal, const css::util::Date &_rNullDate=getStandardDate())
int i
index
const sal_Int32 BASERESULTSET_RESULT_SET_CONCURRENCY
const sal_Int32 BASERESULTSET_FETCH_DIRECTION
const sal_Int32 BASERESULTSET_IS_BOOKMARKABLE
::cppu::IPropertyArrayHelper & getResultSetPropertyArrayHelper()
const sal_Int32 BASERESULTSET_RESULT_SET_TYPE
::cppu::WeakComponentImplHelper< css::sdbc::XCloseable, css::sdbc::XResultSetMetaDataSupplier, css::sdbc::XResultSet, css::sdbc::XRow, css::sdbc::XColumnLocate > BaseResultSet_BASE
const sal_Int32 BASERESULTSET_CURSOR_NAME
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
Definition: pq_tools.cxx:100
const sal_Int32 BASERESULTSET_ESCAPE_PROCESSING
const sal_Int32 BASERESULTSET_FETCH_SIZE
std::vector< Any > parseArray(std::u16string_view str)
Definition: pq_tools.cxx:599
sal_Int32 type
Definition: pq_statics.cxx:60
sal_Int32 nHandle
unsigned char sal_Bool
signed char sal_Int8