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 <sal/config.h>
22 #include <o3tl/safeint.hxx>
23 #include <osl/diagnose.h>
24 #include <file/FStatement.hxx>
25 #include <file/FConnection.hxx>
26 #include <sqlbison.hxx>
27 #include <file/FDriver.hxx>
28 #include <file/FResultSet.hxx>
29 #include <sal/log.hxx>
30 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
31 #include <com/sun/star/sdbc/ResultSetType.hpp>
32 #include <com/sun/star/sdbc/FetchDirection.hpp>
33 #include <com/sun/star/lang/DisposedException.hpp>
34 #include <comphelper/sequence.hxx>
35 #include <comphelper/servicehelper.hxx>
36 #include <cppuhelper/typeprovider.hxx>
37 #include <comphelper/types.hxx>
38 #include <connectivity/dbexception.hxx>
39 #include <strings.hrc>
43 namespace connectivity::file
47 using namespace dbtools
;
48 using namespace com::sun::star::uno
;
49 using namespace com::sun::star::lang
;
50 using namespace com::sun::star::beans
;
51 using namespace com::sun::star::sdbc
;
52 using namespace com::sun::star::sdbcx
;
53 using namespace com::sun::star::container
;
55 OStatement_Base::OStatement_Base(OConnection
* _pConnection
)
56 :OStatement_BASE(m_aMutex
)
57 ,::comphelper::OPropertyContainer(OStatement_BASE::rBHelper
)
58 ,m_xDBMetaData(_pConnection
->getMetaData())
59 ,m_aParser( _pConnection
->getDriver()->getComponentContext() )
60 ,m_aSQLIterator( _pConnection
, _pConnection
->createCatalog()->getTables(), m_aParser
)
61 ,m_pConnection(_pConnection
)
62 ,m_pParseTree(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
);
92 void OStatement_Base::disposeResultSet()
94 SAL_INFO( "connectivity.drivers", "file Ocke.Janssen@sun.com OStatement_Base::disposeResultSet" );
95 // free the cursor if alive
96 rtl::Reference
< OResultSet
> xComp(m_xResultSet
.get());
97 assert(xComp
.is() || !m_xResultSet
.get().is());
100 m_xResultSet
.clear();
103 void OStatement_BASE2::disposing()
105 ::osl::MutexGuard
aGuard(m_aMutex
);
110 m_pSQLAnalyzer
->dispose();
118 m_aSQLIterator
.dispose();
122 m_pConnection
.clear();
127 m_pParseTree
= nullptr;
130 OStatement_Base::disposing();
133 void SAL_CALL
OStatement_Base::acquire() noexcept
135 OStatement_BASE::acquire();
138 void SAL_CALL
OStatement_BASE2::release() noexcept
140 OStatement_BASE::release();
143 Any SAL_CALL
OStatement_Base::queryInterface( const Type
& rType
)
145 const Any aRet
= OStatement_BASE::queryInterface(rType
);
146 return aRet
.hasValue() ? aRet
: OPropertySetHelper::queryInterface(rType
);
149 Sequence
< Type
> SAL_CALL
OStatement_Base::getTypes( )
151 ::cppu::OTypeCollection
aTypes( cppu::UnoType
<css::beans::XMultiPropertySet
>::get(),
152 cppu::UnoType
<css::beans::XFastPropertySet
>::get(),
153 cppu::UnoType
<css::beans::XPropertySet
>::get());
155 return ::comphelper::concatSequences(aTypes
.getTypes(),OStatement_BASE::getTypes());
159 void SAL_CALL
OStatement_Base::cancel( )
163 void SAL_CALL
OStatement_Base::close()
166 ::osl::MutexGuard
aGuard( m_aMutex
);
167 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
172 void OStatement_Base::closeResultSet()
174 SAL_INFO( "connectivity.drivers", "file Ocke.Janssen@sun.com OStatement_Base::clearMyResultSet " );
175 ::osl::MutexGuard
aGuard( m_aMutex
);
176 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
178 rtl::Reference
< OResultSet
> xCloseable(m_xResultSet
.get());
179 assert(xCloseable
.is() || !m_xResultSet
.get().is());
186 catch( const DisposedException
& ) { }
189 m_xResultSet
.clear();
192 Any SAL_CALL
OStatement_Base::getWarnings( )
194 ::osl::MutexGuard
aGuard( m_aMutex
);
195 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
197 return Any(m_aLastWarning
);
200 void SAL_CALL
OStatement_Base::clearWarnings( )
202 ::osl::MutexGuard
aGuard( m_aMutex
);
203 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
205 m_aLastWarning
= SQLWarning();
208 ::cppu::IPropertyArrayHelper
* OStatement_Base::createArrayHelper( ) const
210 Sequence
< Property
> aProps
;
211 describeProperties(aProps
);
212 return new ::cppu::OPropertyArrayHelper(aProps
);
216 ::cppu::IPropertyArrayHelper
& OStatement_Base::getInfoHelper()
218 return *getArrayHelper();
221 rtl::Reference
<OResultSet
> OStatement::createResultSet()
223 return new OResultSet(this,m_aSQLIterator
);
226 IMPLEMENT_SERVICE_INFO(OStatement
,u
"com.sun.star.sdbc.driver.file.Statement"_ustr
,u
"com.sun.star.sdbc.Statement"_ustr
);
228 void SAL_CALL
OStatement::acquire() noexcept
230 OStatement_BASE2::acquire();
233 void SAL_CALL
OStatement::release() noexcept
235 OStatement_BASE2::release();
239 sal_Bool SAL_CALL
OStatement::execute( const OUString
& sql
)
241 ::osl::MutexGuard
aGuard( m_aMutex
);
245 return m_aSQLIterator
.getStatementType() == OSQLStatementType::Select
;
249 Reference
< XResultSet
> SAL_CALL
OStatement::executeQuery( const OUString
& sql
)
251 ::osl::MutexGuard
aGuard( m_aMutex
);
252 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
255 rtl::Reference
<OResultSet
> pResult
= createResultSet();
256 initializeResultSet(pResult
.get());
257 m_xResultSet
= pResult
.get();
264 Reference
< XConnection
> SAL_CALL
OStatement::getConnection( )
266 return m_pConnection
;
269 sal_Int32 SAL_CALL
OStatement::executeUpdate( const OUString
& sql
)
271 ::osl::MutexGuard
aGuard( m_aMutex
);
272 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
276 rtl::Reference
<OResultSet
> pResult
= createResultSet();
277 initializeResultSet(pResult
.get());
280 return pResult
->getRowCountResult();
284 void SAL_CALL
OStatement_Base::disposing()
286 if(m_aEvaluateRow
.is())
288 m_aEvaluateRow
->clear();
289 m_aEvaluateRow
= nullptr;
291 OStatement_BASE::disposing();
294 Reference
< css::beans::XPropertySetInfo
> SAL_CALL
OStatement_Base::getPropertySetInfo( )
296 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
299 Any SAL_CALL
OStatement::queryInterface( const Type
& rType
)
301 Any aRet
= OStatement_XStatement::queryInterface( rType
);
302 return aRet
.hasValue() ? aRet
: OStatement_BASE2::queryInterface( rType
);
305 void OStatement_Base::analyzeSQL()
307 OSL_ENSURE(m_pSQLAnalyzer
,"OResultSet::analyzeSQL: Analyzer isn't set!");
308 // start analysing the statement
309 m_pSQLAnalyzer
->setOrigColumns(m_xColNames
);
310 m_pSQLAnalyzer
->start(m_pParseTree
);
312 const OSQLParseNode
* pOrderbyClause
= m_aSQLIterator
.getOrderTree();
316 OSQLParseNode
* pOrderingSpecCommalist
= pOrderbyClause
->getChild(2);
317 OSL_ENSURE(SQL_ISRULE(pOrderingSpecCommalist
,ordering_spec_commalist
),"OResultSet: Error in Parse Tree");
319 for (size_t m
= 0; m
< pOrderingSpecCommalist
->count(); m
++)
321 OSQLParseNode
* pOrderingSpec
= pOrderingSpecCommalist
->getChild(m
);
322 OSL_ENSURE(SQL_ISRULE(pOrderingSpec
,ordering_spec
),"OResultSet: Error in Parse Tree");
323 OSL_ENSURE(pOrderingSpec
->count() == 2,"OResultSet: Error in Parse Tree");
325 OSQLParseNode
* pColumnRef
= pOrderingSpec
->getChild(0);
326 if(!SQL_ISRULE(pColumnRef
,column_ref
))
328 throw SQLException();
330 OSQLParseNode
* pAscendingDescending
= pOrderingSpec
->getChild(1);
331 setOrderbyColumn(pColumnRef
,pAscendingDescending
);
335 void OStatement_Base::setOrderbyColumn( OSQLParseNode
const * pColumnRef
,
336 OSQLParseNode
const * pAscendingDescending
)
338 OUString aColumnName
;
339 if (pColumnRef
->count() == 1)
340 aColumnName
= pColumnRef
->getChild(0)->getTokenValue();
341 else if (pColumnRef
->count() == 3)
343 pColumnRef
->getChild(2)->parseNodeToStr( aColumnName
, getOwnConnection(), nullptr, false, false );
347 throw SQLException();
350 Reference
<XColumnLocate
> xColLocate(m_xColNames
,UNO_QUERY
);
353 // Everything tested and we have the name of the Column.
354 // What number is the Column?
355 ::rtl::Reference
<OSQLColumns
> aSelectColumns
= m_aSQLIterator
.getSelectColumns();
356 ::comphelper::UStringMixEqual aCase
;
357 OSQLColumns::const_iterator aFind
= ::connectivity::find(aSelectColumns
->begin(),aSelectColumns
->end(),aColumnName
,aCase
);
358 if ( aFind
== aSelectColumns
->end() )
359 throw SQLException();
360 m_aOrderbyColumnNumber
.push_back((aFind
- aSelectColumns
->begin()) + 1);
362 // Ascending or Descending?
363 m_aOrderbyAscending
.push_back(SQL_ISTOKEN(pAscendingDescending
,DESC
) ? TAscendingOrder::DESC
: TAscendingOrder::ASC
);
366 void OStatement_Base::construct(const OUString
& sql
)
369 m_pParseTree
= m_aParser
.parseTree(aErr
,sql
).release();
371 throw SQLException(aErr
,*this,OUString(),0,Any());
373 m_aSQLIterator
.setParseTree(m_pParseTree
);
374 m_aSQLIterator
.traverseAll();
375 const OSQLTables
& rTabs
= m_aSQLIterator
.getTables();
379 // no tables -> nothing to operate on -> error
380 m_pConnection
->throwGenericSQLException(STR_QUERY_NO_TABLE
,*this);
382 if ( rTabs
.size() > 1 || m_aSQLIterator
.hasErrors() )
383 // more than one table -> can't operate on them -> error
384 m_pConnection
->throwGenericSQLException(STR_QUERY_MORE_TABLES
,*this);
386 if ( (m_aSQLIterator
.getStatementType() == OSQLStatementType::Select
) && m_aSQLIterator
.getSelectColumns()->empty() )
387 // SELECT statement without columns -> error
388 m_pConnection
->throwGenericSQLException(STR_QUERY_NO_COLUMN
,*this);
390 switch(m_aSQLIterator
.getStatementType())
392 case OSQLStatementType::CreateTable
:
393 case OSQLStatementType::OdbcCall
:
394 case OSQLStatementType::Unknown
:
395 m_pConnection
->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,*this);
397 case OSQLStatementType::Select
:
398 if(SQL_ISRULE(m_aSQLIterator
.getParseTree(), union_statement
))
400 m_pConnection
->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
, *this);
402 assert(SQL_ISRULE(m_aSQLIterator
.getParseTree(), select_statement
));
408 // at this moment we support only one table per select statement
409 m_pTable
= dynamic_cast<OFileTable
*>(rTabs
.begin()->second
.get());
410 OSL_ENSURE(m_pTable
.is(),"No table!");
412 m_xColNames
= m_pTable
->getColumns();
413 Reference
<XIndexAccess
> xNames(m_xColNames
,UNO_QUERY
);
414 // set the binding of the resultrow
415 m_aRow
= new OValueRefVector(xNames
->getCount());
416 (*m_aRow
)[0]->setBound(true);
417 std::for_each(m_aRow
->begin()+1,m_aRow
->end(),TSetRefBound(false));
419 // set the binding of the resultrow
420 m_aEvaluateRow
= new OValueRefVector(xNames
->getCount());
422 (*m_aEvaluateRow
)[0]->setBound(true);
423 std::for_each(m_aEvaluateRow
->begin()+1,m_aEvaluateRow
->end(),TSetRefBound(false));
425 // set the select row
426 m_aSelectRow
= new OValueRefVector(m_aSQLIterator
.getSelectColumns()->size());
427 std::for_each(m_aSelectRow
->begin(),m_aSelectRow
->end(),TSetRefBound(true));
429 // create the column mapping
430 createColumnMapping();
432 m_pSQLAnalyzer
.reset( new OSQLAnalyzer(m_pConnection
.get()) );
437 void OStatement_Base::createColumnMapping()
439 // initialize the column index map (mapping select columns to table columns)
440 ::rtl::Reference
<connectivity::OSQLColumns
> xColumns
= m_aSQLIterator
.getSelectColumns();
441 m_aColMapping
.resize(xColumns
->size() + 1);
442 for (std::size_t i
=0; i
<m_aColMapping
.size(); ++i
)
443 m_aColMapping
[i
] = i
;
445 Reference
<XIndexAccess
> xNames(m_xColNames
,UNO_QUERY
);
446 // now check which columns are bound
447 OResultSet::setBoundedColumns(m_aRow
,m_aSelectRow
,xColumns
,xNames
,true,m_xDBMetaData
,m_aColMapping
);
450 void OStatement_Base::initializeResultSet(OResultSet
* _pResult
)
454 _pResult
->setSqlAnalyzer(m_pSQLAnalyzer
.get());
455 _pResult
->setOrderByColumns(std::vector(m_aOrderbyColumnNumber
));
456 _pResult
->setOrderByAscending(std::vector(m_aOrderbyAscending
));
457 _pResult
->setBindingRow(m_aRow
);
458 _pResult
->setColumnMapping(std::vector(m_aColMapping
));
459 _pResult
->setEvaluationRow(m_aEvaluateRow
);
460 _pResult
->setAssignValues(m_aAssignValues
);
461 _pResult
->setSelectRow(m_aSelectRow
);
463 m_pSQLAnalyzer
->bindSelectRow(m_aRow
);
464 m_pSQLAnalyzer
->bindEvaluationRow(m_aEvaluateRow
); // Set values in the code of the Compiler
467 void OStatement_Base::GetAssignValues()
469 if (m_pParseTree
== nullptr)
471 ::dbtools::throwFunctionSequenceException(*this);
475 if (SQL_ISRULE(m_pParseTree
,select_statement
))
476 // no values have to be set for SELECT
478 else if (SQL_ISRULE(m_pParseTree
,insert_statement
))
480 // Create Row for the values to be set (Reference through new)
481 if(m_aAssignValues
.is())
482 m_aAssignValues
->clear();
483 sal_Int32 nCount
= Reference
<XIndexAccess
>(m_xColNames
,UNO_QUERY_THROW
)->getCount();
484 m_aAssignValues
= new OAssignValues(nCount
);
486 std::for_each(m_aAssignValues
->begin()+1,m_aAssignValues
->end(),TSetRefBound(false));
488 m_aParameterIndexes
.resize(nCount
+1,SQL_NO_PARAMETER
);
490 // List of Column-Names, that exist in the column_commalist (separated by ;):
491 std::vector
<OUString
> aColumnNameList
;
493 OSL_ENSURE(m_pParseTree
->count() >= 4,"OResultSet: Error in Parse Tree");
495 OSQLParseNode
* pOptColumnCommalist
= m_pParseTree
->getChild(3);
496 OSL_ENSURE(pOptColumnCommalist
!= nullptr,"OResultSet: Error in Parse Tree");
497 OSL_ENSURE(SQL_ISRULE(pOptColumnCommalist
,opt_column_commalist
),"OResultSet: Error in Parse Tree");
498 if (pOptColumnCommalist
->count() == 0)
500 const Sequence
< OUString
> aNames
= m_xColNames
->getElementNames();
501 aColumnNameList
.insert(aColumnNameList
.end(), aNames
.begin(), aNames
.end());
505 OSL_ENSURE(pOptColumnCommalist
->count() == 3,"OResultSet: Error in Parse Tree");
507 OSQLParseNode
* pColumnCommalist
= pOptColumnCommalist
->getChild(1);
508 OSL_ENSURE(pColumnCommalist
!= nullptr,"OResultSet: Error in Parse Tree");
509 OSL_ENSURE(SQL_ISRULE(pColumnCommalist
,column_commalist
),"OResultSet: Error in Parse Tree");
510 OSL_ENSURE(pColumnCommalist
->count() > 0,"OResultSet: Error in Parse Tree");
512 // All Columns in the column_commalist ...
513 for (size_t i
= 0; i
< pColumnCommalist
->count(); i
++)
515 OSQLParseNode
* pCol
= pColumnCommalist
->getChild(i
);
516 OSL_ENSURE(pCol
!= nullptr,"OResultSet: Error in Parse Tree");
517 aColumnNameList
.push_back(pCol
->getTokenValue());
520 if ( aColumnNameList
.empty() )
521 throwFunctionSequenceException(*this);
524 OSQLParseNode
* pValuesOrQuerySpec
= m_pParseTree
->getChild(4);
525 OSL_ENSURE(pValuesOrQuerySpec
!= nullptr,"OResultSet: pValuesOrQuerySpec must not be NULL!");
526 OSL_ENSURE(SQL_ISRULE(pValuesOrQuerySpec
,values_or_query_spec
),"OResultSet: ! SQL_ISRULE(pValuesOrQuerySpec,values_or_query_spec)");
527 OSL_ENSURE(pValuesOrQuerySpec
->count() > 0,"OResultSet: pValuesOrQuerySpec->count() <= 0");
529 // just "VALUES" is allowed ...
530 if (! SQL_ISTOKEN(pValuesOrQuerySpec
->getChild(0),VALUES
))
531 throwFunctionSequenceException(*this);
533 OSL_ENSURE(pValuesOrQuerySpec
->count() == 4,"OResultSet: pValuesOrQuerySpec->count() != 4");
536 OSQLParseNode
* pInsertAtomCommalist
= pValuesOrQuerySpec
->getChild(2);
537 OSL_ENSURE(pInsertAtomCommalist
!= nullptr,"OResultSet: pInsertAtomCommalist must not be NULL!");
538 OSL_ENSURE(pInsertAtomCommalist
->count() > 0,"OResultSet: pInsertAtomCommalist <= 0");
541 for (size_t i
= 0; i
< pInsertAtomCommalist
->count(); i
++)
543 OSQLParseNode
* pRow_Value_Const
= pInsertAtomCommalist
->getChild(i
); // row_value_constructor
544 OSL_ENSURE(pRow_Value_Const
!= nullptr,"OResultSet: pRow_Value_Const must not be NULL!");
545 if(SQL_ISRULE(pRow_Value_Const
,parameter
))
547 ParseAssignValues(aColumnNameList
,pRow_Value_Const
,nIndex
++); // only one Columnname allowed per loop
549 else if(pRow_Value_Const
->isToken())
550 ParseAssignValues(aColumnNameList
,pRow_Value_Const
,i
);
553 if(pRow_Value_Const
->count() == aColumnNameList
.size())
555 for (size_t j
= 0; j
< pRow_Value_Const
->count(); ++j
)
556 ParseAssignValues(aColumnNameList
,pRow_Value_Const
->getChild(j
),nIndex
++);
559 throwFunctionSequenceException(*this);
563 else if (SQL_ISRULE(m_pParseTree
,update_statement_searched
))
565 if(m_aAssignValues
.is())
566 m_aAssignValues
->clear();
567 sal_Int32 nCount
= Reference
<XIndexAccess
>(m_xColNames
,UNO_QUERY_THROW
)->getCount();
568 m_aAssignValues
= new OAssignValues(nCount
);
570 std::for_each(m_aAssignValues
->begin()+1,m_aAssignValues
->end(),TSetRefBound(false));
572 m_aParameterIndexes
.resize(nCount
+1,SQL_NO_PARAMETER
);
574 OSL_ENSURE(m_pParseTree
->count() >= 4,"OResultSet: Error in Parse Tree");
576 OSQLParseNode
* pAssignmentCommalist
= m_pParseTree
->getChild(3);
577 assert(pAssignmentCommalist
&& "OResultSet: pAssignmentCommalist == NULL");
578 OSL_ENSURE(SQL_ISRULE(pAssignmentCommalist
,assignment_commalist
),"OResultSet: Error in Parse Tree");
579 OSL_ENSURE(pAssignmentCommalist
->count() > 0,"OResultSet: pAssignmentCommalist->count() <= 0");
581 // work on all assignments (commalist) ...
582 std::vector
< OUString
> aList(1);
583 for (size_t i
= 0; i
< pAssignmentCommalist
->count(); i
++)
585 OSQLParseNode
* pAssignment
= pAssignmentCommalist
->getChild(i
);
586 assert(pAssignment
&& "OResultSet: pAssignment == NULL");
587 OSL_ENSURE(SQL_ISRULE(pAssignment
,assignment
),"OResultSet: Error in Parse Tree");
588 OSL_ENSURE(pAssignment
->count() == 3,"OResultSet: pAssignment->count() != 3");
590 OSQLParseNode
* pCol
= pAssignment
->getChild(0);
591 assert(pCol
&& "OResultSet: pCol == NULL");
593 OSQLParseNode
* pComp
= pAssignment
->getChild(1);
594 assert(pComp
&& "OResultSet: pComp == NULL");
595 OSL_ENSURE(pComp
->getNodeType() == SQLNodeType::Equal
,"OResultSet: pComp->getNodeType() != SQLNodeType::Comparison");
596 if (pComp
->getTokenValue().toChar() != '=')
598 throwFunctionSequenceException(*this);
601 OSQLParseNode
* pVal
= pAssignment
->getChild(2);
602 OSL_ENSURE(pVal
!= nullptr,"OResultSet: pVal == NULL");
603 aList
[0] = pCol
->getTokenValue();
604 ParseAssignValues(aList
,pVal
,0);
610 void OStatement_Base::ParseAssignValues(const std::vector
< OUString
>& aColumnNameList
,OSQLParseNode
* pRow_Value_Constructor_Elem
, sal_Int32 nIndex
)
612 OSL_ENSURE(o3tl::make_unsigned(nIndex
) <= aColumnNameList
.size(),"SdbFileCursor::ParseAssignValues: nIndex > aColumnNameList.GetTokenCount()");
613 const OUString
& aColumnName(aColumnNameList
[nIndex
]);
614 OSL_ENSURE(aColumnName
.getLength() > 0,"OResultSet: Column-Name not found");
615 assert(pRow_Value_Constructor_Elem
!= nullptr && "OResultSet: pRow_Value_Constructor_Elem must not be NULL!");
617 if (pRow_Value_Constructor_Elem
->getNodeType() == SQLNodeType::String
||
618 pRow_Value_Constructor_Elem
->getNodeType() == SQLNodeType::IntNum
||
619 pRow_Value_Constructor_Elem
->getNodeType() == SQLNodeType::ApproxNum
)
622 SetAssignValue(aColumnName
, pRow_Value_Constructor_Elem
->getTokenValue());
624 else if (SQL_ISTOKEN(pRow_Value_Constructor_Elem
,NULL
))
627 SetAssignValue(aColumnName
, OUString(), true);
629 else if (SQL_ISRULE(pRow_Value_Constructor_Elem
,parameter
))
630 parseParamterElem(aColumnName
,pRow_Value_Constructor_Elem
);
633 throwFunctionSequenceException(*this);
637 void OStatement_Base::SetAssignValue(const OUString
& aColumnName
,
638 const OUString
& aValue
,
640 sal_uInt32 nParameter
)
642 Reference
<XPropertySet
> xCol
;
643 m_xColNames
->getByName(aColumnName
) >>= xCol
;
644 sal_Int32 nId
= Reference
<XColumnLocate
>(m_xColNames
,UNO_QUERY_THROW
)->findColumn(aColumnName
);
645 // does this column actually exist in the file?
649 // This Column doesn't exist!
650 throwFunctionSequenceException(*this);
654 // Everything tested and we have the names of the Column.
655 // Now allocate one Value, set the value and tie the value to the Row.
657 (*m_aAssignValues
)[nId
]->setNull();
660 switch (::comphelper::getINT32(xCol
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE
))))
663 if (aValue
.equalsIgnoreAsciiCase("TRUE") || aValue
[0] == '1')
664 *(*m_aAssignValues
)[nId
] = true;
665 else if (aValue
.equalsIgnoreAsciiCase("FALSE") || aValue
[0] == '0')
666 *(*m_aAssignValues
)[nId
] = false;
668 throwFunctionSequenceException(*this);
671 case DataType::VARCHAR
:
672 case DataType::LONGVARCHAR
:
673 //Characterset is already converted, since the entire statement was converted
674 case DataType::TINYINT
:
675 case DataType::SMALLINT
:
676 case DataType::INTEGER
:
677 case DataType::DECIMAL
:
678 case DataType::NUMERIC
:
680 case DataType::DOUBLE
:
683 case DataType::TIMESTAMP
:
684 *(*m_aAssignValues
)[nId
] = ORowSetValue(aValue
);
687 throwFunctionSequenceException(*this);
691 // save Parameter-No. (as User Data)
692 // SQL_NO_PARAMETER = no Parameter.
693 m_aAssignValues
->setParameterIndex(nId
,nParameter
);
694 if(nParameter
!= SQL_NO_PARAMETER
)
695 m_aParameterIndexes
[nParameter
] = nId
;
698 void OStatement_Base::parseParamterElem(const OUString
& /*_sColumnName*/,OSQLParseNode
* /*pRow_Value_Constructor_Elem*/)
706 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */