LCOV - code coverage report
Current view: top level - dbaccess/source/core/api - OptimisticSet.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 414 0.0 %
Date: 2012-08-25 Functions: 0 24 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 942 0.0 %

           Branch data     Line data    Source code
       1                 :            : 
       2                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       3                 :            : /*
       4                 :            :  * This file is part of the LibreOffice project.
       5                 :            :  *
       6                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       7                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       8                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       9                 :            :  *
      10                 :            :  * This file incorporates work covered by the following license notice:
      11                 :            :  *
      12                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      13                 :            :  *   contributor license agreements. See the NOTICE file distributed
      14                 :            :  *   with this work for additional information regarding copyright
      15                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      16                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      17                 :            :  *   except in compliance with the License. You may obtain a copy of
      18                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      19                 :            :  */
      20                 :            : 
      21                 :            : 
      22                 :            : #include "OptimisticSet.hxx"
      23                 :            : #include "core_resource.hxx"
      24                 :            : #include "core_resource.hrc"
      25                 :            : #include <com/sun/star/beans/XPropertySet.hpp>
      26                 :            : #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
      27                 :            : #include <com/sun/star/sdbc/ColumnValue.hpp>
      28                 :            : #include <com/sun/star/sdbc/XPreparedStatement.hpp>
      29                 :            : #include <com/sun/star/sdbc/XParameters.hpp>
      30                 :            : #include <com/sun/star/sdbc/XGeneratedResultSet.hpp>
      31                 :            : #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
      32                 :            : #include <com/sun/star/sdb/SQLFilterOperator.hpp>
      33                 :            : #include <com/sun/star/sdbc/XColumnLocate.hpp>
      34                 :            : #include <com/sun/star/container/XIndexAccess.hpp>
      35                 :            : #include "dbastrings.hrc"
      36                 :            : #include "apitools.hxx"
      37                 :            : #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
      38                 :            : #include <com/sun/star/sdbcx/XIndexesSupplier.hpp>
      39                 :            : #include <cppuhelper/typeprovider.hxx>
      40                 :            : #include <comphelper/types.hxx>
      41                 :            : #include <com/sun/star/sdbcx/KeyType.hpp>
      42                 :            : #include <connectivity/dbtools.hxx>
      43                 :            : #include <connectivity/dbexception.hxx>
      44                 :            : #include <list>
      45                 :            : #include <algorithm>
      46                 :            : #include <string.h>
      47                 :            : #include <com/sun/star/io/XInputStream.hpp>
      48                 :            : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
      49                 :            : #include "querycomposer.hxx"
      50                 :            : #include "composertools.hxx"
      51                 :            : #include <tools/debug.hxx>
      52                 :            : #include <rtl/logfile.hxx>
      53                 :            : 
      54                 :            : using namespace dbaccess;
      55                 :            : using namespace ::connectivity;
      56                 :            : using namespace ::dbtools;
      57                 :            : using namespace ::com::sun::star::uno;
      58                 :            : using namespace ::com::sun::star::beans;
      59                 :            : using namespace ::com::sun::star::sdbc;
      60                 :            : using namespace ::com::sun::star::sdb;
      61                 :            : using namespace ::com::sun::star::sdbcx;
      62                 :            : using namespace ::com::sun::star::container;
      63                 :            : using namespace ::com::sun::star::lang;
      64                 :            : using namespace ::com::sun::star::util;
      65                 :            : using namespace ::com::sun::star::io;
      66                 :            : using namespace ::com::sun::star;
      67                 :            : using namespace ::cppu;
      68                 :            : using namespace ::osl;
      69                 :            : 
      70                 :            : DECLARE_STL_USTRINGACCESS_MAP(::rtl::OUStringBuffer,TSQLStatements);
      71                 :            : namespace
      72                 :            : {
      73                 :          0 :     void lcl_fillKeyCondition(const ::rtl::OUString& i_sTableName,const ::rtl::OUString& i_sQuotedColumnName,const ORowSetValue& i_aValue,TSQLStatements& io_aKeyConditions)
      74                 :            :     {
      75                 :          0 :         ::rtl::OUStringBuffer& rKeyCondition = io_aKeyConditions[i_sTableName];
      76         [ #  # ]:          0 :         if ( rKeyCondition.getLength() )
      77                 :          0 :             rKeyCondition.appendAscii(" AND ");
      78                 :          0 :         rKeyCondition.append(i_sQuotedColumnName);
      79         [ #  # ]:          0 :         if ( i_aValue.isNull() )
      80                 :          0 :             rKeyCondition.appendAscii(" IS NULL");
      81                 :            :         else
      82                 :          0 :             rKeyCondition.appendAscii(" = ?");
      83                 :          0 :     }
      84                 :            : }
      85                 :            : 
      86                 :            : DBG_NAME(OptimisticSet)
      87                 :            : 
      88                 :          0 : OptimisticSet::OptimisticSet(const ::comphelper::ComponentContext& _rContext,
      89                 :            :                              const Reference< XConnection>& i_xConnection,
      90                 :            :                              const Reference< XSingleSelectQueryAnalyzer >& _xComposer,
      91                 :            :                              const ORowSetValueVector& _aParameterValueForCache,
      92                 :            :                              sal_Int32 i_nMaxRows,
      93                 :            :                              sal_Int32& o_nRowCount)
      94                 :            :             :OKeySet(NULL,NULL,::rtl::OUString(),_xComposer,_aParameterValueForCache,i_nMaxRows,o_nRowCount)
      95                 :            :             ,m_aSqlParser( _rContext.getLegacyServiceFactory() )
      96 [ #  # ][ #  # ]:          0 :             ,m_aSqlIterator( i_xConnection, Reference<XTablesSupplier>(_xComposer,UNO_QUERY)->getTables(), m_aSqlParser, NULL )
      97 [ #  # ][ #  # ]:          0 :             ,m_bResultSetChanged(false)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
      98                 :            : {
      99                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::OptimisticSet" );
     100                 :            :     DBG_CTOR(OptimisticSet,NULL);
     101                 :          0 : }
     102                 :            : 
     103 [ #  # ][ #  # ]:          0 : OptimisticSet::~OptimisticSet()
     104                 :            : {
     105                 :            :     DBG_DTOR(OptimisticSet,NULL);
     106         [ #  # ]:          0 : }
     107                 :            : 
     108                 :          0 : void OptimisticSet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::OUString& i_sRowSetFilter)
     109                 :            : {
     110                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::construct" );
     111         [ #  # ]:          0 :     OCacheSet::construct(_xDriverSet,i_sRowSetFilter);
     112         [ #  # ]:          0 :     initColumns();
     113                 :            : 
     114 [ #  # ][ #  # ]:          0 :     Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
     115 [ #  # ][ #  # ]:          0 :     bool bCase = (xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers()) ? true : false;
         [ #  # ][ #  # ]
     116         [ #  # ]:          0 :     Reference<XColumnsSupplier> xQueryColSup(m_xComposer,UNO_QUERY);
     117 [ #  # ][ #  # ]:          0 :     const Reference<XNameAccess> xQueryColumns = xQueryColSup->getColumns();
     118         [ #  # ]:          0 :     const Reference<XTablesSupplier> xTabSup(m_xComposer,UNO_QUERY);
     119 [ #  # ][ #  # ]:          0 :     const Reference<XNameAccess> xTables = xTabSup->getTables();
     120 [ #  # ][ #  # ]:          0 :     const Sequence< ::rtl::OUString> aTableNames = xTables->getElementNames();
     121                 :          0 :     const ::rtl::OUString* pTableNameIter = aTableNames.getConstArray();
     122                 :          0 :     const ::rtl::OUString* pTableNameEnd = pTableNameIter + aTableNames.getLength();
     123         [ #  # ]:          0 :     for( ; pTableNameIter != pTableNameEnd ; ++pTableNameIter)
     124                 :            :     {
     125                 :            :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     126 [ #  # ][ #  # ]:          0 :         ::std::auto_ptr<SelectColumnsMetaData> pKeyColumNames(new SelectColumnsMetaData(bCase));
     127                 :            :         SAL_WNODEPRECATED_DECLARATIONS_POP
     128 [ #  # ][ #  # ]:          0 :         findTableColumnsMatching_throw(xTables->getByName(*pTableNameIter),*pTableNameIter,xMeta,xQueryColumns,pKeyColumNames);
                 [ #  # ]
     129         [ #  # ]:          0 :         m_pKeyColumnNames->insert(pKeyColumNames->begin(),pKeyColumNames->end());
     130                 :          0 :     }
     131                 :            : 
     132                 :            :     // the first row is empty because it's now easier for us to distinguish when we are beforefirst or first
     133                 :            :     // without extra variable to be set
     134 [ #  # ][ #  # ]:          0 :     m_aKeyMap.insert(OKeySetMatrix::value_type(0,OKeySetValue(NULL,::std::pair<sal_Int32,Reference<XRow> >(0,NULL))));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     135                 :          0 :     m_aKeyIter = m_aKeyMap.begin();
     136                 :            : 
     137         [ #  # ]:          0 :     ::rtl::OUStringBuffer aFilter = createKeyFilter();
     138                 :            : 
     139         [ #  # ]:          0 :     Reference< XSingleSelectQueryComposer> xSourceComposer(m_xComposer,UNO_QUERY);
     140         [ #  # ]:          0 :     Reference< XMultiServiceFactory >  xFactory(m_xConnection, UNO_QUERY_THROW);
     141 [ #  # ][ #  # ]:          0 :     Reference<XSingleSelectQueryComposer> xAnalyzer(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY);
         [ #  # ][ #  # ]
     142 [ #  # ][ #  # ]:          0 :     ::rtl::OUString sQuery = xSourceComposer->getQuery();
     143 [ #  # ][ #  # ]:          0 :     xAnalyzer->setElementaryQuery(xSourceComposer->getElementaryQuery());
         [ #  # ][ #  # ]
     144                 :            :     // check for joins
     145                 :          0 :     ::rtl::OUString aErrorMsg;
     146                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     147         [ #  # ]:          0 :     ::std::auto_ptr<OSQLParseNode> pStatementNode( m_aSqlParser.parseTree( aErrorMsg, sQuery ) );
     148                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
     149         [ #  # ]:          0 :     m_aSqlIterator.setParseTree( pStatementNode.get() );
     150         [ #  # ]:          0 :     m_aSqlIterator.traverseAll();
     151 [ #  # ][ #  # ]:          0 :     fillJoinedColumns_throw(m_aSqlIterator.getJoinConditions());
     152                 :            : 
     153 [ #  # ][ #  # ]:          0 :     const ::rtl::OUString sComposerFilter = m_xComposer->getFilter();
     154 [ #  # ][ #  # ]:          0 :     if ( !i_sRowSetFilter.isEmpty() || (!sComposerFilter.isEmpty() && sComposerFilter != i_sRowSetFilter) )
         [ #  # ][ #  # ]
     155                 :            :     {
     156                 :          0 :         FilterCreator aFilterCreator;
     157 [ #  # ][ #  # ]:          0 :         if ( !sComposerFilter.isEmpty() && sComposerFilter != i_sRowSetFilter )
                 [ #  # ]
     158         [ #  # ]:          0 :             aFilterCreator.append( sComposerFilter );
     159         [ #  # ]:          0 :         aFilterCreator.append( i_sRowSetFilter );
     160 [ #  # ][ #  # ]:          0 :         aFilterCreator.append( aFilter.makeStringAndClear() );
     161 [ #  # ][ #  # ]:          0 :         aFilter = aFilterCreator.getComposedAndClear();
                 [ #  # ]
     162                 :            :     }
     163 [ #  # ][ #  # ]:          0 :     xAnalyzer->setFilter(aFilter.makeStringAndClear());
                 [ #  # ]
     164 [ #  # ][ #  # ]:          0 :     m_xStatement = m_xConnection->prepareStatement(xAnalyzer->getQueryWithSubstitution());
         [ #  # ][ #  # ]
                 [ #  # ]
     165 [ #  # ][ #  # ]:          0 :     ::comphelper::disposeComponent(xAnalyzer);
                 [ #  # ]
     166                 :          0 : }
     167                 :            : 
     168                 :            : // ::com::sun::star::sdbcx::XDeleteRows
     169                 :          0 : Sequence< sal_Int32 > SAL_CALL OptimisticSet::deleteRows( const Sequence< Any >& /*rows*/ ,const connectivity::OSQLTable& /*_xTable*/) throw(SQLException, RuntimeException)
     170                 :            : {
     171                 :          0 :     Sequence< sal_Int32 > aRet;
     172                 :          0 :     return aRet;
     173                 :            : }
     174                 :            : 
     175                 :          0 : void SAL_CALL OptimisticSet::updateRow(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const connectivity::OSQLTable& /*_xTable*/  ) throw(SQLException, RuntimeException)
     176                 :            : {
     177                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::updateRow" );
     178         [ #  # ]:          0 :     if ( m_aJoinedKeyColumns.empty() )
     179         [ #  # ]:          0 :         throw SQLException();
     180                 :            :     // list all cloumns that should be set
     181 [ #  # ][ #  # ]:          0 :     static ::rtl::OUString s_sPara(" = ?");
     182         [ #  # ]:          0 :     ::rtl::OUString aQuote  = getIdentifierQuoteString();
     183                 :            : 
     184                 :          0 :     ::rtl::OUString aColumnName;
     185                 :          0 :     ::rtl::OUStringBuffer sKeyCondition;
     186         [ #  # ]:          0 :     ::std::map< ::rtl::OUString,bool > aResultSetChanged;
     187         [ #  # ]:          0 :     TSQLStatements aKeyConditions;
     188         [ #  # ]:          0 :     TSQLStatements aIndexConditions;
     189         [ #  # ]:          0 :     TSQLStatements aSql;
     190                 :            : 
     191                 :            :     // here we build the condition part for the update statement
     192                 :          0 :     SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
     193                 :          0 :     SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
     194         [ #  # ]:          0 :     for(;aIter != aEnd;++aIter)
     195                 :            :     {
     196 [ #  # ][ #  # ]:          0 :         if ( aResultSetChanged.find( aIter->second.sTableName ) == aResultSetChanged.end() )
     197         [ #  # ]:          0 :             aResultSetChanged[aIter->second.sTableName] = false;
     198         [ #  # ]:          0 :         const ::rtl::OUString sQuotedColumnName = ::dbtools::quoteName( aQuote,aIter->second.sRealName);
     199 [ #  # ][ #  # ]:          0 :         if ( m_pKeyColumnNames->find(aIter->first) != m_pKeyColumnNames->end() )
     200                 :            :         {
     201 [ #  # ][ #  # ]:          0 :             aResultSetChanged[aIter->second.sTableName] = m_aJoinedKeyColumns.find(aIter->second.nPosition) != m_aJoinedKeyColumns.end();
                 [ #  # ]
     202 [ #  # ][ #  # ]:          0 :             lcl_fillKeyCondition(aIter->second.sTableName,sQuotedColumnName,(_rOrginalRow->get())[aIter->second.nPosition],aKeyConditions);
     203                 :            :         }
     204 [ #  # ][ #  # ]:          0 :         if((_rInsertRow->get())[aIter->second.nPosition].isModified())
     205                 :            :         {
     206 [ #  # ][ #  # ]:          0 :             if ( m_aJoinedKeyColumns.find(aIter->second.nPosition) != m_aJoinedKeyColumns.end() )
                 [ #  # ]
     207         [ #  # ]:          0 :                 throw SQLException();
     208                 :            : 
     209 [ #  # ][ #  # ]:          0 :             ::std::map<sal_Int32,sal_Int32>::const_iterator aJoinIter = m_aJoinedColumns.find(aIter->second.nPosition);
     210 [ #  # ][ #  # ]:          0 :             if ( aJoinIter != m_aJoinedColumns.end() )
                 [ #  # ]
     211                 :            :             {
     212 [ #  # ][ #  # ]:          0 :                 (_rInsertRow->get())[aJoinIter->second] = (_rInsertRow->get())[aIter->second.nPosition];
         [ #  # ][ #  # ]
     213                 :            :             }
     214         [ #  # ]:          0 :             ::rtl::OUStringBuffer& rPart = aSql[aIter->second.sTableName];
     215         [ #  # ]:          0 :             if ( rPart.getLength() )
     216         [ #  # ]:          0 :                 rPart.appendAscii(", ");
     217         [ #  # ]:          0 :             rPart.append(sQuotedColumnName);
     218         [ #  # ]:          0 :             rPart.append(s_sPara);
     219                 :            :         }
     220                 :          0 :     }
     221                 :            : 
     222         [ #  # ]:          0 :     if( aSql.empty() )
     223 [ #  # ][ #  # ]:          0 :         ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_VALUE_CHANGED ), SQL_GENERAL_ERROR, m_xConnection );
     224                 :            : 
     225         [ #  # ]:          0 :     if( aKeyConditions.empty() )
     226 [ #  # ][ #  # ]:          0 :         ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_CONDITION_FOR_PK ), SQL_GENERAL_ERROR, m_xConnection );
     227                 :            : 
     228 [ #  # ][ #  # ]:          0 :     static const ::rtl::OUString s_sUPDATE("UPDATE ");
     229 [ #  # ][ #  # ]:          0 :     static const ::rtl::OUString s_sSET(" SET ");
     230                 :            : 
     231 [ #  # ][ #  # ]:          0 :     Reference<XDatabaseMetaData> xMetaData = m_xConnection->getMetaData();
     232                 :            : 
     233                 :          0 :     TSQLStatements::iterator aSqlIter = aSql.begin();
     234                 :          0 :     TSQLStatements::iterator aSqlEnd  = aSql.end();
     235         [ #  # ]:          0 :     for(;aSqlIter != aSqlEnd ; ++aSqlIter)
     236                 :            :     {
     237         [ #  # ]:          0 :         if ( aSqlIter->second.getLength() )
     238                 :            :         {
     239 [ #  # ][ #  # ]:          0 :             m_bResultSetChanged = m_bResultSetChanged || aResultSetChanged[aSqlIter->first];
                 [ #  # ]
     240         [ #  # ]:          0 :             ::rtl::OUStringBuffer sSql(s_sUPDATE);
     241                 :          0 :             ::rtl::OUString sCatalog,sSchema,sTable;
     242         [ #  # ]:          0 :             ::dbtools::qualifiedNameComponents(xMetaData,aSqlIter->first,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);
     243 [ #  # ][ #  # ]:          0 :             sSql.append( ::dbtools::composeTableNameForSelect( m_xConnection, sCatalog, sSchema, sTable ) );
     244         [ #  # ]:          0 :             sSql.append(s_sSET);
     245         [ #  # ]:          0 :             sSql.append(aSqlIter->second.toString());
     246         [ #  # ]:          0 :             ::rtl::OUStringBuffer& rCondition = aKeyConditions[aSqlIter->first];
     247         [ #  # ]:          0 :             if ( rCondition.getLength() )
     248                 :            :             {
     249         [ #  # ]:          0 :                 sSql.appendAscii(" WHERE ");
     250         [ #  # ]:          0 :                 sSql.append( rCondition.toString() );
     251                 :            :             }
     252 [ #  # ][ #  # ]:          0 :             executeUpdate(_rInsertRow ,_rOrginalRow,sSql.makeStringAndClear(),aSqlIter->first);
                 [ #  # ]
     253                 :            :         }
     254                 :          0 :     }
     255                 :          0 : }
     256                 :            : 
     257                 :          0 : void SAL_CALL OptimisticSet::insertRow( const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& /*_xTable*/ ) throw(SQLException, RuntimeException)
     258                 :            : {
     259                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::insertRow" );
     260         [ #  # ]:          0 :     TSQLStatements aSql;
     261         [ #  # ]:          0 :     TSQLStatements aParameter;
     262         [ #  # ]:          0 :     TSQLStatements aKeyConditions;
     263         [ #  # ]:          0 :     ::std::map< ::rtl::OUString,bool > aResultSetChanged;
     264         [ #  # ]:          0 :     ::rtl::OUString aQuote  = getIdentifierQuoteString();
     265                 :            : 
     266                 :            :     // here we build the condition part for the update statement
     267                 :          0 :     SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
     268                 :          0 :     SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
     269         [ #  # ]:          0 :     for(;aIter != aEnd;++aIter)
     270                 :            :     {
     271 [ #  # ][ #  # ]:          0 :         if ( aResultSetChanged.find( aIter->second.sTableName ) == aResultSetChanged.end() )
     272         [ #  # ]:          0 :             aResultSetChanged[aIter->second.sTableName] = false;
     273                 :            : 
     274         [ #  # ]:          0 :         const ::rtl::OUString sQuotedColumnName = ::dbtools::quoteName( aQuote,aIter->second.sRealName);
     275 [ #  # ][ #  # ]:          0 :         if ( (_rInsertRow->get())[aIter->second.nPosition].isModified() )
     276                 :            :         {
     277 [ #  # ][ #  # ]:          0 :             if ( m_aJoinedKeyColumns.find(aIter->second.nPosition) != m_aJoinedKeyColumns.end() )
                 [ #  # ]
     278                 :            :             {
     279 [ #  # ][ #  # ]:          0 :                 lcl_fillKeyCondition(aIter->second.sTableName,sQuotedColumnName,(_rInsertRow->get())[aIter->second.nPosition],aKeyConditions);
     280         [ #  # ]:          0 :                 aResultSetChanged[aIter->second.sTableName] = true;
     281                 :            :             }
     282 [ #  # ][ #  # ]:          0 :             ::std::map<sal_Int32,sal_Int32>::const_iterator aJoinIter = m_aJoinedColumns.find(aIter->second.nPosition);
     283 [ #  # ][ #  # ]:          0 :             if ( aJoinIter != m_aJoinedColumns.end() )
                 [ #  # ]
     284                 :            :             {
     285 [ #  # ][ #  # ]:          0 :                 (_rInsertRow->get())[aJoinIter->second] = (_rInsertRow->get())[aIter->second.nPosition];
         [ #  # ][ #  # ]
     286                 :            :             }
     287         [ #  # ]:          0 :             ::rtl::OUStringBuffer& rPart = aSql[aIter->second.sTableName];
     288         [ #  # ]:          0 :             if ( rPart.getLength() )
     289         [ #  # ]:          0 :                 rPart.appendAscii(", ");
     290         [ #  # ]:          0 :             rPart.append(sQuotedColumnName);
     291         [ #  # ]:          0 :             ::rtl::OUStringBuffer& rParam = aParameter[aIter->second.sTableName];
     292         [ #  # ]:          0 :             if ( rParam.getLength() )
     293         [ #  # ]:          0 :                 rParam.appendAscii(", ");
     294         [ #  # ]:          0 :             rParam.appendAscii("?");
     295                 :            :         }
     296                 :          0 :     }
     297         [ #  # ]:          0 :     if ( aParameter.empty() )
     298 [ #  # ][ #  # ]:          0 :         ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_VALUE_CHANGED ), SQL_GENERAL_ERROR, m_xConnection );
     299                 :            : 
     300 [ #  # ][ #  # ]:          0 :     Reference<XDatabaseMetaData> xMetaData = m_xConnection->getMetaData();
     301 [ #  # ][ #  # ]:          0 :     static const ::rtl::OUString s_sINSERT("INSERT INTO ");
     302 [ #  # ][ #  # ]:          0 :     static const ::rtl::OUString s_sVALUES(") VALUES ( ");
     303                 :          0 :     TSQLStatements::iterator aSqlIter = aSql.begin();
     304                 :          0 :     TSQLStatements::iterator aSqlEnd  = aSql.end();
     305         [ #  # ]:          0 :     for(;aSqlIter != aSqlEnd ; ++aSqlIter)
     306                 :            :     {
     307         [ #  # ]:          0 :         if ( aSqlIter->second.getLength() )
     308                 :            :         {
     309 [ #  # ][ #  # ]:          0 :             m_bResultSetChanged = m_bResultSetChanged || aResultSetChanged[aSqlIter->first];
                 [ #  # ]
     310         [ #  # ]:          0 :             ::rtl::OUStringBuffer sSql(s_sINSERT);
     311                 :          0 :             ::rtl::OUString sCatalog,sSchema,sTable;
     312         [ #  # ]:          0 :             ::dbtools::qualifiedNameComponents(xMetaData,aSqlIter->first,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);
     313         [ #  # ]:          0 :             ::rtl::OUString sComposedTableName = ::dbtools::composeTableNameForSelect( m_xConnection, sCatalog, sSchema, sTable );
     314         [ #  # ]:          0 :             sSql.append(sComposedTableName);
     315         [ #  # ]:          0 :             sSql.appendAscii(" ( ");
     316         [ #  # ]:          0 :             sSql.append(aSqlIter->second.toString());
     317         [ #  # ]:          0 :             sSql.append(s_sVALUES);
     318 [ #  # ][ #  # ]:          0 :             sSql.append(aParameter[aSqlIter->first].toString());
     319         [ #  # ]:          0 :             sSql.appendAscii(" )");
     320                 :            : 
     321         [ #  # ]:          0 :             ::rtl::OUStringBuffer& rCondition = aKeyConditions[aSqlIter->first];
     322         [ #  # ]:          0 :             if ( rCondition.getLength() )
     323                 :            :             {
     324                 :          0 :                 ::rtl::OUStringBuffer sQuery;
     325         [ #  # ]:          0 :                 sQuery.appendAscii("SELECT ");
     326         [ #  # ]:          0 :                 sQuery.append(aSqlIter->second.toString());
     327         [ #  # ]:          0 :                 sQuery.appendAscii(" FROM ");
     328         [ #  # ]:          0 :                 sQuery.append(sComposedTableName);
     329         [ #  # ]:          0 :                 sQuery.appendAscii(" WHERE ");
     330         [ #  # ]:          0 :                 sQuery.append(rCondition.toString());
     331                 :            : 
     332                 :            :                 try
     333                 :            :                 {
     334 [ #  # ][ #  # ]:          0 :                     Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(sQuery.makeStringAndClear()));
                 [ #  # ]
     335         [ #  # ]:          0 :                     Reference< XParameters > xParameter(xPrep,UNO_QUERY);
     336                 :            :                     // and then the values of the where condition
     337                 :          0 :                     SelectColumnsMetaData::iterator aKeyCol = m_pKeyColumnNames->begin();
     338                 :          0 :                     SelectColumnsMetaData::iterator aKeysEnd = m_pKeyColumnNames->end();
     339                 :          0 :                     sal_Int32 i = 1;
     340         [ #  # ]:          0 :                     for(;aKeyCol != aKeysEnd;++aKeyCol)
     341                 :            :                     {
     342         [ #  # ]:          0 :                         if ( aKeyCol->second.sTableName == aSqlIter->first )
     343                 :            :                         {
     344 [ #  # ][ #  # ]:          0 :                             setParameter(i++,xParameter,(_rInsertRow->get())[aKeyCol->second.nPosition],aKeyCol->second.nType,aKeyCol->second.nScale);
     345                 :            :                         }
     346                 :            :                     }
     347 [ #  # ][ #  # ]:          0 :                     Reference<XResultSet> xRes = xPrep->executeQuery();
     348         [ #  # ]:          0 :                     Reference<XRow> xRow(xRes,UNO_QUERY);
     349 [ #  # ][ #  # ]:          0 :                     if ( xRow.is() && xRes->next() )
         [ #  # ][ #  # ]
                 [ #  # ]
     350                 :            :                     {
     351                 :          0 :                         m_bResultSetChanged = true;
     352                 :          0 :                         continue;
     353 [ #  # ][ #  # ]:          0 :                     }
         [ #  # ][ #  # ]
                 [ #  # ]
     354                 :            :                 }
     355         [ #  # ]:          0 :                 catch(const SQLException&)
     356                 :            :                 {
     357         [ #  # ]:          0 :                 }
     358                 :            :             }
     359                 :            : 
     360 [ #  # ][ #  # ]:          0 :             executeInsert(_rInsertRow,sSql.makeStringAndClear(),aSqlIter->first);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     361                 :            :         }
     362                 :          0 :     }
     363                 :          0 : }
     364                 :            : 
     365                 :          0 : void SAL_CALL OptimisticSet::deleteRow(const ORowSetRow& _rDeleteRow,const connectivity::OSQLTable& /*_xTable*/   ) throw(SQLException, RuntimeException)
     366                 :            : {
     367         [ #  # ]:          0 :     ::rtl::OUString aQuote  = getIdentifierQuoteString();
     368                 :          0 :     ::rtl::OUString aColumnName;
     369                 :          0 :     ::rtl::OUStringBuffer sKeyCondition,sIndexCondition;
     370         [ #  # ]:          0 :     ::std::vector<sal_Int32> aIndexColumnPositions;
     371         [ #  # ]:          0 :     TSQLStatements aKeyConditions;
     372         [ #  # ]:          0 :     TSQLStatements aIndexConditions;
     373         [ #  # ]:          0 :     TSQLStatements aSql;
     374                 :            : 
     375                 :            :     // here we build the condition part for the update statement
     376                 :          0 :     SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
     377                 :          0 :     SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
     378         [ #  # ]:          0 :     for(;aIter != aEnd;++aIter)
     379                 :            :     {
     380 [ #  # ][ #  # ]:          0 :         if ( m_aJoinedKeyColumns.find(aIter->second.nPosition) == m_aJoinedKeyColumns.end() && m_pKeyColumnNames->find(aIter->first) != m_pKeyColumnNames->end() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  #  
          #  #  #  #  #  
                #  #  # ]
     381                 :            :         {
     382                 :            :             // only delete rows which aren't the key in the join
     383         [ #  # ]:          0 :             const ::rtl::OUString sQuotedColumnName = ::dbtools::quoteName( aQuote,aIter->second.sRealName);
     384 [ #  # ][ #  # ]:          0 :             lcl_fillKeyCondition(aIter->second.sTableName,sQuotedColumnName,(_rDeleteRow->get())[aIter->second.nPosition],aKeyConditions);
     385                 :            :         }
     386                 :            :     }
     387 [ #  # ][ #  # ]:          0 :     Reference<XDatabaseMetaData> xMetaData = m_xConnection->getMetaData();
     388                 :          0 :     TSQLStatements::iterator aSqlIter = aKeyConditions.begin();
     389                 :          0 :     TSQLStatements::iterator aSqlEnd  = aKeyConditions.end();
     390         [ #  # ]:          0 :     for(;aSqlIter != aSqlEnd ; ++aSqlIter)
     391                 :            :     {
     392                 :          0 :         ::rtl::OUStringBuffer& rCondition = aSqlIter->second;
     393         [ #  # ]:          0 :         if ( rCondition.getLength() )
     394                 :            :         {
     395                 :          0 :             ::rtl::OUStringBuffer sSql;
     396         [ #  # ]:          0 :             sSql.appendAscii("DELETE FROM ");
     397                 :          0 :             ::rtl::OUString sCatalog,sSchema,sTable;
     398         [ #  # ]:          0 :             ::dbtools::qualifiedNameComponents(xMetaData,aSqlIter->first,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);
     399 [ #  # ][ #  # ]:          0 :             sSql.append( ::dbtools::composeTableNameForSelect( m_xConnection, sCatalog, sSchema, sTable ) );
     400         [ #  # ]:          0 :             sSql.appendAscii(" WHERE ");
     401         [ #  # ]:          0 :             sSql.append( rCondition.toString() );
     402 [ #  # ][ #  # ]:          0 :             executeDelete(_rDeleteRow,sSql.makeStringAndClear(),aSqlIter->first);
     403                 :            :         }
     404                 :          0 :     }
     405                 :          0 : }
     406                 :            : 
     407                 :          0 : void OptimisticSet::executeDelete(const ORowSetRow& _rDeleteRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName)
     408                 :            : {
     409                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::executeDelete" );
     410                 :            : 
     411                 :            :     // now create and execute the prepared statement
     412 [ #  # ][ #  # ]:          0 :     Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(i_sSQL));
     413         [ #  # ]:          0 :     Reference< XParameters > xParameter(xPrep,UNO_QUERY);
     414                 :            : 
     415                 :          0 :     SelectColumnsMetaData::const_iterator aIter = m_pKeyColumnNames->begin();
     416                 :          0 :     SelectColumnsMetaData::const_iterator aEnd = m_pKeyColumnNames->end();
     417                 :          0 :     sal_Int32 i = 1;
     418         [ #  # ]:          0 :     for(;aIter != aEnd;++aIter)
     419                 :            :     {
     420         [ #  # ]:          0 :         if ( aIter->second.sTableName == i_sTableName )
     421 [ #  # ][ #  # ]:          0 :             setParameter(i++,xParameter,(_rDeleteRow->get())[aIter->second.nPosition],aIter->second.nType,aIter->second.nScale);
     422                 :            :     }
     423 [ #  # ][ #  # ]:          0 :     m_bDeleted = xPrep->executeUpdate() > 0;
     424                 :            : 
     425         [ #  # ]:          0 :     if(m_bDeleted)
     426                 :            :     {
     427 [ #  # ][ #  # ]:          0 :         sal_Int32 nBookmark = ::comphelper::getINT32((_rDeleteRow->get())[0].getAny());
     428 [ #  # ][ #  # ]:          0 :         if(m_aKeyIter == m_aKeyMap.find(nBookmark) && m_aKeyIter != m_aKeyMap.end())
         [ #  # ][ #  # ]
           [ #  #  #  #  
           #  # ][ #  # ]
     429                 :          0 :             ++m_aKeyIter;
     430         [ #  # ]:          0 :         m_aKeyMap.erase(nBookmark);
     431                 :          0 :         m_bDeleted = sal_True;
     432                 :          0 :     }
     433                 :          0 : }
     434                 :            : 
     435                 :          0 : void OptimisticSet::fillJoinedColumns_throw(const ::std::vector< TNodePair >& i_aJoinColumns)
     436                 :            : {
     437                 :          0 :     ::std::vector< TNodePair >::const_iterator aIter = i_aJoinColumns.begin();
     438 [ #  # ][ #  # ]:          0 :     for(;aIter != i_aJoinColumns.end();++aIter)
                 [ #  # ]
     439                 :            :     {
     440                 :          0 :         ::rtl::OUString sColumnName,sTableName;
     441 [ #  # ][ #  # ]:          0 :         m_aSqlIterator.getColumnRange(aIter->first,sColumnName,sTableName);
     442                 :          0 :         ::rtl::OUStringBuffer sLeft,sRight;
     443         [ #  # ]:          0 :         sLeft.append(sTableName);
     444         [ #  # ]:          0 :         sLeft.appendAscii(".");
     445         [ #  # ]:          0 :         sLeft.append(sColumnName);
     446 [ #  # ][ #  # ]:          0 :         m_aSqlIterator.getColumnRange(aIter->second,sColumnName,sTableName);
     447         [ #  # ]:          0 :         sRight.append(sTableName);
     448         [ #  # ]:          0 :         sRight.appendAscii(".");
     449         [ #  # ]:          0 :         sRight.append(sColumnName);
     450 [ #  # ][ #  # ]:          0 :         fillJoinedColumns_throw(sLeft.makeStringAndClear(),sRight.makeStringAndClear());
                 [ #  # ]
     451                 :          0 :     }
     452                 :          0 : }
     453                 :            : 
     454                 :          0 : void OptimisticSet::fillJoinedColumns_throw(const ::rtl::OUString& i_sLeftColumn,const ::rtl::OUString& i_sRightColumn)
     455                 :            : {
     456                 :          0 :     sal_Int32 nLeft = 0,nRight = 0;
     457         [ #  # ]:          0 :     SelectColumnsMetaData::const_iterator aLeftIter  = m_pKeyColumnNames->find(i_sLeftColumn);
     458         [ #  # ]:          0 :     SelectColumnsMetaData::const_iterator aRightIter = m_pKeyColumnNames->find(i_sRightColumn);
     459                 :            : 
     460                 :          0 :     bool bLeftKey = aLeftIter != m_pKeyColumnNames->end();
     461         [ #  # ]:          0 :     if ( bLeftKey )
     462                 :            :     {
     463                 :          0 :         nLeft = aLeftIter->second.nPosition;
     464                 :            :     }
     465                 :            :     else
     466                 :            :     {
     467         [ #  # ]:          0 :         aLeftIter = m_pColumnNames->find(i_sLeftColumn);
     468         [ #  # ]:          0 :         if ( aLeftIter != m_pColumnNames->end() )
     469                 :          0 :             nLeft = aLeftIter->second.nPosition;
     470                 :            :     }
     471                 :            : 
     472                 :          0 :     bool bRightKey = aRightIter != m_pKeyColumnNames->end();
     473         [ #  # ]:          0 :     if ( bRightKey )
     474                 :            :     {
     475                 :          0 :         nRight = aRightIter->second.nPosition;
     476                 :            :     }
     477                 :            :     else
     478                 :            :     {
     479         [ #  # ]:          0 :         aRightIter = m_pColumnNames->find(i_sRightColumn);
     480         [ #  # ]:          0 :         if ( aRightIter != m_pColumnNames->end() )
     481                 :          0 :             nRight = aRightIter->second.nPosition;
     482                 :            :     }
     483                 :            : 
     484         [ #  # ]:          0 :     if (bLeftKey)
     485         [ #  # ]:          0 :         m_aJoinedKeyColumns[nLeft] = nRight;
     486                 :            :     else
     487         [ #  # ]:          0 :         m_aJoinedColumns[nLeft] = nRight;
     488         [ #  # ]:          0 :     if (bRightKey)
     489         [ #  # ]:          0 :         m_aJoinedKeyColumns[nRight] = nLeft;
     490                 :            :     else
     491         [ #  # ]:          0 :         m_aJoinedColumns[nRight] = nLeft;
     492                 :          0 : }
     493                 :            : 
     494                 :          0 : bool OptimisticSet::isResultSetChanged() const
     495                 :            : {
     496                 :          0 :     bool bOld = m_bResultSetChanged;
     497                 :          0 :     m_bResultSetChanged = false;
     498                 :          0 :     return bOld;
     499                 :            : }
     500                 :            : 
     501                 :          0 : void OptimisticSet::reset(const Reference< XResultSet>& _xDriverSet)
     502                 :            : {
     503         [ #  # ]:          0 :     OCacheSet::construct(_xDriverSet,::rtl::OUString());
     504                 :          0 :     m_bRowCountFinal = sal_False;
     505                 :          0 :     m_aKeyMap.clear();
     506 [ #  # ][ #  # ]:          0 :     m_aKeyMap.insert(OKeySetMatrix::value_type(0,OKeySetValue(NULL,::std::pair<sal_Int32,Reference<XRow> >(0,NULL))));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     507                 :          0 :     m_aKeyIter = m_aKeyMap.begin();
     508                 :          0 : }
     509                 :            : 
     510                 :          0 : void OptimisticSet::mergeColumnValues(sal_Int32 i_nColumnIndex,ORowSetValueVector::Vector& io_aInsertRow,ORowSetValueVector::Vector& io_aRow,::std::vector<sal_Int32>& o_aChangedColumns)
     511                 :            : {
     512         [ #  # ]:          0 :     o_aChangedColumns.push_back(i_nColumnIndex);
     513 [ #  # ][ #  # ]:          0 :     ::std::map<sal_Int32,sal_Int32>::const_iterator aJoinIter = m_aJoinedColumns.find(i_nColumnIndex);
     514 [ #  # ][ #  # ]:          0 :     if ( aJoinIter != m_aJoinedColumns.end() )
                 [ #  # ]
     515                 :            :     {
     516 [ #  # ][ #  # ]:          0 :         io_aRow[aJoinIter->second] = io_aRow[i_nColumnIndex];
         [ #  # ][ #  # ]
     517 [ #  # ][ #  # ]:          0 :         io_aInsertRow[aJoinIter->second] = io_aInsertRow[i_nColumnIndex];
         [ #  # ][ #  # ]
     518 [ #  # ][ #  # ]:          0 :         io_aRow[aJoinIter->second].setModified();
     519 [ #  # ][ #  # ]:          0 :         o_aChangedColumns.push_back(aJoinIter->second);
     520                 :            :     }
     521                 :          0 : }
     522                 :            : namespace
     523                 :            : {
     524                 :            :     struct PositionFunctor : ::std::unary_function<SelectColumnsMetaData::value_type,bool>
     525                 :            :     {
     526                 :            :         sal_Int32 m_nPos;
     527                 :          0 :         PositionFunctor(sal_Int32 i_nPos)
     528                 :          0 :             : m_nPos(i_nPos)
     529                 :            :         {
     530                 :          0 :         }
     531                 :            : 
     532                 :          0 :         inline bool operator()(const SelectColumnsMetaData::value_type& _aType)
     533                 :            :         {
     534                 :          0 :             return m_nPos == _aType.second.nPosition;
     535                 :            :         }
     536                 :            :     };
     537                 :          0 :     struct TableNameFunctor : ::std::unary_function<SelectColumnsMetaData::value_type,bool>
     538                 :            :     {
     539                 :            :         ::rtl::OUString m_sTableName;
     540                 :          0 :         TableNameFunctor(const ::rtl::OUString& i_sTableName)
     541                 :          0 :             : m_sTableName(i_sTableName)
     542                 :            :         {
     543                 :          0 :         }
     544                 :            : 
     545                 :          0 :         inline bool operator()(const SelectColumnsMetaData::value_type& _aType)
     546                 :            :         {
     547                 :          0 :             return m_sTableName == _aType.second.sTableName;
     548                 :            :         }
     549                 :            :     };
     550                 :            : }
     551                 :            : 
     552                 :          0 : bool OptimisticSet::updateColumnValues(const ORowSetValueVector::Vector& io_aCachedRow,ORowSetValueVector::Vector& io_aRow,const ::std::vector<sal_Int32>& i_aChangedColumns)
     553                 :            : {
     554                 :          0 :     bool bRet = false;
     555                 :          0 :     ::std::vector<sal_Int32>::const_iterator aColIdxIter = i_aChangedColumns.begin();
     556 [ #  # ][ #  # ]:          0 :     for(;aColIdxIter != i_aChangedColumns.end();++aColIdxIter)
                 [ #  # ]
     557                 :            :     {
     558 [ #  # ][ #  # ]:          0 :         SelectColumnsMetaData::const_iterator aFind = ::std::find_if(m_pKeyColumnNames->begin(),m_pKeyColumnNames->end(),PositionFunctor(*aColIdxIter));
     559         [ #  # ]:          0 :         if ( aFind != m_pKeyColumnNames->end() )
     560                 :            :         {
     561                 :          0 :             const ::rtl::OUString sTableName = aFind->second.sTableName;
     562         [ #  # ]:          0 :             aFind = ::std::find_if(m_pKeyColumnNames->begin(),m_pKeyColumnNames->end(),TableNameFunctor(sTableName));
     563         [ #  # ]:          0 :             while( aFind != m_pKeyColumnNames->end() )
     564                 :            :             {
     565 [ #  # ][ #  # ]:          0 :                 io_aRow[aFind->second.nPosition].setSigned(io_aCachedRow[aFind->second.nPosition].isSigned());
                 [ #  # ]
     566 [ #  # ][ #  # ]:          0 :                 if ( io_aCachedRow[aFind->second.nPosition] != io_aRow[aFind->second.nPosition] )
         [ #  # ][ #  # ]
     567                 :          0 :                     break;
     568                 :          0 :                 ++aFind;
     569                 :            :             }
     570         [ #  # ]:          0 :             if ( aFind == m_pKeyColumnNames->end() )
     571                 :            :             {
     572                 :          0 :                 bRet = true;
     573                 :          0 :                 SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
     574                 :          0 :                 SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
     575         [ #  # ]:          0 :                 for ( ;aIter != aEnd;++aIter )
     576                 :            :                 {
     577         [ #  # ]:          0 :                     if ( aIter->second.sTableName == sTableName )
     578                 :            :                     {
     579 [ #  # ][ #  # ]:          0 :                         io_aRow[aIter->second.nPosition] = io_aCachedRow[aIter->second.nPosition];
                 [ #  # ]
     580         [ #  # ]:          0 :                         io_aRow[aIter->second.nPosition].setModified();
     581                 :            :                     }
     582                 :            :                 }
     583                 :          0 :             }
     584                 :            :         }
     585                 :            :     }
     586                 :          0 :     return bRet;
     587                 :            : }
     588                 :            : 
     589                 :          0 : bool OptimisticSet::columnValuesUpdated(ORowSetValueVector::Vector& o_aCachedRow,const ORowSetValueVector::Vector& i_aRow)
     590                 :            : {
     591                 :          0 :     bool bRet = false;
     592                 :          0 :     SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
     593                 :          0 :     SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
     594         [ #  # ]:          0 :     for(;aIter != aEnd;++aIter)
     595                 :            :     {
     596         [ #  # ]:          0 :         SelectColumnsMetaData::const_iterator aFind = ::std::find_if(m_pKeyColumnNames->begin(),m_pKeyColumnNames->end(),PositionFunctor(aIter->second.nPosition));
     597         [ #  # ]:          0 :         if ( aFind != m_pKeyColumnNames->end() )
     598                 :            :         {
     599                 :          0 :             const ::rtl::OUString sTableName = aFind->second.sTableName;
     600         [ #  # ]:          0 :             aFind = ::std::find_if(m_pKeyColumnNames->begin(),m_pKeyColumnNames->end(),TableNameFunctor(sTableName));
     601         [ #  # ]:          0 :             while( aFind != m_pKeyColumnNames->end() )
     602                 :            :             {
     603 [ #  # ][ #  # ]:          0 :                 o_aCachedRow[aFind->second.nPosition].setSigned(i_aRow[aFind->second.nPosition].isSigned());
                 [ #  # ]
     604 [ #  # ][ #  # ]:          0 :                 if ( o_aCachedRow[aFind->second.nPosition] != i_aRow[aFind->second.nPosition] )
         [ #  # ][ #  # ]
     605                 :          0 :                     break;
     606                 :          0 :                 ++aFind;
     607                 :            :             }
     608         [ #  # ]:          0 :             if ( aFind == m_pKeyColumnNames->end() )
     609                 :            :             {
     610                 :          0 :                 bRet = true;
     611                 :          0 :                 SelectColumnsMetaData::const_iterator aIter2 = m_pColumnNames->begin();
     612                 :          0 :                 SelectColumnsMetaData::const_iterator aEnd2 = m_pColumnNames->end();
     613         [ #  # ]:          0 :                 for ( ;aIter2 != aEnd2;++aIter2 )
     614                 :            :                 {
     615         [ #  # ]:          0 :                     if ( aIter2->second.sTableName == sTableName )
     616                 :            :                     {
     617 [ #  # ][ #  # ]:          0 :                         o_aCachedRow[aIter2->second.nPosition] = i_aRow[aIter2->second.nPosition];
                 [ #  # ]
     618         [ #  # ]:          0 :                         o_aCachedRow[aIter2->second.nPosition].setModified();
     619                 :            :                     }
     620                 :            :                 }
     621         [ #  # ]:          0 :                 fillMissingValues(o_aCachedRow);
     622                 :          0 :             }
     623                 :            :         }
     624                 :            :     }
     625                 :          0 :     return bRet;
     626                 :            : }
     627                 :            : 
     628                 :          0 : void OptimisticSet::fillMissingValues(ORowSetValueVector::Vector& io_aRow) const
     629                 :            : {
     630         [ #  # ]:          0 :     TSQLStatements aSql;
     631         [ #  # ]:          0 :     TSQLStatements aKeyConditions;
     632         [ #  # ]:          0 :     ::std::map< ::rtl::OUString,bool > aResultSetChanged;
     633         [ #  # ]:          0 :     ::rtl::OUString aQuote  = getIdentifierQuoteString();
     634                 :            :     // here we build the condition part for the update statement
     635                 :          0 :     SelectColumnsMetaData::const_iterator aColIter = m_pColumnNames->begin();
     636                 :          0 :     SelectColumnsMetaData::const_iterator aColEnd = m_pColumnNames->end();
     637         [ #  # ]:          0 :     for(;aColIter != aColEnd;++aColIter)
     638                 :            :     {
     639         [ #  # ]:          0 :         const ::rtl::OUString sQuotedColumnName = ::dbtools::quoteName( aQuote,aColIter->second.sRealName);
     640 [ #  # ][ #  # ]:          0 :         if ( m_aJoinedKeyColumns.find(aColIter->second.nPosition) != m_aJoinedKeyColumns.end() )
                 [ #  # ]
     641                 :            :         {
     642 [ #  # ][ #  # ]:          0 :             lcl_fillKeyCondition(aColIter->second.sTableName,sQuotedColumnName,io_aRow[aColIter->second.nPosition],aKeyConditions);
     643                 :            :         }
     644         [ #  # ]:          0 :         ::rtl::OUStringBuffer& rPart = aSql[aColIter->second.sTableName];
     645         [ #  # ]:          0 :         if ( rPart.getLength() )
     646         [ #  # ]:          0 :             rPart.appendAscii(", ");
     647         [ #  # ]:          0 :         rPart.append(sQuotedColumnName);
     648                 :          0 :     }
     649 [ #  # ][ #  # ]:          0 :     Reference<XDatabaseMetaData> xMetaData = m_xConnection->getMetaData();
     650                 :          0 :     TSQLStatements::iterator aSqlIter = aSql.begin();
     651                 :          0 :     TSQLStatements::iterator aSqlEnd  = aSql.end();
     652         [ #  # ]:          0 :     for(;aSqlIter != aSqlEnd ; ++aSqlIter)
     653                 :            :     {
     654         [ #  # ]:          0 :         if ( aSqlIter->second.getLength() )
     655                 :            :         {
     656         [ #  # ]:          0 :             ::rtl::OUStringBuffer& rCondition = aKeyConditions[aSqlIter->first];
     657         [ #  # ]:          0 :             if ( rCondition.getLength() )
     658                 :            :             {
     659                 :          0 :                 ::rtl::OUString sCatalog,sSchema,sTable;
     660         [ #  # ]:          0 :                 ::dbtools::qualifiedNameComponents(xMetaData,aSqlIter->first,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);
     661         [ #  # ]:          0 :                 ::rtl::OUString sComposedTableName = ::dbtools::composeTableNameForSelect( m_xConnection, sCatalog, sSchema, sTable );
     662                 :          0 :                 ::rtl::OUStringBuffer sQuery;
     663         [ #  # ]:          0 :                 sQuery.appendAscii("SELECT ");
     664         [ #  # ]:          0 :                 sQuery.append(aSqlIter->second.toString());
     665         [ #  # ]:          0 :                 sQuery.appendAscii(" FROM ");
     666         [ #  # ]:          0 :                 sQuery.append(sComposedTableName);
     667         [ #  # ]:          0 :                 sQuery.appendAscii(" WHERE ");
     668 [ #  # ][ #  # ]:          0 :                 sQuery.append(rCondition.makeStringAndClear());
     669                 :            : 
     670                 :            :                 try
     671                 :            :                 {
     672 [ #  # ][ #  # ]:          0 :                     Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(sQuery.makeStringAndClear()));
                 [ #  # ]
     673         [ #  # ]:          0 :                     Reference< XParameters > xParameter(xPrep,UNO_QUERY);
     674                 :            :                     // and then the values of the where condition
     675                 :          0 :                     SelectColumnsMetaData::iterator aKeyIter = m_pKeyColumnNames->begin();
     676                 :          0 :                     SelectColumnsMetaData::iterator aKeyEnd = m_pKeyColumnNames->end();
     677                 :          0 :                     sal_Int32 i = 1;
     678         [ #  # ]:          0 :                     for(;aKeyIter != aKeyEnd;++aKeyIter)
     679                 :            :                     {
     680         [ #  # ]:          0 :                         if ( aKeyIter->second.sTableName == aSqlIter->first )
     681                 :            :                         {
     682 [ #  # ][ #  # ]:          0 :                             setParameter(i++,xParameter,io_aRow[aKeyIter->second.nPosition],aKeyIter->second.nType,aKeyIter->second.nScale);
     683                 :            :                         }
     684                 :            :                     }
     685 [ #  # ][ #  # ]:          0 :                     Reference<XResultSet> xRes = xPrep->executeQuery();
     686         [ #  # ]:          0 :                     Reference<XRow> xRow(xRes,UNO_QUERY);
     687 [ #  # ][ #  # ]:          0 :                     if ( xRow.is() && xRes->next() )
         [ #  # ][ #  # ]
                 [ #  # ]
     688                 :            :                     {
     689                 :          0 :                         i = 1;
     690                 :          0 :                         aColIter = m_pColumnNames->begin();
     691         [ #  # ]:          0 :                         for(;aColIter != aColEnd;++aColIter)
     692                 :            :                         {
     693         [ #  # ]:          0 :                             if ( aColIter->second.sTableName == aSqlIter->first )
     694                 :            :                             {
     695 [ #  # ][ #  # ]:          0 :                                 io_aRow[aColIter->second.nPosition].fill(i++, aColIter->second.nType, xRow);
     696         [ #  # ]:          0 :                                 io_aRow[aColIter->second.nPosition].setModified();
     697                 :            :                             }
     698                 :            :                         }
     699         [ #  # ]:          0 :                     }
     700                 :            :                 }
     701         [ #  # ]:          0 :                 catch(const SQLException&)
     702                 :            :                 {
     703                 :          0 :                 }
     704                 :            :             }
     705                 :            :         }
     706                 :          0 :     }
     707                 :          0 : }
     708                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10