1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * Effective License of whole file:
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.
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.
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,
20 * Parts "Copyright by Sun Microsystems, Inc" prior to August 2011:
22 * The Contents of this file are made available subject to the terms of
23 * the GNU Lesser General Public License Version 2.1
25 * Copyright: 2000 by Sun Microsystems, Inc.
27 * Contributor(s): Joerg Budischewski
29 * All parts contributed on or after August 2011:
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/.
35 ************************************************************************/
37 #include <comphelper/sequence.hxx>
39 #include "pq_tools.hxx"
40 #include "pq_array.hxx"
41 #include "pq_baseresultset.hxx"
43 #include <com/sun/star/script/CannotConvertException.hpp>
44 #include <com/sun/star/sdbc/SQLException.hpp>
45 #include <connectivity/dbconversion.hxx>
47 using osl::MutexGuard
;
50 using com::sun::star::beans::XPropertySetInfo
;
52 using com::sun::star::uno::Any
;
53 using com::sun::star::uno::Type
;
54 using com::sun::star::uno::Sequence
;
55 using com::sun::star::uno::Reference
;
56 using com::sun::star::uno::XInterface
;
58 using com::sun::star::lang::IllegalArgumentException
;
60 using com::sun::star::sdbc::SQLException
;
63 using com::sun::star::beans::Property
;
65 using namespace dbtools
;
67 namespace pq_sdbc_driver
69 static ::cppu::IPropertyArrayHelper
& getResultSetPropertyArrayHelper()
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 u
"CursorName"_ustr
, 0,
78 ::cppu::UnoType
<OUString
>::get() , 0 ),
80 u
"EscapeProcessing"_ustr
, 1,
81 cppu::UnoType
<bool>::get() , 0 ),
83 u
"FetchDirection"_ustr
, 2,
84 ::cppu::UnoType
<sal_Int32
>::get() , 0 ),
87 ::cppu::UnoType
<sal_Int32
>::get() , 0 ),
89 u
"IsBookmarkable"_ustr
, 4,
90 cppu::UnoType
<bool>::get() , 0 ),
92 u
"ResultSetConcurrency"_ustr
, 5,
93 ::cppu::UnoType
<sal_Int32
>::get() , 0 ),
95 u
"ResultSetType"_ustr
, 6,
96 ::cppu::UnoType
<sal_Int32
>::get() , 0 )},
101 BaseResultSet::BaseResultSet(
102 const ::rtl::Reference
< comphelper::RefCountedMutex
> & refMutex
,
103 const Reference
< XInterface
> & owner
,
106 const Reference
< css::script::XTypeConverter
> & tc
)
107 : BaseResultSet_BASE( refMutex
->GetMutex() )
108 , OPropertySetHelper( BaseResultSet_BASE::rBHelper
)
111 , m_xMutex( refMutex
)
113 , m_rowCount( rowCount
)
114 , m_fieldCount( colCount
)
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 :(
122 BaseResultSet::~BaseResultSet()
126 Any
BaseResultSet::queryInterface( const Type
& rType
)
128 Any aRet
= BaseResultSet_BASE::queryInterface(rType
);
129 return aRet
.hasValue() ? aRet
: OPropertySetHelper::queryInterface(rType
);
132 // void BaseResultSet::close( ) throw (SQLException, RuntimeException)
134 // Reference< XInterface > owner;
136 // ResultSetGuard guard(*this);
139 // PQclear(m_result );
148 Sequence
<Type
> BaseResultSet::getTypes()
150 static Sequence
< Type
> collection(
151 ::comphelper::concatSequences(
152 OPropertySetHelper::getTypes(),
153 BaseResultSet_BASE::getTypes()));
157 Sequence
< sal_Int8
> BaseResultSet::getImplementationId()
159 return css::uno::Sequence
<sal_Int8
>();
162 // Reference< XResultSetMetaData > BaseResultSet::getMetaData( ) throw (SQLException, RuntimeException)
164 // ResultSetGuard guard(*this);
166 // return new ResultSetMetaData( m_xMutex, this, &m_result );
169 sal_Bool
BaseResultSet::next( )
171 MutexGuard
guard( m_xMutex
->GetMutex() );
174 return m_row
< m_rowCount
;
177 sal_Bool
BaseResultSet::isBeforeFirst( )
179 MutexGuard
guard( m_xMutex
->GetMutex() );
184 sal_Bool
BaseResultSet::isAfterLast( )
186 MutexGuard
guard( m_xMutex
->GetMutex() );
188 return m_row
>= m_rowCount
;
191 sal_Bool
BaseResultSet::isFirst( )
193 MutexGuard
guard( m_xMutex
->GetMutex() );
195 return m_row
== 0 && m_rowCount
;
198 sal_Bool
BaseResultSet::isLast( )
200 MutexGuard
guard( m_xMutex
->GetMutex() );
202 return m_row
>= 0 && m_row
+ 1 == m_rowCount
;
205 void BaseResultSet::beforeFirst( )
207 MutexGuard
guard( m_xMutex
->GetMutex() );
212 void BaseResultSet::afterLast( )
214 MutexGuard
guard( m_xMutex
->GetMutex() );
219 sal_Bool
BaseResultSet::first( )
221 MutexGuard
guard( m_xMutex
->GetMutex() );
223 bool bRet
= ( m_rowCount
> 0 );
229 sal_Bool
BaseResultSet::last( )
231 MutexGuard
guard( m_xMutex
->GetMutex() );
233 bool bRet
= ( m_rowCount
> 0 );
235 m_row
= m_rowCount
-1;
239 sal_Int32
BaseResultSet::getRow( )
241 MutexGuard
guard( m_xMutex
->GetMutex() );
246 sal_Bool
BaseResultSet::absolute( sal_Int32 row
)
248 MutexGuard
guard( m_xMutex
->GetMutex() );
253 if( m_row
> m_rowCount
)
258 m_row
= m_rowCount
+ row
;
265 sal_Bool
BaseResultSet::relative( sal_Int32 rows
)
267 MutexGuard
guard( m_xMutex
->GetMutex() );
271 if( m_row
> m_rowCount
)
273 else if ( m_row
< -1 )
278 sal_Bool
BaseResultSet::previous( )
280 MutexGuard
guard( m_xMutex
->GetMutex() );
282 bool bRet
= ( m_row
!= -1 );
288 void BaseResultSet::refreshRow( )
290 // TODO: not supported for now
293 sal_Bool
BaseResultSet::rowUpdated( )
298 sal_Bool
BaseResultSet::rowInserted( )
303 sal_Bool
BaseResultSet::rowDeleted( )
308 Reference
< XInterface
> BaseResultSet::getStatement()
310 MutexGuard
guard( m_xMutex
->GetMutex() );
316 //----------------- XRow interface ----------------------------------------------------
318 sal_Bool
BaseResultSet::wasNull( )
323 Any
BaseResultSet::convertTo( const Any
& val
, const Type
& type
)
328 aRet
= m_tc
->convertTo( val
, type
);
330 catch( css::lang::IllegalArgumentException
& )
332 catch( css::script::CannotConvertException
& )
337 sal_Bool
BaseResultSet::getBoolean( sal_Int32 columnIndex
)
339 MutexGuard
guard( m_xMutex
->GetMutex() );
341 checkColumnIndex( columnIndex
);
344 OUString str
= getString( columnIndex
);
346 if( str
.getLength() > 0 )
362 sal_Int8
BaseResultSet::getByte( sal_Int32 columnIndex
)
364 MutexGuard
guard( m_xMutex
->GetMutex() );
366 checkColumnIndex( columnIndex
);
369 convertTo( getValue( columnIndex
), cppu::UnoType
<decltype(b
)>::get()) >>= b
;
373 sal_Int16
BaseResultSet::getShort( sal_Int32 columnIndex
)
375 MutexGuard
guard( m_xMutex
->GetMutex() );
377 checkColumnIndex( columnIndex
);
380 convertTo( getValue( columnIndex
), cppu::UnoType
<decltype(i
)>::get()) >>= i
;
384 OUString
BaseResultSet::getString( sal_Int32 columnIndex
)
386 MutexGuard
guard(m_xMutex
->GetMutex());
388 checkColumnIndex( columnIndex
);
391 convertTo( getValue( columnIndex
), cppu::UnoType
<decltype(ret
)>::get() ) >>= ret
;
392 // printf( "BaseResultSet::getString() %s\n" , OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ).getStr() );
396 sal_Int32
BaseResultSet::getInt( sal_Int32 columnIndex
)
398 MutexGuard
guard( m_xMutex
->GetMutex() );
400 checkColumnIndex( columnIndex
);
403 convertTo( getValue( columnIndex
), cppu::UnoType
<decltype(i
)>::get()) >>= i
;
407 sal_Int64
BaseResultSet::getLong( sal_Int32 columnIndex
)
409 MutexGuard
guard( m_xMutex
->GetMutex() );
411 checkColumnIndex( columnIndex
);
414 convertTo( getValue( columnIndex
), cppu::UnoType
<decltype(i
)>::get()) >>= i
;
418 float BaseResultSet::getFloat( sal_Int32 columnIndex
)
420 MutexGuard
guard( m_xMutex
->GetMutex() );
422 checkColumnIndex( columnIndex
);
425 convertTo( getValue( columnIndex
), cppu::UnoType
<decltype(f
)>::get()) >>= f
;
429 double BaseResultSet::getDouble( sal_Int32 columnIndex
)
431 MutexGuard
guard( m_xMutex
->GetMutex() );
433 checkColumnIndex( columnIndex
);
435 convertTo( getValue( columnIndex
), cppu::UnoType
<decltype(d
)>::get()) >>= d
;
439 Sequence
< sal_Int8
> BaseResultSet::getBytes( sal_Int32 columnIndex
)
441 MutexGuard
guard( m_xMutex
->GetMutex() );
443 checkColumnIndex( columnIndex
);
446 Sequence
< sal_Int8
> ret
;
448 if( ! (getValue( columnIndex
) >>= ustr
) )
452 // if this is a binary, it must contain escaped data !
453 OString val
= OUStringToOString( ustr
, RTL_TEXTENCODING_ASCII_US
);
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
);
465 css::util::Date
BaseResultSet::getDate( sal_Int32 columnIndex
)
467 return DBTypeConversion::toDate( getString( columnIndex
) );
470 css::util::Time
BaseResultSet::getTime( sal_Int32 columnIndex
)
472 return DBTypeConversion::toTime( getString( columnIndex
) );
475 css::util::DateTime
BaseResultSet::getTimestamp( sal_Int32 columnIndex
)
477 return DBTypeConversion::toDateTime( getString( columnIndex
) );
480 // LEM TODO: these look like they are missing an actual implementation
481 Reference
< css::io::XInputStream
> BaseResultSet::getBinaryStream( sal_Int32
/* columnIndex */ )
486 Reference
< css::io::XInputStream
> BaseResultSet::getCharacterStream( sal_Int32
/* columnIndex */ )
491 Any
BaseResultSet::getObject(
492 sal_Int32
/* columnIndex */,
493 const Reference
< css::container::XNameAccess
>& /* typeMap */ )
498 Reference
< css::sdbc::XRef
> BaseResultSet::getRef( sal_Int32
/* columnIndex */ )
500 return Reference
< css::sdbc::XRef
> ();
503 Reference
< css::sdbc::XBlob
> BaseResultSet::getBlob( sal_Int32
/* columnIndex */ )
505 return Reference
< css::sdbc::XBlob
> ();
508 Reference
< css::sdbc::XClob
> BaseResultSet::getClob( sal_Int32
/* columnIndex */ )
510 return Reference
< css::sdbc::XClob
> ();
513 Reference
< css::sdbc::XArray
> BaseResultSet::getArray( sal_Int32 columnIndex
)
515 return new Array( m_xMutex
, parseArray( getString( columnIndex
) ), *this, m_tc
);
518 ::cppu::IPropertyArrayHelper
& BaseResultSet::getInfoHelper()
520 return getResultSetPropertyArrayHelper();
523 sal_Bool
BaseResultSet::convertFastPropertyValue(
524 Any
& /* rConvertedValue */, Any
& /* rOldValue */, sal_Int32 nHandle
, const Any
& rValue
)
529 case BASERESULTSET_CURSOR_NAME
:
532 bRet
= ( rValue
>>= val
);
533 m_props
[nHandle
] <<= val
;
536 case BASERESULTSET_ESCAPE_PROCESSING
:
537 case BASERESULTSET_IS_BOOKMARKABLE
:
540 bRet
= ( rValue
>>= val
);
541 m_props
[nHandle
] <<= val
;
544 case BASERESULTSET_FETCH_DIRECTION
:
545 case BASERESULTSET_FETCH_SIZE
:
546 case BASERESULTSET_RESULT_SET_CONCURRENCY
:
547 case BASERESULTSET_RESULT_SET_TYPE
:
550 bRet
= ( rValue
>>= val
);
551 m_props
[nHandle
] <<= val
;
556 throw IllegalArgumentException(
557 "pq_resultset: Invalid property handle (" + OUString::number( nHandle
) + ")",
565 void BaseResultSet::setFastPropertyValue_NoBroadcast(
566 sal_Int32 nHandle
,const Any
& rValue
)
568 m_props
[nHandle
] = rValue
;
571 void BaseResultSet::getFastPropertyValue( Any
& rValue
, sal_Int32 nHandle
) const
573 rValue
= m_props
[nHandle
];
576 Reference
< XPropertySetInfo
> BaseResultSet::getPropertySetInfo()
578 return OPropertySetHelper::createPropertySetInfo( getResultSetPropertyArrayHelper() );
581 void BaseResultSet::disposing()
586 void BaseResultSet::checkColumnIndex(sal_Int32 index
)
588 if( index
< 1 || index
> m_fieldCount
)
591 "pq_resultset: index out of range ("
592 + OUString::number( index
)
593 + ", allowed range is 1 to " + OUString::number( m_fieldCount
)
595 *this, OUString(), 1, Any() );
600 void BaseResultSet::checkRowIndex()
602 if( m_row
< 0 || m_row
>= m_rowCount
)
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() );
613 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */