/************************************************************************* * * $RCSfile: sqlnode.cxx,v $ * * $Revision: 1.3 $ * * last change: $Author: oj $ $Date: 2000-09-29 15:13:06 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses * * - GNU Lesser General Public License Version 2.1 * - Sun Industry Standards Source License Version 1.1 * * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2000 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library 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 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * * Sun Industry Standards Source License Version 1.1 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.1 (the "License"); You may not use this file * except in compliance with the License. You may obtain a copy of the * License at http://www.openoffice.org/license.html. * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc. * * Copyright: 2000 by Sun Microsystems, Inc. * * All Rights Reserved. * * Contributor(s): _______________________________________ * * ************************************************************************/ #ifndef _CONNECTIVITY_SQLNODE_HXX #include #endif #ifndef _CONNECTIVITY_SQLPARSE_HXX #include #endif #ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_ #include #endif #ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_ #include #endif #ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTYPES_HPP_ #include #endif #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_ #include #endif #ifndef _TOOLS_INTN_HXX //autogen wg. International #include #endif #ifndef _ISOLANG_HXX #include #endif #ifndef __SGI_STL_ROPE #include #endif using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::util; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; using namespace ::osl; using namespace connectivity; extern Any getNumberFormatProperty(const Reference< XNumberFormatsSupplier > & xFormatter, sal_Int32 nKey, const rtl::OUString& ); extern double ToDouble(const Time& rTime); extern double ToDouble(const Reference< XNumberFormatsSupplier > & xSupplier, const Date& rDate); extern String ConvertLikeToken(const OSQLParseNode* pTokenNode, const OSQLParseNode* pEscapeNode, sal_Bool bInternational); //------------------------------------------------------------------ OSQLParseNode::SQLParseNodeParameter::SQLParseNodeParameter(const String& _rIdentifierQuote, const String& _rCatalogSep, const Reference< XNumberFormatter > & _xFormatter, const Reference< XPropertySet > & _xField, const International& _rIntl, const OParseContext* _pContext, sal_Bool _bIntl, sal_Bool _bQuote, char _cDecSep, sal_Bool _bPredicate) :aIdentifierQuote(_rIdentifierQuote) ,aCatalogSeparator(_rCatalogSep) ,rIntl(_rIntl) ,rContext(_pContext ? *_pContext : OSQLParser::s_aDefaultContext) ,bInternational(_bIntl) ,bQuote(_bQuote) ,cDecSep(_cDecSep) ,xField(_xField) ,xFormatter(_xFormatter) ,bPredicate(_bPredicate) { } //------------------------------------------------------------------ String SetQuotation(const String& rValue, const String& rQuot, const String& rQuotToReplace) { String rNewValue = rQuot; rNewValue += rValue; xub_StrLen nIndex = (xub_StrLen)-1; // Quotes durch zweifache Quotes ersetzen, sonst kriegt der Parser Probleme if (rQuot.Len()) { do { nIndex+= 2; nIndex = rNewValue.SearchAndReplace(rQuot,rQuotToReplace,nIndex); } while (nIndex != STRING_NOTFOUND); } // rNewValue.SearchAndReplaceAll(rQuot,rQuotToReplace); rNewValue += rQuot; return rNewValue; } //----------------------------------------------------------------------------- String OSQLParseNode::convertDateString(const SQLParseNodeParameter& rParam, const String& rString) const { xub_StrLen nIndex = 0; sal_Int32 nYear = rString.GetToken(0,'-', nIndex).ToInt32(), nMonth = rString.GetToken(0,'-', nIndex).ToInt32(), nDay = rString.GetToken(0,'-', nIndex).ToInt32(); Date aDate(nDay,nMonth,nYear); Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier()); Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY); String sLanguage, sCountry; ConvertLanguageToIsoNames(rParam.rIntl.GetLanguage(), sLanguage, sCountry); Locale aLocale(sLanguage,sCountry,rtl::OUString()); double fDate = ToDouble(xSupplier, aDate); sal_Int32 nKey = xTypes->getStandardIndex(aLocale) + 36; // XXX hack return rParam.xFormatter->convertNumberToString(nKey, fDate); } //----------------------------------------------------------------------------- String OSQLParseNode::convertDateTimeString(const SQLParseNodeParameter& rParam, const String& rString) const { xub_StrLen nIndex = 0; sal_Int32 nYear = rString.GetToken(0,'-', nIndex).ToInt32(), nMonth = rString.GetToken(0,'-', nIndex).ToInt32(), nDay = rString.GetToken(0,'-', nIndex).ToInt32(); nIndex = 10; // eat white space sal_Int32 nHour = rString.GetToken(0,':', nIndex).ToInt32(), nMinute = rString.GetToken(0,':', nIndex).ToInt32(), nSecond = rString.GetToken(0,':', nIndex).ToInt32(); Date aDate(nDay,nMonth,nYear); Time aTime(nHour,nMinute,nSecond); Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier()); Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY); String sLanguage, sCountry; ConvertLanguageToIsoNames(rParam.rIntl.GetLanguage(), sLanguage, sCountry); Locale aLocale(sLanguage,sCountry,rtl::OUString()); double fDateTime = ToDouble(xSupplier, aDate) + ToDouble(aTime); sal_Int32 nKey = xTypes->getStandardIndex(aLocale) + 51; // XXX hack return rParam.xFormatter->convertNumberToString(nKey, fDateTime); } //----------------------------------------------------------------------------- String OSQLParseNode::convertTimeString(const SQLParseNodeParameter& rParam, const String& rString) const { xub_StrLen nIndex = 0; sal_Int32 nHour = rString.GetToken(0,':', nIndex).ToInt32(), nMinute = rString.GetToken(0,':', nIndex).ToInt32(), nSecond = rString.GetToken(0,':', nIndex).ToInt32(); Time aTime(nHour,nMinute,nSecond); Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier()); Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY); String sLanguage, sCountry; ConvertLanguageToIsoNames(rParam.rIntl.GetLanguage(), sLanguage, sCountry); Locale aLocale(sLanguage,sCountry,rtl::OUString()); double fTime = ToDouble(aTime); sal_Int32 nKey = xTypes->getStandardIndex(aLocale) + 41; // XXX hack return rParam.xFormatter->convertNumberToString(nKey, fTime); } DBG_NAME(OSQLParseNode); //----------------------------------------------------------------------------- OSQLParseNode::OSQLParseNode(const sal_Char * pNewValue, SQLNodeType eNewNodeType, sal_uInt32 nNewNodeID) : m_aNodeValue(String::CreateFromAscii(pNewValue)) , m_eNodeType(eNewNodeType) , m_nNodeID(nNewNodeID) , m_pParent(NULL) { DBG_CTOR(OSQLParseNode,NULL); DBG_ASSERT(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_ACCESS_DATE,"OSQLParseNode: mit unzulaessigem NodeType konstruiert"); } //----------------------------------------------------------------------------- OSQLParseNode::OSQLParseNode(const ByteString &_rNewValue, SQLNodeType eNewNodeType, sal_uInt32 nNewNodeID) : m_aNodeValue(String::CreateFromAscii(_rNewValue.GetBuffer())) , m_eNodeType(eNewNodeType) , m_nNodeID(nNewNodeID) , m_pParent(NULL) { DBG_CTOR(OSQLParseNode,NULL); DBG_ASSERT(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_ACCESS_DATE,"OSQLParseNode: mit unzulaessigem NodeType konstruiert"); } //----------------------------------------------------------------------------- OSQLParseNode::OSQLParseNode(const sal_Unicode * pNewValue, SQLNodeType eNewNodeType, sal_uInt32 nNewNodeID) : m_aNodeValue(pNewValue) , m_eNodeType(eNewNodeType) , m_nNodeID(nNewNodeID) , m_pParent(NULL) { DBG_CTOR(OSQLParseNode,NULL); DBG_ASSERT(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_ACCESS_DATE,"OSQLParseNode: mit unzulaessigem NodeType konstruiert"); } //----------------------------------------------------------------------------- OSQLParseNode::OSQLParseNode(const String &_rNewValue, SQLNodeType eNewNodeType, sal_uInt32 nNewNodeID) : m_aNodeValue(_rNewValue) , m_eNodeType(eNewNodeType) , m_nNodeID(nNewNodeID) , m_pParent(NULL) { DBG_CTOR(OSQLParseNode,NULL); DBG_ASSERT(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_ACCESS_DATE,"OSQLParseNode: mit unzulaessigem NodeType konstruiert"); } //----------------------------------------------------------------------------- OSQLParseNode::OSQLParseNode(const OSQLParseNode& rParseNode) { DBG_CTOR(OSQLParseNode,NULL); // klemm den getParent auf NULL m_pParent = NULL; // kopiere die member m_aNodeValue = rParseNode.m_aNodeValue; m_eNodeType = rParseNode.m_eNodeType; m_nNodeID = rParseNode.m_nNodeID; // denk dran, dass von Container abgeleitet wurde, laut SV-Help erzeugt // copy-Constructor des Containers einen neuen Container mit den gleichen // Zeigern als Inhalt -> d.h. nach dem Kopieren des Container wird fuer // alle Zeiger ungleich NULL eine Kopie hergestellt und anstelle des alten // Zeigers wieder eingehangen. // wenn kein Blatt, dann SubTrees bearbeiten for (::std::vector::const_iterator i = rParseNode.m_aChilds.begin(); i != rParseNode.m_aChilds.end(); i++) append(new OSQLParseNode(**i)); } //----------------------------------------------------------------------------- OSQLParseNode& OSQLParseNode::operator=(const OSQLParseNode& rParseNode) { DBG_CHKTHIS(OSQLParseNode,NULL); if (this != &rParseNode) { // kopiere die member - pParent bleibt der alte m_aNodeValue = rParseNode.m_aNodeValue; m_eNodeType = rParseNode.m_eNodeType; m_nNodeID = rParseNode.m_nNodeID; for (::std::vector::const_iterator i = m_aChilds.begin(); i != m_aChilds.end(); i++) delete *i; m_aChilds.clear(); for (::std::vector::const_iterator j = rParseNode.m_aChilds.begin(); j != rParseNode.m_aChilds.end(); j++) append(new OSQLParseNode(**j)); } return *this; } //----------------------------------------------------------------------------- sal_Bool OSQLParseNode::operator==(OSQLParseNode& rParseNode) const { DBG_CHKTHIS(OSQLParseNode,NULL); // die member muessen gleich sein sal_Bool bResult = (m_nNodeID == rParseNode.m_nNodeID) && (m_eNodeType == rParseNode.m_eNodeType) && (m_aNodeValue == rParseNode.m_aNodeValue) && count() == rParseNode.count(); // Parameters are not equal! bResult = bResult && !SQL_ISRULE(this, parameter); // compare childs for (sal_uInt32 i=0; bResult && i < count(); i++) bResult = *getChild(i) == *rParseNode.getChild(i); return bResult; } //----------------------------------------------------------------------------- OSQLParseNode::~OSQLParseNode() { DBG_DTOR(OSQLParseNode,NULL); for (::std::vector::const_iterator i = m_aChilds.begin(); i != m_aChilds.end(); i++) delete *i; } //----------------------------------------------------------------------------- void OSQLParseNode::append(OSQLParseNode* pNewNode) { DBG_CHKTHIS(OSQLParseNode,NULL); DBG_ASSERT(pNewNode != NULL, "OSQLParseNode: ungueltiger NewSubTree"); DBG_ASSERT(pNewNode->getParent() == NULL, "OSQLParseNode: Knoten ist kein Waise"); DBG_ASSERT(::std::find(m_aChilds.begin(), m_aChilds.end(), pNewNode) == m_aChilds.end(), "OSQLParseNode::append() Node already element of parent"); // stelle Verbindung zum getParent her: pNewNode->setParent( this ); // und haenge den SubTree hinten an m_aChilds.push_back(pNewNode); } //----------------------------------------------------------------------------- void OSQLParseNode::parseNodeToStr(String& rString, const Reference< XDatabaseMetaData > & xMeta, OParseContext* pContext, sal_Bool _bIntl, sal_Bool _bQuote) const { DBG_CHKTHIS(OSQLParseNode,NULL); parseNodeToStr(rString, xMeta, Reference< XNumberFormatter >(), Reference< XPropertySet >(), OParseContext::getDefaultInternational(), pContext, _bIntl, _bQuote, '.', sal_False); } //----------------------------------------------------------------------------- void OSQLParseNode::parseNodeToPredicateStr(String& rString, const Reference< XDatabaseMetaData > & xMeta, const Reference< XNumberFormatter > & xFormatter, const International& rIntl, OParseContext* pContext ) const { DBG_CHKTHIS(OSQLParseNode,NULL); DBG_ASSERT(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!"); if (xFormatter.is()) parseNodeToStr(rString, xMeta, xFormatter, Reference< XPropertySet >(), rIntl, pContext, sal_True, sal_True, rIntl.GetNumDecimalSep(), sal_True); } //----------------------------------------------------------------------------- void OSQLParseNode::parseNodeToPredicateStr(String& rString, const Reference< XDatabaseMetaData > & xMeta, const Reference< XNumberFormatter > & xFormatter, const Reference< XPropertySet > & _xField, const International& rIntl, OParseContext* pContext ) const { DBG_CHKTHIS(OSQLParseNode,NULL); DBG_ASSERT(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!"); if (xFormatter.is()) parseNodeToStr(rString, xMeta, xFormatter, _xField, rIntl, pContext, sal_True, sal_True, rIntl.GetNumDecimalSep(), sal_True); } //----------------------------------------------------------------------------- void OSQLParseNode::parseNodeToStr(String& rString, const Reference< XDatabaseMetaData > & xMeta, const Reference< XNumberFormatter > & xFormatter, const Reference< XPropertySet > & _xField, const International& rIntl, OParseContext* pContext, sal_Bool _bIntl, sal_Bool _bQuote, char _cDecSep, sal_Bool bPredicate) const { DBG_CHKTHIS(OSQLParseNode,NULL); DBG_ASSERT(xMeta.is(), "OSQLParseNode::parseNodeToStr:: no meta data!"); if (xMeta.is()) { String aIdentifierQuote(xMeta->getIdentifierQuoteString()); String aCatalogSeparator(xMeta->getCatalogSeparator()); OSQLParseNode::parseNodeToStr(rString, SQLParseNodeParameter(aIdentifierQuote, aCatalogSeparator, xFormatter, _xField, rIntl, pContext, _bIntl, _bQuote, _cDecSep, bPredicate)); } } //----------------------------------------------------------------------------- void OSQLParseNode::parseNodeToStr(String& rString, const SQLParseNodeParameter& rParam) const { DBG_CHKTHIS(OSQLParseNode,NULL); if (!isToken()) { // einmal auswerten wieviel Subtrees dieser Knoten besitzt sal_uInt32 nCount = count(); // parameter erhalten sonderbehandlung if (SQL_ISRULE(this,parameter)) { if(rString.Len()) rString += ' '; if (nCount == 1) // ? m_aChilds[0]->parseNodeToStr(rString, rParam); else if (nCount == 2) // :Name { m_aChilds[0]->parseNodeToStr(rString, rParam); rString += m_aChilds[1]->m_aNodeValue; } // [Name] else { m_aChilds[0]->parseNodeToStr(rString, rParam); rString += m_aChilds[1]->m_aNodeValue; rString += m_aChilds[2]->m_aNodeValue; } } else if(SQL_ISRULE(this,table_ref) && ((nCount == 4 && SQL_ISPUNCTUATION(m_aChilds[0],"("))|| (nCount == 6 && SQL_ISPUNCTUATION(m_aChilds[0],"(")))) tableRangeNodeToStr(rString, rParam); // je nachdem ob international angegeben wird oder nicht wird like anders behandelt // interanational: *, ? sind Platzhalter // sonst SQL92 konform: %, _ else if (SQL_ISRULE(this,like_predicate)) likeNodeToStr(rString, rParam); else if (SQL_ISRULE(this,general_set_fct) || SQL_ISRULE(this,set_fct_spec) || SQL_ISRULE(this,position_exp) || SQL_ISRULE(this,extract_exp) || SQL_ISRULE(this,length_exp) || SQL_ISRULE(this,char_value_fct)) { if (!addDateValue(rString, rParam)) { // Funktionsname nicht quoten SQLParseNodeParameter aNewParam(rParam); aNewParam.bQuote = sal_False; m_aChilds[0]->parseNodeToStr(rString, aNewParam); String aStringPara; for (sal_uInt32 i=1; iparseNodeToStr(aStringPara, rParam); // bei den CommaListen zwischen alle Subtrees Commas setzen if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i < (nCount - 1))) aStringPara += String(','); } } aStringPara.EraseTrailingChars(' '); rString += aStringPara; } } else { for (::std::vector::const_iterator i = m_aChilds.begin(); i != m_aChilds.end();) { const OSQLParseNode* pSubTree = *i; if (pSubTree) { SQLParseNodeParameter aNewParam(rParam); // don't replace the field for subqueries if (rParam.xField.is() && SQL_ISRULE(pSubTree,subquery)) aNewParam.xField = NULL; // if there is a field given we don't display the fieldname, if there are any if (rParam.xField.is() && SQL_ISRULE(pSubTree,column_ref)) { sal_Bool bFilter = sal_False; // retrieve the fields name String aFieldName; try { // retrieve the fields name rtl::OUString aString; rParam.xField->getPropertyValue(String::CreateFromAscii("Name")) >>= aString; aFieldName = aString.getStr(); } catch ( ... ) { } const OSQLParseNode* pCol = pSubTree->m_aChilds[pSubTree->count()-1]; if ((SQL_ISRULE(pCol,column_val) && pCol->getChild(0)->getTokenValue().EqualsIgnoreCaseAscii(aFieldName)) || pCol->getTokenValue().EqualsIgnoreCaseAscii(aFieldName)) bFilter = sal_True; // ok we found the field, if the following node is the // comparision operator '=' we filter it as well if (bFilter) { if (SQL_ISRULE(this, comparison_predicate)) { ++i; if(i != m_aChilds.end()) { pSubTree = *i; if (pSubTree && pSubTree->getNodeType() == SQL_NODE_EQUAL) i++; } } else i++; } else { pSubTree->parseNodeToStr(rString, aNewParam); i++; // bei den CommaListen zwischen alle Subtrees Commas setzen if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i != m_aChilds.end())) rString += String(','); } } else { pSubTree->parseNodeToStr(rString, aNewParam); i++; // bei den CommaListen zwischen alle Subtrees Commas setzen if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i != m_aChilds.end())) { if (SQL_ISRULE(this,value_exp_commalist) && rParam.bPredicate) rString += String(';'); else rString += String(','); } } } } } } else { // ein Blatt ist gefunden // Inhalt dem Ausgabestring anfuegen switch (m_eNodeType) { case SQL_NODE_KEYWORD: { if (rString.Len()) rString += ' '; rString += String::CreateFromAscii( OSQLParser::TokenIDToStr(m_nNodeID, &const_cast(rParam.rContext)).GetBuffer()); } break; case SQL_NODE_STRING: if (rString.Len()) rString += ' '; rString += SetQuotation(m_aNodeValue,String::CreateFromAscii("\'"),String::CreateFromAscii("\'\'")); break; case SQL_NODE_NAME: if (rString.Len()) { switch(ByteString::ConvertFromUnicode(rString.GetChar((rString.Len()-1)),RTL_TEXTENCODING_ASCII_US) ) { case ' ' : case '.' : break; default : if (!rParam.aCatalogSeparator.Len() || rString.GetChar((sal_uInt32)(rString.Len()-1)) != rParam.aCatalogSeparator.GetChar(0)) rString += ' '; break; } } if (rParam.bQuote) { if (rParam.bPredicate) { rString.AppendAscii("["); rString += m_aNodeValue; rString.AppendAscii("]"); } else rString += SetQuotation(m_aNodeValue, rParam.aIdentifierQuote.GetChar(0), rParam.aIdentifierQuote.GetChar(0)); } else rString += m_aNodeValue; break; case SQL_NODE_ACCESS_DATE: if (rString.Len()) rString += ' '; rString += '#'; rString += m_aNodeValue; rString += '#'; break; case SQL_NODE_INTNUM: case SQL_NODE_APPROXNUM: { String aTmp = m_aNodeValue; if (rParam.bInternational && rParam.bPredicate && rParam.cDecSep != '.') aTmp.SearchAndReplaceAll('.', rParam.cDecSep); if (rString.Len()) rString += ' '; rString += aTmp; } break; // fall through default: if (rString.Len() && m_aNodeValue.GetChar(0) != '.' && m_aNodeValue.GetChar(0) != ':' ) { switch( ByteString::ConvertFromUnicode(rString.GetChar(rString.Len()-1),RTL_TEXTENCODING_ASCII_US) ) { case ' ' : case '.' : break; default : if (!rParam.aCatalogSeparator.Len() || rString.GetChar(rString.Len()-1) != rParam.aCatalogSeparator.GetChar(0)) rString += ' '; break; } } rString += m_aNodeValue; } } } //----------------------------------------------------------------------------- sal_Bool OSQLParseNode::addDateValue(String& rString, const SQLParseNodeParameter& rParam) const { // special display for date/time values if (rParam.bPredicate && SQL_ISRULE(this,set_fct_spec) && SQL_ISPUNCTUATION(m_aChilds[0],"{")) { const OSQLParseNode* pODBCNode = m_aChilds[1]; const OSQLParseNode* pODBCNodeChild = pODBCNode->m_aChilds[0]; if (pODBCNodeChild->getNodeType() == SQL_NODE_KEYWORD && ( SQL_ISTOKEN(pODBCNodeChild, D) || SQL_ISTOKEN(pODBCNodeChild, T) || SQL_ISTOKEN(pODBCNodeChild, TS) )) { if (rString.Len()) rString += ' '; rString += '#'; if (SQL_ISTOKEN(pODBCNodeChild, D)) rString += convertDateString(rParam, pODBCNode->m_aChilds[1]->getTokenValue()); else if (SQL_ISTOKEN(pODBCNodeChild, T)) rString += convertTimeString(rParam, pODBCNode->m_aChilds[1]->getTokenValue()); else rString += convertDateTimeString(rParam, pODBCNode->m_aChilds[1]->getTokenValue()); rString += '#'; return sal_True; } } return sal_False; } //----------------------------------------------------------------------------- void OSQLParseNode::replaceNodeValue(const String& rTableAlias,const String& rColumnName) { for (sal_uInt32 i=0;igetTokenValue() == rColumnName) { OSQLParseNode * pCol = removeAt((sal_uInt32)0); append(new OSQLParseNode(rTableAlias,SQL_NODE_NAME)); append(new OSQLParseNode(String::CreateFromAscii("."),SQL_NODE_PUNCTUATION)); append(pCol); } else getChild(i)->replaceNodeValue(rTableAlias,rColumnName); } } //----------------------------------------------------------------------------- void OSQLParseNode::tableRangeNodeToStr(String& rString, const SQLParseNodeParameter& rParam) const { sal_uInt32 nCount(count()); rString += ' '; SQLParseNodeParameter aNewParam(rParam); aNewParam.bQuote = sal_False; if (nCount == 4) { m_aChilds[0]->parseNodeToStr(rString, rParam); m_aChilds[1]->parseNodeToStr(rString, rParam); m_aChilds[2]->parseNodeToStr(rString, aNewParam); m_aChilds[3]->parseNodeToStr(rString, rParam); } else if(nCount == 6 && SQL_ISPUNCTUATION(m_aChilds[0],"(")) { m_aChilds[0]->parseNodeToStr(rString, rParam); m_aChilds[1]->parseNodeToStr(rString, rParam); m_aChilds[2]->parseNodeToStr(rString, rParam); m_aChilds[3]->parseNodeToStr(rString, rParam); m_aChilds[4]->parseNodeToStr(rString, aNewParam); m_aChilds[5]->parseNodeToStr(rString, rParam); } } //----------------------------------------------------------------------------- void OSQLParseNode::likeNodeToStr(String& rString, const SQLParseNodeParameter& rParam) const { DBG_ASSERT(count() >= 4,"count != 5: Prepare for GPF"); const OSQLParseNode* pEscNode = NULL; const OSQLParseNode* pParaNode = NULL; SQLParseNodeParameter aNewParam(rParam); aNewParam.bQuote = sal_True; // if there is a field given we don't display the fieldname, if there are any sal_Bool bAddName = sal_True; if (rParam.xField.is()) { // retrieve the fields name String aFieldName; try { // retrieve the fields name rtl::OUString aString; rParam.xField->getPropertyValue(String::CreateFromAscii("Name")) >>= aString; aFieldName = aString.getStr(); } catch ( ... ) { } const OSQLParseNode* pCol = m_aChilds[0]->getChild(m_aChilds[0]->count()-1); if ((SQL_ISRULE(pCol,column_val) && pCol->getChild(0)->getTokenValue().EqualsIgnoreCaseAscii(aFieldName)) || pCol->getTokenValue().EqualsIgnoreCaseAscii(aFieldName) ) bAddName = sal_False; } if (bAddName) m_aChilds[0]->parseNodeToStr(rString, aNewParam); m_aChilds[1]->parseNodeToStr(rString, aNewParam); m_aChilds[2]->parseNodeToStr(rString, aNewParam); sal_Int32 nCurentPos = m_aChilds.size()-2; pParaNode = m_aChilds[nCurentPos]; pEscNode = m_aChilds[nCurentPos+1]; if (pParaNode->isToken() && rParam.bInternational) { String aStr = ConvertLikeToken(pParaNode, pEscNode, sal_True); rString += ' '; rString += SetQuotation(aStr,String::CreateFromAscii("\'"),String::CreateFromAscii("\'\'")); } else pParaNode->parseNodeToStr(rString, aNewParam); pEscNode->parseNodeToStr(rString, aNewParam); } //----------------------------------------------------------------------------- OSQLParseNode* OSQLParseNode::getByRule(OSQLParseNode::Rule eRule) const { OSQLParseNode* pRetNode = 0; if (isRule() && OSQLParser::RuleID(eRule) == getRuleID()) pRetNode = (OSQLParseNode*)this; else { for (::std::vector::const_iterator i = m_aChilds.begin(); !pRetNode && i != m_aChilds.end(); i++) pRetNode = (*i)->getByRule(eRule); } return pRetNode; } //----------------------------------------------------------------------------- OSQLParseNode* MakeANDNode(OSQLParseNode *pLeftLeaf,OSQLParseNode *pRightLeaf) { OSQLParseNode* pNewNode = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_term)); pNewNode->append(pLeftLeaf); pNewNode->append(new OSQLParseNode(String::CreateFromAscii("AND"),SQL_NODE_KEYWORD,SQL_TOKEN_AND)); pNewNode->append(pRightLeaf); return pNewNode; } //----------------------------------------------------------------------------- OSQLParseNode* MakeORNode(OSQLParseNode *pLeftLeaf,OSQLParseNode *pRightLeaf) { OSQLParseNode* pNewNode = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::search_condition)); pNewNode->append(pLeftLeaf); pNewNode->append(new OSQLParseNode(String::CreateFromAscii("OR"),SQL_NODE_KEYWORD,SQL_TOKEN_OR)); pNewNode->append(pRightLeaf); return pNewNode; } //----------------------------------------------------------------------------- void OSQLParseNode::disjunctiveNormalForm(OSQLParseNode*& pSearchCondition) { if(!pSearchCondition) // no where condition at entry point return; OSQLParseNode::absorptions(pSearchCondition); // '(' search_condition ')' if (SQL_ISRULE(pSearchCondition,boolean_primary)) { OSQLParseNode* pLeft = pSearchCondition->getChild(1); disjunctiveNormalForm(pLeft); } // search_condition SQL_TOKEN_OR boolean_term else if (SQL_ISRULE(pSearchCondition,search_condition)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0); disjunctiveNormalForm(pLeft); OSQLParseNode* pRight = pSearchCondition->getChild(2); disjunctiveNormalForm(pRight); } // boolean_term SQL_TOKEN_AND boolean_factor else if (SQL_ISRULE(pSearchCondition,boolean_term)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0); disjunctiveNormalForm(pLeft); OSQLParseNode* pRight = pSearchCondition->getChild(2); disjunctiveNormalForm(pRight); OSQLParseNode* pNewNode = NULL; // '(' search_condition ')' if(pLeft->count() == 3 && SQL_ISRULE(pLeft,boolean_primary) && SQL_ISRULE(pLeft->getChild(1),search_condition)) { // and-or tree on left side OSQLParseNode* pOr = pLeft->getChild(1); OSQLParseNode* pNewLeft = NULL; OSQLParseNode* pNewRight = NULL; // cut right from parent pSearchCondition->removeAt(2); pNewRight = MakeANDNode(pOr->removeAt(2) ,pRight); pNewLeft = MakeANDNode(pOr->removeAt((sal_uInt32)0) ,new OSQLParseNode(*pRight)); pNewNode = MakeORNode(pNewLeft,pNewRight); // and append new Node pSearchCondition->getParent()->replace(pSearchCondition, pNewNode); delete pSearchCondition; disjunctiveNormalForm(pNewNode); } else if(pRight->count() == 3 && SQL_ISRULE(pRight,boolean_primary) && SQL_ISRULE(pRight->getChild(1),search_condition)) { // and-or tree on right side OSQLParseNode* pOr = pRight->getChild(1); OSQLParseNode* pNewLeft = NULL; OSQLParseNode* pNewRight = NULL; // cut left from parent pSearchCondition->removeAt((sal_uInt32)0); pNewRight = MakeANDNode(pLeft,pOr->removeAt(2)); pNewLeft = MakeANDNode(new OSQLParseNode(*pLeft),pOr->removeAt((sal_uInt32)0)); pNewNode = MakeORNode(pNewLeft,pNewRight); // and append new Node pSearchCondition->getParent()->replace(pSearchCondition, pNewNode); delete pSearchCondition; disjunctiveNormalForm(pNewNode); } else if(SQL_ISRULE(pLeft,boolean_primary) && (!SQL_ISRULE(pLeft->getChild(1),search_condition) || !SQL_ISRULE(pLeft->getChild(1),boolean_term))) pSearchCondition->replace(pLeft, pLeft->removeAt(1)); else if(SQL_ISRULE(pRight,boolean_primary) && (!SQL_ISRULE(pRight->getChild(1),search_condition) || !SQL_ISRULE(pRight->getChild(1),boolean_term))) pSearchCondition->replace(pRight, pRight->removeAt(1)); } } //----------------------------------------------------------------------------- void OSQLParseNode::negateSearchCondition(OSQLParseNode*& pSearchCondition,sal_Bool bNegate) { if(!pSearchCondition) // no where condition at entry point return; OSQLParseNode* pNode = NULL; // '(' search_condition ')' if (pSearchCondition->count() == 3 && SQL_ISRULE(pSearchCondition,boolean_primary)) { OSQLParseNode* pRight = pSearchCondition->getChild(1); negateSearchCondition(pRight,bNegate); } // search_condition SQL_TOKEN_OR boolean_term else if (SQL_ISRULE(pSearchCondition,search_condition)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0); OSQLParseNode* pRight = pSearchCondition->getChild(2); if(bNegate) { OSQLParseNode* pNewNode = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_term)); pNewNode->append(pSearchCondition->removeAt((sal_uInt32)0)); pNewNode->append(new OSQLParseNode(String::CreateFromAscii("AND"),SQL_NODE_KEYWORD,SQL_TOKEN_AND)); pNewNode->append(pSearchCondition->removeAt((sal_uInt32)1)); pSearchCondition->getParent()->replace(pSearchCondition, pNewNode); delete pSearchCondition; pLeft = pNewNode->getChild(0); pRight = pNewNode->getChild(2); } negateSearchCondition(pLeft,bNegate); negateSearchCondition(pRight,bNegate); } // boolean_term SQL_TOKEN_AND boolean_factor else if (SQL_ISRULE(pSearchCondition,boolean_term)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0); OSQLParseNode* pRight = pSearchCondition->getChild(2); if(bNegate) { OSQLParseNode* pNewNode = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::search_condition)); pNewNode->append(pSearchCondition->removeAt((sal_uInt32)0)); pNewNode->append(new OSQLParseNode(String::CreateFromAscii("OR"),SQL_NODE_KEYWORD,SQL_TOKEN_OR)); pNewNode->append(pSearchCondition->removeAt((sal_uInt32)1)); pSearchCondition->getParent()->replace(pSearchCondition, pNewNode); delete pSearchCondition; pLeft = pNewNode->getChild(0); pRight = pNewNode->getChild(2); } negateSearchCondition(pLeft,bNegate); negateSearchCondition(pRight,bNegate); } // SQL_TOKEN_NOT boolean_test else if (SQL_ISRULE(pSearchCondition,boolean_factor)) { OSQLParseNode *pNot = pSearchCondition->removeAt((sal_uInt32)0); delete pNot; OSQLParseNode *pBooleanTest = pSearchCondition->removeAt((sal_uInt32)0); pBooleanTest->setParent(NULL); pSearchCondition->getParent()->replace(pSearchCondition, pBooleanTest); delete pSearchCondition; if (!bNegate) negateSearchCondition(pBooleanTest,sal_True); // negate all deeper values } // row_value_constructor comparison row_value_constructor // row_value_constructor comparison any_all_some subquery else if(bNegate && SQL_ISRULE(pSearchCondition,comparison_predicate) || SQL_ISRULE(pSearchCondition,all_or_any_predicate)) { OSQLParseNode* pComparison = pSearchCondition->getChild(1); OSQLParseNode* pNewComparison = NULL; switch(pComparison->getNodeType()) { case SQL_NODE_EQUAL: pNewComparison = new OSQLParseNode(String::CreateFromAscii("<>"),SQL_NODE_NOTEQUAL,NOTEQUAL); break; case SQL_NODE_LESS: pNewComparison = new OSQLParseNode(String::CreateFromAscii(">="),SQL_NODE_GREATEQ,GREATEQ); break; case SQL_NODE_GREAT: pNewComparison = new OSQLParseNode(String::CreateFromAscii("<="),SQL_NODE_LESSEQ,LESSEQ); break; case SQL_NODE_LESSEQ: pNewComparison = new OSQLParseNode(String::CreateFromAscii(">"),SQL_NODE_GREAT,GREAT); break; case SQL_NODE_GREATEQ: pNewComparison = new OSQLParseNode(String::CreateFromAscii("<"),SQL_NODE_LESS,LESS); break; case SQL_NODE_NOTEQUAL: pNewComparison = new OSQLParseNode(String::CreateFromAscii("="),SQL_NODE_EQUAL,EQUAL); break; } pSearchCondition->replace(pComparison, pNewComparison); delete pComparison; } else if(bNegate && (SQL_ISRULE(pSearchCondition,test_for_null) || SQL_ISRULE(pSearchCondition,in_predicate) || SQL_ISRULE(pSearchCondition,like_predicate) || SQL_ISRULE(pSearchCondition,between_predicate) || SQL_ISRULE(pSearchCondition,boolean_test) )) { sal_uInt32 nNotPos = 0; // row_value_constructor not SQL_TOKEN_IN in_predicate_value // row_value_constructor not SQL_TOKEN_LIKE num_value_exp opt_escape // row_value_constructor not SQL_TOKEN_BETWEEN row_value_constructor SQL_TOKEN_AND row_value_constructor if(SQL_ISRULE(pSearchCondition,in_predicate) || SQL_ISRULE(pSearchCondition,like_predicate) || SQL_ISRULE(pSearchCondition,between_predicate)) nNotPos = 1; // row_value_constructor SQL_TOKEN_IS not SQL_TOKEN_NULL // boolean_primary SQL_TOKEN_IS not truth_value else if(SQL_ISRULE(pSearchCondition,test_for_null) || SQL_ISRULE(pSearchCondition,boolean_test)) nNotPos = 2; OSQLParseNode* pNot = pSearchCondition->getChild(nNotPos); OSQLParseNode* pNotNot = NULL; if(pNot->isRule()) pNotNot = new OSQLParseNode(String::CreateFromAscii("NOT"),SQL_NODE_KEYWORD,SQL_TOKEN_NOT); else pNotNot = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::not)); pSearchCondition->replace(pNot, pNotNot); delete pNot; } } //----------------------------------------------------------------------------- void OSQLParseNode::eraseBraces(OSQLParseNode*& pSearchCondition) { if (pSearchCondition && (SQL_ISRULE(pSearchCondition,boolean_primary) || (pSearchCondition->count() == 3 && SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") && SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")")))) { OSQLParseNode* pRight = pSearchCondition->getChild(1); absorptions(pRight); // if child is not a or or and tree then delete () around child if(!(SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || SQL_ISRULE(pSearchCondition->getChild(1),search_condition)) || SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || // and can always stand without () (SQL_ISRULE(pSearchCondition->getChild(1),search_condition) && SQL_ISRULE(pSearchCondition->getParent(),search_condition))) { OSQLParseNode* pNode = pSearchCondition->removeAt(1); pSearchCondition->getParent()->replace(pSearchCondition, pNode); delete pSearchCondition; pSearchCondition = pNode; } } } //----------------------------------------------------------------------------- void OSQLParseNode::absorptions(OSQLParseNode*& pSearchCondition) { if(!pSearchCondition) // no where condition at entry point return; eraseBraces(pSearchCondition); if(SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0); absorptions(pLeft); OSQLParseNode* pRight = pSearchCondition->getChild(2); absorptions(pRight); } // a and a || a or a OSQLParseNode* pNewNode = NULL; if(( SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition)) && *pSearchCondition->getChild(0) == *pSearchCondition->getChild(2)) { pNewNode = pSearchCondition->removeAt((sal_uInt32)0); pSearchCondition->getParent()->replace(pSearchCondition, pNewNode); delete pSearchCondition; pSearchCondition = pNewNode; } // (a or b) and a else if(SQL_ISRULE(pSearchCondition,boolean_term) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_primary) && SQL_ISRULE(pSearchCondition->getChild(0)->getChild(1),search_condition) && *pSearchCondition->getChild(0)->getChild(1)->getChild(0) == *pSearchCondition->getChild(2)) { pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt(2)); delete pSearchCondition; pSearchCondition = pNewNode; } // a and ( a or b) else if(SQL_ISRULE(pSearchCondition,boolean_term) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_primary) && SQL_ISRULE(pSearchCondition->getChild(2)->getChild(1),search_condition)) { if(*pSearchCondition->getChild(2)->getChild(1)->getChild(0) == *pSearchCondition->getChild(0)) { pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)0)); delete pSearchCondition; pSearchCondition = pNewNode; } else if(*pSearchCondition->getChild(2)->getChild(1)->getChild(2) == *pSearchCondition->getChild(0)) { pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)2)); delete pSearchCondition; pSearchCondition = pNewNode; } } // a or a and b || a or b and a else if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_term)) { if(*pSearchCondition->getChild(2)->getChild(0) == *pSearchCondition->getChild(0)) { pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)0)); delete pSearchCondition; pSearchCondition = pNewNode; } else if(*pSearchCondition->getChild(2)->getChild(2) == *pSearchCondition->getChild(0)) { pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)0)); delete pSearchCondition; pSearchCondition = pNewNode; } } // a and b or a || b and a or a else if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_term)) { if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)) { pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)2)); delete pSearchCondition; pSearchCondition = pNewNode; } else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)) { pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)2)); delete pSearchCondition; pSearchCondition = pNewNode; } } eraseBraces(pSearchCondition); } //----------------------------------------------------------------------------- void OSQLParseNode::compress(OSQLParseNode *&pSearchCondition) { if(!pSearchCondition) // no where condition at entry point return; OSQLParseNode::eraseBraces(pSearchCondition); if(SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0); compress(pLeft); OSQLParseNode* pRight = pSearchCondition->getChild(2); compress(pRight); } else if( SQL_ISRULE(pSearchCondition,boolean_primary) || (pSearchCondition->count() == 3 && SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") && SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")"))) { OSQLParseNode* pRight = pSearchCondition->getChild(1); compress(pRight); // if child is not a or or and tree then delete () around child if(!(SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || SQL_ISRULE(pSearchCondition->getChild(1),search_condition)) || (SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) && SQL_ISRULE(pSearchCondition->getParent(),boolean_term)) || (SQL_ISRULE(pSearchCondition->getChild(1),search_condition) && SQL_ISRULE(pSearchCondition->getParent(),search_condition))) { OSQLParseNode* pNode = pSearchCondition->removeAt(1); pSearchCondition->getParent()->replace(pSearchCondition, pNode); delete pSearchCondition; pSearchCondition = pNode; } } OSQLParseNode* pNewNode = NULL; // or with two and trees where one element of the and trees are equal if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_term) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_term)) { if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)->getChild(0)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(2); OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(2); OSQLParseNode* pNode = MakeORNode(pLeft,pRight); OSQLParseNode* pNewRule = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary)); pNewRule->append(new OSQLParseNode(String::CreateFromAscii("("),SQL_NODE_PUNCTUATION)); pNewRule->append(pNode); pNewRule->append(new OSQLParseNode(String::CreateFromAscii(")"),SQL_NODE_PUNCTUATION)); OSQLParseNode::eraseBraces(pLeft); OSQLParseNode::eraseBraces(pRight); pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt((sal_uInt32)0),pNewRule); pSearchCondition->getParent()->replace(pSearchCondition, pNode); delete pSearchCondition; pSearchCondition = pNode; } else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)->getChild(0)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt((sal_uInt32)0); OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(2); OSQLParseNode* pNode = MakeORNode(pLeft,pRight); OSQLParseNode* pNewRule = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary)); pNewRule->append(new OSQLParseNode(String::CreateFromAscii("("),SQL_NODE_PUNCTUATION)); pNewRule->append(pNode); pNewRule->append(new OSQLParseNode(String::CreateFromAscii(")"),SQL_NODE_PUNCTUATION)); OSQLParseNode::eraseBraces(pLeft); OSQLParseNode::eraseBraces(pRight); pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(1),pNewRule); pSearchCondition->getParent()->replace(pSearchCondition, pNode); delete pSearchCondition; pSearchCondition = pNode; } else if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)->getChild(2)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(2); OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt((sal_uInt32)0); OSQLParseNode* pNode = MakeORNode(pLeft,pRight); OSQLParseNode* pNewRule = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary)); pNewRule->append(new OSQLParseNode(String::CreateFromAscii("("),SQL_NODE_PUNCTUATION)); pNewRule->append(pNode); pNewRule->append(new OSQLParseNode(String::CreateFromAscii(")"),SQL_NODE_PUNCTUATION)); OSQLParseNode::eraseBraces(pLeft); OSQLParseNode::eraseBraces(pRight); pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt((sal_uInt32)0),pNewRule); pSearchCondition->getParent()->replace(pSearchCondition, pNode); delete pSearchCondition; pSearchCondition = pNode; } else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)->getChild(2)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt((sal_uInt32)0); OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt((sal_uInt32)0); OSQLParseNode* pNode = MakeORNode(pLeft,pRight); OSQLParseNode* pNewRule = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary)); pNewRule->append(new OSQLParseNode(String::CreateFromAscii("("),SQL_NODE_PUNCTUATION)); pNewRule->append(pNode); pNewRule->append(new OSQLParseNode(String::CreateFromAscii(")"),SQL_NODE_PUNCTUATION)); OSQLParseNode::eraseBraces(pLeft); OSQLParseNode::eraseBraces(pRight); pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(1),pNewRule); pSearchCondition->getParent()->replace(pSearchCondition, pNode); delete pSearchCondition; pSearchCondition = pNode; } } } //----------------------------------------------------------------------------- void OSQLParseNode::showParseTree(String& rString, sal_uInt32 nLevel) { DBG_CHKTHIS(OSQLParseNode,NULL); if (!isToken()) { for (sal_uInt32 j=0; j::const_iterator i = m_aChilds.begin(); i != m_aChilds.end(); i++) (*i)->showParseTree(rString, nLevel+1); } else { // ein Token gefunden // tabs fuer das Einruecken entsprechend nLevel for (sal_uInt32 j=0; jgetParent() == NULL, "OSQLParseNode: Knoten ist kein Waise"); // stelle Verbindung zum getParent her: pNewSubTree->setParent( this ); m_aChilds.insert(m_aChilds.begin() + nPos); } // removeAt-Methoden //----------------------------------------------------------------------------- OSQLParseNode* OSQLParseNode::removeAt(sal_uInt32 nPos) { ::std::vector::iterator aPos(m_aChilds.begin() + nPos); OSQLParseNode* pNode = *aPos; // setze den getParent des removeten auf NULL pNode->setParent( NULL ); m_aChilds.erase(aPos); return pNode; } //----------------------------------------------------------------------------- OSQLParseNode* OSQLParseNode::remove(OSQLParseNode* pSubTree) { DBG_ASSERT(pSubTree != NULL, "OSQLParseNode: ungueltiger SubTree"); ::std::vector::iterator aPos = ::std::find(m_aChilds.begin(), m_aChilds.end(), pSubTree); if (aPos != m_aChilds.end()) { // setze den getParent des removeten auf NULL pSubTree->setParent( NULL ); m_aChilds.erase(aPos); return pSubTree; } else return NULL; } // Replace-Methoden //----------------------------------------------------------------------------- OSQLParseNode* OSQLParseNode::replaceAt(sal_uInt32 nPos, OSQLParseNode* pNewSubNode) { DBG_ASSERT(pNewSubNode != NULL, "OSQLParseNode: invalid nodes"); DBG_ASSERT(pNewSubNode->getParent() == NULL, "OSQLParseNode: node already has getParent"); DBG_ASSERT(nPos < m_aChilds.size(), "OSQLParseNode: invalid position"); DBG_ASSERT(::std::find(m_aChilds.begin(), m_aChilds.end(), pNewSubNode) == m_aChilds.end(), "OSQLParseNode::Replace() Node already element of parent"); OSQLParseNode* pOldSubNode = m_aChilds[nPos]; // stelle Verbindung zum getParent her: pNewSubNode->setParent( this ); pOldSubNode->setParent( NULL ); m_aChilds[nPos] = pNewSubNode; return pOldSubNode; } //----------------------------------------------------------------------------- OSQLParseNode* OSQLParseNode::replace (OSQLParseNode* pOldSubNode, OSQLParseNode* pNewSubNode ) { DBG_ASSERT(pOldSubNode != NULL && pNewSubNode != NULL, "OSQLParseNode: invalid nodes"); DBG_ASSERT(pNewSubNode->getParent() == NULL, "OSQLParseNode: node already has getParent"); DBG_ASSERT(::std::find(m_aChilds.begin(), m_aChilds.end(), pOldSubNode) != m_aChilds.end(), "OSQLParseNode::Replace() Node not element of parent"); DBG_ASSERT(::std::find(m_aChilds.begin(), m_aChilds.end(), pNewSubNode) == m_aChilds.end(), "OSQLParseNode::Replace() Node already element of parent"); pOldSubNode->setParent( NULL ); pNewSubNode->setParent( this ); ::std::replace(m_aChilds.begin(), m_aChilds.end(), pOldSubNode, pNewSubNode); return pOldSubNode; }