LCOV - code coverage report
Current view: top level - connectivity/source/drivers/postgresql - pq_statement.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 448 0.0 %
Date: 2012-08-25 Functions: 0 34 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     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