1 /*************************************************************************
3 * $RCSfile: pq_baseresultset.cxx,v $
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,
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>
78 using osl::MutexGuard
;
81 using rtl::OUStringToOString
;
82 using rtl::OUStringBuffer
;
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
;
124 MutexGuard
guard( Mutex::getGlobalMutex() );
127 static Property aTable
[] =
130 OUString( RTL_CONSTASCII_USTRINGPARAM("CursorName") ), 0,
131 ::getCppuType( (OUString
*)0) , 0 ),
133 OUString( RTL_CONSTASCII_USTRINGPARAM("EscapeProcessing") ), 0,
134 ::getBooleanCppuType() , 0 ),
136 OUString( RTL_CONSTASCII_USTRINGPARAM("FetchDirection") ), 0,
137 ::getCppuType( (sal_Int32
*)0) , 0 ),
139 OUString( RTL_CONSTASCII_USTRINGPARAM("FetchSize") ), 0,
140 ::getCppuType( (sal_Int32
*)0) , 0 ),
142 OUString( RTL_CONSTASCII_USTRINGPARAM("ResultSetConcurrency") ), 0,
143 ::getCppuType( (sal_Int32
*)0) , 0 ),
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
,
161 const Reference
< com::sun::star::script::XTypeConverter
> & tc
)
162 : OComponentHelper( refMutex
->mutex
),
163 OPropertySetHelper( OComponentHelper::rBHelper
),
164 m_refMutex( refMutex
),
167 m_rowCount( rowCount
),
168 m_fieldCount( colCount
),
171 POSTGRE_TRACE( "ctor BaseResultSet" );
174 BaseResultSet::~BaseResultSet()
176 POSTGRE_TRACE( "dtor BaseResultSet" );
179 Any
BaseResultSet::queryInterface( const Type
& reqType
) throw (RuntimeException
)
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 ) );
197 // void BaseResultSet::close( ) throw (SQLException, RuntimeException)
199 // Reference< XInterface > owner;
201 // ResultSetGuard guard(*this);
204 // PQclear(m_result );
213 Sequence
<Type
> BaseResultSet::getTypes() throw( RuntimeException
)
215 static cppu::OTypeCollection
*pCollection
;
218 MutexGuard
guard( osl::Mutex::getGlobalMutex() );
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
;
242 MutexGuard
guard( osl::Mutex::getGlobalMutex() );
245 static cppu::OImplementationId
id(sal_False
);
249 return pId
->getImplementationId();
252 // Reference< XResultSetMetaData > BaseResultSet::getMetaData( ) throw (SQLException, RuntimeException)
254 // ResultSetGuard guard(*this);
256 // return new ResultSetMetaData( m_refMutex, this, &m_result );
259 sal_Bool
BaseResultSet::next( ) throw (SQLException
, RuntimeException
)
261 MutexGuard
guard( m_refMutex
->mutex
);
264 return m_row
< m_rowCount
;
267 sal_Bool
BaseResultSet::isBeforeFirst( ) throw (SQLException
, RuntimeException
)
269 MutexGuard
guard( m_refMutex
->mutex
);
274 sal_Bool
BaseResultSet::isAfterLast( ) throw (SQLException
, RuntimeException
)
276 MutexGuard
guard( m_refMutex
->mutex
);
278 return m_row
>= m_rowCount
;
281 sal_Bool
BaseResultSet::isFirst( ) throw (SQLException
, RuntimeException
)
283 MutexGuard
guard( m_refMutex
->mutex
);
285 return m_row
== 0 && m_rowCount
;
288 sal_Bool
BaseResultSet::isLast( ) throw (SQLException
, RuntimeException
)
290 MutexGuard
guard( m_refMutex
->mutex
);
292 return m_row
>= 0 && m_row
+ 1 == m_rowCount
;
295 void BaseResultSet::beforeFirst( ) throw (SQLException
, RuntimeException
)
297 MutexGuard
guard( m_refMutex
->mutex
);
302 void BaseResultSet::afterLast( ) throw (SQLException
, RuntimeException
)
304 MutexGuard
guard( m_refMutex
->mutex
);
309 sal_Bool
BaseResultSet::first( ) throw (SQLException
, RuntimeException
)
311 MutexGuard
guard( m_refMutex
->mutex
);
313 sal_Bool bRet
= ( m_rowCount
> 0 );
319 sal_Bool
BaseResultSet::last( ) throw (SQLException
, RuntimeException
)
321 MutexGuard
guard( m_refMutex
->mutex
);
323 sal_Bool bRet
= ( m_rowCount
> 0 );
325 m_row
= m_rowCount
-1;
329 sal_Int32
BaseResultSet::getRow( ) throw (SQLException
, RuntimeException
)
331 MutexGuard
guard( m_refMutex
->mutex
);
336 sal_Bool
BaseResultSet::absolute( sal_Int32 row
) throw (SQLException
, RuntimeException
)
338 MutexGuard
guard( m_refMutex
->mutex
);
343 if( m_row
> m_rowCount
)
348 m_row
= m_rowCount
+ row
;
355 sal_Bool
BaseResultSet::relative( sal_Int32 rows
) throw (SQLException
, RuntimeException
)
357 MutexGuard
guard( m_refMutex
->mutex
);
361 if( m_row
> m_rowCount
)
363 else if ( m_row
< -1 )
368 sal_Bool
BaseResultSet::previous( ) throw (SQLException
, RuntimeException
)
370 MutexGuard
guard( m_refMutex
->mutex
);
372 sal_Bool bRet
= ( m_row
!= -1 );
378 void BaseResultSet::refreshRow( ) throw (SQLException
, RuntimeException
)
380 // TODO: not supported for now
383 sal_Bool
BaseResultSet::rowUpdated( ) throw (SQLException
, RuntimeException
)
388 sal_Bool
BaseResultSet::rowInserted( ) throw (SQLException
, RuntimeException
)
393 sal_Bool
BaseResultSet::rowDeleted( ) throw (SQLException
, RuntimeException
)
398 Reference
< XInterface
> BaseResultSet::getStatement() throw (SQLException
, RuntimeException
)
400 MutexGuard
guard( m_refMutex
->mutex
);
406 //----------------- XRow interface ----------------------------------------------------
408 sal_Bool
BaseResultSet::wasNull( ) throw (SQLException
, RuntimeException
)
413 Any
BaseResultSet::convertTo( const Any
& val
, const Type
& type
)
418 aRet
= m_tc
->convertTo( val
, type
);
420 catch( com::sun::star::lang::IllegalArgumentException
& e
)
422 catch( com::sun::star::script::CannotConvertException
& e
)
427 sal_Bool
BaseResultSet::getBoolean( sal_Int32 columnIndex
) throw (SQLException
, RuntimeException
)
429 MutexGuard
guard( m_refMutex
->mutex
);
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 )
454 sal_Int8
BaseResultSet::getByte( sal_Int32 columnIndex
)
455 throw (SQLException
, RuntimeException
)
457 MutexGuard
guard( m_refMutex
->mutex
);
459 checkColumnIndex( columnIndex
);
460 checkRowIndex( sal_True
/* must be on row */ );
462 convertTo( getValue( columnIndex
), getCppuType( &b
)) >>= b
;
466 sal_Int16
BaseResultSet::getShort( sal_Int32 columnIndex
)
467 throw (SQLException
, RuntimeException
)
469 MutexGuard
guard( m_refMutex
->mutex
);
471 checkColumnIndex( columnIndex
);
472 checkRowIndex( sal_True
/* must be on row */ );
474 convertTo( getValue( columnIndex
), getCppuType( &i
)) >>= i
;
478 OUString
BaseResultSet::getString( sal_Int32 columnIndex
) throw (SQLException
, RuntimeException
)
480 MutexGuard
guard(m_refMutex
->mutex
);
482 checkColumnIndex( columnIndex
);
483 checkRowIndex( sal_True
/* must be on row */ );
485 convertTo( getValue( columnIndex
), getCppuType( &ret
) ) >>= ret
;
486 // printf( "BaseResultSet::getString() %s\n" , OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ).getStr() );
490 sal_Int32
BaseResultSet::getInt( sal_Int32 columnIndex
)
491 throw (SQLException
, RuntimeException
)
493 MutexGuard
guard( m_refMutex
->mutex
);
495 checkColumnIndex( columnIndex
);
496 checkRowIndex( sal_True
/* must be on row */ );
498 convertTo( getValue( columnIndex
), getCppuType( &i
)) >>= i
;
502 sal_Int64
BaseResultSet::getLong( sal_Int32 columnIndex
)
503 throw (SQLException
, RuntimeException
)
505 MutexGuard
guard( m_refMutex
->mutex
);
507 checkColumnIndex( columnIndex
);
508 checkRowIndex( sal_True
/* must be on row */ );
510 convertTo( getValue( columnIndex
), getCppuType( &i
)) >>= i
;
514 float BaseResultSet::getFloat( sal_Int32 columnIndex
)
515 throw (SQLException
, RuntimeException
)
517 MutexGuard
guard( m_refMutex
->mutex
);
519 checkColumnIndex( columnIndex
);
520 checkRowIndex( sal_True
/* must be on row */ );
522 convertTo( getValue( columnIndex
), getCppuType( &f
)) >>= f
;
526 double BaseResultSet::getDouble( sal_Int32 columnIndex
)
527 throw (SQLException
, RuntimeException
)
529 MutexGuard
guard( m_refMutex
->mutex
);
531 checkColumnIndex( columnIndex
);
533 convertTo( getValue( columnIndex
), getCppuType( &d
)) >>= d
;
537 Sequence
< sal_Int8
> BaseResultSet::getBytes( sal_Int32 columnIndex
)
538 throw (SQLException
, RuntimeException
)
540 MutexGuard
guard( m_refMutex
->mutex
);
542 checkColumnIndex( columnIndex
);
543 checkRowIndex( sal_True
/* must be on row */ );
545 Sequence
< sal_Int8
> ret
;
547 if( ! (getValue( columnIndex
) >>= ustr
) )
551 // if this is a binary, it must contain escaped data !
552 OString val
= rtl::OUStringToOString( ustr
, RTL_TEXTENCODING_ASCII_US
);
555 char * res
= (char*) PQunescapeBytea( (unsigned char *)val
.getStr() , &length
);
556 ret
= Sequence
< sal_Int8
> ( (sal_Int8
*)res
, length
);
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
)
588 Reference
< ::com::sun::star::io::XInputStream
> BaseResultSet::getCharacterStream( sal_Int32 columnIndex
)
589 throw (SQLException
, RuntimeException
)
594 Any
BaseResultSet::getObject(
595 sal_Int32 columnIndex
,
596 const Reference
< ::com::sun::star::container::XNameAccess
>& typeMap
)
597 throw (SQLException
, RuntimeException
)
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
)
640 case BASERESULTSET_CURSOR_NAME
:
643 bRet
= ( rValue
>>= val
);
644 m_props
[nHandle
] = makeAny( val
);
647 case BASERESULTSET_ESCAPE_PROCESSING
:
650 bRet
= ( rValue
>>= val
);
651 m_props
[nHandle
] = makeAny( val
);
654 case BASERESULTSET_FETCH_DIRECTION
:
655 case BASERESULTSET_FETCH_SIZE
:
656 case BASERESULTSET_RESULT_SET_CONCURRENCY
:
657 case BASERESULTSET_RESULT_SET_TYPE
:
660 bRet
= ( rValue
>>= val
);
661 m_props
[nHandle
] = makeAny( val
);
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 );
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()
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 (" );
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 " );
726 throw SQLException( buf
.makeStringAndClear(), *this, OUString(),1, Any() );
731 if( m_row
< -1 || m_row
> m_rowCount
)
733 buf
.appendAscii( "-1 to " );
734 buf
.append( m_rowCount
);
735 buf
.appendAscii( ", got " );
737 throw SQLException( buf
.makeStringAndClear(), *this, OUString(),1, Any() );