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 "file/FDriver.hxx"
24 #include "file/FResultSet.hxx"
25 #include <comphelper/property.hxx>
26 #include <comphelper/uno3.hxx>
27 #include <osl/thread.h>
28 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
29 #include <com/sun/star/sdbc/ResultSetType.hpp>
30 #include <com/sun/star/sdbc/FetchDirection.hpp>
31 #include <com/sun/star/lang/DisposedException.hpp>
32 #include <comphelper/processfactory.hxx>
33 #include <comphelper/sequence.hxx>
34 #include <cppuhelper/typeprovider.hxx>
35 #include "connectivity/dbexception.hxx"
36 #include "resource/file_res.hrc"
38 #include <tools/debug.hxx>
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
,::getCppuBooleanType());
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_BASE2::disposing()
100 ::osl::MutexGuard
aGuard(m_aMutex
);
103 m_pSQLAnalyzer
->dispose();
107 m_aRow
->get().clear();
111 m_aSQLIterator
.dispose();
121 m_pConnection
->release();
122 m_pConnection
= NULL
;
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( ::getCppuType( (const Reference
< ::com::sun::star::beans::XMultiPropertySet
> *)0 ),
155 ::getCppuType( (const Reference
< ::com::sun::star::beans::XFastPropertySet
> *)0 ),
156 ::getCppuType( (const Reference
< ::com::sun::star::beans::XPropertySet
> *)0 ));
158 return ::comphelper::concatSequences(aTypes
.getTypes(),OStatement_BASE::getTypes());
162 void SAL_CALL
OStatement_Base::cancel( ) throw(RuntimeException
, std::exception
)
167 void SAL_CALL
OStatement_Base::close( ) throw(SQLException
, RuntimeException
, std::exception
)
170 ::osl::MutexGuard
aGuard( m_aMutex
);
171 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
177 void OStatement_Base::reset() throw (SQLException
)
179 ::osl::MutexGuard
aGuard( m_aMutex
);
180 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
187 Any SAL_CALL
OStatement_Base::getWarnings( ) throw(SQLException
, RuntimeException
, std::exception
)
189 ::osl::MutexGuard
aGuard( m_aMutex
);
190 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
192 return makeAny(m_aLastWarning
);
195 void SAL_CALL
OStatement_Base::clearWarnings( ) throw(SQLException
, RuntimeException
, std::exception
)
197 ::osl::MutexGuard
aGuard( m_aMutex
);
198 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
200 m_aLastWarning
= SQLWarning();
203 ::cppu::IPropertyArrayHelper
* OStatement_Base::createArrayHelper( ) const
205 Sequence
< Property
> aProps
;
206 describeProperties(aProps
);
207 return new ::cppu::OPropertyArrayHelper(aProps
);
211 ::cppu::IPropertyArrayHelper
& OStatement_Base::getInfoHelper()
213 return *const_cast<OStatement_Base
*>(this)->getArrayHelper();
216 OResultSet
* OStatement::createResultSet()
218 return new OResultSet(this,m_aSQLIterator
);
221 IMPLEMENT_SERVICE_INFO(OStatement
,"com.sun.star.sdbc.driver.file.Statement","com.sun.star.sdbc.Statement");
223 void SAL_CALL
OStatement::acquire() throw()
225 OStatement_BASE2::acquire();
228 void SAL_CALL
OStatement::release() throw()
230 OStatement_BASE2::release();
234 sal_Bool SAL_CALL
OStatement::execute( const OUString
& sql
) throw(SQLException
, RuntimeException
, std::exception
)
236 ::osl::MutexGuard
aGuard( m_aMutex
);
240 return m_aSQLIterator
.getStatementType() == SQL_STATEMENT_SELECT
;
245 Reference
< XResultSet
> SAL_CALL
OStatement::executeQuery( const OUString
& sql
) throw(SQLException
, RuntimeException
, std::exception
)
247 ::osl::MutexGuard
aGuard( m_aMutex
);
248 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
251 Reference
< XResultSet
> xRS
;
252 OResultSet
* pResult
= createResultSet();
254 initializeResultSet(pResult
);
261 Reference
< XConnection
> SAL_CALL
OStatement::getConnection( ) throw(SQLException
, RuntimeException
, std::exception
)
263 return (Reference
< XConnection
>)m_pConnection
;
266 sal_Int32 SAL_CALL
OStatement::executeUpdate( const OUString
& sql
) throw(SQLException
, RuntimeException
, std::exception
)
268 ::osl::MutexGuard
aGuard( m_aMutex
);
269 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
273 OResultSet
* pResult
= createResultSet();
274 Reference
< XResultSet
> xRS
= pResult
;
275 initializeResultSet(pResult
);
278 return pResult
->getRowCountResult();
282 void SAL_CALL
OStatement_Base::disposing(void)
284 if(m_aEvaluateRow
.is())
286 m_aEvaluateRow
->get().clear();
287 m_aEvaluateRow
= NULL
;
289 delete m_pEvaluationKeySet
;
290 OStatement_BASE::disposing();
293 Reference
< ::com::sun::star::beans::XPropertySetInfo
> SAL_CALL
OStatement_Base::getPropertySetInfo( ) throw(RuntimeException
, std::exception
)
295 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
298 Any SAL_CALL
OStatement::queryInterface( const Type
& rType
) throw(RuntimeException
, std::exception
)
300 Any aRet
= OStatement_XStatement::queryInterface( rType
);
301 return aRet
.hasValue() ? aRet
: OStatement_BASE2::queryInterface( rType
);
304 OSQLAnalyzer
* OStatement_Base::createAnalyzer()
306 return new OSQLAnalyzer(m_pConnection
);
309 void OStatement_Base::anylizeSQL()
311 OSL_ENSURE(m_pSQLAnalyzer
,"OResultSet::anylizeSQL: Analyzer isn't set!");
312 // start analysing the statement
313 m_pSQLAnalyzer
->setOrigColumns(m_xColNames
);
314 m_pSQLAnalyzer
->start(m_pParseTree
);
316 const OSQLParseNode
* pOrderbyClause
= m_aSQLIterator
.getOrderTree();
319 OSQLParseNode
* pOrderingSpecCommalist
= pOrderbyClause
->getChild(2);
320 OSL_ENSURE(SQL_ISRULE(pOrderingSpecCommalist
,ordering_spec_commalist
),"OResultSet: Fehler im Parse Tree");
322 for (sal_uInt32 m
= 0; m
< pOrderingSpecCommalist
->count(); m
++)
324 OSQLParseNode
* pOrderingSpec
= pOrderingSpecCommalist
->getChild(m
);
325 OSL_ENSURE(SQL_ISRULE(pOrderingSpec
,ordering_spec
),"OResultSet: Fehler im Parse Tree");
326 OSL_ENSURE(pOrderingSpec
->count() == 2,"OResultSet: Fehler im Parse Tree");
328 OSQLParseNode
* pColumnRef
= pOrderingSpec
->getChild(0);
329 if(!SQL_ISRULE(pColumnRef
,column_ref
))
331 throw SQLException();
333 OSQLParseNode
* pAscendingDescending
= pOrderingSpec
->getChild(1);
334 setOrderbyColumn(pColumnRef
,pAscendingDescending
);
339 void OStatement_Base::setOrderbyColumn( OSQLParseNode
* pColumnRef
,
340 OSQLParseNode
* pAscendingDescending
)
342 OUString aColumnName
;
343 if (pColumnRef
->count() == 1)
344 aColumnName
= pColumnRef
->getChild(0)->getTokenValue();
345 else if (pColumnRef
->count() == 3)
347 pColumnRef
->getChild(2)->parseNodeToStr( aColumnName
, getOwnConnection(), NULL
, false, false );
351 throw SQLException();
354 Reference
<XColumnLocate
> xColLocate(m_xColNames
,UNO_QUERY
);
357 // Everything tested and we have the name of the Column.
358 // What number is the Column?
359 ::rtl::Reference
<OSQLColumns
> aSelectColumns
= m_aSQLIterator
.getSelectColumns();
360 ::comphelper::UStringMixEqual aCase
;
361 OSQLColumns::Vector::const_iterator aFind
= ::connectivity::find(aSelectColumns
->get().begin(),aSelectColumns
->get().end(),aColumnName
,aCase
);
362 if ( aFind
== aSelectColumns
->get().end() )
363 throw SQLException();
364 m_aOrderbyColumnNumber
.push_back((aFind
- aSelectColumns
->get().begin()) + 1);
366 // Ascending or Descending?
367 m_aOrderbyAscending
.push_back((SQL_ISTOKEN(pAscendingDescending
,DESC
)) ? SQL_DESC
: SQL_ASC
);
371 void OStatement_Base::construct(const OUString
& sql
) throw(SQLException
, RuntimeException
)
374 m_pParseTree
= m_aParser
.parseTree(aErr
,sql
);
377 m_aSQLIterator
.setParseTree(m_pParseTree
);
378 m_aSQLIterator
.traverseAll();
379 const OSQLTables
& xTabs
= m_aSQLIterator
.getTables();
383 // no tables -> nothing to operate on -> error
384 m_pConnection
->throwGenericSQLException(STR_QUERY_NO_TABLE
,*this);
386 if ( xTabs
.size() > 1 || m_aSQLIterator
.hasErrors() )
387 // more than one table -> can't operate on them -> error
388 m_pConnection
->throwGenericSQLException(STR_QUERY_MORE_TABLES
,*this);
390 if ( (m_aSQLIterator
.getStatementType() == SQL_STATEMENT_SELECT
) && m_aSQLIterator
.getSelectColumns()->get().empty() )
391 // SELECT statement without columns -> error
392 m_pConnection
->throwGenericSQLException(STR_QUERY_NO_COLUMN
,*this);
394 switch(m_aSQLIterator
.getStatementType())
396 case SQL_STATEMENT_CREATE_TABLE
:
397 case SQL_STATEMENT_ODBC_CALL
:
398 case SQL_STATEMENT_UNKNOWN
:
399 m_pConnection
->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,*this);
405 // at this moment we support only one table per select statement
406 Reference
< ::com::sun::star::lang::XUnoTunnel
> xTunnel(xTabs
.begin()->second
,UNO_QUERY
);
411 m_pTable
= reinterpret_cast<OFileTable
*>(xTunnel
->getSomething(OFileTable::getUnoTunnelImplementationId()));
415 OSL_ENSURE(m_pTable
,"No table!");
417 m_xColNames
= m_pTable
->getColumns();
418 Reference
<XIndexAccess
> xNames(m_xColNames
,UNO_QUERY
);
419 // set the binding of the resultrow
420 m_aRow
= new OValueRefVector(xNames
->getCount());
421 (m_aRow
->get())[0]->setBound(true);
422 ::std::for_each(m_aRow
->get().begin()+1,m_aRow
->get().end(),TSetRefBound(false));
424 // set the binding of the resultrow
425 m_aEvaluateRow
= new OValueRefVector(xNames
->getCount());
427 (m_aEvaluateRow
->get())[0]->setBound(true);
428 ::std::for_each(m_aEvaluateRow
->get().begin()+1,m_aEvaluateRow
->get().end(),TSetRefBound(false));
430 // set the select row
431 m_aSelectRow
= new OValueRefVector(m_aSQLIterator
.getSelectColumns()->get().size());
432 ::std::for_each(m_aSelectRow
->get().begin(),m_aSelectRow
->get().end(),TSetRefBound(true));
434 // create the column mapping
435 createColumnMapping();
437 m_pSQLAnalyzer
= createAnalyzer();
439 Reference
<XIndexesSupplier
> xIndexSup(xTunnel
,UNO_QUERY
);
441 m_pSQLAnalyzer
->setIndexes(xIndexSup
->getIndexes());
446 throw SQLException(aErr
,*this,OUString(),0,Any());
449 void OStatement_Base::createColumnMapping()
451 // initialize the column index map (mapping select columns to table columns)
452 ::rtl::Reference
<connectivity::OSQLColumns
> xColumns
= m_aSQLIterator
.getSelectColumns();
453 m_aColMapping
.resize(xColumns
->get().size() + 1);
454 for (sal_Int32 i
=0; i
<(sal_Int32
)m_aColMapping
.size(); ++i
)
455 m_aColMapping
[i
] = i
;
457 Reference
<XIndexAccess
> xNames(m_xColNames
,UNO_QUERY
);
458 // now check which columns are bound
459 OResultSet::setBoundedColumns(m_aRow
,m_aSelectRow
,xColumns
,xNames
,true,m_xDBMetaData
,m_aColMapping
);
462 void OStatement_Base::initializeResultSet(OResultSet
* _pResult
)
466 _pResult
->setSqlAnalyzer(m_pSQLAnalyzer
);
467 _pResult
->setOrderByColumns(m_aOrderbyColumnNumber
);
468 _pResult
->setOrderByAscending(m_aOrderbyAscending
);
469 _pResult
->setBindingRow(m_aRow
);
470 _pResult
->setColumnMapping(m_aColMapping
);
471 _pResult
->setEvaluationRow(m_aEvaluateRow
);
472 _pResult
->setAssignValues(m_aAssignValues
);
473 _pResult
->setSelectRow(m_aSelectRow
);
475 m_pSQLAnalyzer
->bindSelectRow(m_aRow
);
476 m_pEvaluationKeySet
= m_pSQLAnalyzer
->bindEvaluationRow(m_aEvaluateRow
); // Set values in the code of the Compiler
477 _pResult
->setEvaluationKeySet(m_pEvaluationKeySet
);
480 void OStatement_Base::GetAssignValues()
482 if (m_pParseTree
== NULL
)
484 ::dbtools::throwFunctionSequenceException(*this);
488 if (SQL_ISRULE(m_pParseTree
,select_statement
))
489 // no values have to be set for SELECT
491 else if (SQL_ISRULE(m_pParseTree
,insert_statement
))
493 // Create Row for the values to be set (Reference trough new)
494 if(m_aAssignValues
.is())
495 m_aAssignValues
->get().clear();
496 sal_Int32 nCount
= Reference
<XIndexAccess
>(m_xColNames
,UNO_QUERY
)->getCount();
497 m_aAssignValues
= new OAssignValues(nCount
);
499 ::std::for_each(m_aAssignValues
->get().begin()+1,m_aAssignValues
->get().end(),TSetRefBound(false));
501 m_aParameterIndexes
.resize(nCount
+1,SQL_NO_PARAMETER
);
503 // List of Column-Names, that exist in the column_commalist (separated by ;):
504 ::std::vector
<OUString
> aColumnNameList
;
506 OSL_ENSURE(m_pParseTree
->count() >= 4,"OResultSet: Fehler im Parse Tree");
508 OSQLParseNode
* pOptColumnCommalist
= m_pParseTree
->getChild(3);
509 OSL_ENSURE(pOptColumnCommalist
!= NULL
,"OResultSet: Fehler im Parse Tree");
510 OSL_ENSURE(SQL_ISRULE(pOptColumnCommalist
,opt_column_commalist
),"OResultSet: Fehler im Parse Tree");
511 if (pOptColumnCommalist
->count() == 0)
513 const Sequence
< OUString
>& aNames
= m_xColNames
->getElementNames();
514 const OUString
* pBegin
= aNames
.getConstArray();
515 const OUString
* pEnd
= pBegin
+ aNames
.getLength();
516 for (; pBegin
!= pEnd
; ++pBegin
)
517 aColumnNameList
.push_back(*pBegin
);
521 OSL_ENSURE(pOptColumnCommalist
->count() == 3,"OResultSet: Fehler im Parse Tree");
523 OSQLParseNode
* pColumnCommalist
= pOptColumnCommalist
->getChild(1);
524 OSL_ENSURE(pColumnCommalist
!= NULL
,"OResultSet: Fehler im Parse Tree");
525 OSL_ENSURE(SQL_ISRULE(pColumnCommalist
,column_commalist
),"OResultSet: Fehler im Parse Tree");
526 OSL_ENSURE(pColumnCommalist
->count() > 0,"OResultSet: Fehler im Parse Tree");
528 // All Columns in the column_commalist ...
529 for (sal_uInt32 i
= 0; i
< pColumnCommalist
->count(); i
++)
531 OSQLParseNode
* pCol
= pColumnCommalist
->getChild(i
);
532 OSL_ENSURE(pCol
!= NULL
,"OResultSet: Fehler im Parse Tree");
533 aColumnNameList
.push_back(pCol
->getTokenValue());
536 if ( aColumnNameList
.empty() )
537 throwFunctionSequenceException(*this);
540 OSQLParseNode
* pValuesOrQuerySpec
= m_pParseTree
->getChild(4);
541 OSL_ENSURE(pValuesOrQuerySpec
!= NULL
,"OResultSet: pValuesOrQuerySpec darf nicht NULL sein!");
542 OSL_ENSURE(SQL_ISRULE(pValuesOrQuerySpec
,values_or_query_spec
),"OResultSet: ! SQL_ISRULE(pValuesOrQuerySpec,values_or_query_spec)");
543 OSL_ENSURE(pValuesOrQuerySpec
->count() > 0,"OResultSet: pValuesOrQuerySpec->count() <= 0");
545 // just "VALUES" is allowed ...
546 if (! SQL_ISTOKEN(pValuesOrQuerySpec
->getChild(0),VALUES
))
547 throwFunctionSequenceException(*this);
549 OSL_ENSURE(pValuesOrQuerySpec
->count() == 4,"OResultSet: pValuesOrQuerySpec->count() != 4");
552 OSQLParseNode
* pInsertAtomCommalist
= pValuesOrQuerySpec
->getChild(2);
553 OSL_ENSURE(pInsertAtomCommalist
!= NULL
,"OResultSet: pInsertAtomCommalist darf nicht NULL sein!");
554 OSL_ENSURE(pInsertAtomCommalist
->count() > 0,"OResultSet: pInsertAtomCommalist <= 0");
556 OSQLParseNode
* pRow_Value_Const
;
558 for (sal_uInt32 i
= 0; i
< pInsertAtomCommalist
->count(); i
++)
560 pRow_Value_Const
= pInsertAtomCommalist
->getChild(i
); // row_value_constructor
561 OSL_ENSURE(pRow_Value_Const
!= NULL
,"OResultSet: pRow_Value_Const darf nicht NULL sein!");
562 if(SQL_ISRULE(pRow_Value_Const
,parameter
))
564 ParseAssignValues(aColumnNameList
,pRow_Value_Const
,nIndex
++); // only one Columnname allowed per loop
566 else if(pRow_Value_Const
->isToken())
567 ParseAssignValues(aColumnNameList
,pRow_Value_Const
,i
);
570 if(pRow_Value_Const
->count() == aColumnNameList
.size())
572 for (sal_uInt32 j
= 0; j
< pRow_Value_Const
->count(); ++j
)
573 ParseAssignValues(aColumnNameList
,pRow_Value_Const
->getChild(j
),nIndex
++);
576 throwFunctionSequenceException(*this);
580 else if (SQL_ISRULE(m_pParseTree
,update_statement_searched
))
582 if(m_aAssignValues
.is())
583 m_aAssignValues
->get().clear();
584 sal_Int32 nCount
= Reference
<XIndexAccess
>(m_xColNames
,UNO_QUERY
)->getCount();
585 m_aAssignValues
= new OAssignValues(nCount
);
587 ::std::for_each(m_aAssignValues
->get().begin()+1,m_aAssignValues
->get().end(),TSetRefBound(false));
589 m_aParameterIndexes
.resize(nCount
+1,SQL_NO_PARAMETER
);
591 OSL_ENSURE(m_pParseTree
->count() >= 4,"OResultSet: Fehler im Parse Tree");
593 OSQLParseNode
* pAssignmentCommalist
= m_pParseTree
->getChild(3);
594 OSL_ENSURE(pAssignmentCommalist
!= NULL
,"OResultSet: pAssignmentCommalist == NULL");
595 OSL_ENSURE(SQL_ISRULE(pAssignmentCommalist
,assignment_commalist
),"OResultSet: Fehler im Parse Tree");
596 OSL_ENSURE(pAssignmentCommalist
->count() > 0,"OResultSet: pAssignmentCommalist->count() <= 0");
598 // work on all assignments (commalist) ...
599 ::std::vector
< OUString
> aList(1);
600 for (sal_uInt32 i
= 0; i
< pAssignmentCommalist
->count(); i
++)
602 OSQLParseNode
* pAssignment
= pAssignmentCommalist
->getChild(i
);
603 OSL_ENSURE(pAssignment
!= NULL
,"OResultSet: pAssignment == NULL");
604 OSL_ENSURE(SQL_ISRULE(pAssignment
,assignment
),"OResultSet: Fehler im Parse Tree");
605 OSL_ENSURE(pAssignment
->count() == 3,"OResultSet: pAssignment->count() != 3");
607 OSQLParseNode
* pCol
= pAssignment
->getChild(0);
608 OSL_ENSURE(pCol
!= NULL
,"OResultSet: pCol == NULL");
610 OSQLParseNode
* pComp
= pAssignment
->getChild(1);
611 OSL_ENSURE(pComp
!= NULL
,"OResultSet: pComp == NULL");
612 OSL_ENSURE(pComp
->getNodeType() == SQL_NODE_EQUAL
,"OResultSet: pComp->getNodeType() != SQL_NODE_COMPARISON");
613 if (pComp
->getTokenValue().toChar() != '=')
615 throwFunctionSequenceException(*this);
618 OSQLParseNode
* pVal
= pAssignment
->getChild(2);
619 OSL_ENSURE(pVal
!= NULL
,"OResultSet: pVal == NULL");
620 aList
[0] = pCol
->getTokenValue();
621 ParseAssignValues(aList
,pVal
,0);
627 void OStatement_Base::ParseAssignValues(const ::std::vector
< OUString
>& aColumnNameList
,OSQLParseNode
* pRow_Value_Constructor_Elem
, sal_Int32 nIndex
)
629 OSL_ENSURE(size_t(nIndex
) <= aColumnNameList
.size(),"SdbFileCursor::ParseAssignValues: nIndex > aColumnNameList.GetTokenCount()");
630 OUString
aColumnName(aColumnNameList
[nIndex
]);
631 OSL_ENSURE(aColumnName
.getLength() > 0,"OResultSet: Column-Name nicht gefunden");
632 OSL_ENSURE(pRow_Value_Constructor_Elem
!= NULL
,"OResultSet: pRow_Value_Constructor_Elem darf nicht NULL sein!");
634 if (pRow_Value_Constructor_Elem
->getNodeType() == SQL_NODE_STRING
||
635 pRow_Value_Constructor_Elem
->getNodeType() == SQL_NODE_INTNUM
||
636 pRow_Value_Constructor_Elem
->getNodeType() == SQL_NODE_APPROXNUM
)
639 SetAssignValue(aColumnName
, pRow_Value_Constructor_Elem
->getTokenValue());
641 else if (SQL_ISTOKEN(pRow_Value_Constructor_Elem
,NULL
))
644 SetAssignValue(aColumnName
, OUString(), true);
646 else if (SQL_ISRULE(pRow_Value_Constructor_Elem
,parameter
))
647 parseParamterElem(aColumnName
,pRow_Value_Constructor_Elem
);
650 throwFunctionSequenceException(*this);
654 void OStatement_Base::SetAssignValue(const OUString
& aColumnName
,
655 const OUString
& aValue
,
657 sal_uInt32 nParameter
)
659 Reference
<XPropertySet
> xCol
;
660 m_xColNames
->getByName(aColumnName
) >>= xCol
;
661 sal_Int32 nId
= Reference
<XColumnLocate
>(m_xColNames
,UNO_QUERY
)->findColumn(aColumnName
);
662 // does this column actually exist in the file?
666 // This Column doesn't exist!
667 throwFunctionSequenceException(*this);
671 // Everything tested and we have the names of the Column.
672 // Now allocate one Value, set the value and tie the value to the Row.
674 (m_aAssignValues
->get())[nId
]->setNull();
677 switch (::comphelper::getINT32(xCol
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE
))))
679 // put criteria depending on the Type as String or double in the variable
681 case DataType::VARCHAR
:
682 case DataType::LONGVARCHAR
:
683 *(m_aAssignValues
->get())[nId
] = ORowSetValue(aValue
);
684 //Characterset is already converted, since the entire statement was converted
688 if (aValue
.equalsIgnoreAsciiCase("TRUE") || aValue
[0] == '1')
689 *(m_aAssignValues
->get())[nId
] = sal_True
;
690 else if (aValue
.equalsIgnoreAsciiCase("FALSE") || aValue
[0] == '0')
691 *(m_aAssignValues
->get())[nId
] = sal_False
;
693 throwFunctionSequenceException(*this);
695 case DataType::TINYINT
:
696 case DataType::SMALLINT
:
697 case DataType::INTEGER
:
698 case DataType::DECIMAL
:
699 case DataType::NUMERIC
:
701 case DataType::DOUBLE
:
704 case DataType::TIMESTAMP
:
705 *(m_aAssignValues
->get())[nId
] = ORowSetValue(aValue
);
708 throwFunctionSequenceException(*this);
712 // save Parameter-No. (as User Data)
713 // SQL_NO_PARAMETER = no Parameter.
714 m_aAssignValues
->setParameterIndex(nId
,nParameter
);
715 if(nParameter
!= SQL_NO_PARAMETER
)
716 m_aParameterIndexes
[nParameter
] = nId
;
719 void OStatement_Base::parseParamterElem(const OUString
& /*_sColumnName*/,OSQLParseNode
* /*pRow_Value_Constructor_Elem*/)
726 }// namespace connectivity
729 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */