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
, NULL
)
60 ,m_pConnection(_pConnection
)
63 ,m_pEvaluationKeySet(NULL
)
69 ,m_nResultSetType(ResultSetType::FORWARD_ONLY
)
70 ,m_nFetchDirection(FetchDirection::FORWARD
)
71 ,m_nResultSetConcurrency(ResultSetConcurrency::UPDATABLE
)
72 ,m_bEscapeProcessing(true)
73 ,rBHelper(OStatement_BASE::rBHelper
)
75 m_pConnection
->acquire();
77 sal_Int32 nAttrib
= 0;
79 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CURSORNAME
), PROPERTY_ID_CURSORNAME
, nAttrib
,&m_aCursorName
, ::cppu::UnoType
<OUString
>::get());
80 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXFIELDSIZE
), PROPERTY_ID_MAXFIELDSIZE
, nAttrib
,&m_nMaxFieldSize
, ::cppu::UnoType
<sal_Int32
>::get());
81 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXROWS
), PROPERTY_ID_MAXROWS
, nAttrib
,&m_nMaxRows
, ::cppu::UnoType
<sal_Int32
>::get());
82 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_QUERYTIMEOUT
), PROPERTY_ID_QUERYTIMEOUT
, nAttrib
,&m_nQueryTimeOut
, ::cppu::UnoType
<sal_Int32
>::get());
83 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE
), PROPERTY_ID_FETCHSIZE
, nAttrib
,&m_nFetchSize
, ::cppu::UnoType
<sal_Int32
>::get());
84 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE
), PROPERTY_ID_RESULTSETTYPE
, nAttrib
,&m_nResultSetType
, ::cppu::UnoType
<sal_Int32
>::get());
85 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION
), PROPERTY_ID_FETCHDIRECTION
, nAttrib
,&m_nFetchDirection
, ::cppu::UnoType
<sal_Int32
>::get());
86 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ESCAPEPROCESSING
),PROPERTY_ID_ESCAPEPROCESSING
, nAttrib
,&m_bEscapeProcessing
,cppu::UnoType
<bool>::get());
88 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY
), PROPERTY_ID_RESULTSETCONCURRENCY
, nAttrib
,&m_nResultSetConcurrency
, ::cppu::UnoType
<sal_Int32
>::get());
91 OStatement_Base::~OStatement_Base()
93 osl_atomic_increment( &m_refCount
);
95 delete m_pSQLAnalyzer
;
98 void OStatement_Base::disposeResultSet()
100 SAL_INFO( "connectivity.drivers", "file Ocke.Janssen@sun.com OStatement_Base::disposeResultSet" );
101 // free the cursor if alive
102 Reference
< XComponent
> xComp(m_xResultSet
.get(), UNO_QUERY
);
103 assert(xComp
.is() || !m_xResultSet
.get().is());
106 m_xResultSet
.clear();
109 void OStatement_BASE2::disposing()
111 ::osl::MutexGuard
aGuard(m_aMutex
);
116 m_pSQLAnalyzer
->dispose();
120 m_aRow
->get().clear();
124 m_aSQLIterator
.dispose();
134 m_pConnection
->release();
135 m_pConnection
= NULL
;
146 OStatement_Base::disposing();
149 void SAL_CALL
OStatement_Base::acquire() throw()
151 OStatement_BASE::acquire();
154 void SAL_CALL
OStatement_BASE2::release() throw()
159 Any SAL_CALL
OStatement_Base::queryInterface( const Type
& rType
) throw(RuntimeException
, std::exception
)
161 const Any aRet
= OStatement_BASE::queryInterface(rType
);
162 return aRet
.hasValue() ? aRet
: OPropertySetHelper::queryInterface(rType
);
165 Sequence
< Type
> SAL_CALL
OStatement_Base::getTypes( ) throw(RuntimeException
, std::exception
)
167 ::cppu::OTypeCollection
aTypes( cppu::UnoType
<com::sun::star::beans::XMultiPropertySet
>::get(),
168 cppu::UnoType
<com::sun::star::beans::XFastPropertySet
>::get(),
169 cppu::UnoType
<com::sun::star::beans::XPropertySet
>::get());
171 return ::comphelper::concatSequences(aTypes
.getTypes(),OStatement_BASE::getTypes());
175 void SAL_CALL
OStatement_Base::cancel( ) throw(RuntimeException
, std::exception
)
179 void SAL_CALL
OStatement_Base::close() throw (SQLException
, RuntimeException
, std::exception
)
182 ::osl::MutexGuard
aGuard( m_aMutex
);
183 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
188 void OStatement_Base::closeResultSet() throw (SQLException
, RuntimeException
, std::exception
)
190 SAL_INFO( "connectivity.drivers", "file Ocke.Janssen@sun.com OStatement_Base::clearMyResultSet " );
191 ::osl::MutexGuard
aGuard( m_aMutex
);
192 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
194 Reference
< XCloseable
> xCloseable(m_xResultSet
.get(), UNO_QUERY
);
195 assert(xCloseable
.is() || !m_xResultSet
.get().is());
202 catch( const DisposedException
& ) { }
205 m_xResultSet
.clear();
208 Any SAL_CALL
OStatement_Base::getWarnings( ) throw(SQLException
, RuntimeException
, std::exception
)
210 ::osl::MutexGuard
aGuard( m_aMutex
);
211 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
213 return makeAny(m_aLastWarning
);
216 void SAL_CALL
OStatement_Base::clearWarnings( ) throw(SQLException
, RuntimeException
, std::exception
)
218 ::osl::MutexGuard
aGuard( m_aMutex
);
219 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
221 m_aLastWarning
= SQLWarning();
224 ::cppu::IPropertyArrayHelper
* OStatement_Base::createArrayHelper( ) const
226 Sequence
< Property
> aProps
;
227 describeProperties(aProps
);
228 return new ::cppu::OPropertyArrayHelper(aProps
);
232 ::cppu::IPropertyArrayHelper
& OStatement_Base::getInfoHelper()
234 return *getArrayHelper();
237 OResultSet
* OStatement::createResultSet()
239 return new OResultSet(this,m_aSQLIterator
);
242 IMPLEMENT_SERVICE_INFO(OStatement
,"com.sun.star.sdbc.driver.file.Statement","com.sun.star.sdbc.Statement");
244 void SAL_CALL
OStatement::acquire() throw()
246 OStatement_BASE2::acquire();
249 void SAL_CALL
OStatement::release() throw()
251 OStatement_BASE2::release();
255 sal_Bool SAL_CALL
OStatement::execute( const OUString
& sql
) throw(SQLException
, RuntimeException
, std::exception
)
257 ::osl::MutexGuard
aGuard( m_aMutex
);
261 return m_aSQLIterator
.getStatementType() == SQL_STATEMENT_SELECT
;
266 Reference
< XResultSet
> SAL_CALL
OStatement::executeQuery( const OUString
& sql
) throw(SQLException
, RuntimeException
, std::exception
)
268 ::osl::MutexGuard
aGuard( m_aMutex
);
269 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
272 Reference
< XResultSet
> xRS
;
273 OResultSet
* pResult
= createResultSet();
275 initializeResultSet(pResult
);
283 Reference
< XConnection
> SAL_CALL
OStatement::getConnection( ) throw(SQLException
, RuntimeException
, std::exception
)
285 return Reference
< XConnection
>(m_pConnection
);
288 sal_Int32 SAL_CALL
OStatement::executeUpdate( const OUString
& sql
) throw(SQLException
, RuntimeException
, std::exception
)
290 ::osl::MutexGuard
aGuard( m_aMutex
);
291 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
295 OResultSet
* pResult
= createResultSet();
296 Reference
< XResultSet
> xRS
= pResult
;
297 initializeResultSet(pResult
);
300 return pResult
->getRowCountResult();
304 void SAL_CALL
OStatement_Base::disposing()
306 if(m_aEvaluateRow
.is())
308 m_aEvaluateRow
->get().clear();
309 m_aEvaluateRow
= NULL
;
311 delete m_pEvaluationKeySet
;
312 OStatement_BASE::disposing();
315 Reference
< ::com::sun::star::beans::XPropertySetInfo
> SAL_CALL
OStatement_Base::getPropertySetInfo( ) throw(RuntimeException
, std::exception
)
317 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
320 Any SAL_CALL
OStatement::queryInterface( const Type
& rType
) throw(RuntimeException
, std::exception
)
322 Any aRet
= OStatement_XStatement::queryInterface( rType
);
323 return aRet
.hasValue() ? aRet
: OStatement_BASE2::queryInterface( rType
);
326 OSQLAnalyzer
* OStatement_Base::createAnalyzer()
328 return new OSQLAnalyzer(m_pConnection
);
331 void OStatement_Base::anylizeSQL()
333 OSL_ENSURE(m_pSQLAnalyzer
,"OResultSet::anylizeSQL: Analyzer isn't set!");
334 // start analysing the statement
335 m_pSQLAnalyzer
->setOrigColumns(m_xColNames
);
336 m_pSQLAnalyzer
->start(m_pParseTree
);
338 const OSQLParseNode
* pOrderbyClause
= m_aSQLIterator
.getOrderTree();
341 OSQLParseNode
* pOrderingSpecCommalist
= pOrderbyClause
->getChild(2);
342 OSL_ENSURE(SQL_ISRULE(pOrderingSpecCommalist
,ordering_spec_commalist
),"OResultSet: Fehler im Parse Tree");
344 for (sal_uInt32 m
= 0; m
< pOrderingSpecCommalist
->count(); m
++)
346 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");
350 OSQLParseNode
* pColumnRef
= pOrderingSpec
->getChild(0);
351 if(!SQL_ISRULE(pColumnRef
,column_ref
))
353 throw SQLException();
355 OSQLParseNode
* pAscendingDescending
= pOrderingSpec
->getChild(1);
356 setOrderbyColumn(pColumnRef
,pAscendingDescending
);
361 void OStatement_Base::setOrderbyColumn( OSQLParseNode
* pColumnRef
,
362 OSQLParseNode
* pAscendingDescending
)
364 OUString aColumnName
;
365 if (pColumnRef
->count() == 1)
366 aColumnName
= pColumnRef
->getChild(0)->getTokenValue();
367 else if (pColumnRef
->count() == 3)
369 pColumnRef
->getChild(2)->parseNodeToStr( aColumnName
, getOwnConnection(), NULL
, false, false );
373 throw SQLException();
376 Reference
<XColumnLocate
> xColLocate(m_xColNames
,UNO_QUERY
);
379 // Everything tested and we have the name of the Column.
380 // What number is the Column?
381 ::rtl::Reference
<OSQLColumns
> aSelectColumns
= m_aSQLIterator
.getSelectColumns();
382 ::comphelper::UStringMixEqual aCase
;
383 OSQLColumns::Vector::const_iterator aFind
= ::connectivity::find(aSelectColumns
->get().begin(),aSelectColumns
->get().end(),aColumnName
,aCase
);
384 if ( aFind
== aSelectColumns
->get().end() )
385 throw SQLException();
386 m_aOrderbyColumnNumber
.push_back((aFind
- aSelectColumns
->get().begin()) + 1);
388 // Ascending or Descending?
389 m_aOrderbyAscending
.push_back((SQL_ISTOKEN(pAscendingDescending
,DESC
)) ? SQL_DESC
: SQL_ASC
);
393 void OStatement_Base::construct(const OUString
& sql
) throw(SQLException
, RuntimeException
)
396 m_pParseTree
= m_aParser
.parseTree(aErr
,sql
);
399 m_aSQLIterator
.setParseTree(m_pParseTree
);
400 m_aSQLIterator
.traverseAll();
401 const OSQLTables
& xTabs
= m_aSQLIterator
.getTables();
405 // no tables -> nothing to operate on -> error
406 m_pConnection
->throwGenericSQLException(STR_QUERY_NO_TABLE
,*this);
408 if ( xTabs
.size() > 1 || m_aSQLIterator
.hasErrors() )
409 // more than one table -> can't operate on them -> error
410 m_pConnection
->throwGenericSQLException(STR_QUERY_MORE_TABLES
,*this);
412 if ( (m_aSQLIterator
.getStatementType() == SQL_STATEMENT_SELECT
) && m_aSQLIterator
.getSelectColumns()->get().empty() )
413 // SELECT statement without columns -> error
414 m_pConnection
->throwGenericSQLException(STR_QUERY_NO_COLUMN
,*this);
416 switch(m_aSQLIterator
.getStatementType())
418 case SQL_STATEMENT_CREATE_TABLE
:
419 case SQL_STATEMENT_ODBC_CALL
:
420 case SQL_STATEMENT_UNKNOWN
:
421 m_pConnection
->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,*this);
427 // at this moment we support only one table per select statement
428 Reference
< ::com::sun::star::lang::XUnoTunnel
> xTunnel(xTabs
.begin()->second
,UNO_QUERY
);
433 m_pTable
= reinterpret_cast<OFileTable
*>(xTunnel
->getSomething(OFileTable::getUnoTunnelImplementationId()));
437 OSL_ENSURE(m_pTable
,"No table!");
439 m_xColNames
= m_pTable
->getColumns();
440 Reference
<XIndexAccess
> xNames(m_xColNames
,UNO_QUERY
);
441 // set the binding of the resultrow
442 m_aRow
= new OValueRefVector(xNames
->getCount());
443 (m_aRow
->get())[0]->setBound(true);
444 ::std::for_each(m_aRow
->get().begin()+1,m_aRow
->get().end(),TSetRefBound(false));
446 // set the binding of the resultrow
447 m_aEvaluateRow
= new OValueRefVector(xNames
->getCount());
449 (m_aEvaluateRow
->get())[0]->setBound(true);
450 ::std::for_each(m_aEvaluateRow
->get().begin()+1,m_aEvaluateRow
->get().end(),TSetRefBound(false));
452 // set the select row
453 m_aSelectRow
= new OValueRefVector(m_aSQLIterator
.getSelectColumns()->get().size());
454 ::std::for_each(m_aSelectRow
->get().begin(),m_aSelectRow
->get().end(),TSetRefBound(true));
456 // create the column mapping
457 createColumnMapping();
459 m_pSQLAnalyzer
= createAnalyzer();
461 Reference
<XIndexesSupplier
> xIndexSup(xTunnel
,UNO_QUERY
);
463 m_pSQLAnalyzer
->setIndexes(xIndexSup
->getIndexes());
468 throw SQLException(aErr
,*this,OUString(),0,Any());
471 void OStatement_Base::createColumnMapping()
473 // initialize the column index map (mapping select columns to table columns)
474 ::rtl::Reference
<connectivity::OSQLColumns
> xColumns
= m_aSQLIterator
.getSelectColumns();
475 m_aColMapping
.resize(xColumns
->get().size() + 1);
476 for (sal_Int32 i
=0; i
<(sal_Int32
)m_aColMapping
.size(); ++i
)
477 m_aColMapping
[i
] = i
;
479 Reference
<XIndexAccess
> xNames(m_xColNames
,UNO_QUERY
);
480 // now check which columns are bound
481 OResultSet::setBoundedColumns(m_aRow
,m_aSelectRow
,xColumns
,xNames
,true,m_xDBMetaData
,m_aColMapping
);
484 void OStatement_Base::initializeResultSet(OResultSet
* _pResult
)
488 _pResult
->setSqlAnalyzer(m_pSQLAnalyzer
);
489 _pResult
->setOrderByColumns(m_aOrderbyColumnNumber
);
490 _pResult
->setOrderByAscending(m_aOrderbyAscending
);
491 _pResult
->setBindingRow(m_aRow
);
492 _pResult
->setColumnMapping(m_aColMapping
);
493 _pResult
->setEvaluationRow(m_aEvaluateRow
);
494 _pResult
->setAssignValues(m_aAssignValues
);
495 _pResult
->setSelectRow(m_aSelectRow
);
497 m_pSQLAnalyzer
->bindSelectRow(m_aRow
);
498 m_pEvaluationKeySet
= m_pSQLAnalyzer
->bindEvaluationRow(m_aEvaluateRow
); // Set values in the code of the Compiler
499 _pResult
->setEvaluationKeySet(m_pEvaluationKeySet
);
502 void OStatement_Base::GetAssignValues()
504 if (m_pParseTree
== NULL
)
506 ::dbtools::throwFunctionSequenceException(*this);
510 if (SQL_ISRULE(m_pParseTree
,select_statement
))
511 // no values have to be set for SELECT
513 else if (SQL_ISRULE(m_pParseTree
,insert_statement
))
515 // Create Row for the values to be set (Reference through new)
516 if(m_aAssignValues
.is())
517 m_aAssignValues
->get().clear();
518 sal_Int32 nCount
= Reference
<XIndexAccess
>(m_xColNames
,UNO_QUERY
)->getCount();
519 m_aAssignValues
= new OAssignValues(nCount
);
521 ::std::for_each(m_aAssignValues
->get().begin()+1,m_aAssignValues
->get().end(),TSetRefBound(false));
523 m_aParameterIndexes
.resize(nCount
+1,SQL_NO_PARAMETER
);
525 // List of Column-Names, that exist in the column_commalist (separated by ;):
526 ::std::vector
<OUString
> aColumnNameList
;
528 OSL_ENSURE(m_pParseTree
->count() >= 4,"OResultSet: Fehler im Parse Tree");
530 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 if (pOptColumnCommalist
->count() == 0)
535 const Sequence
< OUString
>& aNames
= m_xColNames
->getElementNames();
536 const OUString
* pBegin
= aNames
.getConstArray();
537 const OUString
* pEnd
= pBegin
+ aNames
.getLength();
538 for (; pBegin
!= pEnd
; ++pBegin
)
539 aColumnNameList
.push_back(*pBegin
);
543 OSL_ENSURE(pOptColumnCommalist
->count() == 3,"OResultSet: Fehler im Parse Tree");
545 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");
550 // All Columns in the column_commalist ...
551 for (sal_uInt32 i
= 0; i
< pColumnCommalist
->count(); i
++)
553 OSQLParseNode
* pCol
= pColumnCommalist
->getChild(i
);
554 OSL_ENSURE(pCol
!= NULL
,"OResultSet: Fehler im Parse Tree");
555 aColumnNameList
.push_back(pCol
->getTokenValue());
558 if ( aColumnNameList
.empty() )
559 throwFunctionSequenceException(*this);
562 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");
567 // just "VALUES" is allowed ...
568 if (! SQL_ISTOKEN(pValuesOrQuerySpec
->getChild(0),VALUES
))
569 throwFunctionSequenceException(*this);
571 OSL_ENSURE(pValuesOrQuerySpec
->count() == 4,"OResultSet: pValuesOrQuerySpec->count() != 4");
574 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");
579 for (sal_uInt32 i
= 0; i
< pInsertAtomCommalist
->count(); i
++)
581 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 if(SQL_ISRULE(pRow_Value_Const
,parameter
))
585 ParseAssignValues(aColumnNameList
,pRow_Value_Const
,nIndex
++); // only one Columnname allowed per loop
587 else if(pRow_Value_Const
->isToken())
588 ParseAssignValues(aColumnNameList
,pRow_Value_Const
,i
);
591 if(pRow_Value_Const
->count() == aColumnNameList
.size())
593 for (sal_uInt32 j
= 0; j
< pRow_Value_Const
->count(); ++j
)
594 ParseAssignValues(aColumnNameList
,pRow_Value_Const
->getChild(j
),nIndex
++);
597 throwFunctionSequenceException(*this);
601 else if (SQL_ISRULE(m_pParseTree
,update_statement_searched
))
603 if(m_aAssignValues
.is())
604 m_aAssignValues
->get().clear();
605 sal_Int32 nCount
= Reference
<XIndexAccess
>(m_xColNames
,UNO_QUERY
)->getCount();
606 m_aAssignValues
= new OAssignValues(nCount
);
608 ::std::for_each(m_aAssignValues
->get().begin()+1,m_aAssignValues
->get().end(),TSetRefBound(false));
610 m_aParameterIndexes
.resize(nCount
+1,SQL_NO_PARAMETER
);
612 OSL_ENSURE(m_pParseTree
->count() >= 4,"OResultSet: Fehler im Parse Tree");
614 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");
619 // work on all assignments (commalist) ...
620 ::std::vector
< OUString
> aList(1);
621 for (sal_uInt32 i
= 0; i
< pAssignmentCommalist
->count(); i
++)
623 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");
628 OSQLParseNode
* pCol
= pAssignment
->getChild(0);
629 OSL_ENSURE(pCol
!= NULL
,"OResultSet: pCol == NULL");
631 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 if (pComp
->getTokenValue().toChar() != '=')
636 throwFunctionSequenceException(*this);
639 OSQLParseNode
* pVal
= pAssignment
->getChild(2);
640 OSL_ENSURE(pVal
!= NULL
,"OResultSet: pVal == NULL");
641 aList
[0] = pCol
->getTokenValue();
642 ParseAssignValues(aList
,pVal
,0);
648 void OStatement_Base::ParseAssignValues(const ::std::vector
< OUString
>& aColumnNameList
,OSQLParseNode
* pRow_Value_Constructor_Elem
, sal_Int32 nIndex
)
650 OSL_ENSURE(size_t(nIndex
) <= aColumnNameList
.size(),"SdbFileCursor::ParseAssignValues: nIndex > aColumnNameList.GetTokenCount()");
651 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!");
655 if (pRow_Value_Constructor_Elem
->getNodeType() == SQL_NODE_STRING
||
656 pRow_Value_Constructor_Elem
->getNodeType() == SQL_NODE_INTNUM
||
657 pRow_Value_Constructor_Elem
->getNodeType() == SQL_NODE_APPROXNUM
)
660 SetAssignValue(aColumnName
, pRow_Value_Constructor_Elem
->getTokenValue());
662 else if (SQL_ISTOKEN(pRow_Value_Constructor_Elem
,NULL
))
665 SetAssignValue(aColumnName
, OUString(), true);
667 else if (SQL_ISRULE(pRow_Value_Constructor_Elem
,parameter
))
668 parseParamterElem(aColumnName
,pRow_Value_Constructor_Elem
);
671 throwFunctionSequenceException(*this);
675 void OStatement_Base::SetAssignValue(const OUString
& aColumnName
,
676 const OUString
& aValue
,
678 sal_uInt32 nParameter
)
680 Reference
<XPropertySet
> xCol
;
681 m_xColNames
->getByName(aColumnName
) >>= xCol
;
682 sal_Int32 nId
= Reference
<XColumnLocate
>(m_xColNames
,UNO_QUERY
)->findColumn(aColumnName
);
683 // does this column actually exist in the file?
687 // This Column doesn't exist!
688 throwFunctionSequenceException(*this);
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.
695 (m_aAssignValues
->get())[nId
]->setNull();
698 switch (::comphelper::getINT32(xCol
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE
))))
700 // put criteria depending on the Type as String or double in the variable
702 case DataType::VARCHAR
:
703 case DataType::LONGVARCHAR
:
704 *(m_aAssignValues
->get())[nId
] = ORowSetValue(aValue
);
705 //Characterset is already converted, since the entire statement was converted
709 if (aValue
.equalsIgnoreAsciiCase("TRUE") || aValue
[0] == '1')
710 *(m_aAssignValues
->get())[nId
] = sal_True
;
711 else if (aValue
.equalsIgnoreAsciiCase("FALSE") || aValue
[0] == '0')
712 *(m_aAssignValues
->get())[nId
] = sal_False
;
714 throwFunctionSequenceException(*this);
716 case DataType::TINYINT
:
717 case DataType::SMALLINT
:
718 case DataType::INTEGER
:
719 case DataType::DECIMAL
:
720 case DataType::NUMERIC
:
722 case DataType::DOUBLE
:
725 case DataType::TIMESTAMP
:
726 *(m_aAssignValues
->get())[nId
] = ORowSetValue(aValue
);
729 throwFunctionSequenceException(*this);
733 // save Parameter-No. (as User Data)
734 // SQL_NO_PARAMETER = no Parameter.
735 m_aAssignValues
->setParameterIndex(nId
,nParameter
);
736 if(nParameter
!= SQL_NO_PARAMETER
)
737 m_aParameterIndexes
[nParameter
] = nId
;
740 void OStatement_Base::parseParamterElem(const OUString
& /*_sColumnName*/,OSQLParseNode
* /*pRow_Value_Constructor_Elem*/)
747 }// namespace connectivity
750 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */