LCOV - code coverage report
Current view: top level - connectivity/source/drivers/file - FStatement.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 189 339 55.8 %
Date: 2014-11-03 Functions: 24 39 61.5 %
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 <osl/diagnose.h>
      21             : #include "file/FStatement.hxx"
      22             : #include "file/FConnection.hxx"
      23             : #include "file/FDriver.hxx"
      24             : #include "file/FResultSet.hxx"
      25             : #include <comphelper/property.hxx>
      26             : #include <comphelper/uno3.hxx>
      27             : #include <osl/thread.h>
      28             : #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
      29             : #include <com/sun/star/sdbc/ResultSetType.hpp>
      30             : #include <com/sun/star/sdbc/FetchDirection.hpp>
      31             : #include <com/sun/star/lang/DisposedException.hpp>
      32             : #include <comphelper/processfactory.hxx>
      33             : #include <comphelper/sequence.hxx>
      34             : #include <cppuhelper/typeprovider.hxx>
      35             : #include <connectivity/dbexception.hxx>
      36             : #include "resource/file_res.hrc"
      37             : #include <algorithm>
      38             : 
      39             : namespace connectivity
      40             : {
      41             :     namespace file
      42             :     {
      43             : 
      44             : 
      45             : using namespace dbtools;
      46             : using namespace com::sun::star::uno;
      47             : using namespace com::sun::star::lang;
      48             : using namespace com::sun::star::beans;
      49             : using namespace com::sun::star::sdbc;
      50             : using namespace com::sun::star::sdbcx;
      51             : using namespace com::sun::star::container;
      52             : 
      53         132 : OStatement_Base::OStatement_Base(OConnection* _pConnection )
      54             :     :OStatement_BASE(m_aMutex)
      55             :     ,::comphelper::OPropertyContainer(OStatement_BASE::rBHelper)
      56         132 :     ,m_xDBMetaData(_pConnection->getMetaData())
      57             :     ,m_aParser( _pConnection->getDriver()->getComponentContext() )
      58         264 :     ,m_aSQLIterator( _pConnection, _pConnection->createCatalog()->getTables(), m_aParser, NULL )
      59             :     ,m_pConnection(_pConnection)
      60             :     ,m_pParseTree(NULL)
      61             :     ,m_pSQLAnalyzer(NULL)
      62             :     ,m_pEvaluationKeySet(NULL)
      63             :     ,m_pTable(NULL)
      64             :     ,m_nMaxFieldSize(0)
      65             :     ,m_nMaxRows(0)
      66             :     ,m_nQueryTimeOut(0)
      67             :     ,m_nFetchSize(0)
      68             :     ,m_nResultSetType(ResultSetType::FORWARD_ONLY)
      69             :     ,m_nFetchDirection(FetchDirection::FORWARD)
      70             :     ,m_nResultSetConcurrency(ResultSetConcurrency::UPDATABLE)
      71             :     ,m_bEscapeProcessing(true)
      72         528 :     ,rBHelper(OStatement_BASE::rBHelper)
      73             : {
      74         132 :     m_pConnection->acquire();
      75             : 
      76         132 :     sal_Int32 nAttrib = 0;
      77             : 
      78         132 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CURSORNAME),      PROPERTY_ID_CURSORNAME,         nAttrib,&m_aCursorName,     ::cppu::UnoType<OUString>::get());
      79         132 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXFIELDSIZE),    PROPERTY_ID_MAXFIELDSIZE,       nAttrib,&m_nMaxFieldSize,       ::cppu::UnoType<sal_Int32>::get());
      80         132 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXROWS),         PROPERTY_ID_MAXROWS,            nAttrib,&m_nMaxRows,        ::cppu::UnoType<sal_Int32>::get());
      81         132 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_QUERYTIMEOUT),    PROPERTY_ID_QUERYTIMEOUT,       nAttrib,&m_nQueryTimeOut,   ::cppu::UnoType<sal_Int32>::get());
      82         132 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE),       PROPERTY_ID_FETCHSIZE,          nAttrib,&m_nFetchSize,      ::cppu::UnoType<sal_Int32>::get());
      83         132 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE),   PROPERTY_ID_RESULTSETTYPE,      nAttrib,&m_nResultSetType,  ::cppu::UnoType<sal_Int32>::get());
      84         132 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION),  PROPERTY_ID_FETCHDIRECTION,     nAttrib,&m_nFetchDirection, ::cppu::UnoType<sal_Int32>::get());
      85         132 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ESCAPEPROCESSING),PROPERTY_ID_ESCAPEPROCESSING,   nAttrib,&m_bEscapeProcessing,::getCppuBooleanType());
      86             : 
      87         132 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY),        PROPERTY_ID_RESULTSETCONCURRENCY,   nAttrib,&m_nResultSetConcurrency,       ::cppu::UnoType<sal_Int32>::get());
      88         132 : }
      89             : 
      90         264 : OStatement_Base::~OStatement_Base()
      91             : {
      92         132 :     osl_atomic_increment( &m_refCount );
      93         132 :     disposing();
      94         132 :     delete m_pSQLAnalyzer;
      95         132 : }
      96             : 
      97         132 : void OStatement_Base::disposeResultSet()
      98             : {
      99             :     SAL_INFO( "connectivity.drivers", "file Ocke.Janssen@sun.com OStatement_Base::disposeResultSet" );
     100             :     // free the cursor if alive
     101         132 :     Reference< XComponent > xComp(m_xResultSet.get(), UNO_QUERY);
     102             :     assert(xComp.is() || !m_xResultSet.get().is());
     103         132 :     if (xComp.is())
     104           0 :         xComp->dispose();
     105         132 :     m_xResultSet.clear();
     106         132 : }
     107             : 
     108         132 : void OStatement_BASE2::disposing()
     109             : {
     110         132 :     ::osl::MutexGuard aGuard(m_aMutex);
     111             : 
     112         132 :     disposeResultSet();
     113             : 
     114         132 :     if(m_pSQLAnalyzer)
     115          88 :         m_pSQLAnalyzer->dispose();
     116             : 
     117         132 :     if(m_aRow.is())
     118             :     {
     119          88 :         m_aRow->get().clear();
     120          88 :         m_aRow = NULL;
     121             :     }
     122             : 
     123         132 :     m_aSQLIterator.dispose();
     124             : 
     125         132 :     if(m_pTable)
     126             :     {
     127          88 :         m_pTable->release();
     128          88 :         m_pTable = NULL;
     129             :     }
     130             : 
     131         132 :     if (m_pConnection)
     132             :     {
     133         132 :         m_pConnection->release();
     134         132 :         m_pConnection = NULL;
     135             :     }
     136             : 
     137         132 :     dispose_ChildImpl();
     138             : 
     139         132 :     if ( m_pParseTree )
     140             :     {
     141         132 :         delete m_pParseTree;
     142         132 :         m_pParseTree = NULL;
     143             :     }
     144             : 
     145         132 :     OStatement_Base::disposing();
     146         132 : }
     147             : 
     148        2998 : void SAL_CALL OStatement_Base::acquire() throw()
     149             : {
     150        2998 :     OStatement_BASE::acquire();
     151        2998 : }
     152             : 
     153        2998 : void SAL_CALL OStatement_BASE2::release() throw()
     154             : {
     155        2998 :     relase_ChildImpl();
     156        2998 : }
     157             : 
     158        1298 : Any SAL_CALL OStatement_Base::queryInterface( const Type & rType ) throw(RuntimeException, std::exception)
     159             : {
     160        1298 :     const Any aRet = OStatement_BASE::queryInterface(rType);
     161        1298 :     return aRet.hasValue() ? aRet : OPropertySetHelper::queryInterface(rType);
     162             : }
     163             : 
     164           0 : Sequence< Type > SAL_CALL OStatement_Base::getTypes(  ) throw(RuntimeException, std::exception)
     165             : {
     166           0 :     ::cppu::OTypeCollection aTypes( cppu::UnoType<com::sun::star::beans::XMultiPropertySet>::get(),
     167           0 :                                                                     cppu::UnoType<com::sun::star::beans::XFastPropertySet>::get(),
     168           0 :                                                                     cppu::UnoType<com::sun::star::beans::XPropertySet>::get());
     169             : 
     170           0 :     return ::comphelper::concatSequences(aTypes.getTypes(),OStatement_BASE::getTypes());
     171             : }
     172             : 
     173             : 
     174           0 : void SAL_CALL OStatement_Base::cancel(  ) throw(RuntimeException, std::exception)
     175             : {
     176           0 : }
     177             : 
     178          22 : void SAL_CALL OStatement_Base::close() throw (SQLException, RuntimeException, std::exception)
     179             : {
     180             :     {
     181          22 :         ::osl::MutexGuard aGuard( m_aMutex );
     182          22 :         checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     183             :     }
     184          22 :     dispose();
     185          22 : }
     186             : 
     187         134 : void OStatement_Base::closeResultSet() throw (SQLException, RuntimeException, std::exception)
     188             : {
     189             :     SAL_INFO( "connectivity.drivers", "file Ocke.Janssen@sun.com OStatement_Base::clearMyResultSet " );
     190         134 :     ::osl::MutexGuard aGuard( m_aMutex );
     191         134 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     192             : 
     193         268 :     Reference< XCloseable > xCloseable(m_xResultSet.get(), UNO_QUERY);
     194             :     assert(xCloseable.is() || !m_xResultSet.get().is());
     195         134 :     if (xCloseable.is())
     196             :     {
     197             :         try
     198             :         {
     199           6 :             xCloseable->close();
     200             :         }
     201           0 :         catch( const DisposedException& ) { }
     202             :     }
     203             : 
     204         268 :     m_xResultSet.clear();
     205         134 : }
     206             : 
     207           0 : Any SAL_CALL OStatement_Base::getWarnings(  ) throw(SQLException, RuntimeException, std::exception)
     208             : {
     209           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     210           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     211             : 
     212           0 :     return makeAny(m_aLastWarning);
     213             : }
     214             : 
     215           0 : void SAL_CALL OStatement_Base::clearWarnings(  ) throw(SQLException, RuntimeException, std::exception)
     216             : {
     217           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     218           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     219             : 
     220           0 :     m_aLastWarning = SQLWarning();
     221           0 : }
     222             : 
     223          62 : ::cppu::IPropertyArrayHelper* OStatement_Base::createArrayHelper( ) const
     224             : {
     225          62 :     Sequence< Property > aProps;
     226          62 :     describeProperties(aProps);
     227          62 :     return new ::cppu::OPropertyArrayHelper(aProps);
     228             : }
     229             : 
     230             : 
     231         466 : ::cppu::IPropertyArrayHelper & OStatement_Base::getInfoHelper()
     232             : {
     233         466 :     return *const_cast<OStatement_Base*>(this)->getArrayHelper();
     234             : }
     235             : 
     236           0 : OResultSet* OStatement::createResultSet()
     237             : {
     238           0 :     return new OResultSet(this,m_aSQLIterator);
     239             : }
     240             : 
     241           0 : IMPLEMENT_SERVICE_INFO(OStatement,"com.sun.star.sdbc.driver.file.Statement","com.sun.star.sdbc.Statement");
     242             : 
     243         484 : void SAL_CALL OStatement::acquire() throw()
     244             : {
     245         484 :     OStatement_BASE2::acquire();
     246         484 : }
     247             : 
     248         484 : void SAL_CALL OStatement::release() throw()
     249             : {
     250         484 :     OStatement_BASE2::release();
     251         484 : }
     252             : 
     253             : 
     254           0 : sal_Bool SAL_CALL OStatement::execute( const OUString& sql ) throw(SQLException, RuntimeException, std::exception)
     255             : {
     256           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     257             : 
     258           0 :     executeQuery(sql);
     259             : 
     260           0 :     return m_aSQLIterator.getStatementType() == SQL_STATEMENT_SELECT;
     261             : }
     262             : 
     263             : 
     264             : 
     265          22 : Reference< XResultSet > SAL_CALL OStatement::executeQuery( const OUString& sql ) throw(SQLException, RuntimeException, std::exception)
     266             : {
     267          22 :     ::osl::MutexGuard aGuard( m_aMutex );
     268          22 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     269             : 
     270          22 :     construct(sql);
     271           0 :     Reference< XResultSet > xRS;
     272           0 :     OResultSet* pResult = createResultSet();
     273           0 :     xRS = pResult;
     274           0 :     initializeResultSet(pResult);
     275           0 :     m_xResultSet = xRS;
     276             : 
     277           0 :     pResult->OpenImpl();
     278             : 
     279           0 :     return xRS;
     280             : }
     281             : 
     282           0 : Reference< XConnection > SAL_CALL OStatement::getConnection(  ) throw(SQLException, RuntimeException, std::exception)
     283             : {
     284           0 :     return Reference< XConnection >(m_pConnection);
     285             : }
     286             : 
     287           0 : sal_Int32 SAL_CALL OStatement::executeUpdate( const OUString& sql ) throw(SQLException, RuntimeException, std::exception)
     288             : {
     289           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     290           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     291             : 
     292             : 
     293           0 :     construct(sql);
     294           0 :     OResultSet* pResult = createResultSet();
     295           0 :     Reference< XResultSet > xRS = pResult;
     296           0 :     initializeResultSet(pResult);
     297           0 :     pResult->OpenImpl();
     298             : 
     299           0 :     return pResult->getRowCountResult();
     300             : }
     301             : 
     302             : 
     303         264 : void SAL_CALL OStatement_Base::disposing(void)
     304             : {
     305         264 :     if(m_aEvaluateRow.is())
     306             :     {
     307          88 :         m_aEvaluateRow->get().clear();
     308          88 :         m_aEvaluateRow = NULL;
     309             :     }
     310         264 :     delete m_pEvaluationKeySet;
     311         264 :     OStatement_BASE::disposing();
     312         264 : }
     313             : 
     314          40 : Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OStatement_Base::getPropertySetInfo(  ) throw(RuntimeException, std::exception)
     315             : {
     316          40 :     return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
     317             : }
     318             : 
     319         198 : Any SAL_CALL OStatement::queryInterface( const Type & rType ) throw(RuntimeException, std::exception)
     320             : {
     321         198 :     Any aRet = OStatement_XStatement::queryInterface( rType);
     322         198 :     return aRet.hasValue() ? aRet : OStatement_BASE2::queryInterface( rType);
     323             : }
     324             : 
     325          88 : OSQLAnalyzer* OStatement_Base::createAnalyzer()
     326             : {
     327          88 :     return new OSQLAnalyzer(m_pConnection);
     328             : }
     329             : 
     330          88 : void OStatement_Base::anylizeSQL()
     331             : {
     332             :     OSL_ENSURE(m_pSQLAnalyzer,"OResultSet::anylizeSQL: Analyzer isn't set!");
     333             :     // start analysing the statement
     334          88 :     m_pSQLAnalyzer->setOrigColumns(m_xColNames);
     335          88 :     m_pSQLAnalyzer->start(m_pParseTree);
     336             : 
     337          88 :     const OSQLParseNode* pOrderbyClause = m_aSQLIterator.getOrderTree();
     338          88 :     if(pOrderbyClause)
     339             :     {
     340           2 :         OSQLParseNode * pOrderingSpecCommalist = pOrderbyClause->getChild(2);
     341             :         OSL_ENSURE(SQL_ISRULE(pOrderingSpecCommalist,ordering_spec_commalist),"OResultSet: Fehler im Parse Tree");
     342             : 
     343           4 :         for (sal_uInt32 m = 0; m < pOrderingSpecCommalist->count(); m++)
     344             :         {
     345           2 :             OSQLParseNode * pOrderingSpec = pOrderingSpecCommalist->getChild(m);
     346             :             OSL_ENSURE(SQL_ISRULE(pOrderingSpec,ordering_spec),"OResultSet: Fehler im Parse Tree");
     347             :             OSL_ENSURE(pOrderingSpec->count() == 2,"OResultSet: Fehler im Parse Tree");
     348             : 
     349           2 :             OSQLParseNode * pColumnRef = pOrderingSpec->getChild(0);
     350           2 :             if(!SQL_ISRULE(pColumnRef,column_ref))
     351             :             {
     352           0 :                 throw SQLException();
     353             :             }
     354           2 :             OSQLParseNode * pAscendingDescending = pOrderingSpec->getChild(1);
     355           2 :             setOrderbyColumn(pColumnRef,pAscendingDescending);
     356             :         }
     357             :     }
     358          88 : }
     359             : 
     360           2 : void OStatement_Base::setOrderbyColumn( OSQLParseNode* pColumnRef,
     361             :                                         OSQLParseNode* pAscendingDescending)
     362             : {
     363           2 :     OUString aColumnName;
     364           2 :     if (pColumnRef->count() == 1)
     365           0 :         aColumnName = pColumnRef->getChild(0)->getTokenValue();
     366           2 :     else if (pColumnRef->count() == 3)
     367             :     {
     368           2 :         pColumnRef->getChild(2)->parseNodeToStr( aColumnName, getOwnConnection(), NULL, false, false );
     369             :     }
     370             :     else
     371             :     {
     372           0 :         throw SQLException();
     373             :     }
     374             : 
     375           4 :     Reference<XColumnLocate> xColLocate(m_xColNames,UNO_QUERY);
     376           2 :     if(!xColLocate.is())
     377           2 :         return;
     378             :     // Everything tested and we have the name of the Column.
     379             :     // What number is the Column?
     380           4 :     ::rtl::Reference<OSQLColumns> aSelectColumns = m_aSQLIterator.getSelectColumns();
     381           2 :     ::comphelper::UStringMixEqual aCase;
     382           2 :     OSQLColumns::Vector::const_iterator aFind = ::connectivity::find(aSelectColumns->get().begin(),aSelectColumns->get().end(),aColumnName,aCase);
     383           2 :     if ( aFind == aSelectColumns->get().end() )
     384           0 :         throw SQLException();
     385           2 :     m_aOrderbyColumnNumber.push_back((aFind - aSelectColumns->get().begin()) + 1);
     386             : 
     387             :     // Ascending or Descending?
     388           4 :     m_aOrderbyAscending.push_back((SQL_ISTOKEN(pAscendingDescending,DESC)) ? SQL_DESC : SQL_ASC);
     389             : }
     390             : 
     391             : 
     392         132 : void OStatement_Base::construct(const OUString& sql)  throw(SQLException, RuntimeException)
     393             : {
     394         132 :     OUString aErr;
     395         132 :     m_pParseTree = m_aParser.parseTree(aErr,sql);
     396         132 :     if(m_pParseTree)
     397             :     {
     398         132 :         m_aSQLIterator.setParseTree(m_pParseTree);
     399         132 :         m_aSQLIterator.traverseAll();
     400         132 :         const OSQLTables& xTabs = m_aSQLIterator.getTables();
     401             : 
     402             :         // sanity checks
     403         132 :         if ( xTabs.empty() )
     404             :             // no tables -> nothing to operate on -> error
     405          88 :             m_pConnection->throwGenericSQLException(STR_QUERY_NO_TABLE,*this);
     406             : 
     407          88 :         if ( xTabs.size() > 1 || m_aSQLIterator.hasErrors() )
     408             :             // more than one table -> can't operate on them -> error
     409           0 :             m_pConnection->throwGenericSQLException(STR_QUERY_MORE_TABLES,*this);
     410             : 
     411          88 :         if ( (m_aSQLIterator.getStatementType() == SQL_STATEMENT_SELECT) && m_aSQLIterator.getSelectColumns()->get().empty() )
     412             :             // SELECT statement without columns -> error
     413           0 :             m_pConnection->throwGenericSQLException(STR_QUERY_NO_COLUMN,*this);
     414             : 
     415          88 :         switch(m_aSQLIterator.getStatementType())
     416             :         {
     417             :             case SQL_STATEMENT_CREATE_TABLE:
     418             :             case SQL_STATEMENT_ODBC_CALL:
     419             :             case SQL_STATEMENT_UNKNOWN:
     420           0 :                 m_pConnection->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,*this);
     421           0 :                 break;
     422             :             default:
     423          88 :                 break;
     424             :         }
     425             : 
     426             :         // at this moment we support only one table per select statement
     427          88 :         Reference< ::com::sun::star::lang::XUnoTunnel> xTunnel(xTabs.begin()->second,UNO_QUERY);
     428          88 :         if(xTunnel.is())
     429             :         {
     430          88 :             if(m_pTable)
     431           0 :                 m_pTable->release();
     432          88 :             m_pTable = reinterpret_cast<OFileTable*>(xTunnel->getSomething(OFileTable::getUnoTunnelImplementationId()));
     433          88 :             if(m_pTable)
     434          88 :                 m_pTable->acquire();
     435             :         }
     436             :         OSL_ENSURE(m_pTable,"No table!");
     437          88 :         if ( m_pTable )
     438          88 :             m_xColNames     = m_pTable->getColumns();
     439         176 :         Reference<XIndexAccess> xNames(m_xColNames,UNO_QUERY);
     440             :         // set the binding of the resultrow
     441          88 :         m_aRow          = new OValueRefVector(xNames->getCount());
     442          88 :         (m_aRow->get())[0]->setBound(true);
     443          88 :         ::std::for_each(m_aRow->get().begin()+1,m_aRow->get().end(),TSetRefBound(false));
     444             : 
     445             :         // set the binding of the resultrow
     446          88 :         m_aEvaluateRow  = new OValueRefVector(xNames->getCount());
     447             : 
     448          88 :         (m_aEvaluateRow->get())[0]->setBound(true);
     449          88 :         ::std::for_each(m_aEvaluateRow->get().begin()+1,m_aEvaluateRow->get().end(),TSetRefBound(false));
     450             : 
     451             :         // set the select row
     452          88 :         m_aSelectRow = new OValueRefVector(m_aSQLIterator.getSelectColumns()->get().size());
     453          88 :         ::std::for_each(m_aSelectRow->get().begin(),m_aSelectRow->get().end(),TSetRefBound(true));
     454             : 
     455             :         // create the column mapping
     456          88 :         createColumnMapping();
     457             : 
     458          88 :         m_pSQLAnalyzer  = createAnalyzer();
     459             : 
     460         176 :         Reference<XIndexesSupplier> xIndexSup(xTunnel,UNO_QUERY);
     461          88 :         if(xIndexSup.is())
     462          80 :             m_pSQLAnalyzer->setIndexes(xIndexSup->getIndexes());
     463             : 
     464         176 :         anylizeSQL();
     465             :     }
     466             :     else
     467           0 :         throw SQLException(aErr,*this,OUString(),0,Any());
     468          88 : }
     469             : 
     470          88 : void OStatement_Base::createColumnMapping()
     471             : {
     472             :     // initialize the column index map (mapping select columns to table columns)
     473          88 :     ::rtl::Reference<connectivity::OSQLColumns> xColumns = m_aSQLIterator.getSelectColumns();
     474          88 :     m_aColMapping.resize(xColumns->get().size() + 1);
     475        1308 :     for (sal_Int32 i=0; i<(sal_Int32)m_aColMapping.size(); ++i)
     476        1220 :         m_aColMapping[i] = i;
     477             : 
     478         176 :     Reference<XIndexAccess> xNames(m_xColNames,UNO_QUERY);
     479             :     // now check which columns are bound
     480         176 :     OResultSet::setBoundedColumns(m_aRow,m_aSelectRow,xColumns,xNames,true,m_xDBMetaData,m_aColMapping);
     481          88 : }
     482             : 
     483          46 : void OStatement_Base::initializeResultSet(OResultSet* _pResult)
     484             : {
     485          46 :     GetAssignValues();
     486             : 
     487          46 :     _pResult->setSqlAnalyzer(m_pSQLAnalyzer);
     488          46 :     _pResult->setOrderByColumns(m_aOrderbyColumnNumber);
     489          46 :     _pResult->setOrderByAscending(m_aOrderbyAscending);
     490          46 :     _pResult->setBindingRow(m_aRow);
     491          46 :     _pResult->setColumnMapping(m_aColMapping);
     492          46 :     _pResult->setEvaluationRow(m_aEvaluateRow);
     493          46 :     _pResult->setAssignValues(m_aAssignValues);
     494          46 :     _pResult->setSelectRow(m_aSelectRow);
     495             : 
     496          46 :     m_pSQLAnalyzer->bindSelectRow(m_aRow);
     497          46 :     m_pEvaluationKeySet = m_pSQLAnalyzer->bindEvaluationRow(m_aEvaluateRow);    // Set values in the code of the Compiler
     498          46 :     _pResult->setEvaluationKeySet(m_pEvaluationKeySet);
     499          46 : }
     500             : 
     501          46 : void OStatement_Base::GetAssignValues()
     502             : {
     503          46 :     if (m_pParseTree == NULL)
     504             :     {
     505           0 :         ::dbtools::throwFunctionSequenceException(*this);
     506           0 :         return;
     507             :     }
     508             : 
     509          46 :     if (SQL_ISRULE(m_pParseTree,select_statement))
     510             :         // no values have to be set for SELECT
     511          46 :         return;
     512           0 :     else if (SQL_ISRULE(m_pParseTree,insert_statement))
     513             :     {
     514             :         // Create Row for the values to be set (Reference trough new)
     515           0 :         if(m_aAssignValues.is())
     516           0 :             m_aAssignValues->get().clear();
     517           0 :         sal_Int32 nCount = Reference<XIndexAccess>(m_xColNames,UNO_QUERY)->getCount();
     518           0 :         m_aAssignValues = new OAssignValues(nCount);
     519             :         // unbound all
     520           0 :         ::std::for_each(m_aAssignValues->get().begin()+1,m_aAssignValues->get().end(),TSetRefBound(false));
     521             : 
     522           0 :         m_aParameterIndexes.resize(nCount+1,SQL_NO_PARAMETER);
     523             : 
     524             :         // List of Column-Names, that exist in the column_commalist (separated by ;):
     525           0 :         ::std::vector<OUString> aColumnNameList;
     526             : 
     527             :         OSL_ENSURE(m_pParseTree->count() >= 4,"OResultSet: Fehler im Parse Tree");
     528             : 
     529           0 :         OSQLParseNode * pOptColumnCommalist = m_pParseTree->getChild(3);
     530             :         OSL_ENSURE(pOptColumnCommalist != NULL,"OResultSet: Fehler im Parse Tree");
     531             :         OSL_ENSURE(SQL_ISRULE(pOptColumnCommalist,opt_column_commalist),"OResultSet: Fehler im Parse Tree");
     532           0 :         if (pOptColumnCommalist->count() == 0)
     533             :         {
     534           0 :             const Sequence< OUString>& aNames = m_xColNames->getElementNames();
     535           0 :             const OUString* pBegin = aNames.getConstArray();
     536           0 :             const OUString* pEnd = pBegin + aNames.getLength();
     537           0 :             for (; pBegin != pEnd; ++pBegin)
     538           0 :                 aColumnNameList.push_back(*pBegin);
     539             :         }
     540             :         else
     541             :         {
     542             :             OSL_ENSURE(pOptColumnCommalist->count() == 3,"OResultSet: Fehler im Parse Tree");
     543             : 
     544           0 :             OSQLParseNode * pColumnCommalist = pOptColumnCommalist->getChild(1);
     545             :             OSL_ENSURE(pColumnCommalist != NULL,"OResultSet: Fehler im Parse Tree");
     546             :             OSL_ENSURE(SQL_ISRULE(pColumnCommalist,column_commalist),"OResultSet: Fehler im Parse Tree");
     547             :             OSL_ENSURE(pColumnCommalist->count() > 0,"OResultSet: Fehler im Parse Tree");
     548             : 
     549             :             // All Columns in the column_commalist ...
     550           0 :             for (sal_uInt32 i = 0; i < pColumnCommalist->count(); i++)
     551             :             {
     552           0 :                 OSQLParseNode * pCol = pColumnCommalist->getChild(i);
     553             :                 OSL_ENSURE(pCol != NULL,"OResultSet: Fehler im Parse Tree");
     554           0 :                 aColumnNameList.push_back(pCol->getTokenValue());
     555             :             }
     556             :         }
     557           0 :         if ( aColumnNameList.empty() )
     558           0 :             throwFunctionSequenceException(*this);
     559             : 
     560             :         // Values ...
     561           0 :         OSQLParseNode * pValuesOrQuerySpec = m_pParseTree->getChild(4);
     562             :         OSL_ENSURE(pValuesOrQuerySpec != NULL,"OResultSet: pValuesOrQuerySpec darf nicht NULL sein!");
     563             :         OSL_ENSURE(SQL_ISRULE(pValuesOrQuerySpec,values_or_query_spec),"OResultSet: ! SQL_ISRULE(pValuesOrQuerySpec,values_or_query_spec)");
     564             :         OSL_ENSURE(pValuesOrQuerySpec->count() > 0,"OResultSet: pValuesOrQuerySpec->count() <= 0");
     565             : 
     566             :         // just "VALUES" is allowed ...
     567           0 :         if (! SQL_ISTOKEN(pValuesOrQuerySpec->getChild(0),VALUES))
     568           0 :             throwFunctionSequenceException(*this);
     569             : 
     570             :         OSL_ENSURE(pValuesOrQuerySpec->count() == 4,"OResultSet: pValuesOrQuerySpec->count() != 4");
     571             : 
     572             :         // List of values
     573           0 :         OSQLParseNode * pInsertAtomCommalist = pValuesOrQuerySpec->getChild(2);
     574             :         OSL_ENSURE(pInsertAtomCommalist != NULL,"OResultSet: pInsertAtomCommalist darf nicht NULL sein!");
     575             :         OSL_ENSURE(pInsertAtomCommalist->count() > 0,"OResultSet: pInsertAtomCommalist <= 0");
     576             : 
     577             :         OSQLParseNode * pRow_Value_Const;
     578           0 :         sal_Int32 nIndex=0;
     579           0 :         for (sal_uInt32 i = 0; i < pInsertAtomCommalist->count(); i++)
     580             :         {
     581           0 :             pRow_Value_Const = pInsertAtomCommalist->getChild(i); // row_value_constructor
     582             :             OSL_ENSURE(pRow_Value_Const != NULL,"OResultSet: pRow_Value_Const darf nicht NULL sein!");
     583           0 :             if(SQL_ISRULE(pRow_Value_Const,parameter))
     584             :             {
     585           0 :                 ParseAssignValues(aColumnNameList,pRow_Value_Const,nIndex++); // only one Columnname allowed per loop
     586             :             }
     587           0 :             else if(pRow_Value_Const->isToken())
     588           0 :                 ParseAssignValues(aColumnNameList,pRow_Value_Const,i);
     589             :             else
     590             :             {
     591           0 :                 if(pRow_Value_Const->count() == aColumnNameList.size())
     592             :                 {
     593           0 :                     for (sal_uInt32 j = 0; j < pRow_Value_Const->count(); ++j)
     594           0 :                         ParseAssignValues(aColumnNameList,pRow_Value_Const->getChild(j),nIndex++);
     595             :                 }
     596             :                 else
     597           0 :                     throwFunctionSequenceException(*this);
     598             :             }
     599           0 :         }
     600             :     }
     601           0 :     else if (SQL_ISRULE(m_pParseTree,update_statement_searched))
     602             :     {
     603           0 :         if(m_aAssignValues.is())
     604           0 :             m_aAssignValues->get().clear();
     605           0 :         sal_Int32 nCount = Reference<XIndexAccess>(m_xColNames,UNO_QUERY)->getCount();
     606           0 :         m_aAssignValues = new OAssignValues(nCount);
     607             :         // unbound all
     608           0 :         ::std::for_each(m_aAssignValues->get().begin()+1,m_aAssignValues->get().end(),TSetRefBound(false));
     609             : 
     610           0 :         m_aParameterIndexes.resize(nCount+1,SQL_NO_PARAMETER);
     611             : 
     612             :         OSL_ENSURE(m_pParseTree->count() >= 4,"OResultSet: Fehler im Parse Tree");
     613             : 
     614           0 :         OSQLParseNode * pAssignmentCommalist = m_pParseTree->getChild(3);
     615             :         OSL_ENSURE(pAssignmentCommalist != NULL,"OResultSet: pAssignmentCommalist == NULL");
     616             :         OSL_ENSURE(SQL_ISRULE(pAssignmentCommalist,assignment_commalist),"OResultSet: Fehler im Parse Tree");
     617             :         OSL_ENSURE(pAssignmentCommalist->count() > 0,"OResultSet: pAssignmentCommalist->count() <= 0");
     618             : 
     619             :         // work on all assignments (commalist) ...
     620           0 :         ::std::vector< OUString> aList(1);
     621           0 :         for (sal_uInt32 i = 0; i < pAssignmentCommalist->count(); i++)
     622             :         {
     623           0 :             OSQLParseNode * pAssignment = pAssignmentCommalist->getChild(i);
     624             :             OSL_ENSURE(pAssignment != NULL,"OResultSet: pAssignment == NULL");
     625             :             OSL_ENSURE(SQL_ISRULE(pAssignment,assignment),"OResultSet: Fehler im Parse Tree");
     626             :             OSL_ENSURE(pAssignment->count() == 3,"OResultSet: pAssignment->count() != 3");
     627             : 
     628           0 :             OSQLParseNode * pCol = pAssignment->getChild(0);
     629             :             OSL_ENSURE(pCol != NULL,"OResultSet: pCol == NULL");
     630             : 
     631           0 :             OSQLParseNode * pComp = pAssignment->getChild(1);
     632             :             OSL_ENSURE(pComp != NULL,"OResultSet: pComp == NULL");
     633             :             OSL_ENSURE(pComp->getNodeType() == SQL_NODE_EQUAL,"OResultSet: pComp->getNodeType() != SQL_NODE_COMPARISON");
     634           0 :             if (pComp->getTokenValue().toChar() != '=')
     635             :             {
     636           0 :                 throwFunctionSequenceException(*this);
     637             :             }
     638             : 
     639           0 :             OSQLParseNode * pVal = pAssignment->getChild(2);
     640             :             OSL_ENSURE(pVal != NULL,"OResultSet: pVal == NULL");
     641           0 :             aList[0] = pCol->getTokenValue();
     642           0 :             ParseAssignValues(aList,pVal,0);
     643           0 :         }
     644             : 
     645             :     }
     646             : }
     647             : 
     648           0 : void OStatement_Base::ParseAssignValues(const ::std::vector< OUString>& aColumnNameList,OSQLParseNode* pRow_Value_Constructor_Elem, sal_Int32 nIndex)
     649             : {
     650             :     OSL_ENSURE(size_t(nIndex) <= aColumnNameList.size(),"SdbFileCursor::ParseAssignValues: nIndex > aColumnNameList.GetTokenCount()");
     651           0 :     OUString aColumnName(aColumnNameList[nIndex]);
     652             :     OSL_ENSURE(aColumnName.getLength() > 0,"OResultSet: Column-Name nicht gefunden");
     653             :     OSL_ENSURE(pRow_Value_Constructor_Elem != NULL,"OResultSet: pRow_Value_Constructor_Elem darf nicht NULL sein!");
     654             : 
     655           0 :     if (pRow_Value_Constructor_Elem->getNodeType() == SQL_NODE_STRING ||
     656           0 :         pRow_Value_Constructor_Elem->getNodeType() == SQL_NODE_INTNUM ||
     657           0 :         pRow_Value_Constructor_Elem->getNodeType() == SQL_NODE_APPROXNUM)
     658             :     {
     659             :         // set value:
     660           0 :         SetAssignValue(aColumnName, pRow_Value_Constructor_Elem->getTokenValue());
     661             :     }
     662           0 :     else if (SQL_ISTOKEN(pRow_Value_Constructor_Elem,NULL))
     663             :     {
     664             :         // set NULL
     665           0 :         SetAssignValue(aColumnName, OUString(), true);
     666             :     }
     667           0 :     else if (SQL_ISRULE(pRow_Value_Constructor_Elem,parameter))
     668           0 :         parseParamterElem(aColumnName,pRow_Value_Constructor_Elem);
     669             :     else
     670             :     {
     671           0 :         throwFunctionSequenceException(*this);
     672           0 :     }
     673           0 : }
     674             : 
     675           0 : void OStatement_Base::SetAssignValue(const OUString& aColumnName,
     676             :                                      const OUString& aValue,
     677             :                                      bool bSetNull,
     678             :                                      sal_uInt32 nParameter)
     679             : {
     680           0 :     Reference<XPropertySet> xCol;
     681           0 :     m_xColNames->getByName(aColumnName) >>= xCol;
     682           0 :     sal_Int32 nId = Reference<XColumnLocate>(m_xColNames,UNO_QUERY)->findColumn(aColumnName);
     683             :     // does this column actually exist in the file?
     684             : 
     685           0 :     if (!xCol.is())
     686             :     {
     687             :         // This Column doesn't exist!
     688           0 :         throwFunctionSequenceException(*this);
     689             :     }
     690             : 
     691             : 
     692             :     // Everything tested and we have the names of the Column.
     693             :     // Now allocate one Value, set the value and tie the value to the Row.
     694           0 :     if (bSetNull)
     695           0 :         (m_aAssignValues->get())[nId]->setNull();
     696             :     else
     697             :     {
     698           0 :         switch (::comphelper::getINT32(xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))))
     699             :         {
     700             :             // put criteria depending on the Type as String or double in the variable
     701             :         case DataType::CHAR:
     702             :         case DataType::VARCHAR:
     703             :         case DataType::LONGVARCHAR:
     704           0 :             *(m_aAssignValues->get())[nId] = ORowSetValue(aValue);
     705             :             //Characterset is already converted, since the entire statement was converted
     706           0 :             break;
     707             : 
     708             :         case DataType::BIT:
     709           0 :             if (aValue.equalsIgnoreAsciiCase("TRUE")  || aValue[0] == '1')
     710           0 :                 *(m_aAssignValues->get())[nId] = sal_True;
     711           0 :             else if (aValue.equalsIgnoreAsciiCase("FALSE") || aValue[0] == '0')
     712           0 :                 *(m_aAssignValues->get())[nId] = sal_False;
     713             :             else
     714           0 :                 throwFunctionSequenceException(*this);
     715           0 :             break;
     716             :         case DataType::TINYINT:
     717             :         case DataType::SMALLINT:
     718             :         case DataType::INTEGER:
     719             :         case DataType::DECIMAL:
     720             :         case DataType::NUMERIC:
     721             :         case DataType::REAL:
     722             :         case DataType::DOUBLE:
     723             :         case DataType::DATE:
     724             :         case DataType::TIME:
     725             :         case DataType::TIMESTAMP:
     726           0 :             *(m_aAssignValues->get())[nId] = ORowSetValue(aValue);
     727           0 :             break;
     728             :         default:
     729           0 :             throwFunctionSequenceException(*this);
     730             :         }
     731             :     }
     732             : 
     733             :     // save Parameter-No. (as User Data)
     734             :     // SQL_NO_PARAMETER = no Parameter.
     735           0 :     m_aAssignValues->setParameterIndex(nId,nParameter);
     736           0 :     if(nParameter != SQL_NO_PARAMETER)
     737           0 :         m_aParameterIndexes[nParameter] = nId;
     738           0 : }
     739             : 
     740           0 : void OStatement_Base::parseParamterElem(const OUString& /*_sColumnName*/,OSQLParseNode* /*pRow_Value_Constructor_Elem*/)
     741             : {
     742             :     // do nothing here
     743           0 : }
     744             : 
     745             :     } // namespace file
     746             : 
     747             : }// namespace connectivity
     748             : 
     749             : 
     750             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10