LCOV - code coverage report
Current view: top level - libreoffice/connectivity/source/drivers/postgresql - pq_statement.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 448 0.0 %
Date: 2012-12-27 Functions: 0 34 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             :  *    Version: MPL 1.1 / GPLv3+ / LGPLv2.1+
      32             :  *
      33             :  *    The contents of this file are subject to the Mozilla Public License Version
      34             :  *    1.1 (the "License"); you may not use this file except in compliance with
      35             :  *    the License or as specified alternatively below. You may obtain a copy of
      36             :  *    the License at http://www.mozilla.org/MPL/
      37             :  *
      38             :  *    Software distributed under the License is distributed on an "AS IS" basis,
      39             :  *    WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      40             :  *    for the specific language governing rights and limitations under the
      41             :  *    License.
      42             :  *
      43             :  *    Major Contributor(s):
      44             :  *    [ Copyright (C) 2011 Lionel Elie Mamane <lionel@mamane.lu> ]
      45             :  *
      46             :  *    All Rights Reserved.
      47             :  *
      48             :  *    For minor contributions see the git repository.
      49             :  *
      50             :  *    Alternatively, the contents of this file may be used under the terms of
      51             :  *    either the GNU General Public License Version 3 or later (the "GPLv3+"), or
      52             :  *    the GNU Lesser General Public License Version 2.1 or later (the "LGPLv2.1+"),
      53             :  *    in which case the provisions of the GPLv3+ or the LGPLv2.1+ are applicable
      54             :  *    instead of those above.
      55             :  *
      56             :  ************************************************************************/
      57             : 
      58             : #include "pq_statement.hxx"
      59             : #include "pq_fakedupdateableresultset.hxx"
      60             : #include "pq_updateableresultset.hxx"
      61             : #include "pq_tools.hxx"
      62             : #include "pq_statics.hxx"
      63             : 
      64             : #include <osl/thread.h>
      65             : #include <osl/time.h>
      66             : 
      67             : #include <rtl/ustrbuf.hxx>
      68             : #include <rtl/strbuf.hxx>
      69             : 
      70             : #include <cppuhelper/typeprovider.hxx>
      71             : #include <cppuhelper/queryinterface.hxx>
      72             : 
      73             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      74             : 
      75             : #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
      76             : #include <com/sun/star/sdbc/ResultSetType.hpp>
      77             : #include <com/sun/star/sdbc/XParameters.hpp>
      78             : 
      79             : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
      80             : #include <com/sun/star/sdbcx/KeyType.hpp>
      81             : #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
      82             : 
      83             : #include <com/sun/star/container/XIndexAccess.hpp>
      84             : #include <com/sun/star/container/XEnumerationAccess.hpp>
      85             : 
      86             : #include <string.h>
      87             : 
      88             : using osl::Mutex;
      89             : using osl::MutexGuard;
      90             : 
      91             : using rtl::OUString;
      92             : using rtl::OUStringBuffer;
      93             : using rtl::OUStringToOString;
      94             : using rtl::OStringToOUString;
      95             : using rtl::OString;
      96             : 
      97             : using com::sun::star::uno::Any;
      98             : using com::sun::star::uno::makeAny;
      99             : using com::sun::star::uno::Type;
     100             : using com::sun::star::uno::RuntimeException;
     101             : using com::sun::star::uno::Exception;
     102             : using com::sun::star::uno::Sequence;
     103             : using com::sun::star::uno::Reference;
     104             : using com::sun::star::uno::XInterface;
     105             : using com::sun::star::uno::UNO_QUERY;
     106             : 
     107             : using com::sun::star::lang::IllegalArgumentException;
     108             : 
     109             : using com::sun::star::sdbc::XWarningsSupplier;
     110             : using com::sun::star::sdbc::XCloseable;
     111             : using com::sun::star::sdbc::XStatement;
     112             : using com::sun::star::sdbc::XPreparedStatement;
     113             : using com::sun::star::sdbc::XParameters;
     114             : using com::sun::star::sdbc::XRow;
     115             : using com::sun::star::sdbc::XResultSet;
     116             : using com::sun::star::sdbc::XGeneratedResultSet;
     117             : using com::sun::star::sdbc::XConnection;
     118             : using com::sun::star::sdbc::SQLException;
     119             : 
     120             : using com::sun::star::sdbcx::XColumnsSupplier;
     121             : using com::sun::star::sdbcx::XTablesSupplier;
     122             : using com::sun::star::sdbcx::XKeysSupplier;
     123             : 
     124             : using com::sun::star::beans::Property;
     125             : using com::sun::star::beans::XPropertySetInfo;
     126             : using com::sun::star::beans::XPropertySet;
     127             : using com::sun::star::beans::XFastPropertySet;
     128             : using com::sun::star::beans::XMultiPropertySet;
     129             : 
     130             : using com::sun::star::container::XNameAccess;
     131             : using com::sun::star::container::XEnumerationAccess;
     132             : using com::sun::star::container::XEnumeration;
     133             : using com::sun::star::container::XIndexAccess;
     134             : 
     135             : #define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
     136             : namespace pq_sdbc_driver
     137             : {
     138           0 : static ::cppu::IPropertyArrayHelper & getStatementPropertyArrayHelper()
     139             : {
     140             :     static ::cppu::IPropertyArrayHelper *pArrayHelper;
     141           0 :     if( ! pArrayHelper )
     142             :     {
     143           0 :         MutexGuard guard( Mutex::getGlobalMutex() );
     144           0 :         if( ! pArrayHelper )
     145             :         {
     146             :             static Property aTable[] =
     147             :                 {
     148             :                     Property(
     149             :                         OUString( RTL_CONSTASCII_USTRINGPARAM("CursorName") ), 0,
     150           0 :                         ::getCppuType( (OUString *)0) , 0 ),
     151             :                     Property(
     152             :                         OUString( RTL_CONSTASCII_USTRINGPARAM("EscapeProcessing") ), 1,
     153           0 :                         ::getBooleanCppuType() , 0 ),
     154             :                     Property(
     155             :                         OUString( RTL_CONSTASCII_USTRINGPARAM("FetchDirection") ), 2,
     156           0 :                         ::getCppuType( (sal_Int32 *)0) , 0 ),
     157             :                     Property(
     158             :                         OUString( RTL_CONSTASCII_USTRINGPARAM("FetchSize") ), 3,
     159           0 :                         ::getCppuType( (sal_Int32 *)0) , 0 ),
     160             :                     Property(
     161             :                         OUString( RTL_CONSTASCII_USTRINGPARAM("MaxFieldSize") ), 4,
     162           0 :                         ::getCppuType( (sal_Int32 *)0) , 0 ),
     163             :                     Property(
     164             :                         OUString( RTL_CONSTASCII_USTRINGPARAM("MaxRows") ), 5,
     165           0 :                         ::getCppuType( (sal_Int32 *)0) , 0 ),
     166             :                     Property(
     167             :                         OUString( RTL_CONSTASCII_USTRINGPARAM("QueryTimeOut") ), 6,
     168           0 :                         ::getCppuType( (sal_Int32 *)0) , 0 ),
     169             :                     Property(
     170             :                         OUString( RTL_CONSTASCII_USTRINGPARAM("ResultSetConcurrency") ), 7,
     171           0 :                         ::getCppuType( (sal_Int32 *)0) , 0 ),
     172             :                     Property(
     173             :                         OUString( RTL_CONSTASCII_USTRINGPARAM("ResultSetType") ), 8,
     174           0 :                         ::getCppuType( (sal_Int32 *)0) , 0 )
     175           0 :                 };
     176             :             OSL_ASSERT( sizeof(aTable)/ sizeof(Property)  == STATEMENT_SIZE );
     177           0 :             static ::cppu::OPropertyArrayHelper arrayHelper( aTable, STATEMENT_SIZE, sal_True );
     178           0 :             pArrayHelper = &arrayHelper;
     179           0 :         }
     180             :     }
     181           0 :     return *pArrayHelper;
     182             : }
     183             : 
     184           0 : Statement::Statement( const ::rtl::Reference< RefCountedMutex > & refMutex,
     185             :                       const Reference< XConnection > & conn,
     186             :                       struct ConnectionSettings *pSettings )
     187           0 :     : OComponentHelper( refMutex->mutex ),
     188             :       OPropertySetHelper( OComponentHelper::rBHelper ),
     189             :       m_connection( conn ),
     190             :       m_pSettings( pSettings ),
     191             :       m_refMutex( refMutex ),
     192           0 :       m_lastOidInserted( InvalidOid )
     193             : {
     194           0 :     m_props[STATEMENT_QUERY_TIME_OUT] = makeAny( (sal_Int32)0 );
     195           0 :     m_props[STATEMENT_MAX_ROWS] = makeAny( (sal_Int32)0 );
     196             :     m_props[STATEMENT_RESULT_SET_CONCURRENCY] = makeAny(
     197           0 :         com::sun::star::sdbc::ResultSetConcurrency::READ_ONLY );
     198             :     m_props[STATEMENT_RESULT_SET_TYPE] = makeAny(
     199           0 :         com::sun::star::sdbc::ResultSetType::SCROLL_INSENSITIVE );
     200           0 : }
     201             : 
     202           0 : Statement::~Statement()
     203             : {
     204             :     POSTGRE_TRACE( "dtor Statement" );
     205           0 : }
     206             : 
     207           0 : void Statement::checkClosed() throw (SQLException, RuntimeException )
     208             : {
     209           0 :     if( ! m_pSettings || ! m_pSettings->pConnection )
     210             :         throw SQLException(
     211             :             ASCII_STR("pq_driver: Statement or connection has already been closed !" ),
     212           0 :             *this, OUString(),1,Any());
     213           0 : }
     214             : 
     215           0 : Any Statement::queryInterface( const Type & reqType ) throw (RuntimeException)
     216             : {
     217           0 :     Any ret;
     218             : 
     219           0 :     ret = OComponentHelper::queryInterface( reqType );
     220           0 :     if( ! ret.hasValue() )
     221             :         ret = ::cppu::queryInterface( reqType,
     222             :                                     static_cast< XWarningsSupplier * > ( this  ),
     223             :                                     static_cast< XStatement * > ( this ),
     224             :                                     static_cast< com::sun::star::sdbc::XResultSetMetaDataSupplier * > ( this ),
     225             :                                     static_cast< XCloseable * > ( this ),
     226             :                                     static_cast< XPropertySet * > ( this ),
     227             :                                     static_cast< XMultiPropertySet * > ( this ),
     228             :                                     static_cast< XGeneratedResultSet * > ( this ),
     229           0 :                                     static_cast< XFastPropertySet * > ( this ) );
     230           0 :     return ret;
     231             : }
     232             : 
     233             : 
     234           0 : Sequence< Type > Statement::getTypes() throw ( RuntimeException )
     235             : {
     236             :     static cppu::OTypeCollection *pCollection;
     237           0 :     if( ! pCollection )
     238             :     {
     239           0 :         MutexGuard guard( osl::Mutex::getGlobalMutex() );
     240           0 :         if( !pCollection )
     241             :         {
     242             :             static cppu::OTypeCollection collection(
     243           0 :                 getCppuType( (Reference< XWarningsSupplier> *) 0 ),
     244           0 :                 getCppuType( (Reference< XStatement> *) 0 ),
     245           0 :                 getCppuType( (Reference< com::sun::star::sdbc::XResultSetMetaDataSupplier> *) 0 ),
     246           0 :                 getCppuType( (Reference< XCloseable> *) 0 ),
     247           0 :                 getCppuType( (Reference< XPropertySet >*) 0 ),
     248           0 :                 getCppuType( (Reference< XFastPropertySet > *) 0 ),
     249           0 :                 getCppuType( (Reference< XMultiPropertySet > *) 0 ),
     250           0 :                 getCppuType( (Reference< XGeneratedResultSet > *) 0 ),
     251           0 :                 OComponentHelper::getTypes());
     252           0 :             pCollection = &collection;
     253           0 :         }
     254             :     }
     255           0 :     return pCollection->getTypes();
     256             : }
     257             : 
     258           0 : Sequence< sal_Int8> Statement::getImplementationId() throw ( RuntimeException )
     259             : {
     260             :     static cppu::OImplementationId *pId;
     261           0 :     if( ! pId )
     262             :     {
     263           0 :         MutexGuard guard( osl::Mutex::getGlobalMutex() );
     264           0 :         if( ! pId )
     265             :         {
     266           0 :             static cppu::OImplementationId id(sal_False);
     267           0 :             pId = &id;
     268           0 :         }
     269             :     }
     270           0 :     return pId->getImplementationId();
     271             : }
     272             : 
     273           0 : void Statement::close(  ) throw (SQLException, RuntimeException)
     274             : {
     275             :     // let the connection die without acquired mutex !
     276           0 :     Reference< XConnection > r;
     277           0 :     Reference< XCloseable > resultSet;
     278             :     {
     279           0 :         MutexGuard guard( m_refMutex->mutex );
     280           0 :         m_pSettings = 0;
     281           0 :         r = m_connection;
     282           0 :         m_connection.clear();
     283             : 
     284           0 :         resultSet = m_lastResultset;
     285           0 :         m_lastResultset.clear();
     286             :     }
     287           0 :     if( resultSet.is() )
     288             :     {
     289           0 :         resultSet->close();
     290             :         POSTGRE_TRACE( "statement closed" );
     291           0 :     }
     292             : 
     293           0 : }
     294             : 
     295           0 : void Statement::raiseSQLException(
     296             :     const OUString & sql, const char * errorMsg, const char *errorType )
     297             :     throw( SQLException )
     298             : {
     299           0 :     OUStringBuffer buf(128);
     300           0 :     buf.appendAscii( "pq_driver: ");
     301           0 :     if( errorType )
     302             :     {
     303           0 :         buf.appendAscii( "[" );
     304           0 :         buf.appendAscii( errorType );
     305           0 :         buf.appendAscii( "]" );
     306             :     }
     307             :     buf.append(
     308           0 :         rtl::OUString( errorMsg, strlen(errorMsg) , m_pSettings->encoding ) );
     309           0 :     buf.appendAscii( " (caused by statement '" );
     310           0 :     buf.append( sql );
     311           0 :     buf.appendAscii( "')" );
     312           0 :     OUString error = buf.makeStringAndClear();
     313           0 :     log( m_pSettings, LogLevel::ERROR, error );
     314           0 :     throw SQLException( error, *this, OUString(), 1, Any() );
     315             : }
     316             : 
     317           0 : Reference< XResultSet > Statement::executeQuery(const OUString& sql )
     318             :         throw (SQLException, RuntimeException)
     319             : {
     320           0 :     Reference< XCloseable > lastResultSetHolder = m_lastResultset;
     321           0 :     if( lastResultSetHolder.is() )
     322           0 :         lastResultSetHolder->close();
     323             : 
     324           0 :     if( ! execute( sql ) )
     325             :     {
     326           0 :         raiseSQLException( sql, "not a query" );
     327             :     }
     328           0 :     return Reference< XResultSet > ( m_lastResultset, com::sun::star::uno::UNO_QUERY );
     329             : }
     330             : 
     331           0 : sal_Int32 Statement::executeUpdate( const OUString& sql )
     332             :         throw (SQLException, RuntimeException)
     333             : {
     334           0 :     if( execute( sql ) )
     335             :     {
     336           0 :         raiseSQLException( sql, "not a command" );
     337             :     }
     338           0 :     return m_multipleResultUpdateCount;
     339             : }
     340             : 
     341             : 
     342           0 : static void raiseSQLException(
     343             :     ConnectionSettings *pSettings,
     344             :     const Reference< XInterface> & owner,
     345             :     const OString & sql,
     346             :     const char * errorMsg,
     347             :     const char *errorType = 0 )
     348             :     throw( SQLException )
     349             : {
     350           0 :     OUStringBuffer buf(128);
     351           0 :     buf.appendAscii( "pq_driver: ");
     352           0 :     if( errorType )
     353             :     {
     354           0 :         buf.appendAscii( "[" );
     355           0 :         buf.appendAscii( errorType );
     356           0 :         buf.appendAscii( "]" );
     357             :     }
     358             :     buf.append(
     359           0 :         rtl::OUString( errorMsg, strlen(errorMsg) , pSettings->encoding ) );
     360           0 :     buf.appendAscii( " (caused by statement '" );
     361           0 :     buf.append( rtl::OStringToOUString( sql, pSettings->encoding ) );
     362           0 :     buf.appendAscii( "')" );
     363           0 :     OUString error = buf.makeStringAndClear();
     364           0 :     log( pSettings, LogLevel::ERROR, error );
     365           0 :     throw SQLException( error, owner, OUString(), 1, Any() );
     366             : }
     367             : 
     368             : 
     369             : // returns the elements of the primary key of the given table
     370             : // static Sequence< Reference< com::sun::star::beans::XPropertySet > > lookupKeys(
     371           0 : static Sequence< ::rtl::OUString > lookupKeys(
     372             :     const Reference< com::sun::star::container::XNameAccess > &tables,
     373             :     const OUString & table,
     374             :     OUString *pSchema,
     375             :     OUString *pTable,
     376             :     ConnectionSettings *pSettings)
     377             : {
     378           0 :     Sequence< ::rtl::OUString  > ret;
     379           0 :     Reference< XKeysSupplier > keySupplier;
     380           0 :     Statics & st = getStatics();
     381             : 
     382           0 :     if( tables->hasByName( table ) )
     383           0 :         tables->getByName( table ) >>= keySupplier;
     384           0 :     else if( -1 == table.indexOf( '.' ) )
     385             :     {
     386             :         // it wasn't a fully qualified name. Now need to skip through all tables.
     387             :         Reference< XEnumerationAccess > enumerationAccess =
     388           0 :             Reference< XEnumerationAccess > ( tables, UNO_QUERY );
     389             : 
     390             :         Reference< com::sun::star::container::XEnumeration > enumeration =
     391           0 :             enumerationAccess->createEnumeration();
     392           0 :         while( enumeration->hasMoreElements() )
     393             :         {
     394           0 :             Reference< XPropertySet > set;
     395           0 :             enumeration->nextElement() >>= set;
     396           0 :             OUString name;
     397             : //             ::rtl::OUString schema;
     398             : 
     399           0 :             if( set->getPropertyValue( st.NAME ) >>= name )
     400             :             {
     401             : //                 printf( "searching %s %s\n",
     402             : //                         OUStringToOString( schema, RTL_TEXTENCODING_ASCII_US ).getStr(),
     403             : //                         OUStringToOString( name, RTL_TEXTENCODING_ASCII_US ).getStr() );
     404           0 :                 if( name == table )
     405             :                 {
     406             : 
     407           0 :                     if( keySupplier.is() )
     408             :                     {
     409             :                         // is ambigous, as I don't know postgresql searchpath,
     410             :                         // I can't continue here, as I may write to a different table
     411           0 :                         keySupplier.clear();
     412           0 :                         if( isLog( pSettings, LogLevel::INFO ) )
     413             :                         {
     414           0 :                             rtl::OStringBuffer buf( 128 );
     415           0 :                             buf.append( "Can't offer updateable result set because table " );
     416           0 :                             buf.append( OUStringToOString(name, pSettings->encoding) );
     417           0 :                             buf.append( " is duplicated, add schema to resolve ambiguity" );
     418           0 :                             log( pSettings, LogLevel::INFO, buf.makeStringAndClear().getStr() );
     419             :                         }
     420             :                         break;
     421             :                     }
     422           0 :                     keySupplier = Reference< XKeysSupplier > ( set, UNO_QUERY );
     423             :                 }
     424             :             }
     425           0 :         }
     426             :     }
     427             :     else
     428             :     {
     429           0 :         if( isLog( pSettings, LogLevel::INFO ) )
     430             :         {
     431           0 :             rtl::OStringBuffer buf( 128 );
     432           0 :             buf.append( "Can't offer updateable result set ( table " );
     433           0 :             buf.append( OUStringToOString(table, pSettings->encoding) );
     434           0 :             buf.append( " is unknown)" );
     435           0 :             log( pSettings, LogLevel::INFO, buf.makeStringAndClear().getStr() );
     436             :         }
     437             :     }
     438             : 
     439           0 :     if( keySupplier.is() )
     440             :     {
     441           0 :         Reference< XPropertySet > set( keySupplier, UNO_QUERY );
     442           0 :         set->getPropertyValue( getStatics().NAME ) >>= (*pTable);
     443           0 :         set->getPropertyValue( getStatics().SCHEMA_NAME ) >>= (*pSchema );
     444           0 :         set.clear();
     445             : 
     446           0 :         Reference< XEnumerationAccess > keys ( keySupplier->getKeys(), UNO_QUERY );
     447           0 :         Reference< XEnumeration > enumeration = keys->createEnumeration();
     448           0 :         while( enumeration->hasMoreElements() )
     449             :         {
     450           0 :             enumeration->nextElement() >>= set;
     451           0 :             sal_Int32 keyType = 0;
     452           0 :             if( (set->getPropertyValue( st.TYPE ) >>= keyType ) &&
     453             :                 keyType == com::sun::star::sdbcx::KeyType::PRIMARY )
     454             :             {
     455           0 :                 Reference< XColumnsSupplier > columns( set, UNO_QUERY );
     456             :                 Reference< XIndexAccess > indexAccess =
     457           0 :                     Reference< XIndexAccess > ( columns->getColumns(), UNO_QUERY );
     458             : 
     459           0 :                 int length = indexAccess->getCount();
     460           0 :                 ret.realloc( length );
     461             : //                 printf( "primary key for Table %s is ",
     462             : //                         OUStringToOString( table, RTL_TEXTENCODING_ASCII_US ).getStr() );
     463           0 :                 for( int i = 0 ; i < length ; i ++ )
     464             :                 {
     465           0 :                     indexAccess->getByIndex( i ) >>= set;
     466           0 :                     OUString name;
     467           0 :                     set->getPropertyValue( st.NAME ) >>= name;
     468           0 :                     ret[i] = name;
     469             : //                     printf( "%s," , OUStringToOString( name, RTL_TEXTENCODING_ASCII_US ).getStr() );
     470           0 :                 }
     471             : //                 printf( "\n" );
     472             :             }
     473             :         }
     474           0 :         if( ! ret.getLength() )
     475             :         {
     476           0 :             if( isLog( pSettings, LogLevel::INFO ) )
     477             :             {
     478           0 :                 rtl::OStringBuffer buf( 128 );
     479           0 :                 buf.append( "Can't offer updateable result set ( table " );
     480           0 :                 buf.append( OUStringToOString(table, pSettings->encoding) );
     481           0 :                 buf.append( " does not have a primary key)" );
     482           0 :                 log( pSettings, LogLevel::INFO, buf.makeStringAndClear().getStr() );
     483             :             }
     484           0 :         }
     485             :     }
     486           0 :     return ret;
     487             : }
     488             : 
     489           0 : bool executePostgresCommand( const rtl::OString & cmd, struct CommandData *data )
     490             : {
     491           0 :     ConnectionSettings *pSettings = *(data->ppSettings);
     492             : 
     493           0 :     sal_Int32 duration = osl_getGlobalTimer();
     494           0 :     PGresult *result = PQexec( pSettings->pConnection, cmd.getStr() );
     495           0 :     duration = osl_getGlobalTimer() - duration;
     496           0 :     if( ! result )
     497             :         raiseSQLException(
     498           0 :             pSettings, data->owner, cmd, PQerrorMessage( pSettings->pConnection ) );
     499             : 
     500           0 :     ExecStatusType state = PQresultStatus( result );
     501           0 :     *(data->pLastOidInserted) = 0;
     502           0 :     *(data->pLastTableInserted) = rtl::OUString();
     503           0 :     *(data->pLastQuery) = cmd;
     504             : 
     505           0 :     sal_Bool ret = sal_False;
     506           0 :     switch( state )
     507             :     {
     508             :     case PGRES_COMMAND_OK:
     509             :     {
     510           0 :         *(data->pMultipleResultUpdateCount) = atoi( PQcmdTuples( result ) );
     511           0 :         *(data->pMultipleResultAvailable) = sal_False;
     512             : 
     513             :         // in case an oid value is available, we retrieve it
     514           0 :         *(data->pLastOidInserted) = PQoidValue( result );
     515             : 
     516             :         // in case it was a single insert, extract the name of the table,
     517             :         // otherwise the table name is empty
     518             :         *(data->pLastTableInserted) =
     519           0 :             extractTableFromInsert( OStringToOUString( cmd, pSettings->encoding ) );
     520           0 :         if( isLog( pSettings, LogLevel::SQL ) )
     521             :         {
     522           0 :             rtl::OStringBuffer buf( 128 );
     523           0 :             buf.append( "executed command '" );
     524           0 :             buf.append( cmd.getStr() );
     525           0 :             buf.append( "' sucessfully (" );
     526           0 :             buf.append( *( data->pMultipleResultUpdateCount ) );
     527           0 :             buf.append( ")" );
     528           0 :             buf.append( ", duration=" );
     529           0 :             buf.append( duration );
     530           0 :             buf.append( "ms" );
     531           0 :             if( *(data->pLastOidInserted) )
     532             :             {
     533           0 :                 buf.append( ", usedOid=" );
     534           0 :                 buf.append( *(data->pLastOidInserted) , 10 );
     535           0 :                 buf.append( ", diagnosedTable=" );
     536             :                 buf.append(
     537           0 :                     OUStringToOString( *data->pLastTableInserted, pSettings->encoding ) );
     538             :             }
     539           0 :             log( pSettings, LogLevel::SQL, buf.makeStringAndClear().getStr() );
     540             :         }
     541           0 :         PQclear( result );
     542           0 :         break;
     543             :     }
     544             :     case PGRES_TUPLES_OK: // success
     545             :     {
     546             :         // In case it is a single table, it has a primary key and all columns
     547             :         // belonging to the primary key are in the result set, allow updateable result sets
     548             :         // otherwise, don't
     549           0 :         rtl::OUString table, schema;
     550           0 :         Sequence< OUString > sourceTableKeys;
     551           0 :         OStringVector vec;
     552           0 :         tokenizeSQL( cmd, vec );
     553             :         OUString sourceTable =
     554             :             OStringToOUString(
     555           0 :                 extractSingleTableFromSelect( vec ), pSettings->encoding );
     556             : 
     557           0 :         if( data->concurrency ==
     558             :             com::sun::star::sdbc::ResultSetConcurrency::UPDATABLE )
     559             :         {
     560           0 :             OString aReason;
     561           0 :             if( sourceTable.getLength() )
     562             :             {
     563             :                 sourceTableKeys = lookupKeys(
     564           0 :                     pSettings->tables.is() ?
     565           0 :                            pSettings->tables : data->tableSupplier->getTables() ,
     566             :                     sourceTable,
     567             :                     &schema,
     568             :                     &table,
     569           0 :                     pSettings);
     570             : 
     571             :                 // check, whether the columns are in the result set (required !)
     572             :                 int i;
     573           0 :                 for( i = 0 ; i < sourceTableKeys.getLength() ;  i ++ )
     574             :                 {
     575           0 :                     if( -1 == PQfnumber(
     576             :                             result,
     577           0 :                             OUStringToOString( sourceTableKeys[i] ,
     578           0 :                                                pSettings->encoding ).getStr()) )
     579             :                     {
     580           0 :                         break;
     581             :                     }
     582             :                 }
     583             : 
     584           0 :                 if( sourceTableKeys.getLength() && i == sourceTableKeys.getLength() )
     585             :                 {
     586             :                     *(data->pLastResultset) =
     587             :                         UpdateableResultSet::createFromPGResultSet(
     588             :                             data->refMutex, data->owner, data->ppSettings, result,
     589           0 :                             schema, table,sourceTableKeys );
     590             :                 }
     591           0 :                 else if( ! table.getLength() )
     592             :                 {
     593           0 :                     rtl::OStringBuffer buf( 128 );
     594             :                     buf.append(
     595             :                         RTL_CONSTASCII_STRINGPARAM(
     596             :                             "can't support updateable resultset, because a single table in the "
     597           0 :                             "WHERE part of the statement could not be identified (" ) );
     598           0 :                     buf.append( cmd );
     599           0 :                     buf.append( RTL_CONSTASCII_STRINGPARAM( "." ) );
     600           0 :                     aReason = buf.makeStringAndClear();
     601             :                 }
     602           0 :                 else if( sourceTableKeys.getLength() )
     603             :                 {
     604           0 :                     ::rtl::OStringBuffer buf( 128 );
     605             :                     buf.append(
     606             :                         RTL_CONSTASCII_STRINGPARAM(
     607           0 :                             "can't support updateable resultset for table " ) );
     608           0 :                     buf.append( rtl::OUStringToOString( schema, pSettings->encoding ) );
     609           0 :                     buf.append( RTL_CONSTASCII_STRINGPARAM( "." ) );
     610           0 :                     buf.append( rtl::OUStringToOString( table, pSettings->encoding ) );
     611           0 :                     buf.append( RTL_CONSTASCII_STRINGPARAM( ", because resultset does not contain a part of the primary key ( column " ) );
     612           0 :                     buf.append( rtl::OUStringToOString( sourceTableKeys[i], pSettings->encoding ) );
     613           0 :                     buf.append( RTL_CONSTASCII_STRINGPARAM( " is missing )") );
     614           0 :                     aReason = buf.makeStringAndClear();
     615             :                 }
     616             :                 else
     617             :                 {
     618             : 
     619           0 :                     ::rtl::OStringBuffer buf( 128 );
     620             :                     buf.append(
     621             :                         RTL_CONSTASCII_STRINGPARAM(
     622           0 :                             "can't support updateable resultset for table " ) );
     623           0 :                     buf.append( rtl::OUStringToOString( schema, pSettings->encoding ) );
     624           0 :                     buf.append( RTL_CONSTASCII_STRINGPARAM( "." ) );
     625           0 :                     buf.append( rtl::OUStringToOString( table, pSettings->encoding ) );
     626           0 :                     buf.append( RTL_CONSTASCII_STRINGPARAM( ", because resultset table does not have a primary key " ) );
     627           0 :                     aReason = buf.makeStringAndClear();
     628             :                 }
     629             :             }
     630             :             else
     631             :             {
     632           0 :                 ::rtl::OStringBuffer buf( 128 );
     633             :                 buf.append(
     634             :                     RTL_CONSTASCII_STRINGPARAM(
     635           0 :                         "can't support updateable result for selects with multiple tables (" ) );
     636           0 :                 buf.append( cmd );
     637           0 :                 buf.append( RTL_CONSTASCII_STRINGPARAM( ")" ) );
     638           0 :                 log( pSettings, LogLevel::SQL, buf.makeStringAndClear().getStr() );
     639             :             }
     640           0 :             if( ! (*(data->pLastResultset)).is() )
     641             :             {
     642           0 :                 if( isLog( pSettings, LogLevel::ERROR ) )
     643             :                 {
     644           0 :                     log( pSettings, LogLevel::ERROR,  aReason.getStr());
     645             :                 }
     646             : 
     647             :                 // TODO: How to react here correctly ?
     648             :                 // remove this piece of code
     649             :                 *(data->pLastResultset) =
     650             :                     new FakedUpdateableResultSet(
     651             :                         data->refMutex, data->owner,
     652             :                         data->ppSettings,result, schema, table,
     653           0 :                         OStringToOUString( aReason, pSettings->encoding) );
     654           0 :             }
     655             : 
     656             :         }
     657           0 :         else if( sourceTable.getLength() && -1 != sourceTable.indexOf( '.' ) )
     658             :         {
     659           0 :             splitConcatenatedIdentifier( sourceTable, &schema, &table );
     660             :         }
     661             : 
     662           0 :         sal_Int32 returnedRows = PQntuples( result );
     663           0 :         if( ! data->pLastResultset->is() )
     664             :             *(data->pLastResultset) =
     665             :                 Reference< XCloseable > (
     666             :                     new ResultSet(
     667             :                         data->refMutex, data->owner,
     668           0 :                         data->ppSettings,result, schema, table ) );
     669           0 :         *(data->pMultipleResultAvailable) = sal_True;
     670           0 :         ret = sal_True;
     671           0 :         if( isLog( pSettings, LogLevel::SQL ) )
     672             :         {
     673           0 :             rtl::OStringBuffer buf( 128 );
     674           0 :             buf.append( RTL_CONSTASCII_STRINGPARAM("executed query '") );
     675           0 :             buf.append( cmd );
     676           0 :             buf.append( RTL_CONSTASCII_STRINGPARAM("' sucessfully") );
     677           0 :             buf.append( RTL_CONSTASCII_STRINGPARAM(", duration=") );
     678           0 :             buf.append( duration );
     679           0 :             buf.append( RTL_CONSTASCII_STRINGPARAM("ms, returnedRows=") );
     680           0 :             buf.append( returnedRows );
     681           0 :             buf.append( RTL_CONSTASCII_STRINGPARAM("." ) );
     682           0 :             log( pSettings, LogLevel::SQL, buf.makeStringAndClear().getStr() );
     683             :         }
     684           0 :         break;
     685             :     }
     686             :     case PGRES_EMPTY_QUERY:
     687             :     case PGRES_COPY_OUT:
     688             :     case PGRES_COPY_IN:
     689             :     case PGRES_BAD_RESPONSE:
     690             :     case PGRES_NONFATAL_ERROR:
     691             :     case PGRES_FATAL_ERROR:
     692             :     default:
     693             :         raiseSQLException(
     694           0 :             pSettings, data->owner, cmd, PQresultErrorMessage( result ) , PQresStatus( state ) );
     695             :     }
     696           0 :     return ret;
     697             : 
     698             : }
     699             : 
     700           0 : static Sequence< OUString > getPrimaryKeyColumnNames(
     701             :     const Reference< XConnection > & connection, const OUString &schemaName, const OUString &tableName )
     702             : {
     703           0 :     Sequence< OUString > ret;
     704             : 
     705           0 :     Int2StringMap mapIndex2Name;
     706           0 :     fillAttnum2attnameMap( mapIndex2Name, connection, schemaName, tableName );
     707             : 
     708             :     // retrieve the primary key ...
     709           0 :     Reference< XPreparedStatement > stmt = connection->prepareStatement(
     710             :         ASCII_STR(
     711             :             "SELECT conkey "              // 7
     712             :             "FROM pg_constraint INNER JOIN pg_class ON conrelid = pg_class.oid "
     713             :                       "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid "
     714             :                       "LEFT JOIN pg_class AS class2 ON confrelid = class2.oid "
     715             :                       "LEFT JOIN pg_namespace AS nmsp2 ON class2.relnamespace=nmsp2.oid "
     716           0 :             "WHERE pg_class.relname = ? AND pg_namespace.nspname = ? AND pg_constraint.contype='p'" ) );
     717           0 :     DisposeGuard guard( stmt );
     718           0 :     Reference< XParameters > paras( stmt, UNO_QUERY );
     719           0 :     paras->setString( 1 , tableName );
     720           0 :     paras->setString( 2 , schemaName );
     721           0 :     Reference< XResultSet > rs = stmt->executeQuery();
     722           0 :     Reference< XRow > xRow( rs , UNO_QUERY );
     723             : 
     724           0 :     if( rs->next() )
     725             :     {
     726           0 :         ret = convertMappedIntArray2StringArray( mapIndex2Name, string2intarray(xRow->getString( 1 ) ) );
     727             :     }
     728           0 :     return ret;
     729             : }
     730             : 
     731           0 : static void getAutoValues(
     732             :     String2StringMap & result,
     733             :     const Reference< XConnection > & connection,
     734             :     const OUString &schemaName,
     735             :     const OUString & tableName )
     736             : {
     737           0 :     Reference< XPreparedStatement > stmt = connection->prepareStatement(
     738             :         ASCII_STR("SELECT   pg_attribute.attname, pg_attrdef.adsrc "
     739             :                   "FROM pg_class, pg_namespace, pg_attribute "
     740             :                   "LEFT JOIN pg_attrdef ON pg_attribute.attrelid = pg_attrdef.adrelid AND "
     741             :                                         "pg_attribute.attnum = pg_attrdef.adnum "
     742             :                   "WHERE pg_attribute.attrelid = pg_class.oid AND "
     743             :                         "pg_class.relnamespace = pg_namespace.oid AND "
     744             :                         "pg_namespace.nspname = ? AND "
     745             :                   // LEM TODO: this is weird; why "LIKE" and not "="?
     746             :                   // Most probably gives problems if tableName contains '%'
     747             :                         "pg_class.relname LIKE ? AND "
     748             :                         "pg_attrdef.adsrc != ''"
     749           0 :             ) );
     750           0 :     DisposeGuard guard( stmt );
     751           0 :     Reference< XParameters > paras( stmt, UNO_QUERY );
     752           0 :     paras->setString( 1 , schemaName );
     753           0 :     paras->setString( 2 , tableName );
     754           0 :     Reference< XResultSet > rs = stmt->executeQuery();
     755           0 :     Reference< XRow > xRow( rs , UNO_QUERY );
     756             : 
     757           0 :     while( rs->next() )
     758             :     {
     759           0 :         result[ OUStringToOString( xRow->getString( 1 ), RTL_TEXTENCODING_ASCII_US) ] =
     760           0 :             OUStringToOString( xRow->getString(2), RTL_TEXTENCODING_ASCII_US );
     761           0 :     }
     762           0 : }
     763             : 
     764           0 : Reference< XResultSet > getGeneratedValuesFromLastInsert(
     765             :     ConnectionSettings *pConnectionSettings,
     766             :     const Reference< XConnection > &connection,
     767             :     sal_Int32 nLastOid,
     768             :     const rtl::OUString & lastTableInserted,
     769             :     const rtl::OString & lastQuery )
     770             : {
     771           0 :     Reference< XResultSet > ret;
     772           0 :     OUString query;
     773           0 :     OUString schemaName, tableName;
     774             :     splitConcatenatedIdentifier(
     775           0 :         lastTableInserted, &schemaName, &tableName );
     776             : 
     777           0 :     if( nLastOid && lastTableInserted.getLength() )
     778             :     {
     779           0 :         OUStringBuffer buf( 128 );
     780           0 :         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SELECT * FROM " ) );
     781           0 :         if( schemaName.getLength() )
     782           0 :             bufferQuoteQualifiedIdentifier(buf, schemaName, tableName, pConnectionSettings );
     783             :         else
     784           0 :             bufferQuoteIdentifier( buf, lastTableInserted, pConnectionSettings );
     785           0 :         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " WHERE oid = " ) );
     786           0 :         buf.append( nLastOid , 10 );
     787           0 :         query = buf.makeStringAndClear();
     788             :     }
     789           0 :     else if ( lastTableInserted.getLength() && lastQuery.getLength() )
     790             :     {
     791             :         // extract nameValue Pairs
     792           0 :         String2StringMap namedValues;
     793           0 :         extractNameValuePairsFromInsert( namedValues, lastQuery );
     794             : 
     795             :         // debug ...
     796             : //         rtl::OStringBuffer buf( 128);
     797             : //         buf.append( "extracting name/value from '" );
     798             : //         buf.append( lastQuery.getStr() );
     799             : //         buf.append( "' to [" );
     800             : //         for( String2StringMap::iterator ii = namedValues.begin() ; ii != namedValues.end() ; ++ii )
     801             : //         {
     802             : //             buf.append( ii->first.getStr() );
     803             : //             buf.append( "=" );
     804             : //             buf.append( ii->second.getStr() );
     805             : //             buf.append( "," );
     806             : //         }
     807             : //         buf.append( "]\n" );
     808             : //         printf( "%s", buf.makeStringAndClear() );
     809             : 
     810             :         // TODO: make also unqualified tables names work here. Have a look at 2.8.3. The Schema Search Path
     811             :         //       in postgresql doc
     812             : 
     813           0 :         Sequence< OUString > keyColumnNames = getPrimaryKeyColumnNames( connection, schemaName, tableName );
     814           0 :         if( keyColumnNames.getLength() )
     815             :         {
     816           0 :             OUStringBuffer buf( 128 );
     817           0 :             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SELECT * FROM " ) );
     818           0 :             bufferQuoteQualifiedIdentifier(buf, schemaName, tableName, pConnectionSettings );
     819           0 :             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " WHERE " ) );
     820           0 :             bool additionalCondition = false;
     821           0 :             String2StringMap autoValues;
     822           0 :             for( int i = 0 ; i < keyColumnNames.getLength() ; i ++ )
     823             :             {
     824           0 :                 OUString value;
     825           0 :                 OString columnName = OUStringToOString( keyColumnNames[i], pConnectionSettings->encoding );
     826           0 :                 String2StringMap::iterator ii = namedValues.begin();
     827           0 :                 for( ; ii != namedValues.end() ; ++ii )
     828             :                 {
     829           0 :                     if( columnName.equalsIgnoreAsciiCase( ii->first ) )
     830             :                     {
     831           0 :                         value = OStringToOUString( ii->second , pConnectionSettings->encoding );
     832           0 :                         break;
     833             :                     }
     834             :                 }
     835             : 
     836             :                 // check, if a column of the primary key was not inserted explicitly,
     837           0 :                 if( ii == namedValues.end() )
     838             :                 {
     839             : 
     840           0 :                     if( autoValues.begin() == autoValues.end() )
     841             :                     {
     842           0 :                         getAutoValues( autoValues, connection, schemaName, tableName );
     843             :                     }
     844             :                     // this could mean, that the column is a default or auto value, check this ...
     845           0 :                     String2StringMap::iterator j = autoValues.begin();
     846           0 :                     for( ; j != autoValues.end() ; ++j )
     847             :                     {
     848           0 :                         if( columnName.equalsIgnoreAsciiCase( j->first ) )
     849             :                         {
     850             :                             // it is indeed an auto value.
     851           0 :                             value = OStringToOUString(j->second, RTL_TEXTENCODING_ASCII_US );
     852             :                             // check, whether it is a sequence
     853             : 
     854           0 :                             if( rtl_str_shortenedCompare_WithLength(
     855           0 :                                     j->second.getStr(), j->second.getLength(),
     856           0 :                                     RTL_CONSTASCII_STRINGPARAM( "nextval(" ), 8 ) == 0 )
     857             :                             {
     858             :                                 // retrieve current sequence value:
     859           0 :                                 OUStringBuffer myBuf(128 );
     860           0 :                                 myBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SELECT currval(" ) );
     861           0 :                                 myBuf.appendAscii( &(j->second.getStr()[8]));
     862           0 :                                 value = querySingleValue( connection, myBuf.makeStringAndClear() );
     863             :                             }
     864           0 :                             break;
     865             :                         }
     866             :                     }
     867           0 :                     if( j == autoValues.end() )
     868             :                     {
     869             :                         // it even was no autovalue, no sense to continue as we can't query the
     870             :                         // inserted row
     871           0 :                         buf = OUStringBuffer();
     872             :                         break;
     873             :                     }
     874             :                 }
     875             : 
     876           0 :                 if( additionalCondition )
     877           0 :                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " AND " ) );
     878           0 :                 bufferQuoteIdentifier( buf, keyColumnNames[i], pConnectionSettings );
     879           0 :                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " = " ) );
     880           0 :                 buf.append( value );
     881           0 :                 additionalCondition = true;
     882           0 :             }
     883           0 :             query = buf.makeStringAndClear();
     884           0 :         }
     885             :     }
     886             : 
     887           0 :     if( query.getLength() )
     888             :     {
     889           0 :         Reference< com::sun::star::sdbc::XStatement > stmt = connection->createStatement();
     890           0 :         ret = stmt->executeQuery( query );
     891             :     }
     892             : 
     893           0 :     return ret;
     894             : 
     895             : }
     896             : 
     897           0 : sal_Bool Statement::execute( const OUString& sql )
     898             :         throw (SQLException, RuntimeException)
     899             : {
     900           0 :     osl::MutexGuard guard( m_refMutex->mutex );
     901           0 :     checkClosed();
     902           0 :     OString cmd = OUStringToOString( sql, m_pSettings );
     903             : 
     904           0 :     m_lastResultset.clear();
     905           0 :     m_lastTableInserted  = rtl::OUString();
     906             : 
     907           0 :     struct CommandData data;
     908           0 :     data.refMutex = m_refMutex;
     909           0 :     data.ppSettings = &m_pSettings;
     910           0 :     data.pLastOidInserted = &m_lastOidInserted;
     911           0 :     data.pLastQuery = &m_lastQuery;
     912           0 :     data.pMultipleResultUpdateCount = &m_multipleResultUpdateCount;
     913           0 :     data.pMultipleResultAvailable = &m_multipleResultAvailable;
     914           0 :     data.pLastTableInserted = &m_lastTableInserted;
     915           0 :     data.pLastResultset = &m_lastResultset;
     916           0 :     data.owner = *this;
     917           0 :     data.tableSupplier = Reference< com::sun::star::sdbcx::XTablesSupplier >( m_connection, UNO_QUERY );
     918             :     data.concurrency =
     919           0 :         extractIntProperty( this, getStatics().RESULT_SET_CONCURRENCY );
     920           0 :     return executePostgresCommand( cmd , &data );
     921             : }
     922             : 
     923           0 : Reference< XConnection > Statement::getConnection(  )
     924             :         throw (SQLException, RuntimeException)
     925             : {
     926           0 :     Reference< XConnection > ret;
     927             :     {
     928           0 :         MutexGuard guard( m_refMutex->mutex );
     929           0 :         checkClosed();
     930           0 :         ret = m_connection;
     931             :     }
     932           0 :     return ret;
     933             : }
     934             : 
     935             : 
     936           0 : Any Statement::getWarnings(  )
     937             :         throw (SQLException,RuntimeException)
     938             : {
     939           0 :     return Any();
     940             : }
     941             : 
     942           0 : void Statement::clearWarnings(  )
     943             :         throw (SQLException, RuntimeException)
     944             : {
     945           0 : }
     946             : 
     947           0 : Reference< ::com::sun::star::sdbc::XResultSetMetaData > Statement::getMetaData()
     948             :             throw (SQLException,RuntimeException)
     949             : {
     950           0 :     Reference< com::sun::star::sdbc::XResultSetMetaData > ret;
     951           0 :     Reference< com::sun::star::sdbc::XResultSetMetaDataSupplier > supplier( m_lastResultset, UNO_QUERY );
     952           0 :     if( supplier.is() )
     953           0 :         ret = supplier->getMetaData();
     954           0 :     return ret;
     955             : }
     956             : 
     957             : 
     958           0 : ::cppu::IPropertyArrayHelper & Statement::getInfoHelper()
     959             : {
     960           0 :     return getStatementPropertyArrayHelper();
     961             : }
     962             : 
     963             : 
     964           0 : sal_Bool Statement::convertFastPropertyValue(
     965             :         Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue )
     966             :         throw (IllegalArgumentException)
     967             : {
     968           0 :     rOldValue = m_props[nHandle];
     969             :     sal_Bool bRet;
     970           0 :     switch( nHandle )
     971             :     {
     972             :     case STATEMENT_CURSOR_NAME:
     973             :     {
     974           0 :         OUString val;
     975           0 :         bRet = ( rValue >>= val );
     976           0 :         rConvertedValue = makeAny( val );
     977           0 :         break;
     978             :     }
     979             :     case STATEMENT_ESCAPE_PROCESSING:
     980             :     {
     981             :         sal_Bool val;
     982           0 :         bRet = ( rValue >>= val );
     983           0 :         rConvertedValue = makeAny( val );
     984             :         break;
     985             :     }
     986             :     case STATEMENT_FETCH_DIRECTION:
     987             :     case STATEMENT_FETCH_SIZE:
     988             :     case STATEMENT_MAX_FIELD_SIZE:
     989             :     case STATEMENT_MAX_ROWS:
     990             :     case STATEMENT_QUERY_TIME_OUT:
     991             :     case STATEMENT_RESULT_SET_CONCURRENCY:
     992             :     case STATEMENT_RESULT_SET_TYPE:
     993             :     {
     994             :         sal_Int32 val;
     995           0 :         bRet = ( rValue >>= val );
     996           0 :         rConvertedValue = makeAny( val );
     997             :         break;
     998             :     }
     999             :     default:
    1000             :     {
    1001           0 :         OUStringBuffer buf(128);
    1002           0 :         buf.appendAscii( "pq_statement: Invalid property handle (" );
    1003           0 :         buf.append( nHandle );
    1004           0 :         buf.appendAscii( ")" );
    1005           0 :         throw IllegalArgumentException( buf.makeStringAndClear(), *this, 2 );
    1006             :     }
    1007             :     }
    1008           0 :     return bRet;
    1009             : }
    1010             : 
    1011             : 
    1012           0 : void Statement::setFastPropertyValue_NoBroadcast(
    1013             :     sal_Int32 nHandle,const Any& rValue ) throw (Exception)
    1014             : {
    1015           0 :     m_props[nHandle] = rValue;
    1016           0 : }
    1017             : 
    1018           0 : void Statement::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
    1019             : {
    1020           0 :     rValue = m_props[nHandle];
    1021           0 : }
    1022             : 
    1023           0 : Reference < XPropertySetInfo >  Statement::getPropertySetInfo()
    1024             :         throw(RuntimeException)
    1025             : {
    1026           0 :     return OPropertySetHelper::createPropertySetInfo( getStatementPropertyArrayHelper() );
    1027             : }
    1028             : 
    1029             : 
    1030           0 : Reference< XResultSet > Statement::getResultSet(  )
    1031             :     throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
    1032             : {
    1033           0 :     return Reference< XResultSet > ( m_lastResultset, com::sun::star::uno::UNO_QUERY );
    1034             : }
    1035             : 
    1036           0 : sal_Int32 Statement::getUpdateCount(  )
    1037             :     throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
    1038             : {
    1039           0 :     return m_multipleResultUpdateCount;
    1040             : }
    1041             : 
    1042           0 : sal_Bool Statement::getMoreResults(  )
    1043             :     throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
    1044             : {
    1045           0 :     return sal_False;
    1046             : }
    1047             : 
    1048             : 
    1049             : 
    1050           0 : void Statement::disposing()
    1051             : {
    1052           0 :     close();
    1053           0 : }
    1054             : 
    1055           0 : Reference< XResultSet > Statement::getGeneratedValues(  )
    1056             :         throw (SQLException, RuntimeException)
    1057             : {
    1058           0 :     osl::MutexGuard guard( m_refMutex->mutex );
    1059             :     return getGeneratedValuesFromLastInsert(
    1060           0 :         m_pSettings, m_connection, m_lastOidInserted, m_lastTableInserted, m_lastQuery );
    1061             : }
    1062             : 
    1063             : }

Generated by: LCOV version 1.10