summaryrefslogtreecommitdiffstats
path: root/connectivity/source/drivers/postgresql/pq_baseresultset.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'connectivity/source/drivers/postgresql/pq_baseresultset.cxx')
-rw-r--r--connectivity/source/drivers/postgresql/pq_baseresultset.cxx613
1 files changed, 613 insertions, 0 deletions
diff --git a/connectivity/source/drivers/postgresql/pq_baseresultset.cxx b/connectivity/source/drivers/postgresql/pq_baseresultset.cxx
new file mode 100644
index 000000000..9ff5e01e0
--- /dev/null
+++ b/connectivity/source/drivers/postgresql/pq_baseresultset.cxx
@@ -0,0 +1,613 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * Effective License of whole file:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Parts "Copyright by Sun Microsystems, Inc" prior to August 2011:
+ *
+ * The Contents of this file are made available subject to the terms of
+ * the GNU Lesser General Public License Version 2.1
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * Contributor(s): Joerg Budischewski
+ *
+ * All parts contributed on or after August 2011:
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ ************************************************************************/
+
+#include <comphelper/sequence.hxx>
+
+#include "pq_tools.hxx"
+#include "pq_array.hxx"
+#include "pq_baseresultset.hxx"
+
+#include <com/sun/star/script/CannotConvertException.hpp>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <connectivity/dbconversion.hxx>
+
+using osl::MutexGuard;
+
+
+using com::sun::star::beans::XPropertySetInfo;
+
+using com::sun::star::uno::Any;
+using com::sun::star::uno::Type;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::XInterface;
+
+using com::sun::star::lang::IllegalArgumentException;
+
+using com::sun::star::sdbc::SQLException;
+
+
+using com::sun::star::beans::Property;
+
+using namespace dbtools;
+
+namespace pq_sdbc_driver
+{
+static ::cppu::IPropertyArrayHelper & getResultSetPropertyArrayHelper()
+{
+ // LEM TODO: this needs to be kept in sync with other, e.g. pq_statics.css:508
+ // Should really share!
+ // At least use for the handles the #define'd values in .hxx file...
+ static ::cppu::OPropertyArrayHelper arrayHelper(
+ Sequence<Property>{
+ Property(
+ "CursorName", 0,
+ ::cppu::UnoType<OUString>::get() , 0 ),
+ Property(
+ "EscapeProcessing", 1,
+ cppu::UnoType<bool>::get() , 0 ),
+ Property(
+ "FetchDirection", 2,
+ ::cppu::UnoType<sal_Int32>::get() , 0 ),
+ Property(
+ "FetchSize", 3,
+ ::cppu::UnoType<sal_Int32>::get() , 0 ),
+ Property(
+ "IsBookmarkable", 4,
+ cppu::UnoType<bool>::get() , 0 ),
+ Property(
+ "ResultSetConcurrency", 5,
+ ::cppu::UnoType<sal_Int32>::get() , 0 ),
+ Property(
+ "ResultSetType", 6,
+ ::cppu::UnoType<sal_Int32>::get() , 0 )},
+ true );
+ return arrayHelper;
+}
+
+BaseResultSet::BaseResultSet(
+ const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
+ const Reference< XInterface > & owner,
+ sal_Int32 rowCount,
+ sal_Int32 colCount,
+ const Reference< css::script::XTypeConverter > & tc )
+ : BaseResultSet_BASE( refMutex->GetMutex() )
+ , OPropertySetHelper( BaseResultSet_BASE::rBHelper )
+ , m_owner( owner )
+ , m_tc( tc )
+ , m_xMutex( refMutex )
+ , m_row( -1 )
+ , m_rowCount( rowCount )
+ , m_fieldCount( colCount )
+ , m_wasNull(false)
+{
+}
+
+// LEM TODO: refMutex->GetMutex() should live longer than OComponentHelper,
+// but calling OComponentHelper::dispose explicitly here calls
+// BaseResultSet::~BaseResultSet in an infinite loop :(
+BaseResultSet::~BaseResultSet()
+{
+}
+
+Any BaseResultSet::queryInterface( const Type & rType )
+{
+ Any aRet = BaseResultSet_BASE::queryInterface(rType);
+ return aRet.hasValue() ? aRet : OPropertySetHelper::queryInterface(rType);
+}
+
+// void BaseResultSet::close( ) throw (SQLException, RuntimeException)
+// {
+// Reference< XInterface > owner;
+// {
+// ResultSetGuard guard(*this);
+// if( m_result )
+// {
+// PQclear(m_result );
+// m_result = 0;
+// m_row = -1;
+// }
+// owner = m_owner;
+// m_owner.clear();
+// }
+// }
+
+Sequence<Type > BaseResultSet::getTypes()
+{
+ static Sequence< Type > collection(
+ ::comphelper::concatSequences(
+ OPropertySetHelper::getTypes(),
+ BaseResultSet_BASE::getTypes()));
+ return collection;
+}
+
+Sequence< sal_Int8> BaseResultSet::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+// Reference< XResultSetMetaData > BaseResultSet::getMetaData( ) throw (SQLException, RuntimeException)
+// {
+// ResultSetGuard guard(*this);
+// checkClosed();
+// return new ResultSetMetaData( m_xMutex, this, &m_result );
+// }
+
+sal_Bool BaseResultSet::next( )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ m_row ++;
+ return m_row < m_rowCount;
+}
+
+sal_Bool BaseResultSet::isBeforeFirst( )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ return m_row == -1;
+}
+
+sal_Bool BaseResultSet::isAfterLast( )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ return m_row >= m_rowCount;
+}
+
+sal_Bool BaseResultSet::isFirst( )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ return m_row == 0 && m_rowCount;
+}
+
+sal_Bool BaseResultSet::isLast( )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ return m_row >= 0 && m_row + 1 == m_rowCount;
+}
+
+void BaseResultSet::beforeFirst( )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ m_row = -1;
+}
+
+void BaseResultSet::afterLast( )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ m_row = m_rowCount;
+}
+
+sal_Bool BaseResultSet::first( )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ bool bRet = ( m_rowCount > 0 );
+ if( bRet )
+ m_row = 0;
+ return bRet;
+}
+
+sal_Bool BaseResultSet::last( )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ bool bRet = ( m_rowCount > 0 );
+ if( bRet )
+ m_row = m_rowCount -1;
+ return bRet;
+}
+
+sal_Int32 BaseResultSet::getRow( )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ return m_row +1;
+}
+
+sal_Bool BaseResultSet::absolute( sal_Int32 row )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ if( row > 0 )
+ {
+ m_row = row -1;
+ if( m_row > m_rowCount )
+ m_row = m_rowCount;
+ }
+ else
+ {
+ m_row = m_rowCount + row;
+ if( m_row < -1 )
+ m_row = -1;
+ }
+ return true;
+}
+
+sal_Bool BaseResultSet::relative( sal_Int32 rows )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ m_row += rows;
+
+ if( m_row > m_rowCount )
+ m_row = m_rowCount;
+ else if ( m_row < -1 )
+ m_row = -1;
+ return true;
+}
+
+sal_Bool BaseResultSet::previous( )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ bool bRet = ( m_row != -1 );
+ if( bRet )
+ m_row --;
+ return bRet;
+}
+
+void BaseResultSet::refreshRow( )
+{
+ // TODO: not supported for now
+}
+
+sal_Bool BaseResultSet::rowUpdated( )
+{
+ return false;
+}
+
+sal_Bool BaseResultSet::rowInserted( )
+{
+ return false;
+}
+
+sal_Bool BaseResultSet::rowDeleted( )
+{
+ return false;
+}
+
+Reference< XInterface > BaseResultSet::getStatement()
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ return m_owner;
+}
+
+
+//----------------- XRow interface ----------------------------------------------------
+
+sal_Bool BaseResultSet::wasNull( )
+{
+ return m_wasNull;
+}
+
+Any BaseResultSet::convertTo( const Any & val , const Type & type )
+{
+ Any aRet;
+ try
+ {
+ aRet = m_tc->convertTo( val , type );
+ }
+ catch( css::lang::IllegalArgumentException & )
+ {}
+ catch( css::script::CannotConvertException & )
+ {}
+ return aRet;
+}
+
+sal_Bool BaseResultSet::getBoolean( sal_Int32 columnIndex )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ checkColumnIndex( columnIndex );
+ checkRowIndex();
+
+ OUString str = getString( columnIndex );
+
+ if( str.getLength() > 0 )
+ {
+ switch(str[0])
+ {
+ case '1':
+ case 't':
+ case 'T':
+ case 'y':
+ case 'Y':
+
+ return true;
+ }
+ }
+ return false;
+}
+
+sal_Int8 BaseResultSet::getByte( sal_Int32 columnIndex )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ checkColumnIndex( columnIndex );
+ checkRowIndex();
+ sal_Int8 b = 0;
+ convertTo( getValue( columnIndex ), cppu::UnoType<decltype(b)>::get()) >>= b;
+ return b;
+}
+
+sal_Int16 BaseResultSet::getShort( sal_Int32 columnIndex )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ checkColumnIndex( columnIndex );
+ checkRowIndex();
+ sal_Int16 i = 0;
+ convertTo( getValue( columnIndex ), cppu::UnoType<decltype(i)>::get()) >>= i;
+ return i;
+}
+
+OUString BaseResultSet::getString( sal_Int32 columnIndex )
+{
+ MutexGuard guard(m_xMutex->GetMutex());
+ checkClosed();
+ checkColumnIndex( columnIndex );
+ checkRowIndex();
+ OUString ret;
+ convertTo( getValue( columnIndex ), cppu::UnoType<decltype(ret)>::get() ) >>= ret;
+// printf( "BaseResultSet::getString() %s\n" , OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ return ret;
+}
+
+sal_Int32 BaseResultSet::getInt( sal_Int32 columnIndex )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ checkColumnIndex( columnIndex );
+ checkRowIndex();
+ sal_Int32 i = 0;
+ convertTo( getValue( columnIndex ), cppu::UnoType<decltype(i)>::get()) >>= i;
+ return i;
+}
+
+sal_Int64 BaseResultSet::getLong( sal_Int32 columnIndex )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ checkColumnIndex( columnIndex );
+ checkRowIndex();
+ sal_Int64 i = 0;
+ convertTo( getValue( columnIndex ), cppu::UnoType<decltype(i)>::get()) >>= i;
+ return i;
+}
+
+float BaseResultSet::getFloat( sal_Int32 columnIndex )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ checkColumnIndex( columnIndex );
+ checkRowIndex();
+ float f = 0.;
+ convertTo( getValue( columnIndex ), cppu::UnoType<decltype(f)>::get()) >>= f;
+ return f;
+}
+
+double BaseResultSet::getDouble( sal_Int32 columnIndex )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ checkColumnIndex( columnIndex );
+ double d = 0.;
+ convertTo( getValue( columnIndex ), cppu::UnoType<decltype(d)>::get()) >>= d;
+ return d;
+}
+
+Sequence< sal_Int8 > BaseResultSet::getBytes( sal_Int32 columnIndex )
+{
+ MutexGuard guard( m_xMutex->GetMutex() );
+ checkClosed();
+ checkColumnIndex( columnIndex );
+ checkRowIndex();
+
+ Sequence< sal_Int8 > ret;
+ OUString ustr;
+ if( ! (getValue( columnIndex ) >>= ustr) )
+ m_wasNull = true;
+ else
+ {
+ // if this is a binary, it must contain escaped data !
+ OString val = OUStringToOString( ustr, RTL_TEXTENCODING_ASCII_US );
+
+ size_t length;
+ char * res = reinterpret_cast<char*>(PQunescapeBytea( reinterpret_cast<unsigned char const *>(val.getStr()), &length));
+ ret = Sequence< sal_Int8 > ( reinterpret_cast<sal_Int8*>(res), length );
+ if( res )
+ PQfreemem( res );
+ }
+ return ret;
+}
+
+
+css::util::Date BaseResultSet::getDate( sal_Int32 columnIndex )
+{
+ return DBTypeConversion::toDate( getString( columnIndex ) );
+}
+
+css::util::Time BaseResultSet::getTime( sal_Int32 columnIndex )
+{
+ return DBTypeConversion::toTime( getString( columnIndex ) );
+}
+
+css::util::DateTime BaseResultSet::getTimestamp( sal_Int32 columnIndex )
+{
+ return DBTypeConversion::toDateTime( getString( columnIndex ) );
+}
+
+ // LEM TODO: these look like they are missing an actual implementation
+Reference< css::io::XInputStream > BaseResultSet::getBinaryStream( sal_Int32 /* columnIndex */ )
+{
+ return nullptr;
+}
+
+Reference< css::io::XInputStream > BaseResultSet::getCharacterStream( sal_Int32 /* columnIndex */ )
+{
+ return nullptr;
+}
+
+Any BaseResultSet::getObject(
+ sal_Int32 /* columnIndex */,
+ const Reference< css::container::XNameAccess >& /* typeMap */ )
+{
+ return Any();
+}
+
+Reference< css::sdbc::XRef > BaseResultSet::getRef( sal_Int32 /* columnIndex */ )
+{
+ return Reference< css::sdbc::XRef > ();
+}
+
+Reference< css::sdbc::XBlob > BaseResultSet::getBlob( sal_Int32 /* columnIndex */ )
+{
+ return Reference< css::sdbc::XBlob > ();
+}
+
+Reference< css::sdbc::XClob > BaseResultSet::getClob( sal_Int32 /* columnIndex */ )
+{
+ return Reference< css::sdbc::XClob > ();
+}
+
+Reference< css::sdbc::XArray > BaseResultSet::getArray( sal_Int32 columnIndex )
+{
+ return new Array( m_xMutex, parseArray( getString( columnIndex ) ), *this, m_tc );
+}
+
+::cppu::IPropertyArrayHelper & BaseResultSet::getInfoHelper()
+{
+ return getResultSetPropertyArrayHelper();
+}
+
+sal_Bool BaseResultSet::convertFastPropertyValue(
+ Any & /* rConvertedValue */, Any & /* rOldValue */, sal_Int32 nHandle, const Any& rValue )
+{
+ bool bRet;
+ switch( nHandle )
+ {
+ case BASERESULTSET_CURSOR_NAME:
+ {
+ OUString val;
+ bRet = ( rValue >>= val );
+ m_props[nHandle] <<= val;
+ break;
+ }
+ case BASERESULTSET_ESCAPE_PROCESSING:
+ case BASERESULTSET_IS_BOOKMARKABLE:
+ {
+ bool val(false);
+ bRet = ( rValue >>= val );
+ m_props[nHandle] <<= val;
+ break;
+ }
+ case BASERESULTSET_FETCH_DIRECTION:
+ case BASERESULTSET_FETCH_SIZE:
+ case BASERESULTSET_RESULT_SET_CONCURRENCY:
+ case BASERESULTSET_RESULT_SET_TYPE:
+ {
+ sal_Int32 val;
+ bRet = ( rValue >>= val );
+ m_props[nHandle] <<= val;
+ break;
+ }
+ default:
+ {
+ throw IllegalArgumentException(
+ "pq_resultset: Invalid property handle (" + OUString::number( nHandle ) + ")",
+ *this, 2 );
+ }
+ }
+ return bRet;
+}
+
+
+void BaseResultSet::setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle,const Any& rValue )
+{
+ m_props[nHandle] = rValue;
+}
+
+void BaseResultSet::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
+{
+ rValue = m_props[nHandle];
+}
+
+Reference < XPropertySetInfo > BaseResultSet::getPropertySetInfo()
+{
+ return OPropertySetHelper::createPropertySetInfo( getResultSetPropertyArrayHelper() );
+}
+
+void BaseResultSet::disposing()
+{
+ close();
+}
+
+void BaseResultSet::checkColumnIndex(sal_Int32 index )
+{
+ if( index < 1 || index > m_fieldCount )
+ {
+ throw SQLException(
+ "pq_resultset: index out of range ("
+ + OUString::number( index )
+ + ", allowed range is 1 to " + OUString::number( m_fieldCount )
+ + ")",
+ *this, OUString(), 1, Any() );
+ }
+
+}
+
+void BaseResultSet::checkRowIndex()
+{
+ if( m_row < 0 || m_row >= m_rowCount )
+ {
+ throw SQLException(
+ "pq_baseresultset: row index out of range, allowed is 0 to " + OUString::number( m_rowCount -1 )
+ + ", got " + OUString::number( m_row ),
+ *this, OUString(),1, Any() );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */