summaryrefslogtreecommitdiff
path: root/connectivity/source/drivers/file/fcode.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'connectivity/source/drivers/file/fcode.cxx')
-rw-r--r--connectivity/source/drivers/file/fcode.cxx514
1 files changed, 514 insertions, 0 deletions
diff --git a/connectivity/source/drivers/file/fcode.cxx b/connectivity/source/drivers/file/fcode.cxx
new file mode 100644
index 000000000000..bd408cd28c29
--- /dev/null
+++ b/connectivity/source/drivers/file/fcode.cxx
@@ -0,0 +1,514 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_connectivity.hxx"
+#include "file/fcode.hxx"
+#include <osl/diagnose.h>
+#include "connectivity/sqlparse.hxx"
+#include <i18npool/mslangid.hxx>
+#include <tools/debug.hxx>
+#include <tools/string.hxx>
+#include "TConnection.hxx"
+#include <com/sun/star/sdb/SQLFilterOperator.hpp>
+#include <comphelper/types.hxx>
+#include <com/sun/star/sdb/SQLFilterOperator.hpp>
+#include <rtl/logfile.hxx>
+
+using namespace ::comphelper;
+using namespace connectivity;
+using namespace connectivity::file;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdb;
+
+TYPEINIT0(OCode);
+TYPEINIT1(OOperand, OCode);
+TYPEINIT1(OOperandRow, OOperand);
+TYPEINIT1(OOperandAttr, OOperandRow);
+TYPEINIT1(OOperandParam, OOperandRow);
+TYPEINIT1(OOperandValue, OOperand);
+TYPEINIT1(OOperandConst, OOperandValue);
+TYPEINIT1(OOperandResult, OOperandValue);
+TYPEINIT1(OStopOperand, OOperandValue);
+
+TYPEINIT1(OOperator, OCode);
+TYPEINIT1(OBoolOperator,OOperator);
+TYPEINIT1(OOp_NOT, OBoolOperator);
+TYPEINIT1(OOp_AND, OBoolOperator);
+TYPEINIT1(OOp_OR, OBoolOperator);
+TYPEINIT1(OOp_ISNULL, OBoolOperator);
+TYPEINIT1(OOp_ISNOTNULL, OOp_ISNULL);
+TYPEINIT1(OOp_LIKE, OBoolOperator);
+TYPEINIT1(OOp_NOTLIKE, OOp_LIKE);
+TYPEINIT1(OOp_COMPARE, OBoolOperator);
+TYPEINIT1(ONumOperator, OOperator);
+TYPEINIT1(ONthOperator, OOperator);
+TYPEINIT1(OBinaryOperator, OOperator);
+TYPEINIT1(OUnaryOperator, OOperator);
+
+//------------------------------------------------------------------
+DBG_NAME(OCode )
+OCode::OCode()
+{
+ DBG_CTOR(OCode ,NULL);
+}
+// -----------------------------------------------------------------------------
+OCode::~OCode()
+{
+ DBG_DTOR(OCode,NULL);
+}
+
+//------------------------------------------------------------------
+OEvaluateSet* OOperand::preProcess(OBoolOperator* /*pOp*/, OOperand* /*pRight*/)
+{
+ return NULL;
+}
+// -----------------------------------------------------------------------------
+OOperandRow::OOperandRow(sal_uInt16 _nPos, sal_Int32 _rType)
+ : OOperand(_rType)
+ , m_nRowPos(_nPos)
+{}
+//------------------------------------------------------------------
+void OOperandRow::bindValue(const OValueRefRow& _pRow)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandRow::OOperandRow" );
+ OSL_ENSURE(_pRow.is(),"NO EMPTY row allowed!");
+ m_pRow = _pRow;
+ OSL_ENSURE(m_pRow.is() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()");
+ (m_pRow->get())[m_nRowPos]->setBound(sal_True);
+}
+// -----------------------------------------------------------------------------
+void OOperandRow::setValue(const ORowSetValue& _rVal)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandRow::setValue" );
+ OSL_ENSURE(m_pRow.is() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()");
+ (*(m_pRow->get())[m_nRowPos]) = _rVal;
+}
+//------------------------------------------------------------------
+const ORowSetValue& OOperandRow::getValue() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandRow::getValue" );
+ OSL_ENSURE(m_pRow.is() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()");
+ return (m_pRow->get())[m_nRowPos]->getValue();
+}
+
+// -----------------------------------------------------------------------------
+void OOperandValue::setValue(const ORowSetValue& _rVal)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandValue::setValue" );
+ m_aValue = _rVal;
+}
+// -------------------------------------------------------------------------
+sal_Bool OOperandAttr::isIndexed() const
+{
+ return sal_False;
+}
+//------------------------------------------------------------------
+OOperandParam::OOperandParam(OSQLParseNode* pNode, sal_Int32 _nPos)
+ : OOperandRow(static_cast<sal_uInt16>(_nPos), DataType::VARCHAR) // Standard-Type
+{
+ OSL_ENSURE(SQL_ISRULE(pNode,parameter),"Argument ist kein Parameter");
+ OSL_ENSURE(pNode->count() > 0,"Fehler im Parse Tree");
+ OSQLParseNode *pMark = pNode->getChild(0);
+
+ String aParameterName;
+ if (SQL_ISPUNCTUATION(pMark,"?"))
+ aParameterName = '?';
+ else if (SQL_ISPUNCTUATION(pMark,":"))
+ aParameterName = pNode->getChild(1)->getTokenValue();
+ else
+ {
+ OSL_FAIL("Fehler im Parse Tree");
+ }
+
+ // set up Parameter-Column with default type, can be specified more precisely later using Describe-Parameter
+
+ // save Identity (not escpecially necessary here, just for the sake of symmetry)
+
+ // todo
+ // OColumn* pColumn = new OFILEColumn(aParameterName,eDBType,255,0,SQL_FLAGS_NULLALLOWED);
+ // rParamColumns->AddColumn(pColumn);
+
+ // the value will be set just before the evaluation
+}
+
+
+//------------------------------------------------------------------
+const ORowSetValue& OOperandValue::getValue() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandValue::getValue" );
+ return m_aValue;
+}
+
+//------------------------------------------------------------------
+OOperandConst::OOperandConst(const OSQLParseNode& rColumnRef, const rtl::OUString& aStrValue)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandConst::OOperandConst" );
+ switch (rColumnRef.getNodeType())
+ {
+ case SQL_NODE_STRING:
+ m_aValue = aStrValue;
+ m_eDBType = DataType::VARCHAR;
+ m_aValue.setBound(sal_True);
+ return;
+ case SQL_NODE_INTNUM:
+ case SQL_NODE_APPROXNUM:
+ {
+ m_aValue = aStrValue.toDouble();
+ m_eDBType = DataType::DOUBLE;
+ m_aValue.setBound(sal_True);
+ return;
+ }
+ default:
+ break;
+ }
+
+ if (SQL_ISTOKEN(&rColumnRef,TRUE))
+ {
+ m_aValue = 1.0;
+ m_eDBType = DataType::BIT;
+ }
+ else if (SQL_ISTOKEN(&rColumnRef,FALSE))
+ {
+ m_aValue = 0.0;
+ m_eDBType = DataType::BIT;
+ }
+ else
+ {
+ OSL_FAIL("Parse Error");
+ }
+ m_aValue.setBound(sal_True);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Implementation of the operators
+
+//------------------------------------------------------------------
+sal_uInt16 OOperator::getRequestedOperands() const {return 2;}
+
+//------------------------------------------------------------------
+sal_Bool OBoolOperator::operate(const OOperand*, const OOperand*) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OBoolOperator::operate" );
+ return sal_False;
+}
+
+
+//------------------------------------------------------------------
+void OBoolOperator::Exec(OCodeStack& rCodeStack)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OBoolOperator::Exec" );
+ OOperand *pRight = rCodeStack.top();
+ rCodeStack.pop();
+ OOperand *pLeft = rCodeStack.top();
+ rCodeStack.pop();
+
+ rCodeStack.push(new OOperandResultBOOL(operate(pLeft, pRight)));
+ if (IS_TYPE(OOperandResult,pLeft))
+ delete pLeft;
+ if (IS_TYPE(OOperandResult,pRight))
+ delete pRight;
+}
+//------------------------------------------------------------------
+sal_Bool OOp_NOT::operate(const OOperand* pLeft, const OOperand* ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_AND::operate" );
+ return !pLeft->isValid();
+}
+//------------------------------------------------------------------
+void OOp_NOT::Exec(OCodeStack& rCodeStack)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::Exec" );
+ OOperand* pOperand = rCodeStack.top();
+ rCodeStack.pop();
+
+ rCodeStack.push(new OOperandResultBOOL(operate(pOperand)));
+ if (IS_TYPE(OOperandResult,pOperand))
+ delete pOperand;
+}
+//------------------------------------------------------------------
+sal_uInt16 OOp_NOT::getRequestedOperands() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_NOT::getRequestedOperands" );
+ return 1;
+}
+
+//------------------------------------------------------------------
+sal_Bool OOp_AND::operate(const OOperand* pLeft, const OOperand* pRight) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_AND::operate" );
+ return pLeft->isValid() && pRight->isValid();
+}
+
+//------------------------------------------------------------------
+sal_Bool OOp_OR::operate(const OOperand* pLeft, const OOperand* pRight) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_OR::operate" );
+ return pLeft->isValid() || pRight->isValid();
+}
+
+//------------------------------------------------------------------
+sal_uInt16 OOp_ISNULL::getRequestedOperands() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::getRequestedOperands" );
+ return 1;
+}
+
+//------------------------------------------------------------------
+void OOp_ISNULL::Exec(OCodeStack& rCodeStack)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::Exec" );
+ OOperand* pOperand = rCodeStack.top();
+ rCodeStack.pop();
+
+ rCodeStack.push(new OOperandResultBOOL(operate(pOperand)));
+ if (IS_TYPE(OOperandResult,pOperand))
+ delete pOperand;
+}
+
+//------------------------------------------------------------------
+sal_Bool OOp_ISNULL::operate(const OOperand* pOperand, const OOperand*) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::operate" );
+ return pOperand->getValue().isNull();
+}
+
+//------------------------------------------------------------------
+sal_Bool OOp_ISNOTNULL::operate(const OOperand* pOperand, const OOperand*) const
+{
+ return !OOp_ISNULL::operate(pOperand);
+}
+
+//------------------------------------------------------------------
+sal_Bool OOp_LIKE::operate(const OOperand* pLeft, const OOperand* pRight) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::operate" );
+ sal_Bool bMatch;
+ ORowSetValue aLH(pLeft->getValue());
+ ORowSetValue aRH(pRight->getValue());
+
+ if (aLH.isNull() || aRH.isNull())
+ bMatch = sal_False;
+ else
+ {
+ bMatch = match(aRH.getString(), aLH.getString(), cEscape);
+ }
+ return bMatch;
+}
+
+//------------------------------------------------------------------
+sal_Bool OOp_NOTLIKE::operate(const OOperand* pLeft, const OOperand* pRight) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_NOTLIKE::operate" );
+ return !OOp_LIKE::operate(pLeft, pRight);
+}
+
+//------------------------------------------------------------------
+sal_Bool OOp_COMPARE::operate(const OOperand* pLeft, const OOperand* pRight) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_COMPARE::operate" );
+ ORowSetValue aLH(pLeft->getValue());
+ ORowSetValue aRH(pRight->getValue());
+
+ if (aLH.isNull() || aRH.isNull()) // if (!aLH.getValue() || !aRH.getValue())
+ return sal_False;
+
+ sal_Bool bResult = sal_False;
+ sal_Int32 eDBType = pLeft->getDBType();
+
+ // Comparison (depending on Data-type):
+ switch (eDBType)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ {
+ rtl::OUString sLH = aLH, sRH = aRH;
+ sal_Int32 nRes = rtl_ustr_compareIgnoreAsciiCase_WithLength
+ (
+ sLH.pData->buffer,
+ sLH.pData->length,
+ sRH.pData->buffer,
+ sRH.pData->length );
+ switch(aPredicateType)
+ {
+ case SQLFilterOperator::EQUAL: bResult = (nRes == 0); break;
+ case SQLFilterOperator::NOT_EQUAL: bResult = (nRes != 0); break;
+ case SQLFilterOperator::LESS: bResult = (nRes < 0); break;
+ case SQLFilterOperator::LESS_EQUAL: bResult = (nRes <= 0); break;
+ case SQLFilterOperator::GREATER: bResult = (nRes > 0); break;
+ case SQLFilterOperator::GREATER_EQUAL: bResult = (nRes >= 0); break;
+ default: bResult = sal_False;
+ }
+ } break;
+ case DataType::TINYINT:
+ case DataType::SMALLINT:
+ case DataType::INTEGER:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::REAL:
+ case DataType::DOUBLE:
+ case DataType::BIT:
+ case DataType::TIMESTAMP:
+ case DataType::DATE:
+ case DataType::TIME:
+ {
+ double n = aLH ,m = aRH;
+
+ switch (aPredicateType)
+ {
+ case SQLFilterOperator::EQUAL: bResult = (n == m); break;
+ case SQLFilterOperator::LIKE: bResult = (n == m); break;
+ case SQLFilterOperator::NOT_EQUAL: bResult = (n != m); break;
+ case SQLFilterOperator::NOT_LIKE: bResult = (n != m); break;
+ case SQLFilterOperator::LESS: bResult = (n < m); break;
+ case SQLFilterOperator::LESS_EQUAL: bResult = (n <= m); break;
+ case SQLFilterOperator::GREATER: bResult = (n > m); break;
+ case SQLFilterOperator::GREATER_EQUAL: bResult = (n >= m); break;
+ default: bResult = sal_False;
+ }
+ } break;
+ default:
+ bResult = aLH == aRH;
+ }
+ return bResult;
+}
+
+//------------------------------------------------------------------
+void ONumOperator::Exec(OCodeStack& rCodeStack)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "ONumOperator::Exec" );
+
+ OOperand *pRight = rCodeStack.top();
+ rCodeStack.pop();
+ OOperand *pLeft = rCodeStack.top();
+ rCodeStack.pop();
+
+ rCodeStack.push(new OOperandResultNUM(operate(pLeft->getValue(), pRight->getValue())));
+ if (IS_TYPE(OOperandResult,pLeft))
+ delete pLeft;
+ if (IS_TYPE(OOperandResult,pRight))
+ delete pRight;
+}
+//------------------------------------------------------------------
+double OOp_ADD::operate(const double& fLeft,const double& fRight) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ADD::operate" );
+ return fLeft + fRight;
+}
+
+//------------------------------------------------------------------
+double OOp_SUB::operate(const double& fLeft,const double& fRight) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_SUB::operate" );
+ return fLeft - fRight;
+}
+
+//------------------------------------------------------------------
+double OOp_MUL::operate(const double& fLeft,const double& fRight) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_MUL::operate" );
+ return fLeft * fRight;
+}
+
+//------------------------------------------------------------------
+double OOp_DIV::operate(const double& fLeft,const double& fRight) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_DIV::operate" );
+ return fLeft / fRight;
+}
+// -----------------------------------------------------------------------------
+OEvaluateSet* OOperandAttr::preProcess(OBoolOperator* /*pOp*/, OOperand* /*pRight*/)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandAttr::preProcess" );
+ return NULL;
+}
+//------------------------------------------------------------------
+void ONthOperator::Exec(OCodeStack& rCodeStack)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "ONthOperator::Exec" );
+ ::std::vector<ORowSetValue> aValues;
+ ::std::vector<OOperand*> aOperands;
+ OOperand* pOperand;
+ do
+ {
+ OSL_ENSURE(!rCodeStack.empty(),"Stack must be none empty!");
+ pOperand = rCodeStack.top();
+ rCodeStack.pop();
+ if ( !IS_TYPE(OStopOperand,pOperand) )
+ aValues.push_back( pOperand->getValue() );
+ aOperands.push_back( pOperand );
+ }
+ while ( !IS_TYPE(OStopOperand,pOperand) );
+
+ rCodeStack.push(new OOperandResult(operate(aValues)));
+
+ ::std::vector<OOperand*>::iterator aIter = aOperands.begin();
+ ::std::vector<OOperand*>::iterator aEnd = aOperands.end();
+ for (; aIter != aEnd; ++aIter)
+ {
+ if (IS_TYPE(OOperandResult,*aIter))
+ delete *aIter;
+ }
+}
+//------------------------------------------------------------------
+void OBinaryOperator::Exec(OCodeStack& rCodeStack)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OBinaryOperator::Exec" );
+ OOperand *pRight = rCodeStack.top();
+ rCodeStack.pop();
+ OOperand *pLeft = rCodeStack.top();
+ rCodeStack.pop();
+
+ if ( !rCodeStack.empty() && IS_TYPE(OStopOperand,rCodeStack.top()) )
+ rCodeStack.pop();
+
+ rCodeStack.push(new OOperandResult(operate(pLeft->getValue(),pRight->getValue())));
+ if (IS_TYPE(OOperandResult,pRight))
+ delete pRight;
+ if (IS_TYPE(OOperandResult,pLeft))
+ delete pLeft;
+}
+//------------------------------------------------------------------
+void OUnaryOperator::Exec(OCodeStack& rCodeStack)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OUnaryOperator::Exec" );
+ OSL_ENSURE(!rCodeStack.empty(),"Stack is empty!");
+ OOperand* pOperand = rCodeStack.top();
+ rCodeStack.pop();
+
+ rCodeStack.push(new OOperandResult(operate(pOperand->getValue())));
+ if (IS_TYPE(OOperandResult,pOperand))
+ delete pOperand;
+}
+// -----------------------------------------------------------------------------
+sal_uInt16 OUnaryOperator::getRequestedOperands() const {return 1;}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */