update dev300-m58
[ooovba.git] / connectivity / source / drivers / file / fcode.cxx
blob1793cf58e3c8de4c57eb591bc45cb99e1cb2dabf
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fcode.cxx,v $
10 * $Revision: 1.31 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #include "file/fcode.hxx"
34 #include <osl/diagnose.h>
35 #include "connectivity/sqlparse.hxx"
36 #include <i18npool/mslangid.hxx>
37 #include <vcl/svapp.hxx>
38 #include <tools/debug.hxx>
39 #include "TConnection.hxx"
40 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
41 #include <comphelper/types.hxx>
42 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
43 #include <rtl/logfile.hxx>
45 using namespace ::comphelper;
46 using namespace connectivity;
47 using namespace connectivity::file;
48 //using namespace ::com::sun::star::uno;
49 //using namespace ::com::sun::star::lang;
50 using namespace ::com::sun::star::sdbc;
51 using namespace ::com::sun::star::sdb;
52 //using namespace ::com::sun::star::container;
53 //using namespace ::com::sun::star::beans;
54 //using namespace ::com::sun::star::sdbcx;
56 TYPEINIT0(OCode);
57 TYPEINIT1(OOperand, OCode);
58 TYPEINIT1(OOperandRow, OOperand);
59 TYPEINIT1(OOperandAttr, OOperandRow);
60 TYPEINIT1(OOperandParam, OOperandRow);
61 TYPEINIT1(OOperandValue, OOperand);
62 TYPEINIT1(OOperandConst, OOperandValue);
63 TYPEINIT1(OOperandResult, OOperandValue);
64 TYPEINIT1(OStopOperand, OOperandValue);
66 TYPEINIT1(OOperator, OCode);
67 TYPEINIT1(OBoolOperator,OOperator);
68 TYPEINIT1(OOp_NOT, OBoolOperator);
69 TYPEINIT1(OOp_AND, OBoolOperator);
70 TYPEINIT1(OOp_OR, OBoolOperator);
71 TYPEINIT1(OOp_ISNULL, OBoolOperator);
72 TYPEINIT1(OOp_ISNOTNULL, OOp_ISNULL);
73 TYPEINIT1(OOp_LIKE, OBoolOperator);
74 TYPEINIT1(OOp_NOTLIKE, OOp_LIKE);
75 TYPEINIT1(OOp_COMPARE, OBoolOperator);
76 TYPEINIT1(ONumOperator, OOperator);
77 TYPEINIT1(ONthOperator, OOperator);
78 TYPEINIT1(OBinaryOperator, OOperator);
79 TYPEINIT1(OUnaryOperator, OOperator);
81 //------------------------------------------------------------------
82 DBG_NAME(OCode )
83 OCode::OCode()
85 DBG_CTOR(OCode ,NULL);
87 // -----------------------------------------------------------------------------
88 OCode::~OCode()
90 DBG_DTOR(OCode,NULL);
93 //------------------------------------------------------------------
94 OEvaluateSet* OOperand::preProcess(OBoolOperator* /*pOp*/, OOperand* /*pRight*/)
96 return NULL;
98 // -----------------------------------------------------------------------------
99 OOperandRow::OOperandRow(sal_uInt16 _nPos, sal_Int32 _rType)
100 : OOperand(_rType)
101 , m_nRowPos(_nPos)
103 //------------------------------------------------------------------
104 void OOperandRow::bindValue(const OValueRefRow& _pRow)
106 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandRow::OOperandRow" );
107 OSL_ENSURE(_pRow.isValid(),"NO EMPTY row allowed!");
108 m_pRow = _pRow;
109 OSL_ENSURE(m_pRow.isValid() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()");
110 (m_pRow->get())[m_nRowPos]->setBound(sal_True);
112 // -----------------------------------------------------------------------------
113 void OOperandRow::setValue(const ORowSetValue& _rVal)
115 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandRow::setValue" );
116 OSL_ENSURE(m_pRow.isValid() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()");
117 (*(m_pRow->get())[m_nRowPos]) = _rVal;
119 //------------------------------------------------------------------
120 const ORowSetValue& OOperandRow::getValue() const
122 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandRow::getValue" );
123 OSL_ENSURE(m_pRow.isValid() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()");
124 return (m_pRow->get())[m_nRowPos]->getValue();
127 // -----------------------------------------------------------------------------
128 void OOperandValue::setValue(const ORowSetValue& _rVal)
130 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandValue::setValue" );
131 m_aValue = _rVal;
133 // -------------------------------------------------------------------------
134 sal_Bool OOperandAttr::isIndexed() const
136 return sal_False;
138 //------------------------------------------------------------------
139 OOperandParam::OOperandParam(OSQLParseNode* pNode, sal_Int32 _nPos)
140 : OOperandRow(static_cast<sal_uInt16>(_nPos), DataType::VARCHAR) // Standard-Typ
142 OSL_ENSURE(SQL_ISRULE(pNode,parameter),"Argument ist kein Parameter");
143 OSL_ENSURE(pNode->count() > 0,"Fehler im Parse Tree");
144 OSQLParseNode *pMark = pNode->getChild(0);
146 String aParameterName;
147 if (SQL_ISPUNCTUATION(pMark,"?"))
148 aParameterName = '?';
149 else if (SQL_ISPUNCTUATION(pMark,":"))
150 aParameterName = pNode->getChild(1)->getTokenValue();
151 else
153 OSL_ASSERT("Fehler im Parse Tree");
156 // Parameter-Column aufsetzen mit defult typ, kann zu einem spaeteren Zeitpunkt ueber DescribeParameter
157 // genauer spezifiziert werden
159 // Identitaet merken (hier eigentlich nicht erforderlich, aber aus
160 // Symmetriegruenden ...)
162 // todo
163 // OColumn* pColumn = new OFILEColumn(aParameterName,eDBType,255,0,SQL_FLAGS_NULLALLOWED);
164 // rParamColumns->AddColumn(pColumn);
166 // der Wert wird erst kurz vor der Auswertung gesetzt
170 //------------------------------------------------------------------
171 const ORowSetValue& OOperandValue::getValue() const
173 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandValue::getValue" );
174 return m_aValue;
177 //------------------------------------------------------------------
178 OOperandConst::OOperandConst(const OSQLParseNode& rColumnRef, const rtl::OUString& aStrValue)
180 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandConst::OOperandConst" );
181 switch (rColumnRef.getNodeType())
183 case SQL_NODE_STRING:
184 m_aValue = aStrValue;
185 m_eDBType = DataType::VARCHAR;
186 m_aValue.setBound(sal_True);
187 return;
188 case SQL_NODE_INTNUM:
189 case SQL_NODE_APPROXNUM:
191 m_aValue = aStrValue.toDouble();
192 m_eDBType = DataType::DOUBLE;
193 m_aValue.setBound(sal_True);
194 return;
196 default:
197 break;
200 if (SQL_ISTOKEN(&rColumnRef,TRUE))
202 m_aValue = 1.0;
203 m_eDBType = DataType::BIT;
205 else if (SQL_ISTOKEN(&rColumnRef,FALSE))
207 m_aValue = 0.0;
208 m_eDBType = DataType::BIT;
210 else
212 OSL_ASSERT("Parse Error");
214 m_aValue.setBound(sal_True);
217 /////////////////////////////////////////////////////////////////////////////////////////
218 // Implementation of the operators
220 //------------------------------------------------------------------
221 sal_uInt16 OOperator::getRequestedOperands() const {return 2;}
223 //------------------------------------------------------------------
224 sal_Bool OBoolOperator::operate(const OOperand*, const OOperand*) const
226 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OBoolOperator::operate" );
227 return sal_False;
231 //------------------------------------------------------------------
232 void OBoolOperator::Exec(OCodeStack& rCodeStack)
234 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OBoolOperator::Exec" );
235 OOperand *pRight = rCodeStack.top();
236 rCodeStack.pop();
237 OOperand *pLeft = rCodeStack.top();
238 rCodeStack.pop();
240 rCodeStack.push(new OOperandResultBOOL(operate(pLeft, pRight)));
241 if (IS_TYPE(OOperandResult,pLeft))
242 delete pLeft;
243 if (IS_TYPE(OOperandResult,pRight))
244 delete pRight;
246 //------------------------------------------------------------------
247 sal_Bool OOp_NOT::operate(const OOperand* pLeft, const OOperand* ) const
249 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_AND::operate" );
250 return !pLeft->isValid();
252 //------------------------------------------------------------------
253 void OOp_NOT::Exec(OCodeStack& rCodeStack)
255 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::Exec" );
256 OOperand* pOperand = rCodeStack.top();
257 rCodeStack.pop();
259 rCodeStack.push(new OOperandResultBOOL(operate(pOperand)));
260 if (IS_TYPE(OOperandResult,pOperand))
261 delete pOperand;
263 //------------------------------------------------------------------
264 sal_uInt16 OOp_NOT::getRequestedOperands() const
266 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_NOT::getRequestedOperands" );
267 return 1;
270 //------------------------------------------------------------------
271 sal_Bool OOp_AND::operate(const OOperand* pLeft, const OOperand* pRight) const
273 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_AND::operate" );
274 return pLeft->isValid() && pRight->isValid();
277 //------------------------------------------------------------------
278 sal_Bool OOp_OR::operate(const OOperand* pLeft, const OOperand* pRight) const
280 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_OR::operate" );
281 return pLeft->isValid() || pRight->isValid();
284 //------------------------------------------------------------------
285 sal_uInt16 OOp_ISNULL::getRequestedOperands() const
287 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::getRequestedOperands" );
288 return 1;
291 //------------------------------------------------------------------
292 void OOp_ISNULL::Exec(OCodeStack& rCodeStack)
294 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::Exec" );
295 OOperand* pOperand = rCodeStack.top();
296 rCodeStack.pop();
298 rCodeStack.push(new OOperandResultBOOL(operate(pOperand)));
299 if (IS_TYPE(OOperandResult,pOperand))
300 delete pOperand;
303 //------------------------------------------------------------------
304 sal_Bool OOp_ISNULL::operate(const OOperand* pOperand, const OOperand*) const
306 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::operate" );
307 return pOperand->getValue().isNull();
310 //------------------------------------------------------------------
311 sal_Bool OOp_ISNOTNULL::operate(const OOperand* pOperand, const OOperand*) const
313 return !OOp_ISNULL::operate(pOperand);
316 //------------------------------------------------------------------
317 sal_Bool OOp_LIKE::operate(const OOperand* pLeft, const OOperand* pRight) const
319 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::operate" );
320 sal_Bool bMatch;
321 ORowSetValue aLH(pLeft->getValue());
322 ORowSetValue aRH(pRight->getValue());
324 if (aLH.isNull() || aRH.isNull())
325 bMatch = sal_False;
326 else
328 bMatch = match(aRH.getString(), aLH.getString(), cEscape);
330 return bMatch;
333 //------------------------------------------------------------------
334 sal_Bool OOp_NOTLIKE::operate(const OOperand* pLeft, const OOperand* pRight) const
336 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_NOTLIKE::operate" );
337 return !OOp_LIKE::operate(pLeft, pRight);
340 //------------------------------------------------------------------
341 sal_Bool OOp_COMPARE::operate(const OOperand* pLeft, const OOperand* pRight) const
343 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_COMPARE::operate" );
344 ORowSetValue aLH(pLeft->getValue());
345 ORowSetValue aRH(pRight->getValue());
347 if (aLH.isNull() || aRH.isNull()) // if (!aLH.getValue() || !aRH.getValue())
348 return sal_False;
350 sal_Bool bResult = sal_False;
351 sal_Int32 eDBType = pLeft->getDBType();
353 // Vergleich (je nach Datentyp):
354 switch (eDBType)
356 case DataType::CHAR:
357 case DataType::VARCHAR:
358 case DataType::LONGVARCHAR:
360 rtl::OUString sLH = aLH, sRH = aRH;
361 INT32 nRes = rtl_ustr_compareIgnoreAsciiCase_WithLength
363 sLH.pData->buffer,
364 sLH.pData->length,
365 sRH.pData->buffer,
366 sRH.pData->length );
367 switch(aPredicateType)
369 case SQLFilterOperator::EQUAL: bResult = (nRes == 0); break;
370 case SQLFilterOperator::NOT_EQUAL: bResult = (nRes != 0); break;
371 case SQLFilterOperator::LESS: bResult = (nRes < 0); break;
372 case SQLFilterOperator::LESS_EQUAL: bResult = (nRes <= 0); break;
373 case SQLFilterOperator::GREATER: bResult = (nRes > 0); break;
374 case SQLFilterOperator::GREATER_EQUAL: bResult = (nRes >= 0); break;
375 default: bResult = sal_False;
377 } break;
378 case DataType::TINYINT:
379 case DataType::SMALLINT:
380 case DataType::INTEGER:
381 case DataType::DECIMAL:
382 case DataType::NUMERIC:
383 case DataType::REAL:
384 case DataType::DOUBLE:
385 case DataType::BIT:
386 case DataType::TIMESTAMP:
387 case DataType::DATE:
388 case DataType::TIME:
390 double n = aLH ,m = aRH;
392 switch (aPredicateType)
394 case SQLFilterOperator::EQUAL: bResult = (n == m); break;
395 case SQLFilterOperator::LIKE: bResult = (n == m); break;
396 case SQLFilterOperator::NOT_EQUAL: bResult = (n != m); break;
397 case SQLFilterOperator::NOT_LIKE: bResult = (n != m); break;
398 case SQLFilterOperator::LESS: bResult = (n < m); break;
399 case SQLFilterOperator::LESS_EQUAL: bResult = (n <= m); break;
400 case SQLFilterOperator::GREATER: bResult = (n > m); break;
401 case SQLFilterOperator::GREATER_EQUAL: bResult = (n >= m); break;
402 default: bResult = sal_False;
404 } break;
405 default:
406 bResult = aLH == aRH;
408 return bResult;
411 //------------------------------------------------------------------
412 void ONumOperator::Exec(OCodeStack& rCodeStack)
414 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "ONumOperator::Exec" );
416 OOperand *pRight = rCodeStack.top();
417 rCodeStack.pop();
418 OOperand *pLeft = rCodeStack.top();
419 rCodeStack.pop();
421 rCodeStack.push(new OOperandResultNUM(operate(pLeft->getValue(), pRight->getValue())));
422 if (IS_TYPE(OOperandResult,pLeft))
423 delete pLeft;
424 if (IS_TYPE(OOperandResult,pRight))
425 delete pRight;
427 //------------------------------------------------------------------
428 double OOp_ADD::operate(const double& fLeft,const double& fRight) const
430 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ADD::operate" );
431 return fLeft + fRight;
434 //------------------------------------------------------------------
435 double OOp_SUB::operate(const double& fLeft,const double& fRight) const
437 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_SUB::operate" );
438 return fLeft - fRight;
441 //------------------------------------------------------------------
442 double OOp_MUL::operate(const double& fLeft,const double& fRight) const
444 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_MUL::operate" );
445 return fLeft * fRight;
448 //------------------------------------------------------------------
449 double OOp_DIV::operate(const double& fLeft,const double& fRight) const
451 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_DIV::operate" );
452 return fLeft / fRight;
454 // -----------------------------------------------------------------------------
455 OEvaluateSet* OOperandAttr::preProcess(OBoolOperator* /*pOp*/, OOperand* /*pRight*/)
457 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandAttr::preProcess" );
458 return NULL;
460 //------------------------------------------------------------------
461 void ONthOperator::Exec(OCodeStack& rCodeStack)
463 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "ONthOperator::Exec" );
464 ::std::vector<ORowSetValue> aValues;
465 ::std::vector<OOperand*> aOperands;
466 OOperand* pOperand;
469 OSL_ENSURE(!rCodeStack.empty(),"Stack must be none empty!");
470 pOperand = rCodeStack.top();
471 rCodeStack.pop();
472 if ( !IS_TYPE(OStopOperand,pOperand) )
473 aValues.push_back( pOperand->getValue() );
474 aOperands.push_back( pOperand );
476 while ( !IS_TYPE(OStopOperand,pOperand) );
478 rCodeStack.push(new OOperandResult(operate(aValues)));
480 ::std::vector<OOperand*>::iterator aIter = aOperands.begin();
481 ::std::vector<OOperand*>::iterator aEnd = aOperands.end();
482 for (; aIter != aEnd; ++aIter)
484 if (IS_TYPE(OOperandResult,*aIter))
485 delete *aIter;
488 //------------------------------------------------------------------
489 void OBinaryOperator::Exec(OCodeStack& rCodeStack)
491 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OBinaryOperator::Exec" );
492 OOperand *pRight = rCodeStack.top();
493 rCodeStack.pop();
494 OOperand *pLeft = rCodeStack.top();
495 rCodeStack.pop();
497 if ( !rCodeStack.empty() && IS_TYPE(OStopOperand,rCodeStack.top()) )
498 rCodeStack.pop();
500 rCodeStack.push(new OOperandResult(operate(pLeft->getValue(),pRight->getValue())));
501 if (IS_TYPE(OOperandResult,pRight))
502 delete pRight;
503 if (IS_TYPE(OOperandResult,pLeft))
504 delete pLeft;
506 //------------------------------------------------------------------
507 void OUnaryOperator::Exec(OCodeStack& rCodeStack)
509 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OUnaryOperator::Exec" );
510 OSL_ENSURE(!rCodeStack.empty(),"Stack is empty!");
511 OOperand* pOperand = rCodeStack.top();
512 rCodeStack.pop();
514 rCodeStack.push(new OOperandResult(operate(pOperand->getValue())));
515 if (IS_TYPE(OOperandResult,pOperand))
516 delete pOperand;
518 // -----------------------------------------------------------------------------
519 sal_uInt16 OUnaryOperator::getRequestedOperands() const {return 1;}