LCOV - code coverage report
Current view: top level - connectivity/source/drivers/file - FStatement.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 189 339 55.8 %
Date: 2015-06-13 12:38:46 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 "sqlbison.hxx"
      24             : #include "file/FDriver.hxx"
      25             : #include "file/FResultSet.hxx"
      26             : #include <comphelper/property.hxx>
      27             : #include <comphelper/uno3.hxx>
      28             : #include <osl/thread.h>
      29             : #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
      30             : #include <com/sun/star/sdbc/ResultSetType.hpp>
      31             : #include <com/sun/star/sdbc/FetchDirection.hpp>
      32             : #include <com/sun/star/lang/DisposedException.hpp>
      33             : #include <comphelper/processfactory.hxx>
      34             : #include <comphelper/sequence.hxx>
      35             : #include <cppuhelper/typeprovider.hxx>
      36             : #include <connectivity/dbexception.hxx>
      37             : #include "resource/file_res.hrc"
      38             : #include <algorithm>
      39             : 
      40             : namespace connectivity
      41             : {
      42             :     namespace file
      43             :     {
      44             : 
      45             : 
      46             : using namespace dbtools;
      47             : using namespace com::sun::star::uno;
      48             : using namespace com::sun::star::lang;
      49             : using namespace com::sun::star::beans;
      50             : using namespace com::sun::star::sdbc;
      51             : using namespace com::sun::star::sdbcx;
      52             : using namespace com::sun::star::container;
      53             : 
      54          80 : OStatement_Base::OStatement_Base(OConnection* _pConnection )
      55             :     :OStatement_BASE(m_aMutex)
      56             :     ,::comphelper::OPropertyContainer(OStatement_BASE::rBHelper)
      57          80 :     ,m_xDBMetaData(_pConnection->getMetaData())
      58             :     ,m_aParser( _pConnection->getDriver()->getComponentContext() )
      59         160 :     ,m_aSQLIterator( _pConnection, _pConnection->createCatalog()->getTables(), m_aParser, NULL )
      60             :     ,m_pConnection(_pConnection)
      61             :     ,m_pParseTree(NULL)
      62             :     ,m_pSQLAnalyzer(NULL)
      63             :     ,m_pEvaluationKeySet(NULL)
      64             :     ,m_pTable(NULL)
      65             :     ,m_nMaxFieldSize(0)
      66             :     ,m_nMaxRows(0)
      67             :     ,m_nQueryTimeOut(0)
      68             :     ,m_nFetchSize(0)
      69             :     ,m_nResultSetType(ResultSetType::FORWARD_ONLY)
      70             :     ,m_nFetchDirection(FetchDirection::FORWARD)
      71             :     ,m_nResultSetConcurrency(ResultSetConcurrency::UPDATABLE)
      72             :     ,m_bEscapeProcessing(true)
      73         320 :     ,rBHelper(OStatement_BASE::rBHelper)
      74             : {
      75          80 :     m_pConnection->acquire();
      76             : 
      77          80 :     sal_Int32 nAttrib = 0;
      78             : 
      79          80 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CURSORNAME),      PROPERTY_ID_CURSORNAME,         nAttrib,&m_aCursorName,     ::cppu::UnoType<OUString>::get());
      80          80 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXFIELDSIZE),    PROPERTY_ID_MAXFIELDSIZE,       nAttrib,&m_nMaxFieldSize,       ::cppu::UnoType<sal_Int32>::get());
      81          80 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXROWS),         PROPERTY_ID_MAXROWS,            nAttrib,&m_nMaxRows,        ::cppu::UnoType<sal_Int32>::get());
      82          80 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_QUERYTIMEOUT),    PROPERTY_ID_QUERYTIMEOUT,       nAttrib,&m_nQueryTimeOut,   ::cppu::UnoType<sal_Int32>::get());
      83          80 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE),       PROPERTY_ID_FETCHSIZE,          nAttrib,&m_nFetchSize,      ::cppu::UnoType<sal_Int32>::get());
      84          80 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE),   PROPERTY_ID_RESULTSETTYPE,      nAttrib,&m_nResultSetType,  ::cppu::UnoType<sal_Int32>::get());
      85          80 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION),  PROPERTY_ID_FETCHDIRECTION,     nAttrib,&m_nFetchDirection, ::cppu::UnoType<sal_Int32>::get());
      86          80 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ESCAPEPROCESSING),PROPERTY_ID_ESCAPEPROCESSING,   nAttrib,&m_bEscapeProcessing,cppu::UnoType<bool>::get());
      87             : 
      88          80 :     registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY),        PROPERTY_ID_RESULTSETCONCURRENCY,   nAttrib,&m_nResultSetConcurrency,       ::cppu::UnoType<sal_Int32>::get());
      89          80 : }
      90             : 
      91         160 : OStatement_Base::~OStatement_Base()
      92             : {
      93          80 :     osl_atomic_increment( &m_refCount );
      94          80 :     disposing();
      95          80 :     delete m_pSQLAnalyzer;
      96          80 : }
      97             : 
      98          80 : void OStatement_Base::disposeResultSet()
      99             : {
     100             :     SAL_INFO( "connectivity.drivers", "file Ocke.Janssen@sun.com OStatement_Base::disposeResultSet" );
     101             :     // free the cursor if alive
     102          80 :     Reference< XComponent > xComp(m_xResultSet.get(), UNO_QUERY);
     103             :     assert(xComp.is() || !m_xResultSet.get().is());
     104          80 :     if (xComp.is())
     105           0 :         xComp->dispose();
     106          80 :     m_xResultSet.clear();
     107          80 : }
     108             : 
     109          80 : void OStatement_BASE2::disposing()
     110             : {
     111          80 :     ::osl::MutexGuard aGuard(m_aMutex);
     112             : 
     113          80 :     disposeResultSet();
     114             : 
     115          80 :     if(m_pSQLAnalyzer)
     116          58 :         m_pSQLAnalyzer->dispose();
     117             : 
     118          80 :     if(m_aRow.is())
     119             :     {
     120          58 :         m_aRow->get().clear();
     121          58 :         m_aRow = NULL;
     122             :     }
     123             : 
     124          80 :     m_aSQLIterator.dispose();
     125             : 
     126          80 :     if(m_pTable)
     127             :     {
     128          58 :         m_pTable->release();
     129          58 :         m_pTable = NULL;
     130             :     }
     131             : 
     132          80 :     if (m_pConnection)
     133             :     {
     134          80 :         m_pConnection->release();
     135          80 :         m_pConnection = NULL;
     136             :     }
     137             : 
     138          80 :     dispose_ChildImpl();
     139             : 
     140          80 :     if ( m_pParseTree )
     141             :     {
     142          80 :         delete m_pParseTree;
     143          80 :         m_pParseTree = NULL;
     144             :     }
     145             : 
     146          80 :     OStatement_Base::disposing();
     147          80 : }
     148             : 
     149        1887 : void SAL_CALL OStatement_Base::acquire() throw()
     150             : {
     151        1887 :     OStatement_BASE::acquire();
     152        1887 : }
     153             : 
     154        1887 : void SAL_CALL OStatement_BASE2::release() throw()
     155             : {
     156        1887 :     relase_ChildImpl();
     157        1887 : }
     158             : 
     159         839 : Any SAL_CALL OStatement_Base::queryInterface( const Type & rType ) throw(RuntimeException, std::exception)
     160             : {
     161         839 :     const Any aRet = OStatement_BASE::queryInterface(rType);
     162         839 :     return aRet.hasValue() ? aRet : OPropertySetHelper::queryInterface(rType);
     163             : }
     164             : 
     165           0 : Sequence< Type > SAL_CALL OStatement_Base::getTypes(  ) throw(RuntimeException, std::exception)
     166             : {
     167           0 :     ::cppu::OTypeCollection aTypes( cppu::UnoType<com::sun::star::beans::XMultiPropertySet>::get(),
     168           0 :                                                                     cppu::UnoType<com::sun::star::beans::XFastPropertySet>::get(),
     169           0 :                                                                     cppu::UnoType<com::sun::star::beans::XPropertySet>::get());
     170             : 
     171           0 :     return ::comphelper::concatSequences(aTypes.getTypes(),OStatement_BASE::getTypes());
     172             : }
     173             : 
     174             : 
     175           0 : void SAL_CALL OStatement_Base::cancel(  ) throw(RuntimeException, std::exception)
     176             : {
     177           0 : }
     178             : 
     179          11 : void SAL_CALL OStatement_Base::close() throw (SQLException, RuntimeException, std::exception)
     180             : {
     181             :     {
     182          11 :         ::osl::MutexGuard aGuard( m_aMutex );
     183          11 :         checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     184             :     }
     185          11 :     dispose();
     186          11 : }
     187             : 
     188          87 : void OStatement_Base::closeResultSet() throw (SQLException, RuntimeException, std::exception)
     189             : {
     190             :     SAL_INFO( "connectivity.drivers", "file Ocke.Janssen@sun.com OStatement_Base::clearMyResultSet " );
     191          87 :     ::osl::MutexGuard aGuard( m_aMutex );
     192          87 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     193             : 
     194         174 :     Reference< XCloseable > xCloseable(m_xResultSet.get(), UNO_QUERY);
     195             :     assert(xCloseable.is() || !m_xResultSet.get().is());
     196          87 :     if (xCloseable.is())
     197             :     {
     198             :         try
     199             :         {
     200           3 :             xCloseable->close();
     201             :         }
     202           0 :         catch( const DisposedException& ) { }
     203             :     }
     204             : 
     205         174 :     m_xResultSet.clear();
     206          87 : }
     207             : 
     208           0 : Any SAL_CALL OStatement_Base::getWarnings(  ) throw(SQLException, RuntimeException, std::exception)
     209             : {
     210           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     211           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     212             : 
     213           0 :     return makeAny(m_aLastWarning);
     214             : }
     215             : 
     216           0 : void SAL_CALL OStatement_Base::clearWarnings(  ) throw(SQLException, RuntimeException, std::exception)
     217             : {
     218           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     219           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     220             : 
     221           0 :     m_aLastWarning = SQLWarning();
     222           0 : }
     223             : 
     224          37 : ::cppu::IPropertyArrayHelper* OStatement_Base::createArrayHelper( ) const
     225             : {
     226          37 :     Sequence< Property > aProps;
     227          37 :     describeProperties(aProps);
     228          37 :     return new ::cppu::OPropertyArrayHelper(aProps);
     229             : }
     230             : 
     231             : 
     232         313 : ::cppu::IPropertyArrayHelper & OStatement_Base::getInfoHelper()
     233             : {
     234         313 :     return *getArrayHelper();
     235             : }
     236             : 
     237           0 : OResultSet* OStatement::createResultSet()
     238             : {
     239           0 :     return new OResultSet(this,m_aSQLIterator);
     240             : }
     241             : 
     242           0 : IMPLEMENT_SERVICE_INFO(OStatement,"com.sun.star.sdbc.driver.file.Statement","com.sun.star.sdbc.Statement");
     243             : 
     244         242 : void SAL_CALL OStatement::acquire() throw()
     245             : {
     246         242 :     OStatement_BASE2::acquire();
     247         242 : }
     248             : 
     249         242 : void SAL_CALL OStatement::release() throw()
     250             : {
     251         242 :     OStatement_BASE2::release();
     252         242 : }
     253             : 
     254             : 
     255           0 : sal_Bool SAL_CALL OStatement::execute( const OUString& sql ) throw(SQLException, RuntimeException, std::exception)
     256             : {
     257           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     258             : 
     259           0 :     executeQuery(sql);
     260             : 
     261           0 :     return m_aSQLIterator.getStatementType() == SQL_STATEMENT_SELECT;
     262             : }
     263             : 
     264             : 
     265             : 
     266          11 : Reference< XResultSet > SAL_CALL OStatement::executeQuery( const OUString& sql ) throw(SQLException, RuntimeException, std::exception)
     267             : {
     268          11 :     ::osl::MutexGuard aGuard( m_aMutex );
     269          11 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     270             : 
     271          11 :     construct(sql);
     272           0 :     Reference< XResultSet > xRS;
     273           0 :     OResultSet* pResult = createResultSet();
     274           0 :     xRS = pResult;
     275           0 :     initializeResultSet(pResult);
     276           0 :     m_xResultSet = xRS;
     277             : 
     278           0 :     pResult->OpenImpl();
     279             : 
     280           0 :     return xRS;
     281             : }
     282             : 
     283           0 : Reference< XConnection > SAL_CALL OStatement::getConnection(  ) throw(SQLException, RuntimeException, std::exception)
     284             : {
     285           0 :     return Reference< XConnection >(m_pConnection);
     286             : }
     287             : 
     288           0 : sal_Int32 SAL_CALL OStatement::executeUpdate( const OUString& sql ) throw(SQLException, RuntimeException, std::exception)
     289             : {
     290           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     291           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     292             : 
     293             : 
     294           0 :     construct(sql);
     295           0 :     OResultSet* pResult = createResultSet();
     296           0 :     Reference< XResultSet > xRS = pResult;
     297           0 :     initializeResultSet(pResult);
     298           0 :     pResult->OpenImpl();
     299             : 
     300           0 :     return pResult->getRowCountResult();
     301             : }
     302             : 
     303             : 
     304         160 : void SAL_CALL OStatement_Base::disposing()
     305             : {
     306         160 :     if(m_aEvaluateRow.is())
     307             :     {
     308          58 :         m_aEvaluateRow->get().clear();
     309          58 :         m_aEvaluateRow = NULL;
     310             :     }
     311         160 :     delete m_pEvaluationKeySet;
     312         160 :     OStatement_BASE::disposing();
     313         160 : }
     314             : 
     315          28 : Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OStatement_Base::getPropertySetInfo(  ) throw(RuntimeException, std::exception)
     316             : {
     317          28 :     return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
     318             : }
     319             : 
     320          99 : Any SAL_CALL OStatement::queryInterface( const Type & rType ) throw(RuntimeException, std::exception)
     321             : {
     322          99 :     Any aRet = OStatement_XStatement::queryInterface( rType);
     323          99 :     return aRet.hasValue() ? aRet : OStatement_BASE2::queryInterface( rType);
     324             : }
     325             : 
     326          58 : OSQLAnalyzer* OStatement_Base::createAnalyzer()
     327             : {
     328          58 :     return new OSQLAnalyzer(m_pConnection);
     329             : }
     330             : 
     331          58 : void OStatement_Base::anylizeSQL()
     332             : {
     333             :     OSL_ENSURE(m_pSQLAnalyzer,"OResultSet::anylizeSQL: Analyzer isn't set!");
     334             :     // start analysing the statement
     335          58 :     m_pSQLAnalyzer->setOrigColumns(m_xColNames);
     336          58 :     m_pSQLAnalyzer->start(m_pParseTree);
     337             : 
     338          58 :     const OSQLParseNode* pOrderbyClause = m_aSQLIterator.getOrderTree();
     339          58 :     if(pOrderbyClause)
     340             :     {
     341           1 :         OSQLParseNode * pOrderingSpecCommalist = pOrderbyClause->getChild(2);
     342             :         OSL_ENSURE(SQL_ISRULE(pOrderingSpecCommalist,ordering_spec_commalist),"OResultSet: Fehler im Parse Tree");
     343             : 
     344           2 :         for (size_t m = 0; m < pOrderingSpecCommalist->count(); m++)
     345             :         {
     346           1 :             OSQLParseNode * pOrderingSpec = pOrderingSpecCommalist->getChild(m);
     347             :             OSL_ENSURE(SQL_ISRULE(pOrderingSpec,ordering_spec),"OResultSet: Fehler im Parse Tree");
     348             :             OSL_ENSURE(pOrderingSpec->count() == 2,"OResultSet: Fehler im Parse Tree");
     349             : 
     350           1 :             OSQLParseNode * pColumnRef = pOrderingSpec->getChild(0);
     351           1 :             if(!SQL_ISRULE(pColumnRef,column_ref))
     352             :             {
     353           0 :                 throw SQLException();
     354             :             }
     355           1 :             OSQLParseNode * pAscendingDescending = pOrderingSpec->getChild(1);
     356           1 :             setOrderbyColumn(pColumnRef,pAscendingDescending);
     357             :         }
     358             :     }
     359          58 : }
     360             : 
     361           1 : void OStatement_Base::setOrderbyColumn( OSQLParseNode* pColumnRef,
     362             :                                         OSQLParseNode* pAscendingDescending)
     363             : {
     364           1 :     OUString aColumnName;
     365           1 :     if (pColumnRef->count() == 1)
     366           0 :         aColumnName = pColumnRef->getChild(0)->getTokenValue();
     367           1 :     else if (pColumnRef->count() == 3)
     368             :     {
     369           1 :         pColumnRef->getChild(2)->parseNodeToStr( aColumnName, getOwnConnection(), NULL, false, false );
     370             :     }
     371             :     else
     372             :     {
     373           0 :         throw SQLException();
     374             :     }
     375             : 
     376           2 :     Reference<XColumnLocate> xColLocate(m_xColNames,UNO_QUERY);
     377           1 :     if(!xColLocate.is())
     378           1 :         return;
     379             :     // Everything tested and we have the name of the Column.
     380             :     // What number is the Column?
     381           2 :     ::rtl::Reference<OSQLColumns> aSelectColumns = m_aSQLIterator.getSelectColumns();
     382           1 :     ::comphelper::UStringMixEqual aCase;
     383           1 :     OSQLColumns::Vector::const_iterator aFind = ::connectivity::find(aSelectColumns->get().begin(),aSelectColumns->get().end(),aColumnName,aCase);
     384           1 :     if ( aFind == aSelectColumns->get().end() )
     385           0 :         throw SQLException();
     386           1 :     m_aOrderbyColumnNumber.push_back((aFind - aSelectColumns->get().begin()) + 1);
     387             : 
     388             :     // Ascending or Descending?
     389           2 :     m_aOrderbyAscending.push_back((SQL_ISTOKEN(pAscendingDescending,DESC)) ? SQL_DESC : SQL_ASC);
     390             : }
     391             : 
     392             : 
     393          80 : void OStatement_Base::construct(const OUString& sql)  throw(SQLException, RuntimeException)
     394             : {
     395          80 :     OUString aErr;
     396          80 :     m_pParseTree = m_aParser.parseTree(aErr,sql);
     397          80 :     if(m_pParseTree)
     398             :     {
     399          80 :         m_aSQLIterator.setParseTree(m_pParseTree);
     400          80 :         m_aSQLIterator.traverseAll();
     401          80 :         const OSQLTables& xTabs = m_aSQLIterator.getTables();
     402             : 
     403             :         // sanity checks
     404          80 :         if ( xTabs.empty() )
     405             :             // no tables -> nothing to operate on -> error
     406          44 :             m_pConnection->throwGenericSQLException(STR_QUERY_NO_TABLE,*this);
     407             : 
     408          58 :         if ( xTabs.size() > 1 || m_aSQLIterator.hasErrors() )
     409             :             // more than one table -> can't operate on them -> error
     410           0 :             m_pConnection->throwGenericSQLException(STR_QUERY_MORE_TABLES,*this);
     411             : 
     412          58 :         if ( (m_aSQLIterator.getStatementType() == SQL_STATEMENT_SELECT) && m_aSQLIterator.getSelectColumns()->get().empty() )
     413             :             // SELECT statement without columns -> error
     414           0 :             m_pConnection->throwGenericSQLException(STR_QUERY_NO_COLUMN,*this);
     415             : 
     416          58 :         switch(m_aSQLIterator.getStatementType())
     417             :         {
     418             :             case SQL_STATEMENT_CREATE_TABLE:
     419             :             case SQL_STATEMENT_ODBC_CALL:
     420             :             case SQL_STATEMENT_UNKNOWN:
     421           0 :                 m_pConnection->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,*this);
     422           0 :                 break;
     423             :             default:
     424          58 :                 break;
     425             :         }
     426             : 
     427             :         // at this moment we support only one table per select statement
     428          58 :         Reference< ::com::sun::star::lang::XUnoTunnel> xTunnel(xTabs.begin()->second,UNO_QUERY);
     429          58 :         if(xTunnel.is())
     430             :         {
     431          58 :             if(m_pTable)
     432           0 :                 m_pTable->release();
     433          58 :             m_pTable = reinterpret_cast<OFileTable*>(xTunnel->getSomething(OFileTable::getUnoTunnelImplementationId()));
     434          58 :             if(m_pTable)
     435          58 :                 m_pTable->acquire();
     436             :         }
     437             :         OSL_ENSURE(m_pTable,"No table!");
     438          58 :         if ( m_pTable )
     439          58 :             m_xColNames     = m_pTable->getColumns();
     440         116 :         Reference<XIndexAccess> xNames(m_xColNames,UNO_QUERY);
     441             :         // set the binding of the resultrow
     442          58 :         m_aRow          = new OValueRefVector(xNames->getCount());
     443          58 :         (m_aRow->get())[0]->setBound(true);
     444          58 :         ::std::for_each(m_aRow->get().begin()+1,m_aRow->get().end(),TSetRefBound(false));
     445             : 
     446             :         // set the binding of the resultrow
     447          58 :         m_aEvaluateRow  = new OValueRefVector(xNames->getCount());
     448             : 
     449          58 :         (m_aEvaluateRow->get())[0]->setBound(true);
     450          58 :         ::std::for_each(m_aEvaluateRow->get().begin()+1,m_aEvaluateRow->get().end(),TSetRefBound(false));
     451             : 
     452             :         // set the select row
     453          58 :         m_aSelectRow = new OValueRefVector(m_aSQLIterator.getSelectColumns()->get().size());
     454          58 :         ::std::for_each(m_aSelectRow->get().begin(),m_aSelectRow->get().end(),TSetRefBound(true));
     455             : 
     456             :         // create the column mapping
     457          58 :         createColumnMapping();
     458             : 
     459          58 :         m_pSQLAnalyzer  = createAnalyzer();
     460             : 
     461         116 :         Reference<XIndexesSupplier> xIndexSup(xTunnel,UNO_QUERY);
     462          58 :         if(xIndexSup.is())
     463          42 :             m_pSQLAnalyzer->setIndexes(xIndexSup->getIndexes());
     464             : 
     465         116 :         anylizeSQL();
     466             :     }
     467             :     else
     468           0 :         throw SQLException(aErr,*this,OUString(),0,Any());
     469          58 : }
     470             : 
     471          58 : void OStatement_Base::createColumnMapping()
     472             : {
     473             :     // initialize the column index map (mapping select columns to table columns)
     474          58 :     ::rtl::Reference<connectivity::OSQLColumns> xColumns = m_aSQLIterator.getSelectColumns();
     475          58 :     m_aColMapping.resize(xColumns->get().size() + 1);
     476         852 :     for (sal_Int32 i=0; i<(sal_Int32)m_aColMapping.size(); ++i)
     477         794 :         m_aColMapping[i] = i;
     478             : 
     479         116 :     Reference<XIndexAccess> xNames(m_xColNames,UNO_QUERY);
     480             :     // now check which columns are bound
     481         116 :     OResultSet::setBoundedColumns(m_aRow,m_aSelectRow,xColumns,xNames,true,m_xDBMetaData,m_aColMapping);
     482          58 : }
     483             : 
     484          29 : void OStatement_Base::initializeResultSet(OResultSet* _pResult)
     485             : {
     486          29 :     GetAssignValues();
     487             : 
     488          29 :     _pResult->setSqlAnalyzer(m_pSQLAnalyzer);
     489          29 :     _pResult->setOrderByColumns(m_aOrderbyColumnNumber);
     490          29 :     _pResult->setOrderByAscending(m_aOrderbyAscending);
     491          29 :     _pResult->setBindingRow(m_aRow);
     492          29 :     _pResult->setColumnMapping(m_aColMapping);
     493          29 :     _pResult->setEvaluationRow(m_aEvaluateRow);
     494          29 :     _pResult->setAssignValues(m_aAssignValues);
     495          29 :     _pResult->setSelectRow(m_aSelectRow);
     496             : 
     497          29 :     m_pSQLAnalyzer->bindSelectRow(m_aRow);
     498          29 :     m_pEvaluationKeySet = m_pSQLAnalyzer->bindEvaluationRow(m_aEvaluateRow);    // Set values in the code of the Compiler
     499          29 :     _pResult->setEvaluationKeySet(m_pEvaluationKeySet);
     500          29 : }
     501             : 
     502          29 : void OStatement_Base::GetAssignValues()
     503             : {
     504          29 :     if (m_pParseTree == NULL)
     505             :     {
     506           0 :         ::dbtools::throwFunctionSequenceException(*this);
     507           0 :         return;
     508             :     }
     509             : 
     510          29 :     if (SQL_ISRULE(m_pParseTree,select_statement))
     511             :         // no values have to be set for SELECT
     512          29 :         return;
     513           0 :     else if (SQL_ISRULE(m_pParseTree,insert_statement))
     514             :     {
     515             :         // Create Row for the values to be set (Reference through new)
     516           0 :         if(m_aAssignValues.is())
     517           0 :             m_aAssignValues->get().clear();
     518           0 :         sal_Int32 nCount = Reference<XIndexAccess>(m_xColNames,UNO_QUERY)->getCount();
     519           0 :         m_aAssignValues = new OAssignValues(nCount);
     520             :         // unbound all
     521           0 :         ::std::for_each(m_aAssignValues->get().begin()+1,m_aAssignValues->get().end(),TSetRefBound(false));
     522             : 
     523           0 :         m_aParameterIndexes.resize(nCount+1,SQL_NO_PARAMETER);
     524             : 
     525             :         // List of Column-Names, that exist in the column_commalist (separated by ;):
     526           0 :         ::std::vector<OUString> aColumnNameList;
     527             : 
     528             :         OSL_ENSURE(m_pParseTree->count() >= 4,"OResultSet: Fehler im Parse Tree");
     529             : 
     530           0 :         OSQLParseNode * pOptColumnCommalist = m_pParseTree->getChild(3);
     531             :         OSL_ENSURE(pOptColumnCommalist != NULL,"OResultSet: Fehler im Parse Tree");
     532             :         OSL_ENSURE(SQL_ISRULE(pOptColumnCommalist,opt_column_commalist),"OResultSet: Fehler im Parse Tree");
     533           0 :         if (pOptColumnCommalist->count() == 0)
     534             :         {
     535           0 :             const Sequence< OUString>& aNames = m_xColNames->getElementNames();
     536           0 :             const OUString* pBegin = aNames.getConstArray();
     537           0 :             const OUString* pEnd = pBegin + aNames.getLength();
     538           0 :             for (; pBegin != pEnd; ++pBegin)
     539           0 :                 aColumnNameList.push_back(*pBegin);
     540             :         }
     541             :         else
     542             :         {
     543             :             OSL_ENSURE(pOptColumnCommalist->count() == 3,"OResultSet: Fehler im Parse Tree");
     544             : 
     545           0 :             OSQLParseNode * pColumnCommalist = pOptColumnCommalist->getChild(1);
     546             :             OSL_ENSURE(pColumnCommalist != NULL,"OResultSet: Fehler im Parse Tree");
     547             :             OSL_ENSURE(SQL_ISRULE(pColumnCommalist,column_commalist),"OResultSet: Fehler im Parse Tree");
     548             :             OSL_ENSURE(pColumnCommalist->count() > 0,"OResultSet: Fehler im Parse Tree");
     549             : 
     550             :             // All Columns in the column_commalist ...
     551           0 :             for (size_t i = 0; i < pColumnCommalist->count(); i++)
     552             :             {
     553           0 :                 OSQLParseNode * pCol = pColumnCommalist->getChild(i);
     554             :                 OSL_ENSURE(pCol != NULL,"OResultSet: Fehler im Parse Tree");
     555           0 :                 aColumnNameList.push_back(pCol->getTokenValue());
     556             :             }
     557             :         }
     558           0 :         if ( aColumnNameList.empty() )
     559           0 :             throwFunctionSequenceException(*this);
     560             : 
     561             :         // Values ...
     562           0 :         OSQLParseNode * pValuesOrQuerySpec = m_pParseTree->getChild(4);
     563             :         OSL_ENSURE(pValuesOrQuerySpec != NULL,"OResultSet: pValuesOrQuerySpec darf nicht NULL sein!");
     564             :         OSL_ENSURE(SQL_ISRULE(pValuesOrQuerySpec,values_or_query_spec),"OResultSet: ! SQL_ISRULE(pValuesOrQuerySpec,values_or_query_spec)");
     565             :         OSL_ENSURE(pValuesOrQuerySpec->count() > 0,"OResultSet: pValuesOrQuerySpec->count() <= 0");
     566             : 
     567             :         // just "VALUES" is allowed ...
     568           0 :         if (! SQL_ISTOKEN(pValuesOrQuerySpec->getChild(0),VALUES))
     569           0 :             throwFunctionSequenceException(*this);
     570             : 
     571             :         OSL_ENSURE(pValuesOrQuerySpec->count() == 4,"OResultSet: pValuesOrQuerySpec->count() != 4");
     572             : 
     573             :         // List of values
     574           0 :         OSQLParseNode * pInsertAtomCommalist = pValuesOrQuerySpec->getChild(2);
     575             :         OSL_ENSURE(pInsertAtomCommalist != NULL,"OResultSet: pInsertAtomCommalist darf nicht NULL sein!");
     576             :         OSL_ENSURE(pInsertAtomCommalist->count() > 0,"OResultSet: pInsertAtomCommalist <= 0");
     577             : 
     578           0 :         sal_Int32 nIndex=0;
     579           0 :         for (size_t i = 0; i < pInsertAtomCommalist->count(); i++)
     580             :         {
     581           0 :             OSQLParseNode * 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 (size_t 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 (size_t 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.11