1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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"
40 namespace connectivity
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
;
54 OStatement_Base::OStatement_Base(OConnection
* _pConnection
)
55 :OStatement_BASE(m_aMutex
)
56 ,::comphelper::OPropertyContainer(OStatement_BASE::rBHelper
)
57 ,m_xDBMetaData(_pConnection
->getMetaData())
58 ,m_aParser( _pConnection
->getDriver()->getComponentContext() )
59 ,m_aSQLIterator( _pConnection
, _pConnection
->createCatalog()->getTables(), m_aParser
)
60 ,m_pConnection(_pConnection
)
61 ,m_pParseTree(nullptr)
62 ,m_pSQLAnalyzer(nullptr)
67 ,m_nResultSetType(ResultSetType::FORWARD_ONLY
)
68 ,m_nFetchDirection(FetchDirection::FORWARD
)
69 ,m_nResultSetConcurrency(ResultSetConcurrency::UPDATABLE
)
70 ,m_bEscapeProcessing(true)
72 sal_Int32 nAttrib
= 0;
74 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CURSORNAME
), PROPERTY_ID_CURSORNAME
, nAttrib
,&m_aCursorName
, ::cppu::UnoType
<OUString
>::get());
75 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXFIELDSIZE
), PROPERTY_ID_MAXFIELDSIZE
, nAttrib
,&m_nMaxFieldSize
, ::cppu::UnoType
<sal_Int32
>::get());
76 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXROWS
), PROPERTY_ID_MAXROWS
, nAttrib
,&m_nMaxRows
, ::cppu::UnoType
<sal_Int32
>::get());
77 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_QUERYTIMEOUT
), PROPERTY_ID_QUERYTIMEOUT
, nAttrib
,&m_nQueryTimeOut
, ::cppu::UnoType
<sal_Int32
>::get());
78 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE
), PROPERTY_ID_FETCHSIZE
, nAttrib
,&m_nFetchSize
, ::cppu::UnoType
<sal_Int32
>::get());
79 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE
), PROPERTY_ID_RESULTSETTYPE
, nAttrib
,&m_nResultSetType
, ::cppu::UnoType
<sal_Int32
>::get());
80 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION
), PROPERTY_ID_FETCHDIRECTION
, nAttrib
,&m_nFetchDirection
, ::cppu::UnoType
<sal_Int32
>::get());
81 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ESCAPEPROCESSING
),PROPERTY_ID_ESCAPEPROCESSING
, nAttrib
,&m_bEscapeProcessing
,cppu::UnoType
<bool>::get());
83 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY
), PROPERTY_ID_RESULTSETCONCURRENCY
, nAttrib
,&m_nResultSetConcurrency
, ::cppu::UnoType
<sal_Int32
>::get());
86 OStatement_Base::~OStatement_Base()
88 osl_atomic_increment( &m_refCount
);
90 delete m_pSQLAnalyzer
;
93 void OStatement_Base::disposeResultSet()
95 SAL_INFO( "connectivity.drivers", "file Ocke.Janssen@sun.com OStatement_Base::disposeResultSet" );
96 // free the cursor if alive
97 Reference
< XComponent
> xComp(m_xResultSet
.get(), UNO_QUERY
);
98 assert(xComp
.is() || !m_xResultSet
.get().is());
101 m_xResultSet
.clear();
104 void OStatement_BASE2::disposing()
106 ::osl::MutexGuard
aGuard(m_aMutex
);
111 m_pSQLAnalyzer
->dispose();
115 m_aRow
->get().clear();
119 m_aSQLIterator
.dispose();
123 m_pConnection
.clear();
130 m_pParseTree
= nullptr;
133 OStatement_Base::disposing();
136 void SAL_CALL
OStatement_Base::acquire() throw()
138 OStatement_BASE::acquire();
141 void SAL_CALL
OStatement_BASE2::release() throw()
146 Any SAL_CALL
OStatement_Base::queryInterface( const Type
& rType
) throw(RuntimeException
, std::exception
)
148 const Any aRet
= OStatement_BASE::queryInterface(rType
);
149 return aRet
.hasValue() ? aRet
: OPropertySetHelper::queryInterface(rType
);
152 Sequence
< Type
> SAL_CALL
OStatement_Base::getTypes( ) throw(RuntimeException
, std::exception
)
154 ::cppu::OTypeCollection
aTypes( cppu::UnoType
<css::beans::XMultiPropertySet
>::get(),
155 cppu::UnoType
<css::beans::XFastPropertySet
>::get(),
156 cppu::UnoType
<css::beans::XPropertySet
>::get());
158 return ::comphelper::concatSequences(aTypes
.getTypes(),OStatement_BASE::getTypes());
162 void SAL_CALL
OStatement_Base::cancel( ) throw(RuntimeException
, std::exception
)
166 void SAL_CALL
OStatement_Base::close() throw (SQLException
, RuntimeException
, std::exception
)
169 ::osl::MutexGuard
aGuard( m_aMutex
);
170 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
175 void OStatement_Base::closeResultSet() throw (SQLException
, RuntimeException
, std::exception
)
177 SAL_INFO( "connectivity.drivers", "file Ocke.Janssen@sun.com OStatement_Base::clearMyResultSet " );
178 ::osl::MutexGuard
aGuard( m_aMutex
);
179 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
181 Reference
< XCloseable
> xCloseable(m_xResultSet
.get(), UNO_QUERY
);
182 assert(xCloseable
.is() || !m_xResultSet
.get().is());
189 catch( const DisposedException
& ) { }
192 m_xResultSet
.clear();
195 Any SAL_CALL
OStatement_Base::getWarnings( ) throw(SQLException
, RuntimeException
, std::exception
)
197 ::osl::MutexGuard
aGuard( m_aMutex
);
198 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
200 return makeAny(m_aLastWarning
);
203 void SAL_CALL
OStatement_Base::clearWarnings( ) throw(SQLException
, RuntimeException
, std::exception
)
205 ::osl::MutexGuard
aGuard( m_aMutex
);
206 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
208 m_aLastWarning
= SQLWarning();
211 ::cppu::IPropertyArrayHelper
* OStatement_Base::createArrayHelper( ) const
213 Sequence
< Property
> aProps
;
214 describeProperties(aProps
);
215 return new ::cppu::OPropertyArrayHelper(aProps
);
219 ::cppu::IPropertyArrayHelper
& OStatement_Base::getInfoHelper()
221 return *getArrayHelper();
224 OResultSet
* OStatement::createResultSet()
226 return new OResultSet(this,m_aSQLIterator
);
229 IMPLEMENT_SERVICE_INFO(OStatement
,"com.sun.star.sdbc.driver.file.Statement","com.sun.star.sdbc.Statement");
231 void SAL_CALL
OStatement::acquire() throw()
233 OStatement_BASE2::acquire();
236 void SAL_CALL
OStatement::release() throw()
238 OStatement_BASE2::release();
242 sal_Bool SAL_CALL
OStatement::execute( const OUString
& sql
) throw(SQLException
, RuntimeException
, std::exception
)
244 ::osl::MutexGuard
aGuard( m_aMutex
);
248 return m_aSQLIterator
.getStatementType() == OSQLStatementType::Select
;
252 Reference
< XResultSet
> SAL_CALL
OStatement::executeQuery( const OUString
& sql
) throw(SQLException
, RuntimeException
, std::exception
)
254 ::osl::MutexGuard
aGuard( m_aMutex
);
255 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
258 Reference
< XResultSet
> xRS
;
259 OResultSet
* pResult
= createResultSet();
261 initializeResultSet(pResult
);
269 Reference
< XConnection
> SAL_CALL
OStatement::getConnection( ) throw(SQLException
, RuntimeException
, std::exception
)
271 return Reference
< XConnection
>(m_pConnection
.get());
274 sal_Int32 SAL_CALL
OStatement::executeUpdate( const OUString
& sql
) throw(SQLException
, RuntimeException
, std::exception
)
276 ::osl::MutexGuard
aGuard( m_aMutex
);
277 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
281 OResultSet
* pResult
= createResultSet();
282 Reference
< XResultSet
> xRS
= pResult
;
283 initializeResultSet(pResult
);
286 return pResult
->getRowCountResult();
290 void SAL_CALL
OStatement_Base::disposing()
292 if(m_aEvaluateRow
.is())
294 m_aEvaluateRow
->get().clear();
295 m_aEvaluateRow
= nullptr;
297 OStatement_BASE::disposing();
300 Reference
< css::beans::XPropertySetInfo
> SAL_CALL
OStatement_Base::getPropertySetInfo( ) throw(RuntimeException
, std::exception
)
302 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
305 Any SAL_CALL
OStatement::queryInterface( const Type
& rType
) throw(RuntimeException
, std::exception
)
307 Any aRet
= OStatement_XStatement::queryInterface( rType
);
308 return aRet
.hasValue() ? aRet
: OStatement_BASE2::queryInterface( rType
);
311 void OStatement_Base::anylizeSQL()
313 OSL_ENSURE(m_pSQLAnalyzer
,"OResultSet::anylizeSQL: Analyzer isn't set!");
314 // start analysing the statement
315 m_pSQLAnalyzer
->setOrigColumns(m_xColNames
);
316 m_pSQLAnalyzer
->start(m_pParseTree
);
318 const OSQLParseNode
* pOrderbyClause
= m_aSQLIterator
.getOrderTree();
321 OSQLParseNode
* pOrderingSpecCommalist
= pOrderbyClause
->getChild(2);
322 OSL_ENSURE(SQL_ISRULE(pOrderingSpecCommalist
,ordering_spec_commalist
),"OResultSet: Fehler im Parse Tree");
324 for (size_t m
= 0; m
< pOrderingSpecCommalist
->count(); m
++)
326 OSQLParseNode
* pOrderingSpec
= pOrderingSpecCommalist
->getChild(m
);
327 OSL_ENSURE(SQL_ISRULE(pOrderingSpec
,ordering_spec
),"OResultSet: Fehler im Parse Tree");
328 OSL_ENSURE(pOrderingSpec
->count() == 2,"OResultSet: Fehler im Parse Tree");
330 OSQLParseNode
* pColumnRef
= pOrderingSpec
->getChild(0);
331 if(!SQL_ISRULE(pColumnRef
,column_ref
))
333 throw SQLException();
335 OSQLParseNode
* pAscendingDescending
= pOrderingSpec
->getChild(1);
336 setOrderbyColumn(pColumnRef
,pAscendingDescending
);
341 void OStatement_Base::setOrderbyColumn( OSQLParseNode
* pColumnRef
,
342 OSQLParseNode
* pAscendingDescending
)
344 OUString aColumnName
;
345 if (pColumnRef
->count() == 1)
346 aColumnName
= pColumnRef
->getChild(0)->getTokenValue();
347 else if (pColumnRef
->count() == 3)
349 pColumnRef
->getChild(2)->parseNodeToStr( aColumnName
, getOwnConnection(), nullptr, false, false );
353 throw SQLException();
356 Reference
<XColumnLocate
> xColLocate(m_xColNames
,UNO_QUERY
);
359 // Everything tested and we have the name of the Column.
360 // What number is the Column?
361 ::rtl::Reference
<OSQLColumns
> aSelectColumns
= m_aSQLIterator
.getSelectColumns();
362 ::comphelper::UStringMixEqual aCase
;
363 OSQLColumns::Vector::const_iterator aFind
= ::connectivity::find(aSelectColumns
->get().begin(),aSelectColumns
->get().end(),aColumnName
,aCase
);
364 if ( aFind
== aSelectColumns
->get().end() )
365 throw SQLException();
366 m_aOrderbyColumnNumber
.push_back((aFind
- aSelectColumns
->get().begin()) + 1);
368 // Ascending or Descending?
369 m_aOrderbyAscending
.push_back((SQL_ISTOKEN(pAscendingDescending
,DESC
)) ? TAscendingOrder::DESC
: TAscendingOrder::ASC
);
372 void OStatement_Base::construct(const OUString
& sql
) throw(SQLException
, RuntimeException
, std::exception
)
375 m_pParseTree
= m_aParser
.parseTree(aErr
,sql
);
378 m_aSQLIterator
.setParseTree(m_pParseTree
);
379 m_aSQLIterator
.traverseAll();
380 const OSQLTables
& rTabs
= m_aSQLIterator
.getTables();
384 // no tables -> nothing to operate on -> error
385 m_pConnection
->throwGenericSQLException(STR_QUERY_NO_TABLE
,*this);
387 if ( rTabs
.size() > 1 || m_aSQLIterator
.hasErrors() )
388 // more than one table -> can't operate on them -> error
389 m_pConnection
->throwGenericSQLException(STR_QUERY_MORE_TABLES
,*this);
391 if ( (m_aSQLIterator
.getStatementType() == OSQLStatementType::Select
) && m_aSQLIterator
.getSelectColumns()->get().empty() )
392 // SELECT statement without columns -> error
393 m_pConnection
->throwGenericSQLException(STR_QUERY_NO_COLUMN
,*this);
395 switch(m_aSQLIterator
.getStatementType())
397 case OSQLStatementType::CreateTable
:
398 case OSQLStatementType::OdbcCall
:
399 case OSQLStatementType::Unknown
:
400 m_pConnection
->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,*this);
406 // at this moment we support only one table per select statement
407 Reference
< css::lang::XUnoTunnel
> xTunnel(rTabs
.begin()->second
,UNO_QUERY
);
410 m_pTable
= reinterpret_cast<OFileTable
*>(xTunnel
->getSomething(OFileTable::getUnoTunnelImplementationId()));
412 OSL_ENSURE(m_pTable
.is(),"No table!");
414 m_xColNames
= m_pTable
->getColumns();
415 Reference
<XIndexAccess
> xNames(m_xColNames
,UNO_QUERY
);
416 // set the binding of the resultrow
417 m_aRow
= new OValueRefVector(xNames
->getCount());
418 (m_aRow
->get())[0]->setBound(true);
419 ::std::for_each(m_aRow
->get().begin()+1,m_aRow
->get().end(),TSetRefBound(false));
421 // set the binding of the resultrow
422 m_aEvaluateRow
= new OValueRefVector(xNames
->getCount());
424 (m_aEvaluateRow
->get())[0]->setBound(true);
425 ::std::for_each(m_aEvaluateRow
->get().begin()+1,m_aEvaluateRow
->get().end(),TSetRefBound(false));
427 // set the select row
428 m_aSelectRow
= new OValueRefVector(m_aSQLIterator
.getSelectColumns()->get().size());
429 ::std::for_each(m_aSelectRow
->get().begin(),m_aSelectRow
->get().end(),TSetRefBound(true));
431 // create the column mapping
432 createColumnMapping();
434 m_pSQLAnalyzer
= new OSQLAnalyzer(m_pConnection
.get());
436 Reference
<XIndexesSupplier
> xIndexSup(xTunnel
,UNO_QUERY
);
438 m_pSQLAnalyzer
->setIndexes(xIndexSup
->getIndexes());
443 throw SQLException(aErr
,*this,OUString(),0,Any());
446 void OStatement_Base::createColumnMapping()
448 // initialize the column index map (mapping select columns to table columns)
449 ::rtl::Reference
<connectivity::OSQLColumns
> xColumns
= m_aSQLIterator
.getSelectColumns();
450 m_aColMapping
.resize(xColumns
->get().size() + 1);
451 for (sal_Int32 i
=0; i
<(sal_Int32
)m_aColMapping
.size(); ++i
)
452 m_aColMapping
[i
] = i
;
454 Reference
<XIndexAccess
> xNames(m_xColNames
,UNO_QUERY
);
455 // now check which columns are bound
456 OResultSet::setBoundedColumns(m_aRow
,m_aSelectRow
,xColumns
,xNames
,true,m_xDBMetaData
,m_aColMapping
);
459 void OStatement_Base::initializeResultSet(OResultSet
* _pResult
)
463 _pResult
->setSqlAnalyzer(m_pSQLAnalyzer
);
464 _pResult
->setOrderByColumns(m_aOrderbyColumnNumber
);
465 _pResult
->setOrderByAscending(m_aOrderbyAscending
);
466 _pResult
->setBindingRow(m_aRow
);
467 _pResult
->setColumnMapping(m_aColMapping
);
468 _pResult
->setEvaluationRow(m_aEvaluateRow
);
469 _pResult
->setAssignValues(m_aAssignValues
);
470 _pResult
->setSelectRow(m_aSelectRow
);
472 m_pSQLAnalyzer
->bindSelectRow(m_aRow
);
473 m_pSQLAnalyzer
->bindEvaluationRow(m_aEvaluateRow
); // Set values in the code of the Compiler
476 void OStatement_Base::GetAssignValues()
478 if (m_pParseTree
== nullptr)
480 ::dbtools::throwFunctionSequenceException(*this);
484 if (SQL_ISRULE(m_pParseTree
,select_statement
))
485 // no values have to be set for SELECT
487 else if (SQL_ISRULE(m_pParseTree
,insert_statement
))
489 // Create Row for the values to be set (Reference through new)
490 if(m_aAssignValues
.is())
491 m_aAssignValues
->get().clear();
492 sal_Int32 nCount
= Reference
<XIndexAccess
>(m_xColNames
,UNO_QUERY
)->getCount();
493 m_aAssignValues
= new OAssignValues(nCount
);
495 ::std::for_each(m_aAssignValues
->get().begin()+1,m_aAssignValues
->get().end(),TSetRefBound(false));
497 m_aParameterIndexes
.resize(nCount
+1,SQL_NO_PARAMETER
);
499 // List of Column-Names, that exist in the column_commalist (separated by ;):
500 ::std::vector
<OUString
> aColumnNameList
;
502 OSL_ENSURE(m_pParseTree
->count() >= 4,"OResultSet: Fehler im Parse Tree");
504 OSQLParseNode
* pOptColumnCommalist
= m_pParseTree
->getChild(3);
505 OSL_ENSURE(pOptColumnCommalist
!= nullptr,"OResultSet: Fehler im Parse Tree");
506 OSL_ENSURE(SQL_ISRULE(pOptColumnCommalist
,opt_column_commalist
),"OResultSet: Fehler im Parse Tree");
507 if (pOptColumnCommalist
->count() == 0)
509 const Sequence
< OUString
>& aNames
= m_xColNames
->getElementNames();
510 const OUString
* pBegin
= aNames
.getConstArray();
511 const OUString
* pEnd
= pBegin
+ aNames
.getLength();
512 for (; pBegin
!= pEnd
; ++pBegin
)
513 aColumnNameList
.push_back(*pBegin
);
517 OSL_ENSURE(pOptColumnCommalist
->count() == 3,"OResultSet: Fehler im Parse Tree");
519 OSQLParseNode
* pColumnCommalist
= pOptColumnCommalist
->getChild(1);
520 OSL_ENSURE(pColumnCommalist
!= nullptr,"OResultSet: Fehler im Parse Tree");
521 OSL_ENSURE(SQL_ISRULE(pColumnCommalist
,column_commalist
),"OResultSet: Fehler im Parse Tree");
522 OSL_ENSURE(pColumnCommalist
->count() > 0,"OResultSet: Fehler im Parse Tree");
524 // All Columns in the column_commalist ...
525 for (size_t i
= 0; i
< pColumnCommalist
->count(); i
++)
527 OSQLParseNode
* pCol
= pColumnCommalist
->getChild(i
);
528 OSL_ENSURE(pCol
!= nullptr,"OResultSet: Fehler im Parse Tree");
529 aColumnNameList
.push_back(pCol
->getTokenValue());
532 if ( aColumnNameList
.empty() )
533 throwFunctionSequenceException(*this);
536 OSQLParseNode
* pValuesOrQuerySpec
= m_pParseTree
->getChild(4);
537 OSL_ENSURE(pValuesOrQuerySpec
!= nullptr,"OResultSet: pValuesOrQuerySpec darf nicht NULL sein!");
538 OSL_ENSURE(SQL_ISRULE(pValuesOrQuerySpec
,values_or_query_spec
),"OResultSet: ! SQL_ISRULE(pValuesOrQuerySpec,values_or_query_spec)");
539 OSL_ENSURE(pValuesOrQuerySpec
->count() > 0,"OResultSet: pValuesOrQuerySpec->count() <= 0");
541 // just "VALUES" is allowed ...
542 if (! SQL_ISTOKEN(pValuesOrQuerySpec
->getChild(0),VALUES
))
543 throwFunctionSequenceException(*this);
545 OSL_ENSURE(pValuesOrQuerySpec
->count() == 4,"OResultSet: pValuesOrQuerySpec->count() != 4");
548 OSQLParseNode
* pInsertAtomCommalist
= pValuesOrQuerySpec
->getChild(2);
549 OSL_ENSURE(pInsertAtomCommalist
!= nullptr,"OResultSet: pInsertAtomCommalist darf nicht NULL sein!");
550 OSL_ENSURE(pInsertAtomCommalist
->count() > 0,"OResultSet: pInsertAtomCommalist <= 0");
553 for (size_t i
= 0; i
< pInsertAtomCommalist
->count(); i
++)
555 OSQLParseNode
* pRow_Value_Const
= pInsertAtomCommalist
->getChild(i
); // row_value_constructor
556 OSL_ENSURE(pRow_Value_Const
!= nullptr,"OResultSet: pRow_Value_Const darf nicht NULL sein!");
557 if(SQL_ISRULE(pRow_Value_Const
,parameter
))
559 ParseAssignValues(aColumnNameList
,pRow_Value_Const
,nIndex
++); // only one Columnname allowed per loop
561 else if(pRow_Value_Const
->isToken())
562 ParseAssignValues(aColumnNameList
,pRow_Value_Const
,i
);
565 if(pRow_Value_Const
->count() == aColumnNameList
.size())
567 for (size_t j
= 0; j
< pRow_Value_Const
->count(); ++j
)
568 ParseAssignValues(aColumnNameList
,pRow_Value_Const
->getChild(j
),nIndex
++);
571 throwFunctionSequenceException(*this);
575 else if (SQL_ISRULE(m_pParseTree
,update_statement_searched
))
577 if(m_aAssignValues
.is())
578 m_aAssignValues
->get().clear();
579 sal_Int32 nCount
= Reference
<XIndexAccess
>(m_xColNames
,UNO_QUERY
)->getCount();
580 m_aAssignValues
= new OAssignValues(nCount
);
582 ::std::for_each(m_aAssignValues
->get().begin()+1,m_aAssignValues
->get().end(),TSetRefBound(false));
584 m_aParameterIndexes
.resize(nCount
+1,SQL_NO_PARAMETER
);
586 OSL_ENSURE(m_pParseTree
->count() >= 4,"OResultSet: Fehler im Parse Tree");
588 OSQLParseNode
* pAssignmentCommalist
= m_pParseTree
->getChild(3);
589 OSL_ENSURE(pAssignmentCommalist
!= nullptr,"OResultSet: pAssignmentCommalist == NULL");
590 OSL_ENSURE(SQL_ISRULE(pAssignmentCommalist
,assignment_commalist
),"OResultSet: Fehler im Parse Tree");
591 OSL_ENSURE(pAssignmentCommalist
->count() > 0,"OResultSet: pAssignmentCommalist->count() <= 0");
593 // work on all assignments (commalist) ...
594 ::std::vector
< OUString
> aList(1);
595 for (size_t i
= 0; i
< pAssignmentCommalist
->count(); i
++)
597 OSQLParseNode
* pAssignment
= pAssignmentCommalist
->getChild(i
);
598 OSL_ENSURE(pAssignment
!= nullptr,"OResultSet: pAssignment == NULL");
599 OSL_ENSURE(SQL_ISRULE(pAssignment
,assignment
),"OResultSet: Fehler im Parse Tree");
600 OSL_ENSURE(pAssignment
->count() == 3,"OResultSet: pAssignment->count() != 3");
602 OSQLParseNode
* pCol
= pAssignment
->getChild(0);
603 OSL_ENSURE(pCol
!= nullptr,"OResultSet: pCol == NULL");
605 OSQLParseNode
* pComp
= pAssignment
->getChild(1);
606 OSL_ENSURE(pComp
!= nullptr,"OResultSet: pComp == NULL");
607 OSL_ENSURE(pComp
->getNodeType() == SQLNodeType::Equal
,"OResultSet: pComp->getNodeType() != SQLNodeType::Comparison");
608 if (pComp
->getTokenValue().toChar() != '=')
610 throwFunctionSequenceException(*this);
613 OSQLParseNode
* pVal
= pAssignment
->getChild(2);
614 OSL_ENSURE(pVal
!= nullptr,"OResultSet: pVal == NULL");
615 aList
[0] = pCol
->getTokenValue();
616 ParseAssignValues(aList
,pVal
,0);
622 void OStatement_Base::ParseAssignValues(const ::std::vector
< OUString
>& aColumnNameList
,OSQLParseNode
* pRow_Value_Constructor_Elem
, sal_Int32 nIndex
)
624 OSL_ENSURE(size_t(nIndex
) <= aColumnNameList
.size(),"SdbFileCursor::ParseAssignValues: nIndex > aColumnNameList.GetTokenCount()");
625 OUString
aColumnName(aColumnNameList
[nIndex
]);
626 OSL_ENSURE(aColumnName
.getLength() > 0,"OResultSet: Column-Name nicht gefunden");
627 OSL_ENSURE(pRow_Value_Constructor_Elem
!= nullptr,"OResultSet: pRow_Value_Constructor_Elem darf nicht NULL sein!");
629 if (pRow_Value_Constructor_Elem
->getNodeType() == SQLNodeType::String
||
630 pRow_Value_Constructor_Elem
->getNodeType() == SQLNodeType::IntNum
||
631 pRow_Value_Constructor_Elem
->getNodeType() == SQLNodeType::ApproxNum
)
634 SetAssignValue(aColumnName
, pRow_Value_Constructor_Elem
->getTokenValue());
636 else if (SQL_ISTOKEN(pRow_Value_Constructor_Elem
,NULL
))
639 SetAssignValue(aColumnName
, OUString(), true);
641 else if (SQL_ISRULE(pRow_Value_Constructor_Elem
,parameter
))
642 parseParamterElem(aColumnName
,pRow_Value_Constructor_Elem
);
645 throwFunctionSequenceException(*this);
649 void OStatement_Base::SetAssignValue(const OUString
& aColumnName
,
650 const OUString
& aValue
,
652 sal_uInt32 nParameter
)
654 Reference
<XPropertySet
> xCol
;
655 m_xColNames
->getByName(aColumnName
) >>= xCol
;
656 sal_Int32 nId
= Reference
<XColumnLocate
>(m_xColNames
,UNO_QUERY
)->findColumn(aColumnName
);
657 // does this column actually exist in the file?
661 // This Column doesn't exist!
662 throwFunctionSequenceException(*this);
666 // Everything tested and we have the names of the Column.
667 // Now allocate one Value, set the value and tie the value to the Row.
669 (m_aAssignValues
->get())[nId
]->setNull();
672 switch (::comphelper::getINT32(xCol
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE
))))
674 // put criteria depending on the Type as String or double in the variable
676 case DataType::VARCHAR
:
677 case DataType::LONGVARCHAR
:
678 *(m_aAssignValues
->get())[nId
] = ORowSetValue(aValue
);
679 //Characterset is already converted, since the entire statement was converted
683 if (aValue
.equalsIgnoreAsciiCase("TRUE") || aValue
[0] == '1')
684 *(m_aAssignValues
->get())[nId
] = true;
685 else if (aValue
.equalsIgnoreAsciiCase("FALSE") || aValue
[0] == '0')
686 *(m_aAssignValues
->get())[nId
] = false;
688 throwFunctionSequenceException(*this);
690 case DataType::TINYINT
:
691 case DataType::SMALLINT
:
692 case DataType::INTEGER
:
693 case DataType::DECIMAL
:
694 case DataType::NUMERIC
:
696 case DataType::DOUBLE
:
699 case DataType::TIMESTAMP
:
700 *(m_aAssignValues
->get())[nId
] = ORowSetValue(aValue
);
703 throwFunctionSequenceException(*this);
707 // save Parameter-No. (as User Data)
708 // SQL_NO_PARAMETER = no Parameter.
709 m_aAssignValues
->setParameterIndex(nId
,nParameter
);
710 if(nParameter
!= SQL_NO_PARAMETER
)
711 m_aParameterIndexes
[nParameter
] = nId
;
714 void OStatement_Base::parseParamterElem(const OUString
& /*_sColumnName*/,OSQLParseNode
* /*pRow_Value_Constructor_Elem*/)
721 }// namespace connectivity
724 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */