LCOV - code coverage report
Current view: top level - libreoffice/dbaccess/source/core/api - KeySet.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 891 0.0 %
Date: 2012-12-27 Functions: 0 78 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             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "KeySet.hxx"
      21             : #include "core_resource.hxx"
      22             : #include "core_resource.hrc"
      23             : #include <com/sun/star/beans/XPropertySet.hpp>
      24             : #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
      25             : #include <com/sun/star/sdbc/ColumnValue.hpp>
      26             : #include <com/sun/star/sdbc/XPreparedStatement.hpp>
      27             : #include <com/sun/star/sdbc/XParameters.hpp>
      28             : #include <com/sun/star/sdbc/XGeneratedResultSet.hpp>
      29             : #include <com/sun/star/sdbc/XColumnLocate.hpp>
      30             : #include <com/sun/star/container/XIndexAccess.hpp>
      31             : #include "dbastrings.hrc"
      32             : #include "apitools.hxx"
      33             : #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
      34             : #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
      35             : #include <com/sun/star/sdbcx/XIndexesSupplier.hpp>
      36             : #include <cppuhelper/typeprovider.hxx>
      37             : #include <comphelper/types.hxx>
      38             : #include <com/sun/star/sdbcx/KeyType.hpp>
      39             : #include <connectivity/dbtools.hxx>
      40             : #include <connectivity/dbexception.hxx>
      41             : #include <list>
      42             : #include <algorithm>
      43             : #include <string.h>
      44             : #include <com/sun/star/io/XInputStream.hpp>
      45             : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
      46             : #include "querycomposer.hxx"
      47             : #include "composertools.hxx"
      48             : #include <tools/debug.hxx>
      49             : #include <rtl/logfile.hxx>
      50             : #include "PrivateRow.hxx"
      51             : 
      52             : using namespace dbaccess;
      53             : using namespace ::connectivity;
      54             : using namespace ::dbtools;
      55             : using namespace ::com::sun::star::uno;
      56             : using namespace ::com::sun::star::beans;
      57             : using namespace ::com::sun::star::sdbc;
      58             : using namespace ::com::sun::star::sdb;
      59             : using namespace ::com::sun::star::sdbcx;
      60             : using namespace ::com::sun::star::container;
      61             : using namespace ::com::sun::star::lang;
      62             : using namespace ::com::sun::star::util;
      63             : using namespace ::com::sun::star::io;
      64             : using namespace ::com::sun::star;
      65             : using namespace ::cppu;
      66             : using namespace ::osl;
      67             : 
      68             : namespace
      69             : {
      70           0 :     void lcl_fillIndexColumns(const Reference<XIndexAccess>& _xIndexes, ::std::vector< Reference<XNameAccess> >& _rAllIndexColumns)
      71             :     {
      72           0 :         if ( _xIndexes.is() )
      73             :         {
      74           0 :             Reference<XPropertySet> xIndexColsSup;
      75           0 :             sal_Int32 nCount = _xIndexes->getCount();
      76           0 :             for(sal_Int32 j = 0 ; j < nCount ; ++j)
      77             :             {
      78           0 :                 xIndexColsSup.set(_xIndexes->getByIndex(j),UNO_QUERY);
      79           0 :                 if( xIndexColsSup.is()
      80           0 :                     && comphelper::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISUNIQUE))
      81           0 :                     && !comphelper::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISPRIMARYKEYINDEX))
      82             :                 )
      83           0 :                     _rAllIndexColumns.push_back(Reference<XColumnsSupplier>(xIndexColsSup,UNO_QUERY)->getColumns());
      84           0 :             }
      85             :         }
      86           0 :     }
      87             : 
      88           0 :     template < typename T > inline void tryDispose( Reference<T> &r )
      89             :     {
      90             :         try
      91             :         {
      92           0 :             ::comphelper::disposeComponent(r);
      93             :         }
      94           0 :         catch(const Exception&)
      95             :         {
      96           0 :             r = NULL;
      97             :         }
      98           0 :         catch(...)
      99             :         {
     100             :             OSL_FAIL("Unknown Exception occurred");
     101             :         }
     102           0 :     }
     103             : }
     104             : DBG_NAME(OKeySet)
     105             : 
     106           0 : OKeySet::OKeySet(const connectivity::OSQLTable& _xTable,
     107             :                  const Reference< XIndexAccess>& _xTableKeys,
     108             :                  const ::rtl::OUString& _rUpdateTableName,    // this can be the alias or the full qualified name
     109             :                  const Reference< XSingleSelectQueryAnalyzer >& _xComposer,
     110             :                  const ORowSetValueVector& _aParameterValueForCache,
     111             :                  sal_Int32 i_nMaxRows,
     112             :                  sal_Int32& o_nRowCount)
     113             :             :OCacheSet(i_nMaxRows)
     114             :             ,m_aParameterValueForCache(_aParameterValueForCache)
     115             :             ,m_pKeyColumnNames(NULL)
     116             :             ,m_pColumnNames(NULL)
     117             :             ,m_pParameterNames(NULL)
     118             :             ,m_pForeignColumnNames(NULL)
     119             :             ,m_xTable(_xTable)
     120             :             ,m_xTableKeys(_xTableKeys)
     121             :             ,m_xComposer(_xComposer)
     122             :             ,m_sUpdateTableName(_rUpdateTableName)
     123             :             ,m_rRowCount(o_nRowCount)
     124           0 :             ,m_bRowCountFinal(sal_False)
     125             : {
     126             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::OKeySet" );
     127             :     DBG_CTOR(OKeySet,NULL);
     128             : 
     129           0 : }
     130             : 
     131           0 : OKeySet::~OKeySet()
     132             : {
     133           0 :     tryDispose(m_xStatement);
     134           0 :     tryDispose(m_xSet);
     135             : 
     136           0 :     m_xComposer = NULL;
     137             : 
     138             :     DBG_DTOR(OKeySet,NULL);
     139           0 : }
     140           0 : void OKeySet::initColumns()
     141             : {
     142           0 :     Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
     143           0 :     bool bCase = (xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers()) ? true : false;
     144           0 :     m_pKeyColumnNames.reset( new SelectColumnsMetaData(bCase) );
     145           0 :     m_pColumnNames.reset( new SelectColumnsMetaData(bCase) );
     146           0 :     m_pParameterNames.reset( new SelectColumnsMetaData(bCase) );
     147           0 :     m_pForeignColumnNames.reset( new SelectColumnsMetaData(bCase) );
     148           0 : }
     149             : 
     150             : SAL_WNODEPRECATED_DECLARATIONS_PUSH
     151           0 : void OKeySet::findTableColumnsMatching_throw(   const Any& i_aTable,
     152             :                                                 const ::rtl::OUString& i_rUpdateTableName,
     153             :                                                 const Reference<XDatabaseMetaData>& i_xMeta,
     154             :                                                 const Reference<XNameAccess>& i_xQueryColumns,
     155             :                                                 ::std::auto_ptr<SelectColumnsMetaData>& o_pKeyColumnNames)
     156             : {
     157             :     // first ask the database itself for the best columns which can be used
     158           0 :     Sequence< ::rtl::OUString> aBestColumnNames;
     159           0 :     Reference<XNameAccess> xKeyColumns  = getPrimaryKeyColumns_throw(i_aTable);
     160           0 :     if ( xKeyColumns.is() )
     161           0 :         aBestColumnNames = xKeyColumns->getElementNames();
     162             : 
     163           0 :     const Reference<XColumnsSupplier> xTblColSup(i_aTable,UNO_QUERY_THROW);
     164           0 :     const Reference<XNameAccess> xTblColumns = xTblColSup->getColumns();
     165             :     // locate parameter in select columns
     166           0 :     Reference<XParametersSupplier> xParaSup(m_xComposer,UNO_QUERY);
     167           0 :     Reference<XIndexAccess> xQueryParameters = xParaSup->getParameters();
     168           0 :     const sal_Int32 nParaCount = xQueryParameters->getCount();
     169           0 :     Sequence< ::rtl::OUString> aParameterColumns(nParaCount);
     170           0 :     for(sal_Int32 i = 0; i< nParaCount;++i)
     171             :     {
     172           0 :         Reference<XPropertySet> xPara(xQueryParameters->getByIndex(i),UNO_QUERY_THROW);
     173           0 :         xPara->getPropertyValue(PROPERTY_REALNAME) >>= aParameterColumns[i];
     174           0 :     }
     175             : 
     176           0 :     ::rtl::OUString sUpdateTableName( i_rUpdateTableName );
     177           0 :     if ( sUpdateTableName.isEmpty() )
     178             :     {
     179             :         OSL_FAIL( "OKeySet::findTableColumnsMatching_throw: This is a fallback only - it won't work when the table has an alias name." );
     180             :         // If i_aTable originates from a query composer, and is a table which appears with an alias in the SELECT statement,
     181             :         // then the below code will not produce correct results.
     182             :         // For instance, imagine a "SELECT alias.col FROM table AS alias". Now i_aTable would be the table named
     183             :         // "table", so our sUpdateTableName would be "table" as well - not the information about the "alias" is
     184             :         // already lost here.
     185             :         // now getColumnPositions would travers the columns, and check which of them belong to the table denoted
     186             :         // by sUpdateTableName. Since the latter is "table", but the columns only know that they belong to a table
     187             :         // named "alias", there will be no matching - so getColumnPositions wouldn't find anything.
     188             : 
     189           0 :         ::rtl::OUString sCatalog, sSchema, sTable;
     190           0 :         Reference<XPropertySet> xTableProp( i_aTable, UNO_QUERY_THROW );
     191           0 :         xTableProp->getPropertyValue( PROPERTY_CATALOGNAME )>>= sCatalog;
     192           0 :         xTableProp->getPropertyValue( PROPERTY_SCHEMANAME ) >>= sSchema;
     193           0 :         xTableProp->getPropertyValue( PROPERTY_NAME )       >>= sTable;
     194           0 :         sUpdateTableName = dbtools::composeTableName( i_xMeta, sCatalog, sSchema, sTable, sal_False, ::dbtools::eInDataManipulation );
     195             :     }
     196             : 
     197           0 :     ::dbaccess::getColumnPositions(i_xQueryColumns,aBestColumnNames,sUpdateTableName,(*o_pKeyColumnNames),true);
     198           0 :     ::dbaccess::getColumnPositions(i_xQueryColumns,xTblColumns->getElementNames(),sUpdateTableName,(*m_pColumnNames),true);
     199           0 :     ::dbaccess::getColumnPositions(i_xQueryColumns,aParameterColumns,sUpdateTableName,(*m_pParameterNames),true);
     200             : 
     201           0 :     if ( o_pKeyColumnNames->empty() )
     202             :     {
     203           0 :         ::dbtools::throwGenericSQLException( ::rtl::OUString( "Could not find any key column."  ), *this );
     204             :     }
     205             : 
     206           0 :     for (   SelectColumnsMetaData::const_iterator keyColumn = o_pKeyColumnNames->begin();
     207           0 :             keyColumn != o_pKeyColumnNames->end();
     208             :             ++keyColumn
     209             :         )
     210             :     {
     211           0 :         if ( !xTblColumns->hasByName( keyColumn->second.sRealName ) )
     212           0 :             continue;
     213             : 
     214           0 :         Reference<XPropertySet> xProp( xTblColumns->getByName( keyColumn->second.sRealName ), UNO_QUERY );
     215           0 :         sal_Bool bAuto = sal_False;
     216           0 :         if ( ( xProp->getPropertyValue( PROPERTY_ISAUTOINCREMENT ) >>= bAuto ) && bAuto )
     217           0 :             m_aAutoColumns.push_back( keyColumn->first );
     218           0 :     }
     219           0 : }
     220             : SAL_WNODEPRECATED_DECLARATIONS_POP
     221             : 
     222             : namespace
     223             : {
     224           0 :     void appendOneKeyColumnClause( const ::rtl::OUString &tblName, const ::rtl::OUString &colName, ::rtl::OUStringBuffer &o_buf )
     225             :     {
     226           0 :         static ::rtl::OUString s_sDot(".");
     227           0 :         static ::rtl::OUString s_sParam0(" ( 1 = ? AND ");
     228           0 :         static ::rtl::OUString s_sParam1(" = ? OR 1 = ? AND ");
     229           0 :         static ::rtl::OUString s_sParam2(" IS NULL ) ");
     230           0 :         o_buf.append(s_sParam0);
     231           0 :         o_buf.append(tblName);
     232           0 :         o_buf.append(s_sDot);
     233           0 :         o_buf.append(colName);
     234           0 :         o_buf.append(s_sParam1);
     235           0 :         o_buf.append(tblName);
     236           0 :         o_buf.append(s_sDot);
     237           0 :         o_buf.append(colName);
     238           0 :         o_buf.append(s_sParam2);
     239           0 :     }
     240             : }
     241             : 
     242           0 : void OKeySet::setOneKeyColumnParameter( sal_Int32 &nPos, const Reference< XParameters > &_xParameter, const connectivity::ORowSetValue &_rValue, sal_Int32 _nType, sal_Int32 _nScale ) const
     243             : {
     244           0 :     if ( _rValue.isNull() )
     245             :     {
     246           0 :         _xParameter->setByte( nPos++, 0 );
     247             :         // We do the full call so that the right sqlType is passed to setNull
     248           0 :         setParameter( nPos++, _xParameter, _rValue, _nType, _nScale );
     249           0 :         _xParameter->setByte( nPos++, 1 );
     250             :     }
     251             :     else
     252             :     {
     253           0 :         _xParameter->setByte( nPos++, 1 );
     254           0 :         setParameter( nPos++, _xParameter, _rValue, _nType, _nScale );
     255           0 :         _xParameter->setByte( nPos++, 0 );
     256             :     }
     257           0 : }
     258             : 
     259           0 : ::rtl::OUStringBuffer OKeySet::createKeyFilter()
     260             : {
     261           0 :     static ::rtl::OUString aAnd(" AND ");
     262           0 :     const ::rtl::OUString aQuote    = getIdentifierQuoteString();
     263           0 :     ::rtl::OUStringBuffer aFilter;
     264             :     // create the where clause
     265           0 :     Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
     266           0 :     SelectColumnsMetaData::iterator aPosEnd = m_pKeyColumnNames->end();
     267           0 :     for(SelectColumnsMetaData::iterator aPosIter = m_pKeyColumnNames->begin();aPosIter != aPosEnd;)
     268             :     {
     269           0 :         appendOneKeyColumnClause(::dbtools::quoteTableName( xMeta,aPosIter->second.sTableName,::dbtools::eInDataManipulation),
     270           0 :                                  ::dbtools::quoteName( aQuote,aPosIter->second.sRealName),
     271           0 :                                  aFilter);
     272           0 :         ++aPosIter;
     273           0 :         if(aPosIter != aPosEnd)
     274           0 :             aFilter.append(aAnd);
     275             :     }
     276           0 :     return aFilter;
     277             : }
     278             : 
     279           0 : void OKeySet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::OUString& i_sRowSetFilter)
     280             : {
     281             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::construct" );
     282           0 :     OCacheSet::construct(_xDriverSet,i_sRowSetFilter);
     283           0 :     initColumns();
     284             : 
     285           0 :     Reference<XNameAccess> xKeyColumns  = getKeyColumns();
     286           0 :     Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
     287           0 :     Reference<XColumnsSupplier> xQueryColSup(m_xComposer,UNO_QUERY);
     288           0 :     const Reference<XNameAccess> xQueryColumns = xQueryColSup->getColumns();
     289           0 :     findTableColumnsMatching_throw(makeAny(m_xTable),m_sUpdateTableName,xMeta,xQueryColumns,m_pKeyColumnNames);
     290             : 
     291             :     // the first row is empty because it's now easier for us to distinguish when we are beforefirst or first
     292             :     // without extra variable to be set
     293           0 :     OKeySetValue keySetValue((ORowSetValueVector *)NULL,::std::pair<sal_Int32,Reference<XRow> >(0,(Reference<XRow>)NULL));
     294           0 :     m_aKeyMap.insert(OKeySetMatrix::value_type(0, keySetValue));
     295           0 :     m_aKeyIter = m_aKeyMap.begin();
     296             : 
     297           0 :     ::rtl::OUStringBuffer aFilter = createKeyFilter();
     298             : 
     299           0 :     Reference< XSingleSelectQueryComposer> xSourceComposer(m_xComposer,UNO_QUERY);
     300           0 :     Reference< XMultiServiceFactory >  xFactory(m_xConnection, UNO_QUERY_THROW);
     301           0 :     Reference<XSingleSelectQueryComposer> xAnalyzer(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY);
     302           0 :     xAnalyzer->setElementaryQuery(xSourceComposer->getElementaryQuery());
     303           0 :     Reference<XTablesSupplier> xTabSup(xAnalyzer,uno::UNO_QUERY);
     304           0 :     Reference<XNameAccess> xSelectTables(xTabSup->getTables(),uno::UNO_QUERY);
     305           0 :     const Sequence< ::rtl::OUString> aSeq = xSelectTables->getElementNames();
     306           0 :     if ( aSeq.getLength() > 1 ) // special handling for join
     307             :     {
     308           0 :         static ::rtl::OUString aAnd(" AND ");
     309           0 :         const ::rtl::OUString aQuote    = getIdentifierQuoteString();
     310           0 :         const ::rtl::OUString* pIter = aSeq.getConstArray();
     311           0 :         const ::rtl::OUString* pEnd   = pIter + aSeq.getLength();
     312           0 :         for(;pIter != pEnd;++pIter)
     313             :         {
     314           0 :             if ( *pIter != m_sUpdateTableName )
     315             :             {
     316           0 :                 connectivity::OSQLTable xSelColSup(xSelectTables->getByName(*pIter),uno::UNO_QUERY);
     317           0 :                 Reference<XPropertySet> xProp(xSelColSup,uno::UNO_QUERY);
     318           0 :                 ::rtl::OUString sSelectTableName = ::dbtools::composeTableName( xMeta, xProp, ::dbtools::eInDataManipulation, false, false, false );
     319             : 
     320           0 :                 ::dbaccess::getColumnPositions(xQueryColumns,xSelColSup->getColumns()->getElementNames(),sSelectTableName,(*m_pForeignColumnNames));
     321             : 
     322           0 :                 const SelectColumnsMetaData::iterator aPosEnd = (*m_pForeignColumnNames).end();
     323           0 :                 for(SelectColumnsMetaData::iterator aPosIter = (*m_pForeignColumnNames).begin();aPosIter != aPosEnd;++aPosIter)
     324             :                 {
     325             :                     // look for columns not in the source columns to use them as filter as well
     326           0 :                     if ( aFilter.getLength() )
     327           0 :                         aFilter.append(aAnd);
     328             :                     appendOneKeyColumnClause(::dbtools::quoteName( aQuote,sSelectTableName),
     329           0 :                                              ::dbtools::quoteName( aQuote,aPosIter->second.sRealName),
     330           0 :                                              aFilter);
     331             :                 }
     332           0 :                 break;
     333             :             }
     334           0 :         }
     335             :     }
     336           0 :     executeStatement(aFilter,i_sRowSetFilter,xAnalyzer);
     337           0 : }
     338           0 : void OKeySet::executeStatement(::rtl::OUStringBuffer& io_aFilter,const ::rtl::OUString& i_sRowSetFilter,Reference<XSingleSelectQueryComposer>& io_xAnalyzer)
     339             : {
     340           0 :     bool bFilterSet = !i_sRowSetFilter.isEmpty();
     341           0 :     if ( bFilterSet )
     342             :     {
     343           0 :         FilterCreator aFilterCreator;
     344           0 :         aFilterCreator.append( i_sRowSetFilter );
     345           0 :         aFilterCreator.append( io_aFilter.makeStringAndClear() );
     346           0 :         io_aFilter = aFilterCreator.getComposedAndClear();
     347             :     }
     348           0 :     io_xAnalyzer->setFilter(io_aFilter.makeStringAndClear());
     349           0 :     if ( bFilterSet )
     350             :     {
     351           0 :         Sequence< Sequence< PropertyValue > > aFilter2 = io_xAnalyzer->getStructuredFilter();
     352           0 :         const Sequence< PropertyValue >* pOr = aFilter2.getConstArray();
     353           0 :         const Sequence< PropertyValue >* pOrEnd = pOr + aFilter2.getLength();
     354           0 :         for(;pOr != pOrEnd;++pOr)
     355             :         {
     356           0 :             const PropertyValue* pAnd = pOr->getConstArray();
     357           0 :             const PropertyValue* pAndEnd = pAnd + pOr->getLength();
     358           0 :             for(;pAnd != pAndEnd;++pAnd)
     359             :             {
     360           0 :                 ::rtl::OUString sValue;
     361           0 :                 if ( !(pAnd->Value >>= sValue) || !( sValue == "?" || sValue.matchAsciiL( ":",1,0 ) ) )
     362             :                 { // we have a criteria which has to be taken into account for updates
     363           0 :                     m_aFilterColumns.push_back(pAnd->Name);
     364             :                 }
     365           0 :             }
     366           0 :         }
     367             :     }
     368           0 :     m_xStatement = m_xConnection->prepareStatement(io_xAnalyzer->getQueryWithSubstitution());
     369           0 :     ::comphelper::disposeComponent(io_xAnalyzer);
     370           0 : }
     371             : 
     372           0 : void OKeySet::invalidateRow()
     373             : {
     374           0 :     m_xRow = NULL;
     375           0 :     ::comphelper::disposeComponent(m_xSet);
     376           0 : }
     377             : 
     378           0 : Any SAL_CALL OKeySet::getBookmark() throw(SQLException, RuntimeException)
     379             : {
     380             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBookmark" );
     381             :     OSL_ENSURE(m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin(),
     382             :         "getBookmark is only possible when we stand on a valid row!");
     383           0 :     return makeAny(m_aKeyIter->first);
     384             : }
     385             : 
     386           0 : sal_Bool SAL_CALL OKeySet::moveToBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
     387             : {
     388             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveToBookmark" );
     389           0 :     m_bInserted = m_bUpdated = m_bDeleted = sal_False;
     390           0 :     m_aKeyIter = m_aKeyMap.find(::comphelper::getINT32(bookmark));
     391           0 :     invalidateRow();
     392           0 :     return m_aKeyIter != m_aKeyMap.end();
     393             : }
     394             : 
     395           0 : sal_Bool SAL_CALL OKeySet::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) throw(SQLException, RuntimeException)
     396             : {
     397             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveRelativeToBookmark" );
     398           0 :     m_bInserted = m_bUpdated = m_bDeleted = sal_False;
     399           0 :     m_aKeyIter = m_aKeyMap.find(::comphelper::getINT32(bookmark));
     400           0 :     if(m_aKeyIter != m_aKeyMap.end())
     401             :     {
     402           0 :         return relative(rows);
     403             :     }
     404             : 
     405           0 :     invalidateRow();
     406           0 :     return false;
     407             : }
     408             : 
     409           0 : sal_Int32 SAL_CALL OKeySet::compareBookmarks( const Any& _first, const Any& _second ) throw(SQLException, RuntimeException)
     410             : {
     411             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::compareBookmarks" );
     412           0 :     sal_Int32 nFirst = 0, nSecond = 0;
     413           0 :     _first >>= nFirst;
     414           0 :     _second >>= nSecond;
     415             : 
     416           0 :     return (nFirst != nSecond) ? CompareBookmark::NOT_EQUAL : CompareBookmark::EQUAL;
     417             : }
     418             : 
     419           0 : sal_Bool SAL_CALL OKeySet::hasOrderedBookmarks(  ) throw(SQLException, RuntimeException)
     420             : {
     421             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::hasOrderedBookmarks" );
     422           0 :     return sal_True;
     423             : }
     424             : 
     425           0 : sal_Int32 SAL_CALL OKeySet::hashBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
     426             : {
     427             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::hashBookmark" );
     428           0 :     return ::comphelper::getINT32(bookmark);
     429             : }
     430             : 
     431             : // ::com::sun::star::sdbcx::XDeleteRows
     432           0 : Sequence< sal_Int32 > SAL_CALL OKeySet::deleteRows( const Sequence< Any >& rows ,const connectivity::OSQLTable& _xTable) throw(SQLException, RuntimeException)
     433             : {
     434             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::deleteRows" );
     435           0 :     Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
     436           0 :     fillTableName(xSet);
     437             : 
     438           0 :     ::rtl::OUStringBuffer aSql = ::rtl::OUString("DELETE FROM ");
     439           0 :     aSql.append(m_aComposedTableName);
     440           0 :     aSql.append(::rtl::OUString(" WHERE "));
     441             : 
     442             :     // list all columns that should be set
     443           0 :     const ::rtl::OUString aQuote    = getIdentifierQuoteString();
     444           0 :     static ::rtl::OUString aAnd(" AND ");
     445           0 :     static ::rtl::OUString aOr(" OR ");
     446           0 :     static ::rtl::OUString aEqual(" = ?");
     447             : 
     448             : 
     449             :     // use keys and indexes for exact postioning
     450             :     // first the keys
     451           0 :     Reference<XNameAccess> xKeyColumns = getKeyColumns();
     452             : 
     453           0 :     ::rtl::OUStringBuffer aCondition = ::rtl::OUString("( ");
     454             : 
     455           0 :     SelectColumnsMetaData::const_iterator aIter = (*m_pKeyColumnNames).begin();
     456           0 :     SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
     457           0 :     for(;aIter != aPosEnd;++aIter)
     458             :     {
     459           0 :         aCondition.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
     460           0 :         aCondition.append(aEqual);
     461           0 :         aCondition.append(aAnd);
     462             :     }
     463           0 :     aCondition.setLength(aCondition.getLength()-5);
     464           0 :     const ::rtl::OUString sCon( aCondition.makeStringAndClear() );
     465             : 
     466           0 :     const Any* pBegin   = rows.getConstArray();
     467           0 :     const Any* pEnd     = pBegin + rows.getLength();
     468             : 
     469           0 :     Sequence< Any > aKeys;
     470           0 :     for(;pBegin != pEnd;++pBegin)
     471             :     {
     472           0 :         aSql.append(sCon);
     473           0 :         aSql.append(aOr);
     474             :     }
     475           0 :     aSql.setLength(aSql.getLength()-3);
     476             : 
     477             :     // now create end execute the prepared statement
     478             : 
     479           0 :     Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql.makeStringAndClear()));
     480           0 :     Reference< XParameters > xParameter(xPrep,UNO_QUERY);
     481             : 
     482           0 :     pBegin  = rows.getConstArray();
     483           0 :     sal_Int32 i=1;
     484           0 :     for(;pBegin != pEnd;++pBegin)
     485             :     {
     486           0 :         m_aKeyIter = m_aKeyMap.find(::comphelper::getINT32(*pBegin));
     487           0 :         if(m_aKeyIter != m_aKeyMap.end())
     488             :         {
     489           0 :             connectivity::ORowVector< ORowSetValue >::Vector::iterator aKeyIter = m_aKeyIter->second.first->get().begin();
     490           0 :             connectivity::ORowVector< ORowSetValue >::Vector::iterator aKeyEnd = m_aKeyIter->second.first->get().end();
     491           0 :             SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
     492           0 :             for(sal_uInt16 j = 0;aKeyIter != aKeyEnd;++aKeyIter,++j,++aPosIter)
     493             :             {
     494           0 :                 setParameter(i++,xParameter,*aKeyIter,aPosIter->second.nType,aPosIter->second.nScale);
     495             :             }
     496             :         }
     497             :     }
     498             : 
     499           0 :     sal_Bool bOk = xPrep->executeUpdate() > 0;
     500           0 :     Sequence< sal_Int32 > aRet(rows.getLength());
     501           0 :     memset(aRet.getArray(),bOk,sizeof(sal_Int32)*aRet.getLength());
     502           0 :     if(bOk)
     503             :     {
     504           0 :         pBegin  = rows.getConstArray();
     505           0 :         pEnd    = pBegin + rows.getLength();
     506             : 
     507           0 :         for(;pBegin != pEnd;++pBegin)
     508             :         {
     509           0 :             sal_Int32 nPos = 0;
     510           0 :             *pBegin >>= nPos;
     511           0 :             if(m_aKeyIter == m_aKeyMap.find(nPos) && m_aKeyIter != m_aKeyMap.end())
     512           0 :                 ++m_aKeyIter;
     513           0 :             m_aKeyMap.erase(nPos);
     514           0 :             m_bDeleted = sal_True;
     515             :         }
     516             :     }
     517           0 :     return aRet;
     518             : }
     519             : 
     520           0 : void SAL_CALL OKeySet::updateRow(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const connectivity::OSQLTable& _xTable  ) throw(SQLException, RuntimeException)
     521             : {
     522             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::updateRow" );
     523           0 :     Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
     524           0 :     fillTableName(xSet);
     525             : 
     526           0 :     ::rtl::OUStringBuffer aSql = ::rtl::OUString("UPDATE ");
     527           0 :     aSql.append(m_aComposedTableName);
     528           0 :     aSql.append(::rtl::OUString(" SET "));
     529             :     // list all cloumns that should be set
     530           0 :     static ::rtl::OUString aPara(" = ?,");
     531           0 :     ::rtl::OUString aQuote  = getIdentifierQuoteString();
     532           0 :     static ::rtl::OUString aAnd(" AND ");
     533           0 :     ::rtl::OUString sIsNull(" IS NULL");
     534           0 :     ::rtl::OUString sParam(" = ?");
     535             : 
     536             :     // use keys and indexes for excat postioning
     537             :     // first the keys
     538           0 :     Reference<XNameAccess> xKeyColumns = getKeyColumns();
     539             : 
     540             :     // second the indexes
     541           0 :     Reference<XIndexesSupplier> xIndexSup(_xTable,UNO_QUERY);
     542           0 :     Reference<XIndexAccess> xIndexes;
     543           0 :     if ( xIndexSup.is() )
     544           0 :         xIndexes.set(xIndexSup->getIndexes(),UNO_QUERY);
     545             : 
     546             : 
     547           0 :     ::std::vector< Reference<XNameAccess> > aAllIndexColumns;
     548           0 :     lcl_fillIndexColumns(xIndexes,aAllIndexColumns);
     549             : 
     550           0 :     ::rtl::OUString aColumnName;
     551           0 :     ::rtl::OUStringBuffer sKeyCondition,sIndexCondition;
     552           0 :     ::std::vector<sal_Int32> aIndexColumnPositions;
     553             : 
     554           0 :     const sal_Int32 nOldLength = aSql.getLength();
     555           0 :     sal_Int32 i = 1;
     556             :     // here we build the condition part for the update statement
     557           0 :     SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
     558           0 :     SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
     559           0 :     for(;aIter != aEnd;++aIter,++i)
     560             :     {
     561           0 :         if ( m_pKeyColumnNames->find(aIter->first) != m_pKeyColumnNames->end() )
     562             :         {
     563           0 :             sKeyCondition.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
     564           0 :             if((_rOrginalRow->get())[aIter->second.nPosition].isNull())
     565           0 :                 sKeyCondition.append(sIsNull);
     566             :             else
     567           0 :                 sKeyCondition.append(sParam);
     568           0 :             sKeyCondition.append(aAnd);
     569             :         }
     570             :         else
     571             :         {
     572           0 :             ::std::vector< Reference<XNameAccess> >::const_iterator aIndexEnd = aAllIndexColumns.end();
     573           0 :             for( ::std::vector< Reference<XNameAccess> >::const_iterator aIndexIter = aAllIndexColumns.begin();
     574             :                 aIndexIter != aIndexEnd;++aIndexIter)
     575             :             {
     576           0 :                 if((*aIndexIter)->hasByName(aIter->first))
     577             :                 {
     578           0 :                     sIndexCondition.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
     579           0 :                     if((_rOrginalRow->get())[aIter->second.nPosition].isNull())
     580           0 :                         sIndexCondition.append(sIsNull);
     581             :                     else
     582             :                     {
     583           0 :                         sIndexCondition.append(sParam);
     584           0 :                         aIndexColumnPositions.push_back(aIter->second.nPosition);
     585             :                     }
     586           0 :                     sIndexCondition.append(aAnd);
     587           0 :                     break;
     588             :                 }
     589             :             }
     590             :         }
     591           0 :         if((_rInsertRow->get())[aIter->second.nPosition].isModified())
     592             :         {
     593           0 :             aSql.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
     594           0 :             aSql.append(aPara);
     595             :         }
     596             :     }
     597             : 
     598           0 :     if( aSql.getLength() != nOldLength )
     599             :     {
     600           0 :         aSql.setLength(aSql.getLength()-1);
     601             :     }
     602             :     else
     603           0 :         ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_VALUE_CHANGED ), SQL_GENERAL_ERROR, m_xConnection );
     604             : 
     605           0 :     if(sKeyCondition.getLength() || sIndexCondition.getLength())
     606             :     {
     607           0 :         aSql.append(::rtl::OUString(" WHERE "));
     608           0 :         if(sKeyCondition.getLength() && sIndexCondition.getLength())
     609             :         {
     610           0 :             aSql.append(sKeyCondition.makeStringAndClear());
     611           0 :             aSql.append(sIndexCondition.makeStringAndClear());
     612             :         }
     613           0 :         else if(sKeyCondition.getLength())
     614             :         {
     615           0 :             aSql.append(sKeyCondition.makeStringAndClear());
     616             :         }
     617           0 :         else if(sIndexCondition.getLength())
     618             :         {
     619           0 :             aSql.append(sIndexCondition.makeStringAndClear());
     620             :         }
     621           0 :         aSql.setLength(aSql.getLength()-5); // remove the last AND
     622             :     }
     623             :     else
     624           0 :         ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_CONDITION_FOR_PK ), SQL_GENERAL_ERROR, m_xConnection );
     625             : 
     626             :     // now create end execute the prepared statement
     627           0 :     ::rtl::OUString sEmpty;
     628           0 :     executeUpdate(_rInsertRow ,_rOrginalRow,aSql.makeStringAndClear(),sEmpty,aIndexColumnPositions);
     629           0 : }
     630             : 
     631           0 : void OKeySet::executeUpdate(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName,const ::std::vector<sal_Int32>& _aIndexColumnPositions)
     632             : {
     633             :     // now create end execute the prepared statement
     634           0 :     Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(i_sSQL));
     635           0 :     Reference< XParameters > xParameter(xPrep,UNO_QUERY);
     636             : 
     637           0 :     bool bRefetch = true;
     638           0 :     Reference<XRow> xRow;
     639           0 :     sal_Int32 i = 1;
     640             :     // first the set values
     641           0 :     SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
     642           0 :     SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
     643           0 :     sal_uInt16 j = 0;
     644           0 :     for(;aIter != aEnd;++aIter,++j)
     645             :     {
     646           0 :         if ( i_sTableName.isEmpty() || aIter->second.sTableName == i_sTableName )
     647             :         {
     648           0 :             sal_Int32 nPos = aIter->second.nPosition;
     649           0 :             if((_rInsertRow->get())[nPos].isModified())
     650             :             {
     651           0 :                 if ( bRefetch )
     652             :                 {
     653           0 :                     bRefetch = ::std::find(m_aFilterColumns.begin(),m_aFilterColumns.end(),aIter->second.sRealName) == m_aFilterColumns.end();
     654             :                 }
     655           0 :                 impl_convertValue_throw(_rInsertRow,aIter->second);
     656           0 :                 (_rInsertRow->get())[nPos].setSigned((_rOrginalRow->get())[nPos].isSigned());
     657           0 :                 setParameter(i++,xParameter,(_rInsertRow->get())[nPos],aIter->second.nType,aIter->second.nScale);
     658             :             }
     659             :         }
     660             :     }
     661             :     // and then the values of the where condition
     662           0 :     aIter = m_pKeyColumnNames->begin();
     663           0 :     aEnd = m_pKeyColumnNames->end();
     664           0 :     j = 0;
     665           0 :     for(;aIter != aEnd;++aIter,++j)
     666             :     {
     667           0 :         if ( i_sTableName.isEmpty() || aIter->second.sTableName == i_sTableName )
     668             :         {
     669           0 :             setParameter(i++,xParameter,(_rOrginalRow->get())[aIter->second.nPosition],aIter->second.nType,aIter->second.nScale);
     670             :         }
     671             :     }
     672           0 :     if ( !_aIndexColumnPositions.empty() )
     673             :     {
     674             :         // now we have to set the index values
     675           0 :         ::std::vector<sal_Int32>::const_iterator aIdxColIter = _aIndexColumnPositions.begin();
     676           0 :         ::std::vector<sal_Int32>::const_iterator aIdxColEnd = _aIndexColumnPositions.end();
     677           0 :         j = 0;
     678           0 :         aIter = m_pColumnNames->begin();
     679           0 :         for(;aIdxColIter != aIdxColEnd;++aIdxColIter,++i,++j,++aIter)
     680             :         {
     681           0 :             setParameter(i,xParameter,(_rOrginalRow->get())[*aIdxColIter],(_rOrginalRow->get())[*aIdxColIter].getTypeKind(),aIter->second.nScale);
     682             :         }
     683             :     }
     684           0 :     const sal_Int32 nRowsUpdated = xPrep->executeUpdate();
     685           0 :      m_bUpdated =  nRowsUpdated > 0;
     686           0 :     if(m_bUpdated)
     687             :     {
     688           0 :         const sal_Int32 nBookmark = ::comphelper::getINT32((_rInsertRow->get())[0].getAny());
     689           0 :         m_aKeyIter = m_aKeyMap.find(nBookmark);
     690           0 :         m_aKeyIter->second.second.first = 2;
     691           0 :         m_aKeyIter->second.second.second = xRow;
     692           0 :         copyRowValue(_rInsertRow,m_aKeyIter->second.first,nBookmark);
     693           0 :         tryRefetch(_rInsertRow,bRefetch);
     694           0 :     }
     695           0 : }
     696             : 
     697           0 : void SAL_CALL OKeySet::insertRow( const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
     698             : {
     699             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::insertRow" );
     700           0 :     ::rtl::OUStringBuffer aSql(::rtl::OUString("INSERT INTO "));
     701           0 :     Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
     702           0 :     fillTableName(xSet);
     703             : 
     704           0 :     aSql.append(m_aComposedTableName);
     705           0 :     aSql.append(::rtl::OUString(" ( "));
     706             :     // set values and column names
     707           0 :     ::rtl::OUStringBuffer aValues(::rtl::OUString(" VALUES ( "));
     708           0 :     static ::rtl::OUString aPara("?,");
     709           0 :     ::rtl::OUString aQuote = getIdentifierQuoteString();
     710           0 :     static ::rtl::OUString aComma(",");
     711             : 
     712           0 :     SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
     713           0 :     SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
     714           0 :     sal_Int32 j = 1;
     715           0 :     bool bRefetch = true;
     716           0 :     sal_Bool bModified = sal_False;
     717           0 :     for(;aIter != aEnd;++aIter,++j)
     718             :     {
     719           0 :         if((_rInsertRow->get())[aIter->second.nPosition].isModified())
     720             :         {
     721           0 :             if ( bRefetch )
     722             :             {
     723           0 :                 bRefetch = ::std::find(m_aFilterColumns.begin(),m_aFilterColumns.end(),aIter->second.sRealName) == m_aFilterColumns.end();
     724             :             }
     725           0 :             aSql.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
     726           0 :             aSql.append(aComma);
     727           0 :             aValues.append(aPara);
     728           0 :             bModified = sal_True;
     729             :         }
     730             :     }
     731           0 :     if ( !bModified )
     732           0 :         ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_VALUE_CHANGED ), SQL_GENERAL_ERROR, m_xConnection );
     733             : 
     734           0 :     aSql[aSql.getLength() - 1] = ')';
     735           0 :     aValues[aValues.getLength() - 1] = ')';
     736           0 :     aSql.append(aValues.makeStringAndClear());
     737             :     // now create,fill and execute the prepared statement
     738           0 :     ::rtl::OUString sEmpty;
     739           0 :     executeInsert(_rInsertRow,aSql.makeStringAndClear(),sEmpty,bRefetch);
     740           0 : }
     741             : 
     742           0 : void OKeySet::executeInsert( const ORowSetRow& _rInsertRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName,bool bRefetch )
     743             : {
     744             :     // now create,fill and execute the prepared statement
     745           0 :     Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(i_sSQL));
     746           0 :     Reference< XParameters > xParameter(xPrep,UNO_QUERY);
     747             : 
     748           0 :     SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
     749           0 :     SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
     750           0 :     for(sal_Int32 i = 1;aIter != aEnd;++aIter)
     751             :     {
     752           0 :         if ( i_sTableName.isEmpty() || aIter->second.sTableName == i_sTableName )
     753             :         {
     754           0 :             const sal_Int32 nPos = aIter->second.nPosition;
     755           0 :             if((_rInsertRow->get())[nPos].isModified())
     756             :             {
     757           0 :                 if((_rInsertRow->get())[nPos].isNull())
     758           0 :                     xParameter->setNull(i++,(_rInsertRow->get())[nPos].getTypeKind());
     759             :                 else
     760             :                 {
     761           0 :                     impl_convertValue_throw(_rInsertRow,aIter->second);
     762           0 :                     (_rInsertRow->get())[nPos].setSigned(m_aSignedFlags[nPos-1]);
     763           0 :                     setParameter(i++,xParameter,(_rInsertRow->get())[nPos],aIter->second.nType,aIter->second.nScale);
     764             :                 }
     765             :             }
     766             :         }
     767             :     }
     768             : 
     769           0 :     m_bInserted = xPrep->executeUpdate() > 0;
     770           0 :     sal_Bool bAutoValuesFetched = sal_False;
     771           0 :     if ( m_bInserted )
     772             :     {
     773             :         // first insert the default values into the insertrow
     774           0 :         aIter = m_pColumnNames->begin();
     775           0 :         for(;aIter != aEnd;++aIter)
     776             :         {
     777           0 :             if ( !(_rInsertRow->get())[aIter->second.nPosition].isModified() )
     778           0 :                 (_rInsertRow->get())[aIter->second.nPosition] = aIter->second.sDefaultValue;
     779             :         }
     780             :         try
     781             :         {
     782           0 :             Reference< XGeneratedResultSet > xGRes(xPrep, UNO_QUERY);
     783           0 :             if ( xGRes.is() )
     784             :             {
     785           0 :                 Reference< XResultSet > xRes = xGRes->getGeneratedValues();
     786           0 :                 Reference< XRow > xRow(xRes,UNO_QUERY);
     787           0 :                 if ( xRow.is() && xRes->next() )
     788             :                 {
     789           0 :                     Reference< XResultSetMetaDataSupplier > xMdSup(xRes,UNO_QUERY);
     790           0 :                     Reference< XResultSetMetaData > xMd = xMdSup->getMetaData();
     791           0 :                     sal_Int32 nColumnCount = xMd->getColumnCount();
     792           0 :                     ::std::vector< ::rtl::OUString >::iterator aAutoIter = m_aAutoColumns.begin();
     793           0 :                     ::std::vector< ::rtl::OUString >::iterator aAutoEnd = m_aAutoColumns.end();
     794           0 :                     for (sal_Int32 i = 1;aAutoIter !=  aAutoEnd && i <= nColumnCount; ++aAutoIter,++i)
     795             :                     {
     796             : #if OSL_DEBUG_LEVEL > 1
     797             :                         ::rtl::OUString sColumnName( xMd->getColumnName(i) );
     798             : #endif
     799           0 :                         SelectColumnsMetaData::iterator aFind = m_pKeyColumnNames->find(*aAutoIter);
     800           0 :                         if ( aFind != m_pKeyColumnNames->end() )
     801           0 :                             (_rInsertRow->get())[aFind->second.nPosition].fill(i, aFind->second.nType, xRow);
     802             :                     }
     803           0 :                     bAutoValuesFetched = sal_True;
     804           0 :                 }
     805           0 :             }
     806             :         }
     807           0 :         catch(const Exception&)
     808             :         {
     809             :             OSL_FAIL("Could not execute GeneratedKeys() stmt");
     810             :         }
     811             :     }
     812             : 
     813           0 :     ::comphelper::disposeComponent(xPrep);
     814             : 
     815           0 :     if ( i_sTableName.isEmpty() && !bAutoValuesFetched && m_bInserted )
     816             :     {
     817             :         // first check if all key column values were set
     818           0 :         const ::rtl::OUString sMax(" MAX(");
     819           0 :         const ::rtl::OUString sMaxEnd("),");
     820           0 :         const ::rtl::OUString sQuote = getIdentifierQuoteString();
     821           0 :         ::rtl::OUString sMaxStmt;
     822           0 :         aEnd = m_pKeyColumnNames->end();
     823           0 :         ::std::vector< ::rtl::OUString >::iterator aAutoIter = m_aAutoColumns.begin();
     824           0 :         ::std::vector< ::rtl::OUString >::iterator aAutoEnd = m_aAutoColumns.end();
     825           0 :         for (;aAutoIter !=  aAutoEnd; ++aAutoIter)
     826             :         {
     827             :             // we will only fetch values which are keycolumns
     828           0 :             SelectColumnsMetaData::iterator aFind = m_pKeyColumnNames->find(*aAutoIter);
     829           0 :             if ( aFind != aEnd )
     830             :             {
     831           0 :                 sMaxStmt += sMax;
     832           0 :                 sMaxStmt += ::dbtools::quoteName( sQuote,aFind->second.sRealName
     833           0 : );
     834           0 :                 sMaxStmt += sMaxEnd;
     835             :             }
     836             :         }
     837             : 
     838           0 :         if(!sMaxStmt.isEmpty())
     839             :         {
     840           0 :             sMaxStmt = sMaxStmt.replaceAt(sMaxStmt.getLength()-1,1,::rtl::OUString(" "));
     841           0 :             ::rtl::OUString sStmt = ::rtl::OUString("SELECT ");
     842           0 :             sStmt += sMaxStmt;
     843           0 :             sStmt += ::rtl::OUString("FROM ");
     844           0 :             ::rtl::OUString sCatalog,sSchema,sTable;
     845           0 :             ::dbtools::qualifiedNameComponents(m_xConnection->getMetaData(),m_sUpdateTableName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);
     846           0 :             sStmt += ::dbtools::composeTableNameForSelect( m_xConnection, sCatalog, sSchema, sTable );
     847             :             try
     848             :             {
     849             :                 // now fetch the autoincrement values
     850           0 :                 Reference<XStatement> xStatement = m_xConnection->createStatement();
     851           0 :                 Reference<XResultSet> xRes = xStatement->executeQuery(sStmt);
     852           0 :                 Reference<XRow> xRow(xRes,UNO_QUERY);
     853           0 :                 if(xRow.is() && xRes->next())
     854             :                 {
     855           0 :                     aAutoIter = m_aAutoColumns.begin();
     856           0 :                     for (sal_Int32 i=1;aAutoIter != aAutoEnd; ++aAutoIter,++i)
     857             :                     {
     858             :                         // we will only fetch values which are keycolumns
     859           0 :                         SelectColumnsMetaData::iterator aFind = m_pKeyColumnNames->find(*aAutoIter);
     860           0 :                         if ( aFind != aEnd )
     861           0 :                             (_rInsertRow->get())[aFind->second.nPosition].fill(i, aFind->second.nType, xRow);
     862             :                     }
     863             :                 }
     864           0 :                 ::comphelper::disposeComponent(xStatement);
     865             :             }
     866           0 :             catch(SQLException&)
     867             :             {
     868             :                 OSL_FAIL("Could not fetch with MAX() ");
     869           0 :             }
     870           0 :         }
     871             :     }
     872           0 :     if ( m_bInserted )
     873             :     {
     874           0 :         OKeySetMatrix::iterator aKeyIter = m_aKeyMap.end();
     875           0 :         --aKeyIter;
     876           0 :         ORowSetRow aKeyRow = new connectivity::ORowVector< ORowSetValue >(m_pKeyColumnNames->size());
     877           0 :         copyRowValue(_rInsertRow,aKeyRow,aKeyIter->first + 1);
     878             : 
     879           0 :         m_aKeyIter = m_aKeyMap.insert(OKeySetMatrix::value_type(aKeyIter->first + 1,OKeySetValue(aKeyRow,::std::pair<sal_Int32,Reference<XRow> >(1,(Reference<XRow>)NULL)))).first;
     880             :         // now we set the bookmark for this row
     881           0 :         (_rInsertRow->get())[0] = makeAny((sal_Int32)m_aKeyIter->first);
     882           0 :         tryRefetch(_rInsertRow,bRefetch);
     883           0 :     }
     884           0 : }
     885           0 : void OKeySet::tryRefetch(const ORowSetRow& _rInsertRow,bool bRefetch)
     886             : {
     887           0 :     if ( bRefetch )
     888             :     {
     889             :         try
     890             :         {
     891           0 :             bRefetch = doTryRefetch_throw();
     892             :         }
     893           0 :         catch(const Exception&)
     894             :         {
     895           0 :             bRefetch = false;
     896             :         }
     897             :     }
     898           0 :     if ( !bRefetch )
     899             :     {
     900           0 :         m_aKeyIter->second.second.second = new OPrivateRow(_rInsertRow->get());
     901             :     }
     902           0 : }
     903             : 
     904           0 : void OKeySet::copyRowValue(const ORowSetRow& _rInsertRow,ORowSetRow& _rKeyRow,sal_Int32 i_nBookmark)
     905             : {
     906             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::copyRowValue" );
     907           0 :     connectivity::ORowVector< ORowSetValue >::Vector::iterator aIter = _rKeyRow->get().begin();
     908             : 
     909             :     // check the if the parameter values have been changed
     910             :     OSL_ENSURE((m_aParameterValueForCache.get().size()-1) == m_pParameterNames->size(),"OKeySet::copyRowValue: Parameter values and names differ!");
     911           0 :     connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aParaValuesIter = m_aParameterValueForCache.get().begin() +1;
     912             : 
     913           0 :     bool bChanged = false;
     914           0 :     SelectColumnsMetaData::const_iterator aParaIter = (*m_pParameterNames).begin();
     915           0 :     SelectColumnsMetaData::const_iterator aParaEnd = (*m_pParameterNames).end();
     916           0 :     for(sal_Int32 i = 1;aParaIter != aParaEnd;++aParaIter,++aParaValuesIter,++i)
     917             :     {
     918           0 :         ORowSetValue aValue(*aParaValuesIter);
     919           0 :         aValue.setSigned(m_aSignedFlags[aParaIter->second.nPosition]);
     920           0 :         if ( (_rInsertRow->get())[aParaIter->second.nPosition] != aValue )
     921             :         {
     922           0 :             ORowSetValueVector aCopy(m_aParameterValueForCache);
     923           0 :             (aCopy.get())[i] = (_rInsertRow->get())[aParaIter->second.nPosition];
     924           0 :             m_aUpdatedParameter[i_nBookmark] = aCopy;
     925           0 :             bChanged = true;
     926             :         }
     927           0 :     }
     928           0 :     if ( !bChanged )
     929             :     {
     930           0 :         m_aUpdatedParameter.erase(i_nBookmark);
     931             :     }
     932             : 
     933             :     // update the key values
     934           0 :     SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
     935           0 :     SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
     936           0 :     for(;aPosIter != aPosEnd;++aPosIter,++aIter)
     937             :     {
     938           0 :         impl_convertValue_throw(_rInsertRow,aPosIter->second);
     939           0 :         *aIter = (_rInsertRow->get())[aPosIter->second.nPosition];
     940           0 :         aIter->setTypeKind(aPosIter->second.nType);
     941             :     }
     942           0 : }
     943             : 
     944           0 : void SAL_CALL OKeySet::deleteRow(const ORowSetRow& _rDeleteRow,const connectivity::OSQLTable& _xTable   ) throw(SQLException, RuntimeException)
     945             : {
     946             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::deleteRow" );
     947           0 :     Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
     948           0 :     fillTableName(xSet);
     949             : 
     950           0 :     ::rtl::OUStringBuffer aSql = ::rtl::OUString("DELETE FROM ");
     951           0 :     aSql.append(m_aComposedTableName);
     952           0 :     aSql.append(::rtl::OUString(" WHERE "));
     953             : 
     954             :     // list all cloumns that should be set
     955           0 :     ::rtl::OUString aQuote  = getIdentifierQuoteString();
     956           0 :     static ::rtl::OUString aAnd(" AND ");
     957             : 
     958             :     // use keys and indexes for excat postioning
     959           0 :     Reference<XNameAccess> xKeyColumns = getKeyColumns();
     960             :     // second the indexes
     961           0 :     Reference<XIndexesSupplier> xIndexSup(_xTable,UNO_QUERY);
     962           0 :     Reference<XIndexAccess> xIndexes;
     963           0 :     if ( xIndexSup.is() )
     964           0 :         xIndexes.set(xIndexSup->getIndexes(),UNO_QUERY);
     965             : 
     966             :     //  Reference<XColumnsSupplier>
     967           0 :     ::std::vector< Reference<XNameAccess> > aAllIndexColumns;
     968           0 :     lcl_fillIndexColumns(xIndexes,aAllIndexColumns);
     969             : 
     970           0 :     ::rtl::OUString aColumnName;
     971           0 :     ::rtl::OUStringBuffer sIndexCondition;
     972           0 :     ::std::vector<sal_Int32> aIndexColumnPositions;
     973           0 :     SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
     974           0 :     SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
     975             : 
     976           0 :     sal_Int32 i = 1;
     977           0 :     for(i = 1;aIter != aEnd;++aIter,++i)
     978             :     {
     979           0 :         if ( m_pKeyColumnNames->find(aIter->first) != m_pKeyColumnNames->end() )
     980             :         {
     981           0 :             aSql.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
     982           0 :             if((_rDeleteRow->get())[aIter->second.nPosition].isNull())
     983             :             {
     984             :                 OSL_FAIL("can a primary key be null");
     985           0 :                 aSql.append(::rtl::OUString(" IS NULL"));
     986             :             }
     987             :             else
     988           0 :                 aSql.append(::rtl::OUString(" = ?"));
     989           0 :             aSql.append(aAnd);
     990             :         }
     991             :         else
     992             :         {
     993           0 :             ::std::vector< Reference<XNameAccess> >::const_iterator aIndexEnd = aAllIndexColumns.end();
     994           0 :             for( ::std::vector< Reference<XNameAccess> >::const_iterator aIndexIter = aAllIndexColumns.begin();
     995             :                     aIndexIter != aIndexEnd;++aIndexIter)
     996             :             {
     997           0 :                 if((*aIndexIter)->hasByName(aIter->first))
     998             :                 {
     999           0 :                     sIndexCondition.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
    1000           0 :                     if((_rDeleteRow->get())[aIter->second.nPosition].isNull())
    1001           0 :                         sIndexCondition.append(::rtl::OUString(" IS NULL"));
    1002             :                     else
    1003             :                     {
    1004           0 :                         sIndexCondition.append(::rtl::OUString(" = ?"));
    1005           0 :                         aIndexColumnPositions.push_back(aIter->second.nPosition);
    1006             :                     }
    1007           0 :                     sIndexCondition.append(aAnd);
    1008             : 
    1009           0 :                     break;
    1010             :                 }
    1011             :             }
    1012             :         }
    1013             :     }
    1014           0 :     aSql.append(sIndexCondition.makeStringAndClear());
    1015           0 :     aSql.setLength(aSql.getLength()-5);
    1016             : 
    1017             :     // now create end execute the prepared statement
    1018           0 :     Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql.makeStringAndClear()));
    1019           0 :     Reference< XParameters > xParameter(xPrep,UNO_QUERY);
    1020             : 
    1021           0 :     aIter = (*m_pKeyColumnNames).begin();
    1022           0 :     aEnd = (*m_pKeyColumnNames).end();
    1023           0 :     i = 1;
    1024           0 :     for(;aIter != aEnd;++aIter,++i)
    1025             :     {
    1026           0 :         setParameter(i,xParameter,(_rDeleteRow->get())[aIter->second.nPosition],aIter->second.nType,aIter->second.nScale);
    1027             :     }
    1028             : 
    1029             :     // now we have to set the index values
    1030           0 :     ::std::vector<sal_Int32>::iterator aIdxColIter = aIndexColumnPositions.begin();
    1031           0 :     ::std::vector<sal_Int32>::iterator aIdxColEnd = aIndexColumnPositions.end();
    1032           0 :     aIter = m_pColumnNames->begin();
    1033           0 :     for(;aIdxColIter != aIdxColEnd;++aIdxColIter,++i,++aIter)
    1034             :     {
    1035           0 :         setParameter(i,xParameter,(_rDeleteRow->get())[*aIdxColIter],(_rDeleteRow->get())[*aIdxColIter].getTypeKind(),aIter->second.nScale);
    1036             :     }
    1037             : 
    1038           0 :     m_bDeleted = xPrep->executeUpdate() > 0;
    1039             : 
    1040           0 :     if(m_bDeleted)
    1041             :     {
    1042           0 :         sal_Int32 nBookmark = ::comphelper::getINT32((_rDeleteRow->get())[0].getAny());
    1043           0 :         if(m_aKeyIter == m_aKeyMap.find(nBookmark) && m_aKeyIter != m_aKeyMap.end())
    1044           0 :             ++m_aKeyIter;
    1045           0 :         m_aKeyMap.erase(nBookmark);
    1046           0 :         m_bDeleted = sal_True;
    1047           0 :     }
    1048           0 : }
    1049             : 
    1050           0 : void SAL_CALL OKeySet::cancelRowUpdates(  ) throw(SQLException, RuntimeException)
    1051             : {
    1052             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::cancelRowUpdates" );
    1053           0 :     m_bInserted = m_bUpdated = m_bDeleted = sal_False;
    1054           0 : }
    1055             : 
    1056           0 : void SAL_CALL OKeySet::moveToInsertRow(  ) throw(SQLException, RuntimeException)
    1057             : {
    1058             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveToInsertRow" );
    1059           0 : }
    1060             : 
    1061           0 : void SAL_CALL OKeySet::moveToCurrentRow(  ) throw(SQLException, RuntimeException)
    1062             : {
    1063             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveToCurrentRow" );
    1064           0 : }
    1065             : 
    1066           0 : Reference<XNameAccess> OKeySet::getKeyColumns() const
    1067             : {
    1068             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getKeyColumns" );
    1069             :     // use keys and indexes for excat postioning
    1070             :     // first the keys
    1071             : 
    1072           0 :     Reference<XIndexAccess> xKeys = m_xTableKeys;
    1073           0 :     if ( !xKeys.is() )
    1074             :     {
    1075           0 :         Reference<XPropertySet> xSet(m_xTable,UNO_QUERY);
    1076           0 :         const Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(xSet);
    1077           0 :         return xPrimaryKeyColumns;
    1078             :     }
    1079             : 
    1080           0 :     Reference<XColumnsSupplier> xKeyColsSup;
    1081           0 :     Reference<XNameAccess> xKeyColumns;
    1082           0 :     if(xKeys.is())
    1083             :     {
    1084           0 :         Reference<XPropertySet> xProp;
    1085           0 :         sal_Int32 nCount = xKeys->getCount();
    1086           0 :         for(sal_Int32 i = 0;i< nCount;++i)
    1087             :         {
    1088           0 :             xProp.set(xKeys->getByIndex(i),UNO_QUERY);
    1089           0 :             if ( xProp.is() )
    1090             :             {
    1091           0 :                 sal_Int32 nKeyType = 0;
    1092           0 :                 xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
    1093           0 :                 if(KeyType::PRIMARY == nKeyType)
    1094             :                 {
    1095           0 :                     xKeyColsSup.set(xProp,UNO_QUERY);
    1096             :                     OSL_ENSURE(xKeyColsSup.is(),"Columnsupplier is null!");
    1097           0 :                     xKeyColumns = xKeyColsSup->getColumns();
    1098             :                     break;
    1099             :                 }
    1100             :             }
    1101           0 :         }
    1102             :     }
    1103             : 
    1104           0 :     return xKeyColumns;
    1105             : }
    1106             : 
    1107           0 : sal_Bool SAL_CALL OKeySet::next(  ) throw(SQLException, RuntimeException)
    1108             : {
    1109             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::next" );
    1110           0 :     m_bInserted = m_bUpdated = m_bDeleted = sal_False;
    1111             : 
    1112           0 :     if(isAfterLast())
    1113           0 :         return sal_False;
    1114           0 :     ++m_aKeyIter;
    1115           0 :     if(!m_bRowCountFinal && m_aKeyIter == m_aKeyMap.end())
    1116             :     {
    1117             :         // not yet all records fetched, but we reached the end of those we fetched
    1118             :         // try to fetch one more row
    1119           0 :         if (fetchRow())
    1120             :         {
    1121             :             OSL_ENSURE(!isAfterLast(), "fetchRow succeeded, but isAfterLast()");
    1122           0 :             return true;
    1123             :         }
    1124             :         else
    1125             :         {
    1126             :             // nope, we arrived at end of data
    1127           0 :             m_aKeyIter = m_aKeyMap.end();
    1128             :             OSL_ENSURE(isAfterLast(), "fetchRow failed, but not end of data");
    1129             :         }
    1130             :     }
    1131             : 
    1132           0 :     invalidateRow();
    1133           0 :     return !isAfterLast();
    1134             : }
    1135             : 
    1136           0 : sal_Bool SAL_CALL OKeySet::isBeforeFirst(  ) throw(SQLException, RuntimeException)
    1137             : {
    1138             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isBeforeFirst" );
    1139           0 :     return m_aKeyIter == m_aKeyMap.begin();
    1140             : }
    1141             : 
    1142           0 : sal_Bool SAL_CALL OKeySet::isAfterLast(  ) throw(SQLException, RuntimeException)
    1143             : {
    1144             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isAfterLast" );
    1145           0 :     return  m_bRowCountFinal && m_aKeyIter == m_aKeyMap.end();
    1146             : }
    1147             : 
    1148           0 : sal_Bool SAL_CALL OKeySet::isFirst(  ) throw(SQLException, RuntimeException)
    1149             : {
    1150             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isFirst" );
    1151           0 :     OKeySetMatrix::iterator aTemp = m_aKeyMap.begin();
    1152           0 :     ++aTemp;
    1153           0 :     return m_aKeyIter == aTemp && m_aKeyIter != m_aKeyMap.end();
    1154             : }
    1155             : 
    1156           0 : sal_Bool SAL_CALL OKeySet::isLast(  ) throw(SQLException, RuntimeException)
    1157             : {
    1158             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isLast" );
    1159           0 :     if(!m_bRowCountFinal)
    1160           0 :         return sal_False;
    1161             : 
    1162           0 :     OKeySetMatrix::iterator aTemp = m_aKeyMap.end();
    1163           0 :     --aTemp;
    1164           0 :     return m_aKeyIter == aTemp;
    1165             : }
    1166             : 
    1167           0 : void SAL_CALL OKeySet::beforeFirst(  ) throw(SQLException, RuntimeException)
    1168             : {
    1169             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::beforeFirst" );
    1170           0 :     m_bInserted = m_bUpdated = m_bDeleted = sal_False;
    1171           0 :     m_aKeyIter = m_aKeyMap.begin();
    1172           0 :     invalidateRow();
    1173           0 : }
    1174             : 
    1175           0 : void SAL_CALL OKeySet::afterLast(  ) throw(SQLException, RuntimeException)
    1176             : {
    1177             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::afterLast" );
    1178           0 :     m_bInserted = m_bUpdated = m_bDeleted = sal_False;
    1179           0 :     fillAllRows();
    1180           0 :     m_aKeyIter = m_aKeyMap.end();
    1181           0 :     invalidateRow();
    1182           0 : }
    1183             : 
    1184           0 : sal_Bool SAL_CALL OKeySet::first(  ) throw(SQLException, RuntimeException)
    1185             : {
    1186             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::first" );
    1187           0 :     m_bInserted = m_bUpdated = m_bDeleted = sal_False;
    1188           0 :     m_aKeyIter = m_aKeyMap.begin();
    1189           0 :     ++m_aKeyIter;
    1190           0 :     if(m_aKeyIter == m_aKeyMap.end())
    1191             :     {
    1192           0 :         if (!fetchRow())
    1193             :         {
    1194           0 :             m_aKeyIter = m_aKeyMap.end();
    1195           0 :             return false;
    1196             :         }
    1197             :     }
    1198             :     else
    1199           0 :         invalidateRow();
    1200           0 :     return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin();
    1201             : }
    1202             : 
    1203           0 : sal_Bool SAL_CALL OKeySet::last(  ) throw(SQLException, RuntimeException)
    1204             : {
    1205           0 :     return last_checked(sal_True);
    1206             : }
    1207             : 
    1208           0 : sal_Bool OKeySet::last_checked( sal_Bool /* i_bFetchRow */ )
    1209             : {
    1210             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::last_checked" );
    1211           0 :     m_bInserted = m_bUpdated = m_bDeleted = sal_False;
    1212           0 :     bool fetchedRow = fillAllRows();
    1213             : 
    1214           0 :     m_aKeyIter = m_aKeyMap.end();
    1215           0 :     --m_aKeyIter;
    1216           0 :     if ( !fetchedRow )
    1217             :     {
    1218           0 :         invalidateRow();
    1219             :     }
    1220           0 :     return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin();
    1221             : }
    1222             : 
    1223           0 : sal_Int32 SAL_CALL OKeySet::getRow(  ) throw(SQLException, RuntimeException)
    1224             : {
    1225             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getRow" );
    1226             :     OSL_ENSURE(!isAfterLast(),"getRow is not allowed when afterlast record!");
    1227             :     OSL_ENSURE(!isBeforeFirst(),"getRow is not allowed when beforefirst record!");
    1228             : 
    1229           0 :     return ::std::distance(m_aKeyMap.begin(),m_aKeyIter);
    1230             : }
    1231             : 
    1232           0 : sal_Bool SAL_CALL OKeySet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException)
    1233             : {
    1234           0 :     return absolute_checked(row,sal_True);
    1235             : }
    1236           0 : sal_Bool OKeySet::absolute_checked( sal_Int32 row, sal_Bool /* i_bFetchRow */ )
    1237             : {
    1238             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::absolute" );
    1239           0 :     m_bInserted = m_bUpdated = m_bDeleted = sal_False;
    1240             :     OSL_ENSURE(row,"absolute(0) isn't allowed!");
    1241           0 :     bool fetchedRow = false;
    1242           0 :     if(row < 0)
    1243             :     {
    1244           0 :         if(!m_bRowCountFinal)
    1245           0 :             fetchedRow = fillAllRows();
    1246             : 
    1247           0 :         for(;row < 0 && m_aKeyIter != m_aKeyMap.begin();++row)
    1248           0 :             --m_aKeyIter;
    1249             :     }
    1250             :     else
    1251             :     {
    1252           0 :         if(row >= (sal_Int32)m_aKeyMap.size())
    1253             :         {
    1254             :             // we don't have this row
    1255           0 :             if(!m_bRowCountFinal)
    1256             :             {
    1257             :                 // but there may still be rows to fetch.
    1258           0 :                 sal_Bool bNext = sal_True;
    1259           0 :                 for(sal_Int32 i=m_aKeyMap.size()-1;i < row && bNext;++i)
    1260           0 :                     bNext = fetchRow();
    1261             :                 // it is guaranteed that the above loop has executed at least once,
    1262             :                 // that is fetchRow called at least once.
    1263           0 :                 if ( bNext )
    1264             :                 {
    1265           0 :                     fetchedRow = true;
    1266             :                 }
    1267             :                 else
    1268             :                 {
    1269             :                     // reached end of data before desired row
    1270           0 :                     m_aKeyIter = m_aKeyMap.end();
    1271           0 :                     return false;
    1272             :                 }
    1273             :             }
    1274             :             else
    1275             :             {
    1276             :                 // no more rows to fetch -> fail
    1277           0 :                 m_aKeyIter = m_aKeyMap.end();
    1278           0 :                 return false;
    1279             :             }
    1280             :         }
    1281             :         else
    1282             :         {
    1283           0 :             m_aKeyIter = m_aKeyMap.begin();
    1284           0 :             for(;row > 0 && m_aKeyIter != m_aKeyMap.end();--row)
    1285           0 :                 ++m_aKeyIter;
    1286             :         }
    1287             :     }
    1288           0 :     if ( !fetchedRow )
    1289             :     {
    1290           0 :         invalidateRow();
    1291             :     }
    1292             : 
    1293           0 :     return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin();
    1294             : }
    1295             : 
    1296           0 : sal_Bool SAL_CALL OKeySet::relative( sal_Int32 rows ) throw(SQLException, RuntimeException)
    1297             : {
    1298             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::relative" );
    1299           0 :     if(!rows)
    1300             :     {
    1301           0 :         invalidateRow();
    1302           0 :         return sal_True;
    1303             :     }
    1304           0 :     return absolute(getRow()+rows);
    1305             : }
    1306             : 
    1307           0 : sal_Bool OKeySet::previous_checked( sal_Bool /* i_bFetchRow */ )
    1308             : {
    1309             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::previous" );
    1310           0 :     m_bInserted = m_bUpdated = m_bDeleted = sal_False;
    1311           0 :     if(m_aKeyIter != m_aKeyMap.begin())
    1312             :     {
    1313           0 :         --m_aKeyIter;
    1314           0 :         invalidateRow();
    1315             :     }
    1316           0 :     return m_aKeyIter != m_aKeyMap.begin();
    1317             : }
    1318           0 : sal_Bool SAL_CALL OKeySet::previous(  ) throw(SQLException, RuntimeException)
    1319             : {
    1320           0 :     return previous_checked(sal_True);
    1321             : }
    1322             : 
    1323           0 : bool OKeySet::doTryRefetch_throw()  throw(SQLException, RuntimeException)
    1324             : {
    1325             :     // we just reassign the base members
    1326           0 :     Reference< XParameters > xParameter(m_xStatement,UNO_QUERY);
    1327             :     OSL_ENSURE(xParameter.is(),"No Parameter interface!");
    1328           0 :     xParameter->clearParameters();
    1329             : 
    1330           0 :     sal_Int32 nPos=1;
    1331           0 :     connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aParaIter;
    1332           0 :     connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aParaEnd;
    1333           0 :     OUpdatedParameter::iterator aUpdateFind = m_aUpdatedParameter.find(m_aKeyIter->first);
    1334           0 :     if ( aUpdateFind == m_aUpdatedParameter.end() )
    1335             :     {
    1336           0 :         aParaIter = m_aParameterValueForCache.get().begin();
    1337           0 :         aParaEnd = m_aParameterValueForCache.get().end();
    1338             :     }
    1339             :     else
    1340             :     {
    1341           0 :         aParaIter = aUpdateFind->second.get().begin();
    1342           0 :         aParaEnd = aUpdateFind->second.get().end();
    1343             :     }
    1344             : 
    1345           0 :     for(++aParaIter;aParaIter != aParaEnd;++aParaIter,++nPos)
    1346             :     {
    1347           0 :         ::dbtools::setObjectWithInfo( xParameter, nPos, aParaIter->makeAny(), aParaIter->getTypeKind() );
    1348             :     }
    1349             : 
    1350             :     // now set the primary key column values
    1351           0 :     connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aIter = m_aKeyIter->second.first->get().begin();
    1352           0 :     SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
    1353           0 :     SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
    1354           0 :     for(;aPosIter != aPosEnd;++aPosIter,++aIter)
    1355           0 :         setOneKeyColumnParameter(nPos,xParameter,*aIter,aPosIter->second.nType,aPosIter->second.nScale);
    1356           0 :     aPosIter = (*m_pForeignColumnNames).begin();
    1357           0 :     aPosEnd = (*m_pForeignColumnNames).end();
    1358           0 :     for(;aPosIter != aPosEnd;++aPosIter,++aIter)
    1359           0 :         setOneKeyColumnParameter(nPos,xParameter,*aIter,aPosIter->second.nType,aPosIter->second.nScale);
    1360             : 
    1361           0 :     m_xSet = m_xStatement->executeQuery();
    1362             :     OSL_ENSURE(m_xSet.is(),"No resultset from statement!");
    1363           0 :     return m_xSet->next();
    1364             : }
    1365             : 
    1366             : // -----------------------------------------------------------------------------
    1367           0 : void SAL_CALL OKeySet::refreshRow() throw(SQLException, RuntimeException)
    1368             : {
    1369             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::refreshRow" );
    1370             : 
    1371           0 :     invalidateRow();
    1372             : 
    1373           0 :     if(isBeforeFirst() || isAfterLast() || !m_xStatement.is())
    1374           0 :         return;
    1375             : 
    1376           0 :     if ( m_aKeyIter->second.second.second.is() )
    1377             :     {
    1378           0 :         m_xRow = m_aKeyIter->second.second.second;
    1379           0 :         return;
    1380             :     }
    1381             : 
    1382           0 :     sal_Bool bOK = doTryRefetch_throw();
    1383           0 :     if ( !bOK )
    1384             :     {
    1385             :         // This row has disappeared; remove it.
    1386           0 :         OKeySetMatrix::iterator aTemp = m_aKeyIter;
    1387             :         // use *next* row
    1388           0 :         ++m_aKeyIter;
    1389           0 :         m_aKeyMap.erase(aTemp);
    1390             : 
    1391             :         // adjust RowCount for the row we have removed
    1392           0 :         if (m_rRowCount > 0)
    1393           0 :             --m_rRowCount;
    1394             :         else
    1395             :             OSL_FAIL("m_rRowCount got out of sync: non-empty m_aKeyMap, but m_rRowCount <= 0");
    1396             : 
    1397           0 :         if (m_aKeyIter == m_aKeyMap.end())
    1398             :         {
    1399           0 :             ::comphelper::disposeComponent(m_xSet);
    1400           0 :             if (!isAfterLast())
    1401             :             {
    1402             :                 // it was the last fetched row,
    1403             :                 // but there may be another one to fetch
    1404           0 :                 if (!fetchRow())
    1405             :                 {
    1406             :                     // nope, that really was the last
    1407           0 :                     m_aKeyIter = m_aKeyMap.end();
    1408             :                     OSL_ENSURE(isAfterLast(), "fetchRow() failed but not isAfterLast()!");
    1409             :                 }
    1410             :             }
    1411             :             // Now, either fetchRow has set m_xRow or isAfterLast()
    1412             :         }
    1413             :         else
    1414             :         {
    1415           0 :             refreshRow();
    1416             :         }
    1417             :     }
    1418             :     else
    1419             :     {
    1420           0 :         m_xRow.set(m_xSet,UNO_QUERY);
    1421             :         OSL_ENSURE(m_xRow.is(),"No row from statement!");
    1422             :     }
    1423             : }
    1424             : 
    1425           0 : sal_Bool OKeySet::fetchRow()
    1426             : {
    1427             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::fetchRow" );
    1428             :     // fetch the next row and append on the keyset
    1429           0 :     sal_Bool bRet = sal_False;
    1430           0 :     if ( !m_bRowCountFinal && (!m_nMaxRows || sal_Int32(m_aKeyMap.size()) < m_nMaxRows) )
    1431           0 :         bRet = m_xDriverSet->next();
    1432           0 :     if ( bRet )
    1433             :     {
    1434           0 :         ORowSetRow aKeyRow = new connectivity::ORowVector< ORowSetValue >((*m_pKeyColumnNames).size() + m_pForeignColumnNames->size());
    1435             : 
    1436           0 :         ::comphelper::disposeComponent(m_xSet);
    1437           0 :         m_xRow.set(m_xDriverRow, UNO_QUERY_THROW);
    1438             : 
    1439           0 :         connectivity::ORowVector< ORowSetValue >::Vector::iterator aIter = aKeyRow->get().begin();
    1440             :         // copy key columns
    1441           0 :         SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
    1442           0 :         SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
    1443           0 :         for(;aPosIter != aPosEnd;++aPosIter,++aIter)
    1444             :         {
    1445           0 :             const SelectColumnDescription& rColDesc = aPosIter->second;
    1446           0 :             aIter->fill(rColDesc.nPosition, rColDesc.nType, m_xRow);
    1447             :         }
    1448             :         // copy missing columns from other tables
    1449           0 :         aPosIter = (*m_pForeignColumnNames).begin();
    1450           0 :         aPosEnd  = (*m_pForeignColumnNames).end();
    1451           0 :         for(;aPosIter != aPosEnd;++aPosIter,++aIter)
    1452             :         {
    1453           0 :             const SelectColumnDescription& rColDesc = aPosIter->second;
    1454           0 :             aIter->fill(rColDesc.nPosition, rColDesc.nType, m_xRow);
    1455             :         }
    1456           0 :         m_aKeyIter = m_aKeyMap.insert(OKeySetMatrix::value_type(m_aKeyMap.rbegin()->first+1,OKeySetValue(aKeyRow,::std::pair<sal_Int32,Reference<XRow> >(0,(Reference<XRow>)NULL)))).first;
    1457             :     }
    1458             :     else
    1459           0 :         m_bRowCountFinal = sal_True;
    1460           0 :     return bRet;
    1461             : }
    1462             : 
    1463           0 : bool OKeySet::fillAllRows()
    1464             : {
    1465             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::fillAllRows" );
    1466           0 :     if(m_bRowCountFinal)
    1467             :     {
    1468           0 :         return false;
    1469             :     }
    1470             :     else
    1471             :     {
    1472           0 :         while(fetchRow())
    1473             :             ;
    1474           0 :         return true;
    1475             :     }
    1476             : }
    1477             : // XRow
    1478           0 : sal_Bool SAL_CALL OKeySet::wasNull(  ) throw(SQLException, RuntimeException)
    1479             : {
    1480             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::wasNull" );
    1481           0 :     if ( ! m_xRow.is() )
    1482           0 :         throwGenericSQLException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Must call getFOO() for some FOO before wasNull()")), *this);
    1483             : 
    1484             :     OSL_ENSURE(m_xRow.is(),"m_xRow is null! I've thrown, but function execution continued?");
    1485           0 :     return m_xRow->wasNull();
    1486             : }
    1487             : 
    1488           0 : inline void OKeySet::ensureRowForData( ) throw(SQLException, RuntimeException)
    1489             : {
    1490           0 :     if (! m_xRow.is() )
    1491           0 :         refreshRow();
    1492           0 :     if (! m_xRow.is() )
    1493           0 :         throwSQLException("Failed to refetch row", "02000", *this, -2);
    1494             : 
    1495             :     OSL_ENSURE(m_xRow.is(),"m_xRow is null! I've called throwSQLException but execution continued?");
    1496           0 : }
    1497             : 
    1498           0 : ::rtl::OUString SAL_CALL OKeySet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1499             : {
    1500             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getString" );
    1501           0 :     ensureRowForData();
    1502           0 :     return m_xRow->getString(columnIndex);
    1503             : }
    1504             : 
    1505           0 : sal_Bool SAL_CALL OKeySet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1506             : {
    1507             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBoolean" );
    1508           0 :     ensureRowForData();
    1509           0 :     return m_xRow->getBoolean(columnIndex);
    1510             : }
    1511             : 
    1512           0 : sal_Int8 SAL_CALL OKeySet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1513             : {
    1514             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getByte" );
    1515           0 :     ensureRowForData();
    1516           0 :     return m_xRow->getByte(columnIndex);
    1517             : }
    1518             : 
    1519           0 : sal_Int16 SAL_CALL OKeySet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1520             : {
    1521             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getShort" );
    1522           0 :     ensureRowForData();
    1523           0 :     return m_xRow->getShort(columnIndex);
    1524             : }
    1525             : 
    1526           0 : sal_Int32 SAL_CALL OKeySet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1527             : {
    1528             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getInt" );
    1529           0 :     ensureRowForData();
    1530           0 :     return m_xRow->getInt(columnIndex);
    1531             : }
    1532             : 
    1533           0 : sal_Int64 SAL_CALL OKeySet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1534             : {
    1535             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getLong" );
    1536           0 :     ensureRowForData();
    1537           0 :     return m_xRow->getLong(columnIndex);
    1538             : }
    1539             : 
    1540           0 : float SAL_CALL OKeySet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1541             : {
    1542             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getFloat" );
    1543           0 :     ensureRowForData();
    1544           0 :     return m_xRow->getFloat(columnIndex);
    1545             : }
    1546             : 
    1547           0 : double SAL_CALL OKeySet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1548             : {
    1549             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getDouble" );
    1550           0 :     ensureRowForData();
    1551           0 :     return m_xRow->getDouble(columnIndex);
    1552             : }
    1553             : 
    1554           0 : Sequence< sal_Int8 > SAL_CALL OKeySet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1555             : {
    1556             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBytes" );
    1557           0 :     ensureRowForData();
    1558           0 :     return m_xRow->getBytes(columnIndex);
    1559             : }
    1560             : 
    1561           0 : ::com::sun::star::util::Date SAL_CALL OKeySet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1562             : {
    1563             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getDate" );
    1564           0 :     ensureRowForData();
    1565           0 :     return m_xRow->getDate(columnIndex);
    1566             : }
    1567             : 
    1568           0 : ::com::sun::star::util::Time SAL_CALL OKeySet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1569             : {
    1570             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getTime" );
    1571           0 :     ensureRowForData();
    1572           0 :     return m_xRow->getTime(columnIndex);
    1573             : }
    1574             : 
    1575           0 : ::com::sun::star::util::DateTime SAL_CALL OKeySet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1576             : {
    1577             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getTimestamp" );
    1578           0 :     ensureRowForData();
    1579           0 :     return m_xRow->getTimestamp(columnIndex);
    1580             : }
    1581             : 
    1582           0 : Reference< ::com::sun::star::io::XInputStream > SAL_CALL OKeySet::getBinaryStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1583             : {
    1584             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBinaryStream" );
    1585           0 :     ensureRowForData();
    1586           0 :     return m_xRow->getBinaryStream(columnIndex);
    1587             : }
    1588             : 
    1589           0 : Reference< ::com::sun::star::io::XInputStream > SAL_CALL OKeySet::getCharacterStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1590             : {
    1591             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getCharacterStream" );
    1592           0 :     ensureRowForData();
    1593           0 :     return m_xRow->getCharacterStream(columnIndex);
    1594             : }
    1595             : 
    1596           0 : Any SAL_CALL OKeySet::getObject( sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& typeMap ) throw(SQLException, RuntimeException)
    1597             : {
    1598             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getObject" );
    1599           0 :     ensureRowForData();
    1600           0 :     return m_xRow->getObject(columnIndex,typeMap);
    1601             : }
    1602             : 
    1603           0 : Reference< XRef > SAL_CALL OKeySet::getRef( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1604             : {
    1605             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getRef" );
    1606           0 :     ensureRowForData();
    1607           0 :     return m_xRow->getRef(columnIndex);
    1608             : }
    1609             : 
    1610           0 : Reference< XBlob > SAL_CALL OKeySet::getBlob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1611             : {
    1612             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBlob" );
    1613           0 :     ensureRowForData();
    1614           0 :     return m_xRow->getBlob(columnIndex);
    1615             : }
    1616             : 
    1617           0 : Reference< XClob > SAL_CALL OKeySet::getClob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1618             : {
    1619             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getClob" );
    1620           0 :     ensureRowForData();
    1621           0 :     return m_xRow->getClob(columnIndex);
    1622             : }
    1623             : 
    1624           0 : Reference< XArray > SAL_CALL OKeySet::getArray( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
    1625             : {
    1626             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getArray" );
    1627           0 :     ensureRowForData();
    1628           0 :     return m_xRow->getArray(columnIndex);
    1629             : }
    1630             : 
    1631           0 : sal_Bool SAL_CALL OKeySet::rowUpdated(  ) throw(SQLException, RuntimeException)
    1632             : {
    1633             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::rowUpdated" );
    1634           0 :     return m_aKeyIter != m_aKeyMap.begin() && m_aKeyIter != m_aKeyMap.end() && m_aKeyIter->second.second.first == 2;
    1635             : }
    1636             : 
    1637           0 : sal_Bool SAL_CALL OKeySet::rowInserted(  ) throw(SQLException, RuntimeException)
    1638             : {
    1639             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::rowInserted" );
    1640           0 :     return m_aKeyIter != m_aKeyMap.begin() && m_aKeyIter != m_aKeyMap.end() && m_aKeyIter->second.second.first == 1;
    1641             : }
    1642             : 
    1643           0 : sal_Bool SAL_CALL OKeySet::rowDeleted(  ) throw(SQLException, RuntimeException)
    1644             : {
    1645             :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::rowDeleted" );
    1646           0 :     sal_Bool bDeleted = m_bDeleted;
    1647           0 :     m_bDeleted = sal_False;
    1648           0 :     return bDeleted;
    1649             : }
    1650             : 
    1651             : namespace dbaccess
    1652             : {
    1653             : 
    1654           0 : void getColumnPositions(const Reference<XNameAccess>& _rxQueryColumns,
    1655             :                             const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _aColumnNames,
    1656             :                             const ::rtl::OUString& _rsUpdateTableName,
    1657             :                             SelectColumnsMetaData& o_rColumnNames,
    1658             :                             bool i_bAppendTableName)
    1659             :     {
    1660             :         // get the real name of the columns
    1661           0 :         Sequence< ::rtl::OUString> aSelNames(_rxQueryColumns->getElementNames());
    1662           0 :         const ::rtl::OUString* pSelIter     = aSelNames.getConstArray();
    1663           0 :         const ::rtl::OUString* pSelEnd      = pSelIter + aSelNames.getLength();
    1664             : 
    1665           0 :         const ::rtl::OUString* pTblColumnIter   = _aColumnNames.getConstArray();
    1666           0 :         const ::rtl::OUString* pTblColumnEnd    = pTblColumnIter + _aColumnNames.getLength();
    1667             : 
    1668             : 
    1669           0 :         ::comphelper::UStringMixLess aTmp(o_rColumnNames.key_comp());
    1670           0 :         ::comphelper::UStringMixEqual bCase(static_cast< ::comphelper::UStringMixLess*>(&aTmp)->isCaseSensitive());
    1671             : 
    1672           0 :         for(sal_Int32 nPos = 1;pSelIter != pSelEnd;++pSelIter,++nPos)
    1673             :         {
    1674           0 :             Reference<XPropertySet> xQueryColumnProp(_rxQueryColumns->getByName(*pSelIter),UNO_QUERY_THROW);
    1675           0 :             ::rtl::OUString sRealName,sTableName;
    1676             :             OSL_ENSURE(xQueryColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME),"Property REALNAME not available!");
    1677             :             OSL_ENSURE(xQueryColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!");
    1678           0 :             xQueryColumnProp->getPropertyValue(PROPERTY_REALNAME)   >>= sRealName;
    1679           0 :             xQueryColumnProp->getPropertyValue(PROPERTY_TABLENAME)  >>= sTableName;
    1680             : 
    1681           0 :             for(;pTblColumnIter != pTblColumnEnd;++pTblColumnIter)
    1682             :             {
    1683           0 :                 if(bCase(sRealName,*pTblColumnIter) && bCase(_rsUpdateTableName,sTableName) && o_rColumnNames.find(*pTblColumnIter) == o_rColumnNames.end())
    1684             :                 {
    1685           0 :                     sal_Int32 nType = 0;
    1686           0 :                     xQueryColumnProp->getPropertyValue(PROPERTY_TYPE)   >>= nType;
    1687           0 :                     sal_Int32 nScale = 0;
    1688           0 :                     xQueryColumnProp->getPropertyValue(PROPERTY_SCALE)  >>= nScale;
    1689           0 :                     ::rtl::OUString sColumnDefault;
    1690           0 :                     if ( xQueryColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_DEFAULTVALUE) )
    1691           0 :                         xQueryColumnProp->getPropertyValue(PROPERTY_DEFAULTVALUE) >>= sColumnDefault;
    1692             : 
    1693           0 :                     sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN;
    1694           0 :                     OSL_VERIFY( xQueryColumnProp->getPropertyValue( PROPERTY_ISNULLABLE ) >>= nNullable );
    1695             : 
    1696           0 :                     if ( i_bAppendTableName )
    1697             :                     {
    1698           0 :                         ::rtl::OUStringBuffer sName;
    1699           0 :                         sName.append(sTableName);
    1700           0 :                         sName.appendAscii(".");
    1701           0 :                         sName.append(sRealName);
    1702           0 :                         SelectColumnDescription aColDesc( nPos, nType,nScale,nNullable != sdbc::ColumnValue::NO_NULLS, sColumnDefault );
    1703           0 :                         aColDesc.sRealName = sRealName;
    1704           0 :                         aColDesc.sTableName = sTableName;
    1705           0 :                         o_rColumnNames[sName.makeStringAndClear()] = aColDesc;
    1706             :                     }
    1707             :                     else
    1708           0 :                         o_rColumnNames[sRealName] = SelectColumnDescription( nPos, nType,nScale,nNullable != sdbc::ColumnValue::NO_NULLS, sColumnDefault );
    1709             : 
    1710           0 :                     break;
    1711             :                 }
    1712             :             }
    1713           0 :             pTblColumnIter = _aColumnNames.getConstArray();
    1714           0 :         }
    1715           0 :     }
    1716             : }
    1717             : 
    1718           0 : void OKeySet::impl_convertValue_throw(const ORowSetRow& _rInsertRow,const SelectColumnDescription& i_aMetaData)
    1719             : {
    1720           0 :     ORowSetValue& aValue((_rInsertRow->get())[i_aMetaData.nPosition]);
    1721           0 :     switch(i_aMetaData.nType)
    1722             :     {
    1723             :         case DataType::DECIMAL:
    1724             :         case DataType::NUMERIC:
    1725             :             {
    1726           0 :                 ::rtl::OUString sValue = aValue.getString();
    1727           0 :                 sal_Int32 nIndex = sValue.indexOf('.');
    1728           0 :                 if ( nIndex != -1 )
    1729             :                 {
    1730           0 :                     aValue = sValue.copy(0,::std::min(sValue.getLength(),nIndex + (i_aMetaData.nScale > 0 ? i_aMetaData.nScale + 1 : 0)));
    1731           0 :                 }
    1732             :             }
    1733           0 :             break;
    1734             :         default:
    1735           0 :             break;
    1736             :     }
    1737           0 : }
    1738             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10