merge the formfield patch from ooo-build
[ooovba.git] / connectivity / source / drivers / postgresql / pq_baseresultset.cxx
blob51ced2915d545e8e0f0dddc0742bb29d54a1e7ad
1 /*************************************************************************
3 * $RCSfile: pq_baseresultset.cxx,v $
5 * $Revision: 1.1.2.4 $
7 * last change: $Author: jbu $ $Date: 2004/08/29 08:33:28 $
9 * The Contents of this file are made available subject to the terms of
10 * either of the following licenses
12 * - GNU Lesser General Public License Version 2.1
13 * - Sun Industry Standards Source License Version 1.1
15 * Sun Microsystems Inc., October, 2000
17 * GNU Lesser General Public License Version 2.1
18 * =============================================
19 * Copyright 2000 by Sun Microsystems, Inc.
20 * 901 San Antonio Road, Palo Alto, CA 94303, USA
22 * This library is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU Lesser General Public
24 * License version 2.1, as published by the Free Software Foundation.
26 * This library is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 * Lesser General Public License for more details.
31 * You should have received a copy of the GNU Lesser General Public
32 * License along with this library; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
34 * MA 02111-1307 USA
37 * Sun Industry Standards Source License Version 1.1
38 * =================================================
39 * The contents of this file are subject to the Sun Industry Standards
40 * Source License Version 1.1 (the "License"); You may not use this file
41 * except in compliance with the License. You may obtain a copy of the
42 * License at http://www.openoffice.org/license.html.
44 * Software provided under this License is provided on an "AS IS" basis,
45 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
46 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
47 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
48 * See the License for the specific provisions governing your rights and
49 * obligations concerning the Software.
51 * The Initial Developer of the Original Code is: Joerg Budischewski
53 * Copyright: 2000 by Sun Microsystems, Inc.
55 * All Rights Reserved.
57 * Contributor(s): Joerg Budischewski
60 ************************************************************************/
62 #include <osl/thread.h>
64 #include <rtl/ustrbuf.hxx>
66 #include <cppuhelper/typeprovider.hxx>
67 #include <cppuhelper/queryinterface.hxx>
69 #include "pq_tools.hxx"
70 #include "pq_array.hxx"
71 #include "pq_statement.hxx"
72 #include "pq_baseresultset.hxx"
73 #include "pq_resultsetmetadata.hxx"
75 #include <com/sun/star/lang/DisposedException.hpp>
77 using osl::Mutex;
78 using osl::MutexGuard;
80 using rtl::OUString;
81 using rtl::OUStringToOString;
82 using rtl::OUStringBuffer;
83 using rtl::OString;
85 using com::sun::star::beans::XPropertySetInfo;
86 using com::sun::star::beans::XPropertySet;
87 using com::sun::star::beans::XMultiPropertySet;
88 using com::sun::star::beans::XFastPropertySet;
90 using com::sun::star::uno::Any;
91 using com::sun::star::uno::makeAny;
92 using com::sun::star::uno::Type;
93 using com::sun::star::uno::RuntimeException;
94 using com::sun::star::uno::Exception;
95 using com::sun::star::uno::Sequence;
96 using com::sun::star::uno::Reference;
97 using com::sun::star::uno::XInterface;
99 using com::sun::star::lang::IllegalArgumentException;
101 using com::sun::star::sdbc::XWarningsSupplier;
102 using com::sun::star::sdbc::XCloseable;
103 using com::sun::star::sdbc::XStatement;
104 using com::sun::star::sdbc::XResultSet;
105 using com::sun::star::sdbc::XConnection;
106 using com::sun::star::sdbc::SQLException;
107 using com::sun::star::sdbc::XRow;
108 using com::sun::star::sdbc::XColumnLocate;
109 using com::sun::star::sdbc::XResultSetMetaData;
110 using com::sun::star::sdbc::XResultSetMetaDataSupplier;
113 using com::sun::star::beans::Property;
115 namespace pq_sdbc_driver
117 #define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
119 static ::cppu::IPropertyArrayHelper & getResultSetPropertyArrayHelper()
121 static ::cppu::IPropertyArrayHelper *pArrayHelper;
122 if( ! pArrayHelper )
124 MutexGuard guard( Mutex::getGlobalMutex() );
125 if( ! pArrayHelper )
127 static Property aTable[] =
129 Property(
130 OUString( RTL_CONSTASCII_USTRINGPARAM("CursorName") ), 0,
131 ::getCppuType( (OUString *)0) , 0 ),
132 Property(
133 OUString( RTL_CONSTASCII_USTRINGPARAM("EscapeProcessing") ), 0,
134 ::getBooleanCppuType() , 0 ),
135 Property(
136 OUString( RTL_CONSTASCII_USTRINGPARAM("FetchDirection") ), 0,
137 ::getCppuType( (sal_Int32 *)0) , 0 ),
138 Property(
139 OUString( RTL_CONSTASCII_USTRINGPARAM("FetchSize") ), 0,
140 ::getCppuType( (sal_Int32 *)0) , 0 ),
141 Property(
142 OUString( RTL_CONSTASCII_USTRINGPARAM("ResultSetConcurrency") ), 0,
143 ::getCppuType( (sal_Int32 *)0) , 0 ),
144 Property(
145 OUString( RTL_CONSTASCII_USTRINGPARAM("ResultSetType") ), 0,
146 ::getCppuType( (sal_Int32 *)0) , 0 )
148 OSL_ASSERT( sizeof(aTable) / sizeof(Property) == BASERESULTSET_SIZE );
149 static ::cppu::OPropertyArrayHelper arrayHelper( aTable, BASERESULTSET_SIZE, sal_True );
150 pArrayHelper = &arrayHelper;
153 return *pArrayHelper;
156 BaseResultSet::BaseResultSet(
157 const ::rtl::Reference< RefCountedMutex > & refMutex,
158 const Reference< XInterface > & owner,
159 sal_Int32 rowCount,
160 sal_Int32 colCount,
161 const Reference< com::sun::star::script::XTypeConverter > & tc )
162 : OComponentHelper( refMutex->mutex ),
163 OPropertySetHelper( OComponentHelper::rBHelper ),
164 m_refMutex( refMutex ),
165 m_owner( owner ),
166 m_row( -1 ),
167 m_rowCount( rowCount ),
168 m_fieldCount( colCount ),
169 m_tc( tc )
171 POSTGRE_TRACE( "ctor BaseResultSet" );
174 BaseResultSet::~BaseResultSet()
176 POSTGRE_TRACE( "dtor BaseResultSet" );
179 Any BaseResultSet::queryInterface( const Type & reqType ) throw (RuntimeException)
181 Any ret;
183 ret = OComponentHelper::queryInterface( reqType );
184 if( ! ret.hasValue() )
185 ret = ::cppu::queryInterface( reqType,
186 static_cast< XResultSet * > ( this ),
187 static_cast< XResultSetMetaDataSupplier * > ( this ),
188 static_cast< XRow * > ( this ),
189 static_cast< XColumnLocate * > ( this ),
190 static_cast< XCloseable * > ( this ),
191 static_cast< XPropertySet * > ( this ),
192 static_cast< XMultiPropertySet * > ( this ),
193 static_cast< XFastPropertySet * > ( this ) );
194 return ret;
197 // void BaseResultSet::close( ) throw (SQLException, RuntimeException)
198 // {
199 // Reference< XInterface > owner;
200 // {
201 // ResultSetGuard guard(*this);
202 // if( m_result )
203 // {
204 // PQclear(m_result );
205 // m_result = 0;
206 // m_row = -1;
207 // }
208 // owner = m_owner;
209 // m_owner.clear();
210 // }
211 // }
213 Sequence<Type > BaseResultSet::getTypes() throw( RuntimeException )
215 static cppu::OTypeCollection *pCollection;
216 if( ! pCollection )
218 MutexGuard guard( osl::Mutex::getGlobalMutex() );
219 if( !pCollection )
221 static cppu::OTypeCollection collection(
222 getCppuType( (Reference< XResultSet> *) 0 ),
223 getCppuType( (Reference< XResultSetMetaDataSupplier> *) 0 ),
224 getCppuType( (Reference< XRow> *) 0 ),
225 getCppuType( (Reference< XColumnLocate> *) 0 ),
226 getCppuType( (Reference< XCloseable> *) 0 ),
227 getCppuType( (Reference< XPropertySet >*) 0 ),
228 getCppuType( (Reference< XFastPropertySet > *) 0 ),
229 getCppuType( (Reference< XMultiPropertySet > *) 0 ),
230 OComponentHelper::getTypes());
231 pCollection = &collection;
234 return pCollection->getTypes();
237 Sequence< sal_Int8> BaseResultSet::getImplementationId() throw( RuntimeException )
239 static cppu::OImplementationId *pId;
240 if( ! pId )
242 MutexGuard guard( osl::Mutex::getGlobalMutex() );
243 if( ! pId )
245 static cppu::OImplementationId id(sal_False);
246 pId = &id;
249 return pId->getImplementationId();
252 // Reference< XResultSetMetaData > BaseResultSet::getMetaData( ) throw (SQLException, RuntimeException)
253 // {
254 // ResultSetGuard guard(*this);
255 // checkClosed();
256 // return new ResultSetMetaData( m_refMutex, this, &m_result );
257 // }
259 sal_Bool BaseResultSet::next( ) throw (SQLException, RuntimeException)
261 MutexGuard guard( m_refMutex->mutex );
262 checkClosed();
263 m_row ++;
264 return m_row < m_rowCount;
267 sal_Bool BaseResultSet::isBeforeFirst( ) throw (SQLException, RuntimeException)
269 MutexGuard guard( m_refMutex->mutex );
270 checkClosed();
271 return m_row == -1;
274 sal_Bool BaseResultSet::isAfterLast( ) throw (SQLException, RuntimeException)
276 MutexGuard guard( m_refMutex->mutex );
277 checkClosed();
278 return m_row >= m_rowCount;
281 sal_Bool BaseResultSet::isFirst( ) throw (SQLException, RuntimeException)
283 MutexGuard guard( m_refMutex->mutex );
284 checkClosed();
285 return m_row == 0 && m_rowCount;
288 sal_Bool BaseResultSet::isLast( ) throw (SQLException, RuntimeException)
290 MutexGuard guard( m_refMutex->mutex );
291 checkClosed();
292 return m_row >= 0 && m_row + 1 == m_rowCount;
295 void BaseResultSet::beforeFirst( ) throw (SQLException, RuntimeException)
297 MutexGuard guard( m_refMutex->mutex );
298 checkClosed();
299 m_row = -1;
302 void BaseResultSet::afterLast( ) throw (SQLException, RuntimeException)
304 MutexGuard guard( m_refMutex->mutex );
305 checkClosed();
306 m_row = m_rowCount;
309 sal_Bool BaseResultSet::first( ) throw (SQLException, RuntimeException)
311 MutexGuard guard( m_refMutex->mutex );
312 checkClosed();
313 sal_Bool bRet = ( m_rowCount > 0 );
314 if( bRet )
315 m_row = 0;
316 return bRet;
319 sal_Bool BaseResultSet::last( ) throw (SQLException, RuntimeException)
321 MutexGuard guard( m_refMutex->mutex );
322 checkClosed();
323 sal_Bool bRet = ( m_rowCount > 0 );
324 if( bRet )
325 m_row = m_rowCount -1;
326 return bRet;
329 sal_Int32 BaseResultSet::getRow( ) throw (SQLException, RuntimeException)
331 MutexGuard guard( m_refMutex->mutex );
332 checkClosed();
333 return m_row +1;
336 sal_Bool BaseResultSet::absolute( sal_Int32 row ) throw (SQLException, RuntimeException)
338 MutexGuard guard( m_refMutex->mutex );
339 checkClosed();
340 if( row > 0 )
342 m_row = row -1;
343 if( m_row > m_rowCount )
344 m_row = m_rowCount;
346 else
348 m_row = m_rowCount + row;
349 if( m_row < -1 )
350 m_row = -1;
352 return sal_True;
355 sal_Bool BaseResultSet::relative( sal_Int32 rows ) throw (SQLException, RuntimeException)
357 MutexGuard guard( m_refMutex->mutex );
358 checkClosed();
359 m_row += rows;
361 if( m_row > m_rowCount )
362 m_row = m_rowCount;
363 else if ( m_row < -1 )
364 m_row = -1;
365 return sal_True;
368 sal_Bool BaseResultSet::previous( ) throw (SQLException, RuntimeException)
370 MutexGuard guard( m_refMutex->mutex );
371 checkClosed();
372 sal_Bool bRet = ( m_row != -1 );
373 if( bRet )
374 m_row --;
375 return bRet;
378 void BaseResultSet::refreshRow( ) throw (SQLException, RuntimeException)
380 // TODO: not supported for now
383 sal_Bool BaseResultSet::rowUpdated( ) throw (SQLException, RuntimeException)
385 return sal_False;
388 sal_Bool BaseResultSet::rowInserted( ) throw (SQLException, RuntimeException)
390 return sal_False;
393 sal_Bool BaseResultSet::rowDeleted( ) throw (SQLException, RuntimeException)
395 return sal_False;
398 Reference< XInterface > BaseResultSet::getStatement() throw (SQLException, RuntimeException)
400 MutexGuard guard( m_refMutex->mutex );
401 checkClosed();
402 return m_owner;
406 //----------------- XRow interface ----------------------------------------------------
408 sal_Bool BaseResultSet::wasNull( ) throw (SQLException, RuntimeException)
410 return m_wasNull;
413 Any BaseResultSet::convertTo( const Any & val , const Type & type )
415 Any aRet;
418 aRet = m_tc->convertTo( val , type );
420 catch( com::sun::star::lang::IllegalArgumentException & e )
422 catch( com::sun::star::script::CannotConvertException & e )
424 return aRet;
427 sal_Bool BaseResultSet::getBoolean( sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
429 MutexGuard guard( m_refMutex->mutex );
430 checkClosed();
431 checkColumnIndex( columnIndex );
432 checkRowIndex( sal_True /* must be on row */ );
434 sal_Bool b = sal_False;
436 OUString str = getString( columnIndex );
438 if( str.getLength() > 0 )
440 switch(str[0])
442 case '1':
443 case 't':
444 case 'T':
445 case 'y':
446 case 'Y':
448 return sal_True;
451 return sal_False;
454 sal_Int8 BaseResultSet::getByte( sal_Int32 columnIndex )
455 throw (SQLException, RuntimeException)
457 MutexGuard guard( m_refMutex->mutex );
458 checkClosed();
459 checkColumnIndex( columnIndex );
460 checkRowIndex( sal_True /* must be on row */ );
461 sal_Int8 b = 0;
462 convertTo( getValue( columnIndex ), getCppuType( &b )) >>= b;
463 return b;
466 sal_Int16 BaseResultSet::getShort( sal_Int32 columnIndex )
467 throw (SQLException, RuntimeException)
469 MutexGuard guard( m_refMutex->mutex );
470 checkClosed();
471 checkColumnIndex( columnIndex );
472 checkRowIndex( sal_True /* must be on row */ );
473 sal_Int16 i = 0;
474 convertTo( getValue( columnIndex ), getCppuType( &i )) >>= i;
475 return i;
478 OUString BaseResultSet::getString( sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
480 MutexGuard guard(m_refMutex->mutex);
481 checkClosed();
482 checkColumnIndex( columnIndex );
483 checkRowIndex( sal_True /* must be on row */ );
484 OUString ret;
485 convertTo( getValue( columnIndex ), getCppuType( &ret ) ) >>= ret;
486 // printf( "BaseResultSet::getString() %s\n" , OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ).getStr() );
487 return ret;
490 sal_Int32 BaseResultSet::getInt( sal_Int32 columnIndex )
491 throw (SQLException, RuntimeException)
493 MutexGuard guard( m_refMutex->mutex );
494 checkClosed();
495 checkColumnIndex( columnIndex );
496 checkRowIndex( sal_True /* must be on row */ );
497 sal_Int32 i = 0;
498 convertTo( getValue( columnIndex ), getCppuType( &i )) >>= i;
499 return i;
502 sal_Int64 BaseResultSet::getLong( sal_Int32 columnIndex )
503 throw (SQLException, RuntimeException)
505 MutexGuard guard( m_refMutex->mutex );
506 checkClosed();
507 checkColumnIndex( columnIndex );
508 checkRowIndex( sal_True /* must be on row */ );
509 sal_Int64 i = 0;
510 convertTo( getValue( columnIndex ), getCppuType( &i )) >>= i;
511 return i;
514 float BaseResultSet::getFloat( sal_Int32 columnIndex )
515 throw (SQLException, RuntimeException)
517 MutexGuard guard( m_refMutex->mutex );
518 checkClosed();
519 checkColumnIndex( columnIndex );
520 checkRowIndex( sal_True /* must be on row */ );
521 float f = 0.;
522 convertTo( getValue( columnIndex ), getCppuType( &f )) >>= f;
523 return f;
526 double BaseResultSet::getDouble( sal_Int32 columnIndex )
527 throw (SQLException, RuntimeException)
529 MutexGuard guard( m_refMutex->mutex );
530 checkClosed();
531 checkColumnIndex( columnIndex );
532 double d = 0.;
533 convertTo( getValue( columnIndex ), getCppuType( &d )) >>= d;
534 return d;
537 Sequence< sal_Int8 > BaseResultSet::getBytes( sal_Int32 columnIndex )
538 throw (SQLException, RuntimeException)
540 MutexGuard guard( m_refMutex->mutex );
541 checkClosed();
542 checkColumnIndex( columnIndex );
543 checkRowIndex( sal_True /* must be on row */ );
545 Sequence< sal_Int8 > ret;
546 OUString ustr;
547 if( ! (getValue( columnIndex ) >>= ustr) )
548 m_wasNull = true;
549 else
551 // if this is a binary, it must contain escaped data !
552 OString val = rtl::OUStringToOString( ustr, RTL_TEXTENCODING_ASCII_US );
554 size_t length;
555 char * res = (char*) PQunescapeBytea( (unsigned char *)val.getStr() , &length);
556 ret = Sequence< sal_Int8 > ( (sal_Int8*)res, length );
557 if( res )
558 free( res );
560 return ret;
564 ::com::sun::star::util::Date BaseResultSet::getDate( sal_Int32 columnIndex )
565 throw (SQLException, RuntimeException)
567 return string2Date( getString( columnIndex ) );
570 ::com::sun::star::util::Time BaseResultSet::getTime( sal_Int32 columnIndex )
571 throw (SQLException, RuntimeException)
573 return string2Time( getString( columnIndex ) );
576 ::com::sun::star::util::DateTime BaseResultSet::getTimestamp( sal_Int32 columnIndex )
577 throw (SQLException, RuntimeException)
579 return string2DateTime( getString( columnIndex ) );
582 Reference< ::com::sun::star::io::XInputStream > BaseResultSet::getBinaryStream( sal_Int32 columnIndex )
583 throw (SQLException, RuntimeException)
585 return 0;
588 Reference< ::com::sun::star::io::XInputStream > BaseResultSet::getCharacterStream( sal_Int32 columnIndex )
589 throw (SQLException, RuntimeException)
591 return 0;
594 Any BaseResultSet::getObject(
595 sal_Int32 columnIndex,
596 const Reference< ::com::sun::star::container::XNameAccess >& typeMap )
597 throw (SQLException, RuntimeException)
599 return Any();
602 Reference< ::com::sun::star::sdbc::XRef > BaseResultSet::getRef( sal_Int32 columnIndex )
603 throw (SQLException, RuntimeException)
605 return Reference< com::sun::star::sdbc::XRef > ();
608 Reference< ::com::sun::star::sdbc::XBlob > BaseResultSet::getBlob( sal_Int32 columnIndex )
609 throw (SQLException, RuntimeException)
611 return Reference< com::sun::star::sdbc::XBlob > ();
614 Reference< ::com::sun::star::sdbc::XClob > BaseResultSet::getClob( sal_Int32 columnIndex )
615 throw (SQLException, RuntimeException)
617 return Reference< com::sun::star::sdbc::XClob > ();
620 Reference< ::com::sun::star::sdbc::XArray > BaseResultSet::getArray( sal_Int32 columnIndex )
621 throw (SQLException, RuntimeException)
623 return new Array( m_refMutex, parseArray( getString( columnIndex ) ), *this, m_tc );
627 ::cppu::IPropertyArrayHelper & BaseResultSet::getInfoHelper()
629 return getResultSetPropertyArrayHelper();
633 sal_Bool BaseResultSet::convertFastPropertyValue(
634 Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue )
635 throw (IllegalArgumentException)
637 sal_Bool bRet;
638 switch( nHandle )
640 case BASERESULTSET_CURSOR_NAME:
642 OUString val;
643 bRet = ( rValue >>= val );
644 m_props[nHandle] = makeAny( val );
645 break;
647 case BASERESULTSET_ESCAPE_PROCESSING:
649 sal_Bool val;
650 bRet = ( rValue >>= val );
651 m_props[nHandle] = makeAny( val );
652 break;
654 case BASERESULTSET_FETCH_DIRECTION:
655 case BASERESULTSET_FETCH_SIZE:
656 case BASERESULTSET_RESULT_SET_CONCURRENCY:
657 case BASERESULTSET_RESULT_SET_TYPE:
659 sal_Int32 val;
660 bRet = ( rValue >>= val );
661 m_props[nHandle] = makeAny( val );
662 break;
664 default:
666 OUStringBuffer buf(128);
667 buf.appendAscii( "pq_resultset: Invalid property handle (" );
668 buf.append( nHandle );
669 buf.appendAscii( ")" );
670 throw IllegalArgumentException( buf.makeStringAndClear(), *this, 2 );
673 return bRet;
677 void BaseResultSet::setFastPropertyValue_NoBroadcast(
678 sal_Int32 nHandle,const Any& rValue ) throw (Exception)
680 m_props[nHandle] = rValue;
683 void BaseResultSet::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
685 rValue = m_props[nHandle];
688 Reference < XPropertySetInfo > BaseResultSet::getPropertySetInfo()
689 throw(RuntimeException)
691 return OPropertySetHelper::createPropertySetInfo( getResultSetPropertyArrayHelper() );
694 void BaseResultSet::disposing()
696 close();
699 void BaseResultSet::checkColumnIndex(sal_Int32 index ) throw ( SQLException, RuntimeException )
701 if( index < 1 || index > m_fieldCount )
703 OUStringBuffer buf(128);
704 buf.appendAscii( "pq_resultset: index out of range (" );
705 buf.append( index );
706 buf.appendAscii( ", allowed range is 1 to " );
707 buf.append( m_fieldCount );
708 buf.appendAscii( ")" );
709 throw SQLException( buf.makeStringAndClear(), *this, OUString(), 1, Any() );
714 void BaseResultSet::checkRowIndex( sal_Bool mustBeOnValidRow )
716 OUStringBuffer buf( 128 );
717 buf.appendAscii( "pq_baseresultset: row index out of range, allowed is " );
718 if( mustBeOnValidRow )
720 if( m_row < 0 || m_row >= m_rowCount )
722 buf.appendAscii( "0 to " );
723 buf.append( ((sal_Int32)(m_rowCount -1)) );
724 buf.appendAscii( ", got " );
725 buf.append( m_row );
726 throw SQLException( buf.makeStringAndClear(), *this, OUString(),1, Any() );
729 else
731 if( m_row < -1 || m_row > m_rowCount )
733 buf.appendAscii( "-1 to " );
734 buf.append( m_rowCount );
735 buf.appendAscii( ", got " );
736 buf.append( m_row );
737 throw SQLException( buf.makeStringAndClear(), *this, OUString(),1, Any() );