diff options
-rw-r--r-- | dbaccess/source/ui/querydesign/QueryDesignView.cxx | 4022 |
1 files changed, 2055 insertions, 1967 deletions
diff --git a/dbaccess/source/ui/querydesign/QueryDesignView.cxx b/dbaccess/source/ui/querydesign/QueryDesignView.cxx index 43cbd0f6ac56..32f42b504591 100644 --- a/dbaccess/source/ui/querydesign/QueryDesignView.cxx +++ b/dbaccess/source/ui/querydesign/QueryDesignView.cxx @@ -2,9 +2,9 @@ * * $RCSfile: QueryDesignView.cxx,v $ * - * $Revision: 1.39 $ + * $Revision: 1.40 $ * - * last change: $Author: fs $ $Date: 2002-02-04 13:47:01 $ + * last change: $Author: oj $ $Date: 2002-02-06 08:08:30 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -154,6 +154,9 @@ #ifndef _ISOLANG_HXX #include <tools/isolang.hxx> #endif +#ifndef DBAUI_QUERYTABLEVIEW_HXX +#include "QueryTableView.hxx" +#endif using namespace ::dbaui; using namespace ::utl; @@ -165,15 +168,2045 @@ using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::container; -OQueryDesignView::OQueryDesignView(OQueryContainerWindow* _pParent, OQueryController* _pController,const Reference< XMultiServiceFactory >& _rFactory) +extern ::rtl::OUString ConvertAlias(const ::rtl::OUString& rName); +// here we define our functions used in the anonymous namespace to get our header file smaller +// please look at the book LargeScale C++ to know why +namespace +{ + static const ::rtl::OUString C_AND = ::rtl::OUString::createFromAscii(" AND "); + static const ::rtl::OUString C_OR = ::rtl::OUString::createFromAscii(" OR "); + + // forward declarations + sal_Bool InsertJoin( const OQueryDesignView* _pView, + const ::connectivity::OSQLParseNode *pNode); + + int InstallFields( OQueryDesignView* _pView, + const ::connectivity::OSQLParseNode* pNode, + OJoinTableView::OTableWindowMap* pTabList ); + + void GetGroupCriteria( OQueryDesignView* _pView, + OSelectionBrowseBox* _pSelectionBrw, + const ::connectivity::OSQLParseNode* pSelectRoot ); + + void GetHavingCriteria( OQueryDesignView* _pView, + OSelectionBrowseBox* _pSelectionBrw, + const ::connectivity::OSQLParseNode* pSelectRoot, + int &rLevel ); + + void GetOrderCriteria( OQueryDesignView* _pView, + OSelectionBrowseBox* _pSelectionBrw, + const ::connectivity::OSQLParseNode* pParseRoot ); + + //------------------------------------------------------------------------------ + void FillOuterJoins(OQueryDesignView* _pView, + const ::connectivity::OSQLParseNode* pTableRefList) + { + sal_uInt32 ncount = pTableRefList->count(); + + if (ncount == 0) + { + ErrorBox( _pView, ModuleRes( ERR_QRY_ILLEGAL_JOIN ) ).Execute(); + } + else + { + for (sal_uInt32 i=0; i < ncount; i++) + { + const ::connectivity::OSQLParseNode* pParseNode = pTableRefList->getChild(i); + if (SQL_ISRULE(pParseNode , qualified_join) || + SQL_ISRULE(pParseNode , joined_table)) + { + if (!InsertJoin(_pView,pParseNode)) + { + ErrorBox( _pView, ModuleRes( ERR_QRY_ILLEGAL_JOIN ) ).Execute(); + return; + } + } + else if(pParseNode->count() == 4 && SQL_ISPUNCTUATION(pParseNode->getChild(0),"{") && SQL_ISRULE(pParseNode,table_ref)) + { + if (!InsertJoin(_pView,pParseNode->getChild(2))) + { + ErrorBox( _pView, ModuleRes( ERR_QRY_ILLEGAL_JOIN ) ).Execute(); + return; + } + } + } + } + } + //------------------------------------------------------------------------------ + ::rtl::OUString QuoteField( const OQueryDesignView* _pView,const ::rtl::OUString& rValue, sal_Int32 aType ) + { + ::rtl::OUString rNewValue; + switch (rValue.toChar()) + { + case '?': + if (rValue.getLength() != 1) + break; + case '\'': // ::rtl::OUString Quotierung oder Datum + //case '#': // Datumsquotierung // jetengine + case ':': // Parameter + case '[': // Parameter + return rValue; + } + + Reference< XConnection> xConnection = static_cast<OQueryController*>(_pView->getController())->getConnection(); + Reference< XDatabaseMetaData > xMetaData; + if(xConnection.is()) + xMetaData = xConnection->getMetaData(); + ::rtl::OUString aQuote; + try + { + if(xMetaData.is()) + aQuote = xMetaData->getIdentifierQuoteString(); + + switch( aType ) + { + case DataType::DATE: + case DataType::TIME: + case DataType::TIMESTAMP: + if (rValue.toChar() != '{') // nur quoten, wenn kein Access Datum + rNewValue = ::dbtools::quoteName(aQuote,rValue); + else + rNewValue = rValue; + break; + case DataType::CHAR: + case DataType::VARCHAR: + case DataType::LONGVARCHAR: + rNewValue = ::dbtools::quoteName(aQuote,rValue); + break; + case DataType::DECIMAL: + case DataType::NUMERIC: + case DataType::TINYINT: + case DataType::SMALLINT: + case DataType::INTEGER: + case DataType::BIGINT: + case DataType::REAL: + case DataType::DOUBLE: + case DataType::BINARY: + case DataType::VARBINARY: + case DataType::LONGVARBINARY: + rNewValue = rValue; + break; + case DataType::BIT: + { + if(xMetaData.is()) + { + ::comphelper::UStringMixEqual bCase(xMetaData->storesMixedCaseQuotedIdentifiers()); + if (bCase(rValue, ::rtl::OUString(ModuleRes(STR_QUERY_TRUE)))) + rNewValue = ::rtl::OUString::createFromAscii("TRUE"); + else if (bCase(rValue, ::rtl::OUString(ModuleRes(STR_QUERY_FALSE)))) + rNewValue = ::rtl::OUString::createFromAscii("FALSE"); + else + rNewValue = rValue; + } + } + break; + default: + DBG_ERROR( "QuoteField: illegal type" ); + break; + } + } + catch(SQLException&) + { + DBG_ERROR( "QuoteField: Exception" ); + } + return rNewValue; + } + // ----------------------------------------------------------------------------- + + //------------------------------------------------------------------------------ + sal_Bool FillDragInfo( const OQueryDesignView* _pView, + const ::connectivity::OSQLParseNode* pColumnRef, + OTableFieldDescRef& _rDragInfo) + { + + sal_Bool bErg = sal_False; + + ::rtl::OUString aTableRange,aColumnName; + sal_uInt16 nCntAccount; + ::connectivity::OSQLParseTreeIterator& rParseIter = static_cast<OQueryController*>(_pView->getController())->getParseIterator(); + rParseIter.getColumnRange( pColumnRef, aColumnName, aTableRange ); + + if (aTableRange.getLength()) + { + OQueryTableWindow* pSTW = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( aTableRange ); + if(pSTW && pSTW->ExistsField( aColumnName, _rDragInfo ) ) + bErg = sal_True; + } + if(!bErg) + bErg = static_cast<OQueryTableView*>(_pView->getTableView())->FindTableFromField(aColumnName, _rDragInfo, nCntAccount); + + return bErg; + } + //------------------------------------------------------------------------------ + ::rtl::OUString BuildJoinCriteria( const OQueryDesignView* _pView, + OConnectionLineDataVec* pLineDataList, + OQueryTableConnectionData* pData) + { + ::rtl::OUString aCondition; + Reference< XConnection> xConnection = static_cast<OQueryController*>(_pView->getController())->getConnection(); + if(!xConnection.is()) + return aCondition; + + OConnectionLineDataVec::iterator aIter = pLineDataList->begin(); + try + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString(); + + for(;aIter != pLineDataList->end();++aIter) + { + OConnectionLineDataRef pLineData = *aIter; + if(pLineData->IsValid()) + { + if(aCondition.getLength()) + aCondition += C_AND; + aCondition += ::dbtools::quoteName(aQuote, ConvertAlias( pData->GetAliasName(JTCS_FROM) )); + aCondition += ::rtl::OUString('.'); + aCondition += ::dbtools::quoteName(aQuote, pLineData->GetFieldName(JTCS_FROM) ); + aCondition += ::rtl::OUString::createFromAscii(" = "); + aCondition += ::dbtools::quoteName(aQuote, ConvertAlias( pData->GetAliasName(JTCS_TO) )); + aCondition += ::rtl::OUString('.'); + aCondition += ::dbtools::quoteName(aQuote, pLineData->GetFieldName(JTCS_TO) ); + } + } + } + catch(SQLException&) + { + OSL_ASSERT(!"Failure while building Join criteria!"); + } + + return aCondition; + } + //------------------------------------------------------------------------------ + /** JoinCycle looks for a join cycle and append it to the string + @param _pView the view + @param _pEntryConn the table connection which holds the data + @param _pEntryTabTo the corresponding table window + @param _rJoin the String which will contain the resulting string + */ + void JoinCycle( const OQueryDesignView* _pView, + OQueryTableConnection* _pEntryConn, + const OQueryTableWindow* _pEntryTabTo, + ::rtl::OUString& _rJoin ) + { + OSL_ENSURE(_pView,"The view can not be null!"); + OSL_ENSURE(_pEntryConn,"TableConnection can not be null!"); + + OQueryTableConnectionData* pData = static_cast< OQueryTableConnectionData*>(_pEntryConn->GetData()); + if ( pData->GetJoinType() != INNER_JOIN && _pEntryTabTo->ExistsAVisitedConn() ) + { + sal_Bool bBrace = sal_False; + if(_rJoin.getLength() && _rJoin.lastIndexOf(')') == (_rJoin.getLength()-1)) + { + bBrace = sal_True; + _rJoin = _rJoin.replaceAt(_rJoin.getLength()-1,1,::rtl::OUString(' ')); + } + (_rJoin += C_AND) += BuildJoinCriteria(_pView,pData->GetConnLineDataList(),pData); + if(bBrace) + _rJoin += ::rtl::OUString(')'); + _pEntryConn->SetVisited(sal_True); + } + } + //------------------------------------------------------------------------------ + ::rtl::OUString BuildTable(const OQueryDesignView* _pView,const OQueryTableWindow* pEntryTab) + { + ::rtl::OUString aDBName(pEntryTab->GetComposedName()); + + Reference< XConnection> xConnection = static_cast<OQueryController*>(_pView->getController())->getConnection(); + if( xConnection.is() ) + { + try + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + ::rtl::OUString aCatalog,aSchema,aTable,sComposedName; + ::dbtools::qualifiedNameComponents(xMetaData,aDBName,aCatalog,aSchema,aTable); + ::dbtools::composeTableName(xMetaData,aCatalog,aSchema,aTable,sComposedName,sal_True); + + ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString(); + ::rtl::OUString aTableListStr(sComposedName); + aTableListStr += ::rtl::OUString(' '); + aTableListStr += ::dbtools::quoteName(aQuote, ConvertAlias(pEntryTab->GetAliasName())).getStr(); + aDBName = aTableListStr; + } + catch(SQLException&) + { + } + } + return aDBName; + } + //------------------------------------------------------------------------------ + ::rtl::OUString BuildJoin( const OQueryDesignView* _pView, + const ::rtl::OUString& rLh, + const ::rtl::OUString& rRh, + OQueryTableConnectionData* pData) + { + + String aErg(rLh); + switch(pData->GetJoinType()) + { + case LEFT_JOIN: + aErg.AppendAscii(" LEFT OUTER "); + break; + case RIGHT_JOIN: + aErg.AppendAscii(" RIGHT OUTER "); + break; + case INNER_JOIN: + DBG_ERROR("OQueryDesignView::BuildJoin: This should not happen!"); + //aErg.AppendAscii(" INNER "); + break; + default: + aErg.AppendAscii(" FULL OUTER "); + break; + } + aErg.AppendAscii("JOIN "); + aErg += String(rRh); + aErg.AppendAscii(" ON "); + aErg += String(BuildJoinCriteria(_pView,pData->GetConnLineDataList(),pData)); + + return aErg; + } + //------------------------------------------------------------------------------ + ::rtl::OUString BuildJoin( const OQueryDesignView* _pView, + OQueryTableWindow* pLh, + OQueryTableWindow* pRh, + OQueryTableConnectionData* pData) + { + return BuildJoin(_pView,BuildTable(_pView,pLh),BuildTable(_pView,pRh),pData); + } + //------------------------------------------------------------------------------ + ::rtl::OUString BuildJoin( const OQueryDesignView* _pView, + const ::rtl::OUString &rLh, + OQueryTableWindow* pRh, + OQueryTableConnectionData* pData) + { + return BuildJoin(_pView,rLh,BuildTable(_pView,pRh),pData); + } + //------------------------------------------------------------------------------ + ::rtl::OUString BuildJoin( const OQueryDesignView* _pView, + OQueryTableWindow* pLh, + const ::rtl::OUString &rRh, + OQueryTableConnectionData* pData) + { + return BuildJoin(_pView,BuildTable(_pView,pLh),rRh,pData); + } + //------------------------------------------------------------------------------ + void GetNextJoin( const OQueryDesignView* _pView, + OQueryTableConnection* pEntryConn, + OQueryTableWindow* pEntryTabTo, + ::rtl::OUString &aJoin) + { + OQueryTableConnectionData* pEntryConnData = static_cast<OQueryTableConnectionData*>(pEntryConn->GetData()); + if(pEntryConnData->GetJoinType() == INNER_JOIN) + return; + + if(!aJoin.getLength()) + { + OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin()); + aJoin = BuildJoin(_pView,pEntryTabFrom,pEntryTabTo,pEntryConnData); + } + else if(pEntryTabTo == pEntryConn->GetDestWin()) + { + ::rtl::OUString aTmpJoin('('); + (aTmpJoin += aJoin) += ::rtl::OUString(')'); + aJoin = BuildJoin(_pView,aTmpJoin,pEntryTabTo,pEntryConnData); + } + else if(pEntryTabTo == pEntryConn->GetSourceWin()) + { + ::rtl::OUString aTmpJoin('('); + (aTmpJoin += aJoin) += ::rtl::OUString(')'); + aJoin = BuildJoin(_pView,pEntryTabTo,aTmpJoin,pEntryConnData); + } + + pEntryConn->SetVisited(sal_True); + + // first search for the "to" window + ::std::vector<OTableConnection*>::iterator aIter = pEntryConn->GetParent()->GetTabConnList()->begin(); + for(;aIter != pEntryConn->GetParent()->GetTabConnList()->end();++aIter) + { + OQueryTableConnection* pNext = static_cast<OQueryTableConnection*>(*aIter); + if(!pNext->IsVisited() && (pNext->GetSourceWin() == pEntryTabTo || pNext->GetDestWin() == pEntryTabTo)) + { + OQueryTableWindow* pEntryTab = pNext->GetSourceWin() == pEntryTabTo ? static_cast<OQueryTableWindow*>(pNext->GetDestWin()) : static_cast<OQueryTableWindow*>(pNext->GetSourceWin()); + // exists there a connection to a OQueryTableWindow that holds a connection that has been already visited + JoinCycle(_pView,pNext,pEntryTab,aJoin); + if(!pNext->IsVisited()) + GetNextJoin(_pView,pNext,pEntryTab,aJoin); + } + } + + // when nothing found found look for the "from" window + if(aIter == pEntryConn->GetParent()->GetTabConnList()->end()) + { + OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin()); + aIter = pEntryConn->GetParent()->GetTabConnList()->begin(); + for(;aIter != pEntryConn->GetParent()->GetTabConnList()->end();++aIter) + { + OQueryTableConnection* pNext = static_cast<OQueryTableConnection*>(*aIter); + if(!pNext->IsVisited() && (pNext->GetSourceWin() == pEntryTabFrom || pNext->GetDestWin() == pEntryTabFrom)) + { + OQueryTableWindow* pEntryTab = pNext->GetSourceWin() == pEntryTabFrom ? static_cast<OQueryTableWindow*>(pNext->GetDestWin()) : static_cast<OQueryTableWindow*>(pNext->GetSourceWin()); + // exists there a connection to a OQueryTableWindow that holds a connection that has been already visited + JoinCycle(_pView,pNext,pEntryTab,aJoin); + if(!pNext->IsVisited()) + GetNextJoin(_pView,pNext,pEntryTab,aJoin); + } + } + } + } + //------------------------------------------------------------------------------ + sal_Bool InsertJoinConnection( const OQueryDesignView* _pView, + const ::connectivity::OSQLParseNode *pNode, + const EJoinType& _eJoinType) + { + if (pNode->count() == 3 && // Ausdruck is geklammert + SQL_ISPUNCTUATION(pNode->getChild(0),"(") && + SQL_ISPUNCTUATION(pNode->getChild(2),")")) + { + return InsertJoinConnection(_pView,pNode->getChild(1), _eJoinType); + } + else if (SQL_ISRULE(pNode,search_condition) || + SQL_ISRULE(pNode,boolean_term) && // AND/OR-Verknuepfung: + pNode->count() == 3) + { + // nur AND Verknpfung zulassen + if (!SQL_ISTOKEN(pNode->getChild(1),AND)) + return sal_False; + else + return InsertJoinConnection(_pView,pNode->getChild(0), _eJoinType) && + InsertJoinConnection(_pView,pNode->getChild(2), _eJoinType); + } + else if (SQL_ISRULE(pNode,comparison_predicate)) + { + // Nur ein Vergleich auf Spalten ist erlaubt + DBG_ASSERT(pNode->count() == 3,"OQueryDesignView::InsertJoinConnection: Fehler im Parse Tree"); + if (!(SQL_ISRULE(pNode->getChild(0),column_ref) && + SQL_ISRULE(pNode->getChild(2),column_ref) && + pNode->getChild(1)->getNodeType() == SQL_NODE_EQUAL)) + return sal_False; + + OTableFieldDescRef aDragLeft = new OTableFieldDesc(); + OTableFieldDescRef aDragRight = new OTableFieldDesc(); + if (!FillDragInfo(_pView,pNode->getChild(0),aDragLeft) || + !FillDragInfo(_pView,pNode->getChild(2),aDragRight)) + return sal_False; + + OQueryTableView* pTableView = static_cast<OQueryTableView*>(_pView->getTableView()); + OQueryTableConnection* pConn = static_cast<OQueryTableConnection*>( pTableView->GetTabConn(static_cast<OQueryTableWindow*>(aDragLeft->GetTabWindow()),static_cast<OQueryTableWindow*>(aDragRight->GetTabWindow()))); + if(!pConn) + { + OQueryTableConnectionData aInfoData; + aInfoData.InitFromDrag(aDragLeft, aDragRight); + aInfoData.SetJoinType(_eJoinType); + + OQueryTableConnection aInfo(pTableView, &aInfoData); + // da ein OQueryTableConnection-Objekt nie den Besitz der uebergebenen Daten uebernimmt, sondern sich nur den Zeiger merkt, + // ist dieser Zeiger auf eine lokale Variable hier unkritisch, denn aInfoData und aInfo haben die selbe Lebensdauer + pTableView->NotifyTabConnection( aInfo ); + } + else + { + ::rtl::OUString aSourceFieldName(aDragLeft->GetField()); + ::rtl::OUString aDestFieldName(aDragRight->GetField()); + // the connection could point on the other side + if(pConn->GetSourceWin() == aDragRight->GetTabWindow()) + { + ::rtl::OUString aTmp(aSourceFieldName); + aSourceFieldName = aDestFieldName; + aDestFieldName = aTmp; + } + pConn->GetData()->AppendConnLine( aSourceFieldName,aDestFieldName); + pConn->UpdateLineList(); + // Modified-Flag + // SetModified(); + // und neu zeichnen + pConn->RecalcLines(); + // fuer das unten folgende Invalidate muss ich dieser neuen Connection erst mal die Moeglichkeit geben, + // ihr BoundingRect zu ermitteln + pConn->Invalidate(); + } + return sal_True; + } + return sal_False; + } + //------------------------------------------------------------------------------ + sal_Bool GetInnerJoinCriteria( const OQueryDesignView* _pView, + const ::connectivity::OSQLParseNode *pCondition) + { + return InsertJoinConnection(_pView,pCondition, INNER_JOIN); + } + //------------------------------------------------------------------------------ + ::rtl::OUString GenerateSelectList( const OQueryDesignView* _pView, + OTableFields& _rFieldList, + sal_Bool bAlias) + { + ::rtl::OUString aTmpStr,aFieldListStr; + + sal_Bool bAsterix = sal_False; + int nVis = 0; + OTableFields::iterator aIter = _rFieldList.begin(); + for(;aIter != _rFieldList.end();++aIter) + { + OTableFieldDescRef pEntryField = *aIter; + if(pEntryField->IsVisible()) + { + if(pEntryField->GetField().toChar() == '*') + bAsterix = sal_True; + ++nVis; + } + } + if(nVis == 1) + bAsterix = sal_False; + + Reference< XConnection> xConnection = static_cast<OQueryController*>(_pView->getController())->getConnection(); + if(!xConnection.is()) + return aFieldListStr; + + try + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString(); + + aIter = _rFieldList.begin(); + for(;aIter != _rFieldList.end();++aIter) + { + OTableFieldDescRef pEntryField = *aIter; + ::rtl::OUString rFieldName = pEntryField->GetField(); + if (rFieldName.getLength() && pEntryField->IsVisible()) + { + aTmpStr = ::rtl::OUString(); + ::rtl::OUString rAlias = pEntryField->GetAlias(); + ::rtl::OUString rFieldAlias = pEntryField->GetFieldAlias(); + if((bAlias || bAsterix) && rAlias.getLength()) + { + aTmpStr += ::dbtools::quoteName(aQuote,ConvertAlias(rAlias)); + aTmpStr += ::rtl::OUString('.'); + } + // we have to look if we have alias.* here + String sTemp = rFieldName; + if(sTemp.GetTokenCount('.') == 2) + rFieldName = sTemp.GetToken(1,'.'); + + if(pEntryField->GetTable().getLength() && rFieldName.toChar() != '*') + aTmpStr += ::dbtools::quoteName(aQuote, rFieldName).getStr(); + else + aTmpStr += rFieldName; + + if(pEntryField->GetFunctionType() == FKT_AGGREGATE) + { + DBG_ASSERT(pEntryField->GetFunction().getLength(),"Functionname darf hier nicht leer sein! ;-("); + ::rtl::OUString aTmpStr2(pEntryField->GetFunction()); + aTmpStr2 += ::rtl::OUString('('); + aTmpStr2 += aTmpStr; + aTmpStr2 += ::rtl::OUString(')'); + aTmpStr = aTmpStr2; + } + + if( rFieldAlias.getLength() && + (rFieldName.toChar() != '*' || + pEntryField->GetFunctionType() == FKT_AGGREGATE || + pEntryField->GetFunctionType() == FKT_OTHER)) + { + aTmpStr += ::rtl::OUString::createFromAscii(" AS "); + aTmpStr += ::dbtools::quoteName(aQuote, rFieldAlias); + } + aFieldListStr += aTmpStr; + aFieldListStr += ::rtl::OUString::createFromAscii(", "); + } + } + if(aFieldListStr.getLength()) + aFieldListStr = aFieldListStr.replaceAt(aFieldListStr.getLength()-2,2, ::rtl::OUString() ); + } + catch(SQLException&) + { + OSL_ASSERT(!"Failure while building select list!"); + } + return aFieldListStr; + } + //------------------------------------------------------------------------------ + sal_Bool GenerateCriterias( OQueryDesignView* _pView, + ::rtl::OUString& rRetStr, + ::rtl::OUString& rHavingStr, + OTableFields& _rFieldList, + sal_Bool bMulti ) + { + // * darf keine Filter enthalten : habe ich die entsprechende Warnung schon angezeigt ? + sal_Bool bCritsOnAsterikWarning = sal_False; // ** TMFS ** + + ::rtl::OUString aFieldName,aCriteria,aWhereStr,aHavingStr,aWork/*,aOrderStr*/; + // Zeilenweise werden die Ausdr"ucke mit AND verknuepft + sal_uInt16 nMaxCriteria = 0; + OTableFields::iterator aIter = _rFieldList.begin(); + for(;aIter != _rFieldList.end();++aIter) + { + nMaxCriteria = ::std::max<sal_uInt16>(nMaxCriteria,(*aIter)->GetCriteria().size()); + } + Reference< XConnection> xConnection = static_cast<OQueryController*>(_pView->getController())->getConnection(); + if(!xConnection.is()) + return FALSE; + try + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString(); + const OParseContext& rContext = static_cast<OQueryController*>(_pView->getController())->getParser()->getContext(); + + for (sal_uInt16 i=0 ; i < nMaxCriteria ; i++) + { + aHavingStr = aWhereStr = ::rtl::OUString(); + + for(aIter = _rFieldList.begin();aIter != _rFieldList.end();++aIter) + { + OTableFieldDescRef pEntryField = *aIter; + aFieldName = pEntryField->GetField(); + + if (!aFieldName.getLength()) + continue; + aCriteria = pEntryField->GetCriteria( i ); + if (aCriteria.getLength()) + { + if (aFieldName.toChar() == '*' && pEntryField->GetFunctionType() == FKT_NONE) // * darf keine Filter besitzen + { + // only show the messagebox the first time + if (!bCritsOnAsterikWarning) + ErrorBox(_pView, ModuleRes( ERR_QRY_CRITERIA_ON_ASTERISK)).Execute(); + bCritsOnAsterikWarning = sal_True; + continue; + } + aWork = ::rtl::OUString(); + + + if (bMulti) + { + if(pEntryField->GetFunctionType() == FKT_OTHER || (aFieldName.toChar() == '*')) + aWork += aFieldName; + else + aWork += ::dbtools::quoteName(aQuote, ConvertAlias(pEntryField->GetAlias())); + aWork += ::rtl::OUString('.'); + } + if(pEntryField->GetFunctionType() == FKT_OTHER || (aFieldName.toChar() == '*')) + aWork += aFieldName; + else + aWork += ::dbtools::quoteName(aQuote, aFieldName).getStr(); + + if(pEntryField->GetFunctionType() == FKT_AGGREGATE || pEntryField->IsGroupBy()) + { + if (!aHavingStr.getLength()) // noch keine Kriterien + aHavingStr += ::rtl::OUString('('); // Klammern + else + aHavingStr += C_AND; + + if(pEntryField->GetFunctionType() == FKT_AGGREGATE) + { + aHavingStr += pEntryField->GetFunction(); + aHavingStr += ::rtl::OUString('('); // Klammern + aHavingStr += aWork; + aHavingStr += ::rtl::OUString(')'); // Klammern + } + else + aHavingStr += aWork; + + ::rtl::OUString aTmp = aCriteria; + ::rtl::OUString aErrorMsg; + Reference<XPropertySet> xColumn; + ::connectivity::OSQLParseNode* pParseNode = _pView->getPredicateTreeFromEntry(pEntryField,aTmp,aErrorMsg,xColumn); + if (pParseNode) + { + if (bMulti && !(pEntryField->GetFunctionType() == FKT_OTHER || (aFieldName.toChar() == '*'))) + pParseNode->replaceNodeValue(ConvertAlias(pEntryField->GetAlias()),aFieldName); + ::rtl::OUString sHavingStr = aHavingStr; + OSL_ENSURE(pParseNode->count() == 3,"Count must be three here!"); + pParseNode->getChild(1)->parseNodeToStr( sHavingStr, + xMetaData, + &rContext, + sal_False, + pEntryField->GetFunctionType() != FKT_OTHER); + pParseNode->getChild(2)->parseNodeToStr( sHavingStr, + xMetaData, + &rContext, + sal_False, + pEntryField->GetFunctionType() != FKT_OTHER); + aHavingStr = sHavingStr; + delete pParseNode; + } + else + aHavingStr += aCriteria; + } + else + { + if (!aWhereStr.getLength()) // noch keine Kriterien + aWhereStr += ::rtl::OUString('('); // Klammern + else + aWhereStr += C_AND; + + aWhereStr += ::rtl::OUString(' '); + // aCriteria could have some german numbers so I have to be sure here + ::rtl::OUString aTmp = aCriteria; + ::rtl::OUString aErrorMsg; + Reference<XPropertySet> xColumn; + ::connectivity::OSQLParseNode* pParseNode = _pView->getPredicateTreeFromEntry(pEntryField,aTmp,aErrorMsg,xColumn); + if (pParseNode) + { + if (bMulti && !(pEntryField->GetFunctionType() == FKT_OTHER || (aFieldName.toChar() == '*'))) + pParseNode->replaceNodeValue(ConvertAlias(pEntryField->GetAlias()),aFieldName); + ::rtl::OUString aWhere = aWhereStr; + pParseNode->parseNodeToStr( aWhere, + xMetaData, + &rContext, + sal_False, + pEntryField->GetFunctionType() != FKT_OTHER); + aWhereStr = aWhere; + delete pParseNode; + } + else + { + aWhereStr += aWork; + aWhereStr += aCriteria; + } + } + } + // nur einmal fr jedes Feld + else if(!i && pEntryField->GetFunctionType() == FKT_CONDITION) + { + if (!aWhereStr.getLength()) // noch keine Kriterien + aWhereStr += ::rtl::OUString('('); // Klammern + else + aWhereStr += C_AND; + aWhereStr += pEntryField->GetField(); + } + } + if (aWhereStr.getLength()) + { + aWhereStr += ::rtl::OUString(')'); // Klammern zu fuer 'AND' Zweig + if (rRetStr.getLength()) // schon Feldbedingungen ? + rRetStr += C_OR; + else // Klammern auf fuer 'OR' Zweig + rRetStr += ::rtl::OUString('('); + rRetStr += aWhereStr; + } + if (aHavingStr.getLength()) + { + aHavingStr += ::rtl::OUString(')'); // Klammern zu fuer 'AND' Zweig + if (rHavingStr.getLength()) // schon Feldbedingungen ? + rHavingStr += C_OR; + else // Klammern auf fuer 'OR' Zweig + rHavingStr += ::rtl::OUString('('); + rHavingStr += aHavingStr; + } + } + + if (rRetStr.getLength()) + rRetStr += ::rtl::OUString(')'); // Klammern zu fuer 'OR' Zweig + if (rHavingStr.getLength()) + rHavingStr += ::rtl::OUString(')'); // Klammern zu fuer 'OR' Zweig + } + catch(SQLException&) + { + OSL_ASSERT(!"Failure while building where clause!"); + } + return sal_True; + } + //------------------------------------------------------------------------------ + ::rtl::OUString GenerateOrder( OQueryDesignView* _pView,OTableFields& _rFieldList,sal_Bool bMulti ) + { + + ::rtl::OUString aRetStr, aColumnName; + String aWorkStr; + Reference< XConnection> xConnection = static_cast<OQueryController*>(_pView->getController())->getConnection(); + if(!xConnection.is()) + return aRetStr; + + try + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString(); + // * darf keine Filter enthalten : habe ich die entsprechende Warnung schon angezeigt ? + sal_Bool bCritsOnAsterikWarning = sal_False; // ** TMFS ** + OTableFields::iterator aIter = _rFieldList.begin(); + + for(;aIter != _rFieldList.end();++aIter) + { + OTableFieldDescRef pEntryField = *aIter; + EOrderDir eOrder = pEntryField->GetOrderDir(); + + // nur wenn eine Sortierung und ein Tabellenname vorhanden ist-> erzeugen + // sonst werden die Expressions vom Order By im GenerateCriteria mit erzeugt + if (eOrder != ORDER_NONE && pEntryField->GetTable().getLength()) + { + aColumnName = pEntryField->GetField(); + if(aColumnName.toChar() == '*') + { + // die entsprechende MessageBox nur beim ersten mal anzeigen + if (!bCritsOnAsterikWarning) + ErrorBox(_pView, ModuleRes( ERR_QRY_ORDERBY_ON_ASTERISK)).Execute(); + bCritsOnAsterikWarning = sal_True; + continue; + } + if(pEntryField->GetFunctionType() == FKT_NONE) + { + if (bMulti && pEntryField->GetAlias().getLength()) + { + aWorkStr += ::dbtools::quoteName(aQuote, ConvertAlias(pEntryField->GetAlias())).getStr(); + aWorkStr += String('.'); + } + aWorkStr += ::dbtools::quoteName(aQuote, aColumnName).getStr(); + } + else if(pEntryField->GetFieldAlias().getLength()) + { + aWorkStr += ::dbtools::quoteName(aQuote, pEntryField->GetFieldAlias()).getStr(); + } + else if(pEntryField->GetFunctionType() == FKT_AGGREGATE) + { + DBG_ASSERT(pEntryField->GetFunction().getLength(),"Functionname darf hier nicht leer sein! ;-("); + aWorkStr += pEntryField->GetFunction().getStr(); + aWorkStr += String('('); + if (bMulti && pEntryField->GetAlias().getLength()) + { + aWorkStr += ::dbtools::quoteName(aQuote, ConvertAlias(pEntryField->GetAlias())).getStr(); + aWorkStr += String('.'); + } + aWorkStr += ::dbtools::quoteName(aQuote, aColumnName).getStr(); + aWorkStr += String(')'); + } + else + { + if (bMulti && pEntryField->GetAlias().getLength()) + { + aWorkStr += ::dbtools::quoteName(aQuote, ConvertAlias(pEntryField->GetAlias())).getStr(); + aWorkStr += String('.'); + } + aWorkStr += ::dbtools::quoteName(aQuote, aColumnName).getStr(); + } + aWorkStr += String(' '); + aWorkStr += String::CreateFromAscii( ";ASC;DESC" ).GetToken( eOrder ); + aWorkStr += String(','); + } + } + + aWorkStr.EraseTrailingChars( ',' ); + + if( aWorkStr.Len() ) + { + sal_Int32 nMaxOrder = xMetaData->getMaxColumnsInOrderBy(); + if(nMaxOrder && nMaxOrder < aWorkStr.GetTokenCount(',')) + { + ErrorBox aBox( _pView, ModuleRes( ERR_QRY_TOO_LONG_STATEMENT ) ); + aBox.Execute(); + } + else + { + aRetStr = ::rtl::OUString::createFromAscii(" ORDER BY "); + aRetStr += aWorkStr; + } + } + } + catch(SQLException&) + { + OSL_ASSERT(!"Failure while building group by!"); + } + + return aRetStr; + } + + //------------------------------------------------------------------------------ + + ::rtl::OUString BuildACriteria( const OQueryDesignView* _pView,const ::rtl::OUString& _rVal, sal_Int32 aType ) + { + + ::rtl::OUString aRetStr; + String aVal,rVal; + String aOpList;aOpList.AssignAscii("<>;>=;<=;<;>;=;LIKE"); + xub_StrLen nOpListCnt = aOpList.GetTokenCount(); + + String aToken; + for( xub_StrLen nIdx=0 ; nIdx < nOpListCnt ; nIdx++ ) + { + aToken = aOpList.GetToken(nIdx); + if (rVal.Search( aToken ) == 0) + { + aRetStr = ::rtl::OUString(' '); + aRetStr += aToken; + aRetStr += ::rtl::OUString(' '); + aVal = rVal.Copy( aToken.Len() ); + aVal.EraseLeadingChars( ' ' ); + if( aVal.Search( '\'' ) == STRING_NOTFOUND )//XXX O'Brien??? + { + aVal = QuoteField(_pView, aVal, aType ); + } + aRetStr += aVal; + break; + } + } + + if( !aRetStr.getLength()) // == 0 + { + aRetStr = rVal.Search( '%' ) == STRING_NOTFOUND ? ::rtl::OUString::createFromAscii(" = ") : ::rtl::OUString::createFromAscii(" LIKE "); + aVal = rVal; + if( aVal.Search( '\'' ) == STRING_NOTFOUND )//XXX O'Brien??? + { + aVal = QuoteField( _pView,aVal, aType ); + } + aRetStr += aVal; + } + + return aRetStr;//XXX + } + //------------------------------------------------------------------------------ + void GenerateInnerJoinCriterias(const OQueryDesignView* _pView, + ::rtl::OUString& _rJoinCrit, + const ::std::vector<OTableConnection*>* _pConnList) + { + ::std::vector<OTableConnection*>::const_iterator aIter = _pConnList->begin(); + for(;aIter != _pConnList->end();++aIter) + { + const OQueryTableConnection* pEntryConn = static_cast<const OQueryTableConnection*>(*aIter); + OQueryTableConnectionData* pEntryConnData = static_cast<OQueryTableConnectionData*>(pEntryConn->GetData()); + if(pEntryConnData->GetJoinType() == INNER_JOIN) + { + if(_rJoinCrit.getLength()) + _rJoinCrit += C_AND; + _rJoinCrit += BuildJoinCriteria(_pView,pEntryConnData->GetConnLineDataList(),pEntryConnData); + } + } + } + //------------------------------------------------------------------------------ + ::rtl::OUString GenerateFromClause( const OQueryDesignView* _pView, + const OQueryTableView::OTableWindowMap* pTabList, + ::std::vector<OTableConnection*>* pConnList) + { + + ::rtl::OUString aTableListStr; + // wird gebraucht um sicher zustelllen das eine Tabelle nicht doppelt vorkommt + + // generate outer join clause in from + if(!pConnList->empty()) + { + ::std::vector<OTableConnection*>::iterator aIter = pConnList->begin(); + for(;aIter != pConnList->end();++aIter) + static_cast<OQueryTableConnection*>(*aIter)->SetVisited(sal_False); + + aIter = pConnList->begin(); + for(;aIter != pConnList->end();++aIter) + { + OQueryTableConnection* pEntryConn = static_cast<OQueryTableConnection*>(*aIter); + if(!pEntryConn->IsVisited()) + { + ::rtl::OUString aJoin; + GetNextJoin(_pView,pEntryConn,static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin()),aJoin); + + if(aJoin.getLength()) + { + ::rtl::OUString aStr = ::rtl::OUString::createFromAscii("{ OJ "); + aStr += aJoin; + aStr += ::rtl::OUString::createFromAscii(" },"); + aTableListStr += aStr; + } + } + } + + // and now all inner joins + map< ::rtl::OUString,sal_Bool,::comphelper::UStringMixLess> aTableNames; + aIter = pConnList->begin(); + for(;aIter != pConnList->end();++aIter) + { + OQueryTableConnection* pEntryConn = static_cast<OQueryTableConnection*>(*aIter); + if(!pEntryConn->IsVisited()) + { + ::rtl::OUString aTabName(BuildTable(_pView,static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin()))); + if(aTableNames.find(aTabName) == aTableNames.end()) + { + aTableNames[aTabName] = sal_True; + aTableListStr += aTabName; + aTableListStr += ::rtl::OUString(','); + } + aTabName = BuildTable(_pView,static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin())); + if(aTableNames.find(aTabName) == aTableNames.end()) + { + aTableNames[aTabName] = sal_True; + aTableListStr += aTabName; + aTableListStr += ::rtl::OUString(','); + } + } + } + } + // all tables that haven't a connection to anyone + OQueryTableView::OTableWindowMap::const_iterator aTabIter = pTabList->begin(); + for(;aTabIter != pTabList->end();++aTabIter) + { + const OQueryTableWindow* pEntryTab = static_cast<const OQueryTableWindow*>(aTabIter->second); + if(!pEntryTab->ExistsAConn()) + { + aTableListStr += BuildTable(_pView,pEntryTab); + aTableListStr += ::rtl::OUString(','); + } + } + + if(aTableListStr.getLength()) + aTableListStr = aTableListStr.replaceAt(aTableListStr.getLength()-1,1, ::rtl::OUString() ); + return aTableListStr; + } + //------------------------------------------------------------------------------ + ::rtl::OUString GenerateGroupBy(const OQueryDesignView* _pView,OTableFields& _rFieldList, sal_Bool bMulti ) + { + + Reference< XConnection> xConnection = static_cast<OQueryController*>(_pView->getController())->getConnection(); + if(!xConnection.is()) + return ::rtl::OUString(); + + ::rtl::OUString aGroupByStr; + try + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString(); + + OTableFields::iterator aIter = _rFieldList.begin(); + for(;aIter != _rFieldList.end();++aIter) + { + OTableFieldDescRef pEntryField = *aIter; + if(pEntryField->IsGroupBy()) + { + DBG_ASSERT(pEntryField->GetField().getLength(),"Kein FieldName vorhanden!;-("); + if (bMulti) + { + aGroupByStr += ::dbtools::quoteName(aQuote, ConvertAlias(pEntryField->GetAlias())); + aGroupByStr += ::rtl::OUString('.'); + } + + aGroupByStr += ::dbtools::quoteName(aQuote, pEntryField->GetField()); + aGroupByStr += ::rtl::OUString(','); + } + } + if(aGroupByStr.getLength()) + { + aGroupByStr = aGroupByStr.replaceAt(aGroupByStr.getLength()-1,1, ::rtl::OUString(' ') ); + ::rtl::OUString aGroupByStr2 = ::rtl::OUString::createFromAscii(" GROUP BY "); + aGroupByStr2 += aGroupByStr; + aGroupByStr = aGroupByStr2; + } + } + catch(SQLException&) + { + OSL_ASSERT(!"Failure while building group by!"); + } + return aGroupByStr; + } + // ----------------------------------------------------------------------------- + int GetORCriteria( OQueryDesignView* _pView, + OSelectionBrowseBox* _pSelectionBrw, + const ::connectivity::OSQLParseNode * pCondition, + int& nLevel , + sal_Bool bHaving = sal_False); + // ----------------------------------------------------------------------------- + int GetSelectionCriteria( OQueryDesignView* _pView, + OSelectionBrowseBox* _pSelectionBrw, + const ::connectivity::OSQLParseNode* pNode, + int& rLevel, + sal_Bool bJoinWhere = sal_False) + { + + // Naechster freier Satz ... + int nRet = 0; + int nJoins=0; + + if (!SQL_ISRULE(pNode, select_statement)) + { + ErrorBox aBox( _pView, ModuleRes( ERR_QRY_NOSELECT ) ); + aBox.Execute(); + return 1; + } + + // nyi: mehr Pruefung auf korrekte Struktur! + pNode = pNode ? pNode->getChild(3)->getChild(1) : NULL; + // Keine WHERE-Klausel. + if (!pNode || pNode->isLeaf()) + return nRet; + + ::connectivity::OSQLParseNode * pCondition = pNode->getChild(1); + if (!pCondition) // kein where clause + return nRet; + + // jetzt die anderen Bedingungen eintragen + ::connectivity::OSQLParseNode::negateSearchCondition(pCondition); + + ::connectivity::OSQLParseNode *pNodeTmp = pNode->getChild(1); + ::connectivity::OSQLParseNode::disjunctiveNormalForm(pNodeTmp); + pNodeTmp = pNode->getChild(1); + ::connectivity::OSQLParseNode::absorptions(pNodeTmp); + pNodeTmp = pNode->getChild(1); + + // first extract the inner joins conditions + GetInnerJoinCriteria(_pView,pNodeTmp); + + // it could happen that pCondition is not more valid + nRet = GetORCriteria(_pView,_pSelectionBrw,pNodeTmp, rLevel); + + if (nRet != 0) // mindestens eine OR Verknuepfung + { + ErrorBox aBox( _pView, ModuleRes( ERR_QRY_TOOCOMPLEX ) ); + aBox.Execute(); + return 99; + } + return nRet; + } + //------------------------------------------------------------------------------ + int GetANDCriteria( OQueryDesignView* _pView, + OSelectionBrowseBox* _pSelectionBrw, + const ::connectivity::OSQLParseNode * pCondition, + const int nLevel, + sal_Bool bHaving ); + //------------------------------------------------------------------------------ + int ComparsionPredicate(OQueryDesignView* _pView, + OSelectionBrowseBox* _pSelectionBrw, + const ::connectivity::OSQLParseNode * pCondition, + const int nLevel, + sal_Bool bHaving ); + //------------------------------------------------------------------------------ + int GetORCriteria( OQueryDesignView* _pView, + OSelectionBrowseBox* _pSelectionBrw, + const ::connectivity::OSQLParseNode * pCondition, + int& nLevel , + sal_Bool bHaving) + { + int nRet = 0; + + // Runde Klammern um den Ausdruck + if (pCondition->count() == 3 && + SQL_ISPUNCTUATION(pCondition->getChild(0),"(") && + SQL_ISPUNCTUATION(pCondition->getChild(2),")")) + { + nRet = GetORCriteria(_pView,_pSelectionBrw,pCondition->getChild(1),nLevel,bHaving); + } + // oder Verknuepfung + // a searchcondition can only look like this: search_condition SQL_TOKEN_OR boolean_term + else if (SQL_ISRULE(pCondition,search_condition)) + { + for (int i = 0; i < 3; i+=2) + { + // Ist das erste Element wieder eine OR-Verknuepfung? + // Dann rekursiv absteigen ... + //if (!i && SQL_ISRULE(pCondition->getChild(i),search_condition)) + if (SQL_ISRULE(pCondition->getChild(i),search_condition)) + { + nRet = GetORCriteria(_pView,_pSelectionBrw,pCondition->getChild(i),nLevel,bHaving); + } + else if (!nRet) + { + nRet = GetANDCriteria(_pView,_pSelectionBrw,pCondition->getChild(i), nLevel++,bHaving); + } + else + { + ErrorBox aBox( _pView, ModuleRes( ERR_QRY_TOOMANYCOND ) ); + aBox.Execute(); + return 1; + } + } + } + else + { + nRet = GetANDCriteria( _pView,_pSelectionBrw,pCondition, nLevel, bHaving ); + } + return nRet; + } + //-------------------------------------------------------------------------------------------------- + int GetANDCriteria( OQueryDesignView* _pView, + OSelectionBrowseBox* _pSelectionBrw, + const ::connectivity::OSQLParseNode * pCondition, + const int nLevel, + sal_Bool bHaving ) + { + ::com::sun::star::lang::Locale aLocale = _pView->getLocale(); + ::rtl::OUString sDecimal = _pView->getDecimalSeparator(); + + // ich werde ein paar Mal einen gecasteten Pointer auf meinen ::com::sun::star::sdbcx::Container brauchen + OQueryController* pController = static_cast<OQueryController*>(_pView->getController()); + int nRet = 0; + + // Runde Klammern + if (SQL_ISRULE(pCondition,boolean_primary)) + { + int nLevel2 = nLevel; + nRet = GetORCriteria(_pView,_pSelectionBrw,pCondition->getChild(1), nLevel2,bHaving ); + } + // Das erste Element ist (wieder) eine AND-Verknuepfung + else if ( SQL_ISRULE(pCondition,boolean_term) && pCondition->count() == 3 ) + { + nRet = GetANDCriteria(_pView,_pSelectionBrw,pCondition->getChild(0), nLevel,bHaving ); + if (!nRet) + nRet = GetANDCriteria(_pView,_pSelectionBrw,pCondition->getChild(2), nLevel,bHaving ); + } + else if (SQL_ISRULE( pCondition, comparison_predicate)) + { + nRet = ComparsionPredicate(_pView,_pSelectionBrw,pCondition,nLevel,bHaving); + } + else if((SQL_ISRULE(pCondition,like_predicate))) + { + ::rtl::OUString aCondition; + OTableFieldDescRef aDragLeft = new OTableFieldDesc(); + if(SQL_ISRULE(pCondition->getChild(0), column_ref )) + { + ::rtl::OUString aColumnName; + Reference< XConnection> xConnection = pController->getConnection(); + if(xConnection.is()) + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + // the international doesn't matter I have a string + pCondition->parseNodeToPredicateStr(aCondition, + xMetaData, + pController->getNumberFormatter(), + aLocale, + static_cast<sal_Char>(sDecimal.toChar()), + &pController->getParser()->getContext()); + + pCondition->getChild(0)->parseNodeToPredicateStr( aColumnName, + xMetaData, + pController->getNumberFormatter(), + aLocale, + static_cast<sal_Char>(sDecimal.toChar()), + &pController->getParser()->getContext()); + + // don't display the column name + aCondition = aCondition.copy(aColumnName.getLength()); + aCondition = aCondition.trim(); + } + + if (FillDragInfo(_pView,pCondition->getChild(0),aDragLeft)) + _pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel); + else + { + ErrorBox( _pView, ModuleRes( ERR_QRY_SYNTAX ) ).Execute(); + nRet = 5; + } + } + else + { + ErrorBox( _pView, ModuleRes( ERR_QRY_SYNTAX ) ).Execute(); + nRet = 5; + } + } + else if( SQL_ISRULE(pCondition,test_for_null) + || SQL_ISRULE(pCondition,in_predicate) + || SQL_ISRULE(pCondition,all_or_any_predicate) + || SQL_ISRULE(pCondition,between_predicate)) + { + ::rtl::OUString aCondition; + OTableFieldDescRef aDragLeft = new OTableFieldDesc(); + if(SQL_ISRULE(pCondition->getChild(0), column_ref )) + { + // parse condition + Reference< XConnection> xConnection = pController->getConnection(); + if(xConnection.is()) + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + for(sal_uInt16 i=1;i< pCondition->count();i++) + pCondition->getChild(i)->parseNodeToPredicateStr(aCondition, + xMetaData, + pController->getNumberFormatter(), + aLocale, + static_cast<sal_Char>(sDecimal.toChar()), + &pController->getParser()->getContext()); + } + } + + if (FillDragInfo(_pView,pCondition->getChild(0),aDragLeft)) + _pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel); + else + { + ErrorBox( _pView, ModuleRes( ERR_QRY_SYNTAX ) ).Execute(); + nRet = 5; + } + } + else if((SQL_ISRULE(pCondition,existence_test) || SQL_ISRULE(pCondition,unique_test))) + { + ::rtl::OUString aCondition; + OTableFieldDescRef aDragLeft = new OTableFieldDesc(); + + // Funktions-Bedingung parsen + Reference< XConnection> xConnection = pController->getConnection(); + if(xConnection.is()) + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + for(sal_uInt16 i=0;i< pCondition->count();i++) + pCondition->getChild(i)->parseNodeToPredicateStr(aCondition, + xMetaData, + pController->getNumberFormatter(), + aLocale, + static_cast<sal_Char>(sDecimal.toChar()), + &pController->getParser()->getContext()); + } + + aDragLeft->SetField(aCondition); + aDragLeft->SetFunctionType(FKT_CONDITION); + + _pSelectionBrw->InsertField(aDragLeft,-1,sal_False,sal_True); + } + else + { + // Etwas anderes unterstuetzen wir (noch) nicht. Basta! + ErrorBox( _pView, ModuleRes( ERR_QRY_SYNTAX ) ).Execute(); + nRet = 5; + } + // Fehler einfach weiterreichen. + return nRet; + } + //------------------------------------------------------------------------------ + int ComparsionPredicate(OQueryDesignView* _pView, + OSelectionBrowseBox* _pSelectionBrw, + const ::connectivity::OSQLParseNode * pCondition, + const int nLevel, + sal_Bool bHaving ) + { + OQueryController* pController = static_cast<OQueryController*>(_pView->getController()); + + DBG_ASSERT(SQL_ISRULE( pCondition, comparison_predicate),"ComparsionPredicate: pCondition ist kein ComparsionPredicate"); + sal_uInt32 nRet = 0; + if(SQL_ISRULE(pCondition->getChild(0), column_ref ) || SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref )) + { + ::rtl::OUString aCondition; + OTableFieldDescRef aDragLeft = new OTableFieldDesc(); + sal_uInt32 nPos; + if(SQL_ISRULE(pCondition->getChild(0), column_ref ) && SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref )) + { + OTableFieldDescRef aDragRight = new OTableFieldDesc(); + if (!FillDragInfo(_pView,pCondition->getChild(0),aDragLeft) || + !FillDragInfo(_pView,pCondition->getChild(2),aDragRight)) + return nRet; + + OQueryTableConnection* pConn = static_cast<OQueryTableConnection*>(_pView->getTableView()->GetTabConn(static_cast<OQueryTableWindow*>(aDragLeft->GetTabWindow()), + static_cast<OQueryTableWindow*>(aDragRight->GetTabWindow()))); + if(pConn) + { + OConnectionLineDataVec* pLineDataList = pConn->GetData()->GetConnLineDataList(); + OConnectionLineDataVec::iterator aIter = pLineDataList->begin(); + for(;aIter != pLineDataList->end();++aIter) + { + if((*aIter)->GetSourceFieldName() == aDragLeft->GetField() || + (*aIter)->GetDestFieldName() == aDragLeft->GetField() ) + break; + } + if(aIter != pLineDataList->end()) + return 0; + } + } + + if(SQL_ISRULE(pCondition->getChild(0), column_ref )) + { + nPos = 0; + sal_uInt32 i=1; + + // don't display the equal + if (pCondition->getChild(i)->getNodeType() == SQL_NODE_EQUAL) + i++; + + // Bedingung parsen + Reference< XConnection> xConnection = pController->getConnection(); + if(xConnection.is()) + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + for(;i< pCondition->count();i++) + pCondition->getChild(i)->parseNodeToPredicateStr(aCondition, + xMetaData, + pController->getNumberFormatter(), + _pView->getLocale(), + static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()), + &pController->getParser()->getContext()); + } + } + else if(SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref )) + { + nPos = pCondition->count()-1; + + sal_uInt32 i = pCondition->count() - 2; + switch (pCondition->getChild(i)->getNodeType()) + { + case SQL_NODE_EQUAL: + // don't display the equal + i--; + break; + case SQL_NODE_LESS: + // take the opposite as we change the order + i--; + aCondition = aCondition + ::rtl::OUString::createFromAscii(">"); + break; + case SQL_NODE_LESSEQ: + // take the opposite as we change the order + i--; + aCondition = aCondition + ::rtl::OUString::createFromAscii(">="); + break; + case SQL_NODE_GREAT: + // take the opposite as we change the order + i--; + aCondition = aCondition + ::rtl::OUString::createFromAscii("<"); + break; + case SQL_NODE_GREATEQ: + // take the opposite as we change the order + i--; + aCondition = aCondition + ::rtl::OUString::createFromAscii("<="); + break; + } + + // go backward + Reference< XConnection> xConnection = pController->getConnection(); + if(xConnection.is()) + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + for (; i >= 0; i--) + pCondition->getChild(i)->parseNodeToPredicateStr(aCondition, + xMetaData, + pController->getNumberFormatter(), + _pView->getLocale(), + static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()), + &pController->getParser()->getContext()); + } + } + if(FillDragInfo(_pView,pCondition->getChild(nPos),aDragLeft)) + { + if(bHaving) + aDragLeft->SetGroupBy(sal_True); + _pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel); + } + else + { + ErrorBox( _pView, ModuleRes( ERR_QRY_SYNTAX ) ).Execute(); + nRet = 5; + } + } + else if(SQL_ISRULE(pCondition->getChild(0), set_fct_spec ) || SQL_ISRULE(pCondition->getChild(0), general_set_fct )) + { + ::rtl::OUString aName, + aCondition; + OTableFieldDescRef aDragLeft = new OTableFieldDesc(); + + OSQLParseNode* pFunction = pCondition->getChild(0); + + ::rtl::OUString aColumnName; + Reference< XConnection> xConnection = pController->getConnection(); + if(xConnection.is()) + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + pCondition->parseNodeToPredicateStr(aCondition, + xMetaData, + pController->getNumberFormatter(), + _pView->getLocale(), + static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()), + &pController->getParser()->getContext()); + + pFunction->parseNodeToPredicateStr(aColumnName, + xMetaData, + pController->getNumberFormatter(), + _pView->getLocale(), + static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()), + &pController->getParser()->getContext()); + // don't display the column name + aCondition = aCondition.copy(aColumnName.getLength()); + aCondition = aCondition.trim(); + if(aCondition.indexOf('=',0) == 1) // ignore the equal sign + aCondition = aCondition.copy(1); + + + if(SQL_ISRULE(pFunction, general_set_fct )) + { + if(!FillDragInfo(_pView,pFunction->getChild(pFunction->count()-2),aDragLeft)) + { + OSL_ENSURE(pFunction->count() > 3,"Invalid format for general_set_fct!"); + ::rtl::OUString sParameterValue; + pFunction->getChild(pFunction->count()-2)->parseNodeToPredicateStr(sParameterValue, + xMetaData, + pController->getNumberFormatter(), + _pView->getLocale(), + static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()), + &pController->getParser()->getContext()); + aDragLeft->SetField(sParameterValue); + } + aDragLeft->SetFunctionType(FKT_AGGREGATE); + if(bHaving) + aDragLeft->SetGroupBy(sal_True); + sal_Int32 nIndex = 0; + aDragLeft->SetFunction(aColumnName.getToken(0,'(',nIndex)); + } + else + { + // bei unbekannten Funktionen wird der gesamte Text in das Field gechrieben + aDragLeft->SetField(aColumnName); + if(bHaving) + aDragLeft->SetGroupBy(sal_True); + aDragLeft->SetFunctionType(FKT_OTHER); + } + _pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel); + } + } + else // kann sich nur um einen Expr. Ausdruck handeln + { + OTableFieldDescRef aDragLeft = new OTableFieldDesc(); + ::rtl::OUString aName,aCondition; + + ::connectivity::OSQLParseNode *pLhs = pCondition->getChild(0); + ::connectivity::OSQLParseNode *pRhs = pCondition->getChild(2); + // Feldnamen + Reference< XConnection> xConnection = pController->getConnection(); + if(xConnection.is()) + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + for(sal_uInt16 i=0;i< pLhs->count();i++) + pCondition->getChild(i)->parseNodeToStr(aName, + xMetaData, + &pController->getParser()->getContext(), + sal_True); + // Kriterium + aCondition = pCondition->getChild(1)->getTokenValue(); + for(i=0;i< pRhs->count();i++) + pCondition->getChild(i)->parseNodeToPredicateStr(aCondition, + xMetaData, + pController->getNumberFormatter(), + _pView->getLocale(), + static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()), + &pController->getParser()->getContext()); + } + + aDragLeft->SetField(aName); + aDragLeft->SetFunctionType(FKT_OTHER); + // und anh"angen + _pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel); + } + return nRet; + } + //------------------------------------------------------------------------------ + int InsertColumnRef(const OQueryDesignView* _pView, + const ::connectivity::OSQLParseNode * pColumnRef, + ::rtl::OUString& aColumnName, + const ::rtl::OUString& aColumnAlias, + ::rtl::OUString& aTableRange, + OTableFieldDescRef& _raInfo, + OJoinTableView::OTableWindowMap* pTabList) + { + + // Tabellennamen zusammen setzen + ::connectivity::OSQLParseTreeIterator& rParseIter = static_cast<OQueryController*>(_pView->getController())->getParseIterator(); + rParseIter.getColumnRange( pColumnRef, aColumnName, aTableRange ); + + DBG_ASSERT(aColumnName.getLength(),"Columnname darf nicht leer sein"); + if (!aTableRange.getLength()) + { + // SELECT column, ... + sal_Bool bFound(sal_False); + OJoinTableView::OTableWindowMap::iterator aIter = pTabList->begin(); + for(;aIter != pTabList->end();++aIter) + { + OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second); + if (pTabWin->ExistsField( aColumnName, _raInfo ) ) + { + if(aColumnName.toChar() != '*') + _raInfo->SetFieldAlias(aColumnAlias); + bFound = sal_True; + break; + } + } + if (!bFound) + { + _raInfo->SetTable(::rtl::OUString()); + _raInfo->SetAlias(::rtl::OUString()); + _raInfo->SetField(aColumnName); + _raInfo->SetFieldAlias(aColumnAlias); // nyi : hier ein fortlaufendes Expr_1, Expr_2 ... + _raInfo->SetFunctionType(FKT_OTHER); + } + } + else + { + // SELECT range.column, ... + OQueryTableWindow* pTabWin = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable(aTableRange); + + if (pTabWin && pTabWin->ExistsField(aColumnName, _raInfo)) + { + if(aColumnName.toChar() != '*') + _raInfo->SetFieldAlias(aColumnAlias); + } + else + { + _raInfo->SetTable(::rtl::OUString()); + _raInfo->SetAlias(::rtl::OUString()); + _raInfo->SetField(aColumnName); + _raInfo->SetFieldAlias(aColumnAlias); // nyi : hier ein fortlaufendes Expr_1, Expr_2 ... + _raInfo->SetFunctionType(FKT_OTHER); + } + } + return 0; + } + //----------------------------------------------------------------------------- + sal_Bool InsertJoin(const OQueryDesignView* _pView,const ::connectivity::OSQLParseNode *pNode) + { + DBG_ASSERT(SQL_ISRULE(pNode, qualified_join) || SQL_ISRULE(pNode, joined_table), + "OQueryDesignView::InsertJoin: Fehler im Parse Tree"); + + if (SQL_ISRULE(pNode,joined_table)) + return InsertJoin(_pView,pNode->getChild(1)); + + if (SQL_ISRULE(pNode->getChild(0),qualified_join)) + { + if (!InsertJoin(_pView,pNode->getChild(0))) + return sal_False; + } + else if (SQL_ISRULE(pNode->getChild(0), joined_table)) + { + if (!InsertJoin(_pView,pNode->getChild(0)->getChild(1))) + return sal_False; + } + else if (!(SQL_ISRULE(pNode->getChild(0), table_ref) && ( + SQL_ISRULE(pNode->getChild(0)->getChild(0), catalog_name) || + SQL_ISRULE(pNode->getChild(0)->getChild(0), schema_name) || + SQL_ISRULE(pNode->getChild(0)->getChild(0), table_name)))) + return sal_False; + + // geschachtelter join? + if (SQL_ISRULE(pNode->getChild(3),qualified_join)) + { + if (!InsertJoin(_pView,pNode->getChild(3))) + return sal_False; + } + else if (SQL_ISRULE(pNode->getChild(3), joined_table)) + { + if (!InsertJoin(_pView,pNode->getChild(3)->getChild(1))) + return sal_False; + } + // sonst sollte es eine Tabelle sein + else if (!(SQL_ISRULE(pNode->getChild(3), table_ref) && ( + SQL_ISRULE(pNode->getChild(3)->getChild(0), catalog_name) || + SQL_ISRULE(pNode->getChild(3)->getChild(0), schema_name) || + SQL_ISRULE(pNode->getChild(3)->getChild(0), table_name)))) + return sal_False; + + // named column join wird spter vieleicht noch implementiert + // SQL_ISRULE(pNode->getChild(4),named_columns_join) + if (SQL_ISRULE(pNode->getChild(4),join_condition)) + { + EJoinType eJoinType; + ::connectivity::OSQLParseNode* pJoinType = pNode->getChild(1); // join_type + if (SQL_ISRULE(pJoinType,join_type) && SQL_ISTOKEN(pJoinType->getChild(0),INNER)) + { + eJoinType = INNER_JOIN; + } + else + { + if (SQL_ISRULE(pJoinType,join_type)) // eine Ebene tiefer + pJoinType = pJoinType->getChild(0); + + if (SQL_ISTOKEN(pJoinType->getChild(0),LEFT)) + eJoinType = LEFT_JOIN; + else if(SQL_ISTOKEN(pJoinType->getChild(0),RIGHT)) + eJoinType = RIGHT_JOIN; + else + eJoinType = FULL_JOIN; + } + if(!InsertJoinConnection(_pView,pNode->getChild(4)->getChild(1), eJoinType)) + return sal_False; + } + else + return sal_False; + + return sal_True; + } + //------------------------------------------------------------------------------ + void InitFromParseNodeImpl(OQueryDesignView* _pView,OSelectionBrowseBox* _pSelectionBrw) + { + _pSelectionBrw->PreFill(); + _pSelectionBrw->Fill(); + + OQueryController* pController = static_cast<OQueryController*>(_pView->getController()); + ::connectivity::OSQLParseTreeIterator& aIterator = pController->getParseIterator(); + const ::connectivity::OSQLParseNode* pParseTree = aIterator.getParseTree(); + const ::connectivity::OSQLParseNode* pTableRefCommaList = 0; + + if (pParseTree) + { + if (!pController->isEsacpeProcessing()) + { + WarningBox( _pView, ModuleRes(WARN_QRY_NATIVE) ).Execute(); + } + else if (SQL_ISRULE(pParseTree,select_statement)) + { + + ::connectivity::OSQLParseNode* pTree = pParseTree->getChild(1); + + const OSQLTables& aMap = aIterator.getTables(); + ::comphelper::UStringMixLess aTmp(aMap.key_comp()); + ::comphelper::UStringMixEqual aKeyComp(static_cast< ::comphelper::UStringMixLess*>(&aTmp)->isCaseSensitive()); + + Reference< XConnection> xConnection = pController->getConnection(); + if(xConnection.is()) + { + sal_Int32 nMax = 0; + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + try + { + nMax = xMetaData->getMaxTablesInSelect(); + + if(!nMax || nMax >= (sal_Int32)aMap.size()) // Anzahl der Tabellen im Select-Statement "uberpr"ufen + { + ::rtl::OUString sComposedName; + ::rtl::OUString aQualifierName; + ::rtl::OUString sAlias; + + OQueryTableView* pTableView = static_cast<OQueryTableView*>(_pView->getTableView()); + OSQLTables::const_iterator aIter = aMap.begin(); + for(;aIter != aMap.end();++aIter) + { + OSQLTable xTable = aIter->second; + ::dbaui::composeTableName(xMetaData,Reference<XPropertySet>(xTable,UNO_QUERY),sComposedName,sal_False); + sAlias = aIter->first; + if(aKeyComp(sComposedName,aIter->first)) + { + ::rtl::OUString sCatalog,sSchema,sTable; + ::dbtools::qualifiedNameComponents(xMetaData,sComposedName,sCatalog,sSchema,sTable); + sAlias = sTable; + } + + + OQueryTableWindow* pExistentWin = pTableView->FindTable(sAlias); + if (!pExistentWin) + { + pTableView->AddTabWin(sComposedName, sAlias,sal_False);// don't create data here + } + else + { + // es existiert schon ein Fenster mit dem selben Alias ... + if (!aKeyComp(pExistentWin->GetData()->GetComposedName(),sComposedName)) + // ... aber anderem Tabellennamen -> neues Fenster + pTableView->AddTabWin(sComposedName, sAlias); + } + } + + // now delete the data for which we haven't any tablewindow + OJoinTableView::OTableWindowMap* pTableMap = pTableView->GetTabWinMap(); + OJoinTableView::OTableWindowMap::iterator aIterTableMap = pTableMap->begin(); + for(;aIterTableMap != pTableMap->end();++aIterTableMap) + { + if(aMap.find(aIterTableMap->second->GetComposedName()) == aMap.end() && + aMap.find(aIterTableMap->first) == aMap.end()) + pTableView->RemoveTabWin(aIterTableMap->second); + } + + FillOuterJoins(_pView,pParseTree->getChild(3)->getChild(0)->getChild(1)); + + // check if we have a distinct statement + if(SQL_ISTOKEN(pParseTree->getChild(1),DISTINCT)) + { + pController->setDistinct(sal_True); + pController->InvalidateFeature(ID_BROWSER_QUERY_DISTINCT_VALUES); + } + if (!InstallFields(_pView,pParseTree, pTableView->GetTabWinMap())) + { + // GetSelectionCriteria mu"s vor GetHavingCriteria aufgerufen werden + int nLevel=0; + + GetSelectionCriteria(_pView,_pSelectionBrw,pParseTree,nLevel,sal_True); + GetGroupCriteria(_pView,_pSelectionBrw,pParseTree); + GetHavingCriteria(_pView,_pSelectionBrw,pParseTree,nLevel); + GetOrderCriteria(_pView,_pSelectionBrw,pParseTree); + // now we have to insert the fields which aren't in the statement + OTableFields& rUnUsedFields = pController->getUnUsedFields(); + for(OTableFields::iterator aIter = rUnUsedFields.begin();aIter != rUnUsedFields.end();++aIter) + if(_pSelectionBrw->InsertField(*aIter,-1,sal_False,sal_False).isValid()) + (*aIter) = NULL; + OTableFields().swap( rUnUsedFields ); + } + } + else + { + ErrorBox aBox(_pView, ModuleRes( ERR_QRY_TOO_MANY_TABLES)); + aBox.Execute(); + } + } + catch(SQLException&) + { + OSL_ASSERT(!"getMaxTablesInSelect!"); + } + } + } + else + { + ErrorBox aBox(_pView, ModuleRes( ERR_QRY_NOSELECT)); + aBox.Execute(); + } + } + + // Durch das Neuerzeugen wurden wieder Undo-Actions in den Manager gestellt + pController->getUndoMgr()->Clear(); + _pSelectionBrw->Invalidate(); + } + //------------------------------------------------------------------------------ + int InstallFields( OQueryDesignView* _pView, + const ::connectivity::OSQLParseNode* pNode, + OJoinTableView::OTableWindowMap* pTabList ) + { + if( pNode==0 || !SQL_ISRULE(pNode,select_statement)) + { + ErrorBox aBox( _pView, ModuleRes( ERR_QRY_NOSELECT ) ); + aBox.Execute(); + return 1; + } + + ::connectivity::OSQLParseNode* pParseTree = pNode->getChild(2); + sal_Bool bFirstField = sal_True; // bei der Initialisierung mu auf alle Faelle das erste Feld neu aktiviert werden + + if(pParseTree->isRule() && SQL_ISPUNCTUATION(pParseTree->getChild(0),"*")) + { + // SELECT * ... + + OTableFieldDescRef aInfo = new OTableFieldDesc(); + OJoinTableView::OTableWindowMap::iterator aIter = pTabList->begin(); + for(;aIter != pTabList->end();++aIter) + { + OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second); + + if (pTabWin->ExistsField( ::rtl::OUString::createFromAscii("*"), aInfo )) + { + if( !_pView->InsertField(aInfo, sal_True, bFirstField) ) + return 1; + bFirstField = sal_False; + } + } + + // Einfach alle Columns der Datei direkt uebernehmen: + } + else if (SQL_ISRULE(pParseTree,scalar_exp_commalist) ) + { + // SELECT column, ... + + ::rtl::OUString aColumnName,aTableRange; + for (sal_uInt32 i = 0; i < pParseTree->count(); i++) + { + ::connectivity::OSQLParseNode * pColumnRef = pParseTree->getChild(i); + + if (SQL_ISRULE(pColumnRef,select_sublist)) + { + OTableFieldDescRef aInfo = new OTableFieldDesc(); + OJoinTableView::OTableWindowMap::iterator aIter = pTabList->begin(); + for(;aIter != pTabList->end();++aIter) + { + OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second); + + if (pTabWin->ExistsField( ::rtl::OUString::createFromAscii("*"), aInfo )) + { + if( !_pView->InsertField(aInfo, sal_True, bFirstField) ) + return 1; + + bFirstField = sal_False; + } + } + } + else if (SQL_ISRULE(pColumnRef,derived_column)) + { + OQueryController* pController = static_cast<OQueryController*>(_pView->getController()); + Reference< XConnection> xConnection = pController->getConnection(); + if(xConnection.is()) + { + Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); + ::rtl::OUString aColumnAlias(pController->getParseIterator().getColumnAlias(pColumnRef)); // kann leer sein + pColumnRef = pColumnRef->getChild(0); + if (SQL_ISRULE(pColumnRef,column_ref)) + { + OTableFieldDescRef aInfo = new OTableFieldDesc(); + switch(InsertColumnRef(_pView,pColumnRef,aColumnName,aColumnAlias,aTableRange,aInfo,pTabList)) + { + case 5: + ErrorBox( _pView, ModuleRes( ERR_QRY_AMB_FIELD ) ).Execute(); + break; + default: + if( !_pView->InsertField(aInfo, sal_True, bFirstField) ) + return 1; + bFirstField = sal_False; + } + } + else if(SQL_ISRULE(pColumnRef,general_set_fct) || SQL_ISRULE(pColumnRef,set_fct_spec) || + SQL_ISRULE(pColumnRef,position_exp) || SQL_ISRULE(pColumnRef,extract_exp) || + SQL_ISRULE(pColumnRef,length_exp) || SQL_ISRULE(pColumnRef,char_value_fct)) + { + OTableFieldDescRef aInfo = new OTableFieldDesc(); + ::rtl::OUString aColumns; + pColumnRef->parseNodeToStr( aColumns, + xMetaData, + &pController->getParser()->getContext(), + sal_True, + sal_True); // quote is to true because we need quoted elements inside the function + + ::connectivity::OSQLParseNode * pParamRef = pColumnRef->getChild(pColumnRef->count()-2); + if (SQL_ISRULE(pColumnRef,general_set_fct) + && SQL_ISRULE(pParamRef = pColumnRef->getChild(pColumnRef->count()-2),column_ref)) + { + // Parameter auf Columnref pr"ufen + switch(InsertColumnRef(_pView,pParamRef,aColumnName,aColumnAlias,aTableRange,aInfo,pTabList)) + { + case 5: + ErrorBox( _pView, ModuleRes( ERR_QRY_AMB_FIELD ) ).Execute(); + break; + } + } + else + { + if(pParamRef && pParamRef->getTokenValue().toChar() == '*') + { + OJoinTableView::OTableWindowMap::iterator aIter = pTabList->begin(); + for(;aIter != pTabList->end();++aIter) + { + OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second); + if (pTabWin->ExistsField( ::rtl::OUString::createFromAscii("*"), aInfo )) + { + aInfo->SetAlias(String()); + aInfo->SetTable(String()); + break; + } + } + } + else + { + aInfo->SetDataType(DataType::DOUBLE); + aInfo->SetFieldType(TAB_NORMAL_FIELD); + aInfo->SetField(aColumns); + + } + aInfo->SetTabWindow(NULL); + aInfo->SetFieldAlias(aColumnAlias); + } + + if(SQL_ISRULE(pColumnRef,general_set_fct)) + { + aInfo->SetFunctionType(FKT_AGGREGATE); + String aCol(aColumns); + aInfo->SetFunction(aCol.GetToken(0,'(').EraseTrailingChars(' ')); + } + else + aInfo->SetFunctionType(FKT_OTHER); + + if( !_pView->InsertField(aInfo, sal_True, bFirstField) ) + return 1; + bFirstField = sal_False; + } + else //if(SQL_ISRULE(pColumnRef,num_value_exp) || SQL_ISRULE(pColumnRef,term)) + { + ::rtl::OUString aColumns; + pColumnRef->parseNodeToStr( aColumns, + xMetaData, + &pController->getParser()->getContext(), + sal_True, + sal_False); + + OTableFieldDescRef aInfo = new OTableFieldDesc(); + aInfo->SetDataType(DataType::DOUBLE); + aInfo->SetFieldType(TAB_NORMAL_FIELD); + aInfo->SetTabWindow(NULL); + aInfo->SetField(aColumns); + aInfo->SetFieldAlias(aColumnAlias); + aInfo->SetFunctionType(FKT_OTHER); + + if( !_pView->InsertField(aInfo, sal_True, bFirstField) ) + return 1; + bFirstField = sal_False; + } + } + } + } + } + else + { + ErrorBox( _pView, ModuleRes( ERR_QRY_SYNTAX ) ).Execute(); + return 4; + } + + return 0; + } + //------------------------------------------------------------------------------ + void GetOrderCriteria( OQueryDesignView* _pView, + OSelectionBrowseBox* _pSelectionBrw, + const ::connectivity::OSQLParseNode* pParseRoot ) + { + if (!pParseRoot->getChild(3)->getChild(4)->isLeaf()) + { + ::connectivity::OSQLParseNode* pNode = pParseRoot->getChild(3)->getChild(4)->getChild(2); + ::connectivity::OSQLParseNode* pParamRef = NULL; + ::rtl::OUString aField, aAlias; + sal_uInt16 nPos = 0; + + EOrderDir eOrderDir; + OTableFieldDescRef aDragLeft = new OTableFieldDesc(); + for( sal_uInt32 i=0 ; i<pNode->count() ; i++ ) + { + eOrderDir = ORDER_ASC; + ::connectivity::OSQLParseNode* pChild = pNode->getChild( i ); + + if (SQL_ISTOKEN( pChild->getChild(1), DESC ) ) + eOrderDir = ORDER_DESC; + + if(SQL_ISRULE(pChild->getChild(0),column_ref)) + { + if(FillDragInfo(_pView,pChild->getChild(0),aDragLeft)) + _pSelectionBrw->AddOrder( aDragLeft, eOrderDir, nPos); + else // it could be a alias name for a field + { + ::rtl::OUString aTableRange,aColumnName; + OQueryController* pController = static_cast<OQueryController*>(_pView->getController()); + + ::connectivity::OSQLParseTreeIterator& rParseIter = pController->getParseIterator(); + rParseIter.getColumnRange( pChild->getChild(0), aColumnName, aTableRange ); + + OTableFields& aList = pController->getTableFieldDesc(); + OTableFields::iterator aIter = aList.begin(); + for(;aIter != aList.end();++aIter) + { + OTableFieldDescRef pEntry = *aIter; + if(pEntry.isValid() && pEntry->GetFieldAlias() == aColumnName.getStr()) + pEntry->SetOrderDir( eOrderDir ); + } + } + } + else if(SQL_ISRULE(pChild->getChild(0),general_set_fct) && + SQL_ISRULE(pParamRef = pChild->getChild(0)->getChild(pChild->getChild(0)->count()-2),column_ref) && + FillDragInfo(_pView,pParamRef,aDragLeft)) + _pSelectionBrw->AddOrder( aDragLeft, eOrderDir, nPos); + } + } + } + //------------------------------------------------------------------------------ + void GetHavingCriteria( OQueryDesignView* _pView, + OSelectionBrowseBox* _pSelectionBrw, + const ::connectivity::OSQLParseNode* pSelectRoot, + int &rLevel ) + { + if (!pSelectRoot->getChild(3)->getChild(3)->isLeaf()) + GetORCriteria(_pView,_pSelectionBrw,pSelectRoot->getChild(3)->getChild(3)->getChild(1),rLevel, sal_True); + } + //------------------------------------------------------------------------------ + void GetGroupCriteria( OQueryDesignView* _pView, + OSelectionBrowseBox* _pSelectionBrw, + const ::connectivity::OSQLParseNode* pSelectRoot ) + { + if (!pSelectRoot->getChild(3)->getChild(2)->isLeaf()) + { + ::connectivity::OSQLParseNode* pGroupBy = pSelectRoot->getChild(3)->getChild(2)->getChild(2); + OTableFieldDescRef aDragInfo = new OTableFieldDesc(); + for( sal_uInt32 i=0 ; i < pGroupBy->count() ; i++ ) + { + ::connectivity::OSQLParseNode* pColumnRef = pGroupBy->getChild( i ); + if(SQL_ISRULE(pColumnRef,column_ref)) + { + if(FillDragInfo(_pView,pColumnRef,aDragInfo)) + { + aDragInfo->SetGroupBy(sal_True); + _pSelectionBrw->AddGroupBy(aDragInfo); + } + } + } + } + } + //------------------------------------------------------------------------------ + //------------------------------------------------------------------------------ + //------------------------------------------------------------------------------ +} // end of anonymouse namespace + +OQueryDesignView::OQueryDesignView( OQueryContainerWindow* _pParent, + OQueryController* _pController, + const Reference< XMultiServiceFactory >& _rFactory) :OQueryView(_pParent,_pController,_rFactory) ,m_aSplitter( this ) ,m_eChildFocus(NONE) { try { -// Any aValue = ConfigManager::GetDirectConfigProperty(ConfigManager::LOCALE); -// m_aLocale.Language = ::comphelper::getString(aValue); String sLanguage, sCountry; ConvertLanguageToIsoNames(Window::GetSettings().GetLanguage(), sLanguage, sCountry); m_aLocale = Locale(sLanguage, sCountry, ::rtl::OUString()); @@ -492,399 +2525,16 @@ long OQueryDesignView::PreNotify(NotifyEvent& rNEvt) return OQueryView::PreNotify(rNEvt); return 1L; } -// ----------------------------------------------------------------------------- -sal_Bool OQueryDesignView::HasFields() -{ - OTableFields& aList = static_cast<OQueryController*>(getController())->getTableFieldDesc(); - OTableFields::iterator aIter = aList.begin(); - ::rtl::OUString aFieldName; - for(;aIter != aList.end();++aIter) - { - aFieldName = (*aIter)->GetField(); - if (aFieldName.getLength() != 0 && (*aIter)->IsVisible()) - return sal_True; - } - return sal_False; -} -static const ::rtl::OUString C_AND = ::rtl::OUString::createFromAscii(" AND "); -static const ::rtl::OUString C_OR = ::rtl::OUString::createFromAscii(" OR "); -//------------------------------------------------------------------------------ -extern ::rtl::OUString ConvertAlias(const ::rtl::OUString& rName); -//------------------------------------------------------------------------------ -::rtl::OUString OQueryDesignView::BuildTable(const OQueryTableWindow* pEntryTab) -{ - ::rtl::OUString aDBName(pEntryTab->GetComposedName()); - - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(!xConnection.is()) - return aDBName; - - try - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - ::rtl::OUString aCatalog,aSchema,aTable,sComposedName; - ::dbtools::qualifiedNameComponents(xMetaData,aDBName,aCatalog,aSchema,aTable); - ::dbtools::composeTableName(xMetaData,aCatalog,aSchema,aTable,sComposedName,sal_True); - - ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString(); - ::rtl::OUString aTableListStr(sComposedName); - aTableListStr += ::rtl::OUString(' '); - aTableListStr += ::dbtools::quoteName(aQuote, ConvertAlias(pEntryTab->GetAliasName())).getStr(); - return aTableListStr; - } - catch(SQLException&) - { - } - return aDBName; -} -//------------------------------------------------------------------------------ -::rtl::OUString OQueryDesignView::BuildJoin(OQueryTableWindow* pLh, OQueryTableWindow* pRh, OQueryTableConnectionData* pData) -{ - return BuildJoin(BuildTable(pLh),BuildTable(pRh),pData); -} -//------------------------------------------------------------------------------ -::rtl::OUString OQueryDesignView::BuildJoin(const ::rtl::OUString &rLh, OQueryTableWindow* pRh, OQueryTableConnectionData* pData) -{ - return BuildJoin(rLh,BuildTable(pRh),pData); -} -//------------------------------------------------------------------------------ -::rtl::OUString OQueryDesignView::BuildJoin(OQueryTableWindow* pLh, const ::rtl::OUString &rRh, OQueryTableConnectionData* pData) -{ - return BuildJoin(BuildTable(pLh),rRh,pData); -} -//------------------------------------------------------------------------------ -::rtl::OUString OQueryDesignView::BuildJoin(const ::rtl::OUString& rLh, const ::rtl::OUString& rRh, OQueryTableConnectionData* pData) -{ - - String aErg(rLh); - switch(pData->GetJoinType()) - { - case LEFT_JOIN: - aErg.AppendAscii(" LEFT OUTER "); - break; - case RIGHT_JOIN: - aErg.AppendAscii(" RIGHT OUTER "); - break; - case INNER_JOIN: - DBG_ERROR("OQueryDesignView::BuildJoin: This should not happen!"); - //aErg.AppendAscii(" INNER "); - break; - default: - aErg.AppendAscii(" FULL OUTER "); - break; - } - aErg.AppendAscii("JOIN "); - aErg += String(rRh); - aErg.AppendAscii(" ON "); - aErg += String(BuildJoinCriteria(pData->GetConnLineDataList(),pData)); - - return aErg; -} -//------------------------------------------------------------------------------ -::rtl::OUString OQueryDesignView::BuildJoinCriteria(OConnectionLineDataVec* pLineDataList,OQueryTableConnectionData* pData) -{ - ::rtl::OUString aCondition; - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(!xConnection.is()) - return aCondition; - - OConnectionLineDataVec::iterator aIter = pLineDataList->begin(); - try - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString(); - - for(;aIter != pLineDataList->end();++aIter) - { - OConnectionLineDataRef pLineData = *aIter; - if(pLineData->IsValid()) - { - if(aCondition.getLength()) - aCondition += C_AND; - aCondition += ::dbtools::quoteName(aQuote, ConvertAlias( pData->GetAliasName(JTCS_FROM) )).getStr(); - aCondition += ::rtl::OUString('.'); - aCondition += ::dbtools::quoteName(aQuote, pLineData->GetFieldName(JTCS_FROM) ).getStr(); - aCondition += ::rtl::OUString::createFromAscii(" = "); - aCondition += ::dbtools::quoteName(aQuote, ConvertAlias( pData->GetAliasName(JTCS_TO) )).getStr(); - aCondition += ::rtl::OUString('.'); - aCondition += ::dbtools::quoteName(aQuote, pLineData->GetFieldName(JTCS_TO) ).getStr(); - } - } - } - catch(SQLException&) - { - OSL_ASSERT(!"Failure while building Join criteria!"); - } - - return aCondition; -} -//------------------------------------------------------------------------------ -::rtl::OUString OQueryDesignView::GenerateSelectList(OTableFields& _rFieldList,sal_Bool bAlias) -{ - ::rtl::OUString aTmpStr,aFieldListStr; - - sal_Bool bAsterix = sal_False; - int nVis = 0; - OTableFields::iterator aIter = _rFieldList.begin(); - for(;aIter != _rFieldList.end();++aIter) - { - OTableFieldDescRef pEntryField = *aIter; - if(pEntryField->IsVisible()) - { - if(pEntryField->GetField().toChar() == '*') - bAsterix = sal_True; - ++nVis; - } - } - if(nVis == 1) - bAsterix = sal_False; - - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(!xConnection.is()) - return aFieldListStr; - - try - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString(); - - aIter = _rFieldList.begin(); - for(;aIter != _rFieldList.end();++aIter) - { - OTableFieldDescRef pEntryField = *aIter; - ::rtl::OUString rFieldName = pEntryField->GetField(); - if (rFieldName.getLength() && pEntryField->IsVisible()) - { - aTmpStr = ::rtl::OUString(); - ::rtl::OUString rAlias = pEntryField->GetAlias(); - ::rtl::OUString rFieldAlias = pEntryField->GetFieldAlias(); - if((bAlias || bAsterix) && rAlias.getLength()) - { - aTmpStr += ::dbtools::quoteName(aQuote,ConvertAlias(rAlias)); - aTmpStr += ::rtl::OUString('.'); - } - // we have to look if we have alias.* here - String sTemp = rFieldName; - if(sTemp.GetTokenCount('.') == 2) - rFieldName = sTemp.GetToken(1,'.'); - - if(pEntryField->GetTable().getLength() && rFieldName.toChar() != '*') - aTmpStr += ::dbtools::quoteName(aQuote, rFieldName).getStr(); - else - aTmpStr += rFieldName; - - if(pEntryField->GetFunctionType() == FKT_AGGREGATE) - { - DBG_ASSERT(pEntryField->GetFunction().getLength(),"Functionname darf hier nicht leer sein! ;-("); - ::rtl::OUString aTmpStr2(pEntryField->GetFunction()); - aTmpStr2 += ::rtl::OUString('('); - aTmpStr2 += aTmpStr; - aTmpStr2 += ::rtl::OUString(')'); - aTmpStr = aTmpStr2; - } - - if( rFieldAlias.getLength() && - (rFieldName.toChar() != '*' || - pEntryField->GetFunctionType() == FKT_AGGREGATE || - pEntryField->GetFunctionType() == FKT_OTHER)) - { - aTmpStr += ::rtl::OUString::createFromAscii(" AS "); - aTmpStr += ::dbtools::quoteName(aQuote, rFieldAlias); - } - aFieldListStr += aTmpStr; - aFieldListStr += ::rtl::OUString::createFromAscii(", "); - } - } - if(aFieldListStr.getLength()) - aFieldListStr = aFieldListStr.replaceAt(aFieldListStr.getLength()-2,2, ::rtl::OUString() ); - } - catch(SQLException&) - { - OSL_ASSERT(!"Failure while building select list!"); - } - return aFieldListStr; -} -//------------------------------------------------------------------------------ -void OQueryDesignView::JoinCycle(OQueryTableConnection* pEntryConn,::rtl::OUString &rJoin,OQueryTableWindow* pEntryTabTo) -{ - OQueryTableConnectionData* pData = static_cast<OQueryTableConnectionData*>(pEntryConn->GetData()); - if(pData->GetJoinType() == INNER_JOIN) - return; - if(pEntryTabTo->ExistsAVisitedConn()) // then we have a cycle - { - sal_Bool bBrace = sal_False; - if(rJoin.getLength() && rJoin.lastIndexOf(')') == (rJoin.getLength()-1)) - { - bBrace = sal_True; - rJoin = rJoin.replaceAt(rJoin.getLength()-1,1,::rtl::OUString(' ')); - } - (rJoin += C_AND) += BuildJoinCriteria(pData->GetConnLineDataList(),pData); - if(bBrace) - rJoin += ::rtl::OUString(')'); - pEntryConn->SetVisited(sal_True); - } -} - -//------------------------------------------------------------------------------ -void OQueryDesignView::GenerateInnerJoinCriterias(::rtl::OUString& _rJoinCrit,const ::std::vector<OTableConnection*>* _pConnList) -{ - ::std::vector<OTableConnection*>::const_iterator aIter = _pConnList->begin(); - for(;aIter != _pConnList->end();++aIter) - { - const OQueryTableConnection* pEntryConn = static_cast<const OQueryTableConnection*>(*aIter); - OQueryTableConnectionData* pEntryConnData = static_cast<OQueryTableConnectionData*>(pEntryConn->GetData()); - if(pEntryConnData->GetJoinType() == INNER_JOIN) - { - if(_rJoinCrit.getLength()) - _rJoinCrit += C_AND; - _rJoinCrit += BuildJoinCriteria(pEntryConnData->GetConnLineDataList(),pEntryConnData); - } - } -} -//------------------------------------------------------------------------------ -void OQueryDesignView::GetNextJoin(OQueryTableConnection* pEntryConn,::rtl::OUString &aJoin,OQueryTableWindow* pEntryTabTo) -{ - - OQueryTableConnectionData* pEntryConnData = static_cast<OQueryTableConnectionData*>(pEntryConn->GetData()); - if(pEntryConnData->GetJoinType() == INNER_JOIN) - return; - - if(!aJoin.getLength()) - { - OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin()); - aJoin = BuildJoin(pEntryTabFrom,pEntryTabTo,pEntryConnData); - } - else if(pEntryTabTo == pEntryConn->GetDestWin()) - { - ::rtl::OUString aTmpJoin('('); - (aTmpJoin += aJoin) += ::rtl::OUString(')'); - aJoin = BuildJoin(aTmpJoin,pEntryTabTo,pEntryConnData); - } - else if(pEntryTabTo == pEntryConn->GetSourceWin()) - { - ::rtl::OUString aTmpJoin('('); - (aTmpJoin += aJoin) += ::rtl::OUString(')'); - aJoin = BuildJoin(pEntryTabTo,aTmpJoin,pEntryConnData); - } - - pEntryConn->SetVisited(sal_True); - - // first search for the "to" window - ::std::vector<OTableConnection*>::iterator aIter = pEntryConn->GetParent()->GetTabConnList()->begin(); - for(;aIter != pEntryConn->GetParent()->GetTabConnList()->end();++aIter) - { - OQueryTableConnection* pNext = static_cast<OQueryTableConnection*>(*aIter); - if(!pNext->IsVisited() && (pNext->GetSourceWin() == pEntryTabTo || pNext->GetDestWin() == pEntryTabTo)) - { - OQueryTableWindow* pEntryTab = pNext->GetSourceWin() == pEntryTabTo ? static_cast<OQueryTableWindow*>(pNext->GetDestWin()) : static_cast<OQueryTableWindow*>(pNext->GetSourceWin()); - // exists there a connection to a OQueryTableWindow that holds a connection that has been already visited - JoinCycle(pNext,aJoin,pEntryTab); - if(!pNext->IsVisited()) - GetNextJoin(pNext,aJoin,pEntryTab); - } - } - - // when nothing found found look for the "from" window - if(aIter == pEntryConn->GetParent()->GetTabConnList()->end()) - { - OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin()); - aIter = pEntryConn->GetParent()->GetTabConnList()->begin(); - for(;aIter != pEntryConn->GetParent()->GetTabConnList()->end();++aIter) - { - OQueryTableConnection* pNext = static_cast<OQueryTableConnection*>(*aIter); - if(!pNext->IsVisited() && (pNext->GetSourceWin() == pEntryTabFrom || pNext->GetDestWin() == pEntryTabFrom)) - { - OQueryTableWindow* pEntryTab = pNext->GetSourceWin() == pEntryTabFrom ? static_cast<OQueryTableWindow*>(pNext->GetDestWin()) : static_cast<OQueryTableWindow*>(pNext->GetSourceWin()); - // exists there a connection to a OQueryTableWindow that holds a connection that has been already visited - JoinCycle(pNext,aJoin,pEntryTab); - if(!pNext->IsVisited()) - GetNextJoin(pNext,aJoin,pEntryTab); - } - } - } -} - //------------------------------------------------------------------------------ -::rtl::OUString OQueryDesignView::GenerateFromClause(const OQueryTableView::OTableWindowMap* pTabList,::std::vector<OTableConnection*>* pConnList) -{ - - ::rtl::OUString aTableListStr; - // wird gebraucht um sicher zustelllen das eine Tabelle nicht doppelt vorkommt - - // generate outer join clause in from - if(pConnList->size()) - { - ::std::vector<OTableConnection*>::iterator aIter = pConnList->begin(); - for(;aIter != pConnList->end();++aIter) - static_cast<OQueryTableConnection*>(*aIter)->SetVisited(sal_False); - - aIter = pConnList->begin(); - for(;aIter != pConnList->end();++aIter) - { - OQueryTableConnection* pEntryConn = static_cast<OQueryTableConnection*>(*aIter); - if(!pEntryConn->IsVisited()) - { - ::rtl::OUString aJoin; - GetNextJoin(pEntryConn,aJoin,static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin())); - - if(aJoin.getLength()) - { - ::rtl::OUString aStr = ::rtl::OUString::createFromAscii("{ OJ "); - aStr += aJoin; - aStr += ::rtl::OUString::createFromAscii(" },"); - aTableListStr += aStr; - } - } - } - // and now all inner joins - map< ::rtl::OUString,sal_Bool,::comphelper::UStringMixLess> aTableNames; - aIter = pConnList->begin(); - for(;aIter != pConnList->end();++aIter) - { - OQueryTableConnection* pEntryConn = static_cast<OQueryTableConnection*>(*aIter); - if(!pEntryConn->IsVisited()) - { - ::rtl::OUString aTabName(BuildTable(static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin()))); - if(aTableNames.find(aTabName) == aTableNames.end()) - { - aTableNames[aTabName] = sal_True; - aTableListStr += aTabName; - aTableListStr += ::rtl::OUString(','); - } - aTabName = BuildTable(static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin())); - if(aTableNames.find(aTabName) == aTableNames.end()) - { - aTableNames[aTabName] = sal_True; - aTableListStr += aTabName; - aTableListStr += ::rtl::OUString(','); - } - } - } - } - // all tables that haven't a connection to anyone - OQueryTableView::OTableWindowMap::const_iterator aTabIter = pTabList->begin(); - for(;aTabIter != pTabList->end();++aTabIter) - { - const OQueryTableWindow* pEntryTab = static_cast<const OQueryTableWindow*>(aTabIter->second); - if(!pEntryTab->ExistsAConn()) - { - aTableListStr += BuildTable(pEntryTab); - aTableListStr += ::rtl::OUString(','); - } - } - if(aTableListStr.getLength()) - aTableListStr = aTableListStr.replaceAt(aTableListStr.getLength()-1,1, ::rtl::OUString() ); - return aTableListStr; -} // ----------------------------------------------------------------------------- // check if the statement is correct when not returning false sal_Bool OQueryDesignView::checkStatement() { return m_pSelectionBox->Save(); // a error occured so we return no } -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------- ::rtl::OUString OQueryDesignView::getStatement() { OQueryController* pController = static_cast<OQueryController*>(getController()); @@ -914,7 +2564,7 @@ sal_Bool OQueryDesignView::checkStatement() OQueryTableView::OTableWindowMap* pTabList = m_pTableView->GetTabWinMap(); sal_uInt32 nTabcount = pTabList->size(); - ::rtl::OUString aFieldListStr(GenerateSelectList(rFieldList,nTabcount>1)); + ::rtl::OUString aFieldListStr(GenerateSelectList(this,rFieldList,nTabcount>1)); if( !aFieldListStr.getLength() ) return ::rtl::OUString(); // Ausnahmebehandlung, wenn keine Felder angegeben worden sind @@ -924,18 +2574,18 @@ sal_Bool OQueryDesignView::checkStatement() // ----------------- Tabellenliste aufbauen ---------------------- ::std::vector<OTableConnection*>* pConnList = m_pTableView->GetTabConnList(); - ::rtl::OUString aTableListStr(GenerateFromClause(pTabList,pConnList)); + ::rtl::OUString aTableListStr(GenerateFromClause(this,pTabList,pConnList)); DBG_ASSERT(aTableListStr.getLength(), "OQueryDesignView::getStatement() : unerwartet : habe Felder, aber keine Tabellen !"); // wenn es Felder gibt, koennen die nur durch Einfuegen aus einer schon existenten Tabelle entstanden sein; wenn andererseits // eine Tabelle geloescht wird, verschwinden auch die zugehoerigen Felder -> ergo KANN es das nicht geben, dass Felder // existieren, aber keine Tabellen (und aFieldListStr hat schon eine Laenge, das stelle ich oben sicher) ::rtl::OUString aHavingStr,aCriteriaListStr; // ----------------- Kriterien aufbauen ---------------------- - if (!GenerateCriterias(aCriteriaListStr,aHavingStr,rFieldList, nTabcount > 1)) + if (!GenerateCriterias(this,aCriteriaListStr,aHavingStr,rFieldList, nTabcount > 1)) return ::rtl::OUString(); ::rtl::OUString aJoinCrit; - GenerateInnerJoinCriterias(aJoinCrit,pConnList); + GenerateInnerJoinCriterias(this,aJoinCrit,pConnList); if(aJoinCrit.getLength()) { ::rtl::OUString aTmp = ::rtl::OUString::createFromAscii("( "); @@ -971,7 +2621,7 @@ sal_Bool OQueryDesignView::checkStatement() { bUseAlias = bUseAlias || !xMeta->supportsGroupByUnrelated(); } - aSqlCmd += GenerateGroupBy(rFieldList,bUseAlias); + aSqlCmd += GenerateGroupBy(this,rFieldList,bUseAlias); // ----------------- having Anh"angen ------------ if(aHavingStr.getLength()) { @@ -979,1043 +2629,11 @@ sal_Bool OQueryDesignView::checkStatement() aSqlCmd += aHavingStr; } // ----------------- Sortierung aufbauen und Anh"angen ------------ - aSqlCmd += GenerateOrder(rFieldList,nTabcount > 1); + aSqlCmd += GenerateOrder(this,rFieldList,nTabcount > 1); return aSqlCmd; } -//------------------------------------------------------------------------------ -::rtl::OUString OQueryDesignView::GenerateGroupBy(OTableFields& _rFieldList, sal_Bool bMulti ) -{ - - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(!xConnection.is()) - return ::rtl::OUString(); - - ::rtl::OUString aGroupByStr; - try - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString(); - - OTableFields::iterator aIter = _rFieldList.begin(); - for(;aIter != _rFieldList.end();++aIter) - { - OTableFieldDescRef pEntryField = *aIter; - if(pEntryField->IsGroupBy()) - { - DBG_ASSERT(pEntryField->GetField().getLength(),"Kein FieldName vorhanden!;-("); - if (bMulti) - { - aGroupByStr += ::dbtools::quoteName(aQuote, ConvertAlias(pEntryField->GetAlias())); - aGroupByStr += ::rtl::OUString('.'); - } - - aGroupByStr += ::dbtools::quoteName(aQuote, pEntryField->GetField()); - aGroupByStr += ::rtl::OUString(','); - } - } - if(aGroupByStr.getLength()) - { - aGroupByStr = aGroupByStr.replaceAt(aGroupByStr.getLength()-1,1, ::rtl::OUString(' ') ); - ::rtl::OUString aGroupByStr2 = ::rtl::OUString::createFromAscii(" GROUP BY "); - aGroupByStr2 += aGroupByStr; - aGroupByStr = aGroupByStr2; - } - } - catch(SQLException&) - { - OSL_ASSERT(!"Failure while building group by!"); - } - return aGroupByStr; -} -//------------------------------------------------------------------------------ -sal_Bool OQueryDesignView::GenerateCriterias(::rtl::OUString& rRetStr,::rtl::OUString& rHavingStr, OTableFields& _rFieldList, sal_Bool bMulti ) -{ - // * darf keine Filter enthalten : habe ich die entsprechende Warnung schon angezeigt ? - sal_Bool bCritsOnAsterikWarning = sal_False; // ** TMFS ** - - ::rtl::OUString aFieldName,aCriteria,aWhereStr,aHavingStr,aWork/*,aOrderStr*/; - // Zeilenweise werden die Ausdr"ucke mit AND verknuepft - sal_uInt16 nMaxCriteria = 0; - OTableFields::iterator aIter = _rFieldList.begin(); - for(;aIter != _rFieldList.end();++aIter) - { - nMaxCriteria = ::std::max<sal_uInt16>(nMaxCriteria,(*aIter)->GetCriteria().size()); - } - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(!xConnection.is()) - return FALSE; - try - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString(); - - for (sal_uInt16 i=0 ; i < nMaxCriteria ; i++) - { - aHavingStr = aWhereStr = ::rtl::OUString(); - - for(aIter = _rFieldList.begin();aIter != _rFieldList.end();++aIter) - { - OTableFieldDescRef pEntryField = *aIter; - aFieldName = pEntryField->GetField(); - - if (!aFieldName.getLength()) - continue; - aCriteria = pEntryField->GetCriteria( i ); - if (aCriteria.getLength()) - { - if (aFieldName.toChar() == '*' && pEntryField->GetFunctionType() == FKT_NONE) // * darf keine Filter besitzen - { - // only show the messagebox the first time - if (!bCritsOnAsterikWarning) - ErrorBox((OQueryDesignView*)this, ModuleRes( ERR_QRY_CRITERIA_ON_ASTERISK)).Execute(); - bCritsOnAsterikWarning = sal_True; - continue; - } - aWork = ::rtl::OUString(); - - - if (bMulti) - { - if(pEntryField->GetFunctionType() == FKT_OTHER || (aFieldName.toChar() == '*')) - aWork += aFieldName; - else - aWork += ::dbtools::quoteName(aQuote, ConvertAlias(pEntryField->GetAlias())); - aWork += ::rtl::OUString('.'); - } - if(pEntryField->GetFunctionType() == FKT_OTHER || (aFieldName.toChar() == '*')) - aWork += aFieldName; - else - aWork += ::dbtools::quoteName(aQuote, aFieldName).getStr(); - - if(pEntryField->GetFunctionType() == FKT_AGGREGATE || pEntryField->IsGroupBy()) - { - if (!aHavingStr.getLength()) // noch keine Kriterien - aHavingStr += ::rtl::OUString('('); // Klammern - else - aHavingStr += C_AND; - - if(pEntryField->GetFunctionType() == FKT_AGGREGATE) - { - aHavingStr += pEntryField->GetFunction(); - aHavingStr += ::rtl::OUString('('); // Klammern - aHavingStr += aWork; - aHavingStr += ::rtl::OUString(')'); // Klammern - } - else - aHavingStr += aWork; - - ::rtl::OUString aTmp = aCriteria; - ::rtl::OUString aErrorMsg; - Reference<XPropertySet> xColumn; - ::connectivity::OSQLParseNode* pParseNode = getPredicateTreeFromEntry(pEntryField,aTmp,aErrorMsg,xColumn); - if (pParseNode) - { - if (bMulti && !(pEntryField->GetFunctionType() == FKT_OTHER || (aFieldName.toChar() == '*'))) - pParseNode->replaceNodeValue(ConvertAlias(pEntryField->GetAlias()),aFieldName); - ::rtl::OUString sHavingStr = aHavingStr; - OSL_ENSURE(pParseNode->count() == 3,"Count must be three here!"); - pParseNode->getChild(1)->parseNodeToStr( sHavingStr, - xMetaData, - &(static_cast<OQueryController*>(getController())->getParser()->getContext()), - sal_False, - pEntryField->GetFunctionType() != FKT_OTHER); - pParseNode->getChild(2)->parseNodeToStr( sHavingStr, - xMetaData, - &(static_cast<OQueryController*>(getController())->getParser()->getContext()), - sal_False, - pEntryField->GetFunctionType() != FKT_OTHER); - aHavingStr = sHavingStr; - delete pParseNode; - } - else - aHavingStr += aCriteria; - } - else - { - if (!aWhereStr.getLength()) // noch keine Kriterien - aWhereStr += ::rtl::OUString('('); // Klammern - else - aWhereStr += C_AND; - - aWhereStr += ::rtl::OUString(' '); - // aCriteria could have some german numbers so I have to be sure here - ::rtl::OUString aTmp = aCriteria; - ::rtl::OUString aErrorMsg; - Reference<XPropertySet> xColumn; - ::connectivity::OSQLParseNode* pParseNode = getPredicateTreeFromEntry(pEntryField,aTmp,aErrorMsg,xColumn); - if (pParseNode) - { - if (bMulti && !(pEntryField->GetFunctionType() == FKT_OTHER || (aFieldName.toChar() == '*'))) - pParseNode->replaceNodeValue(ConvertAlias(pEntryField->GetAlias()),aFieldName); - ::rtl::OUString aWhere = aWhereStr; - pParseNode->parseNodeToStr( aWhere, - xMetaData, - &(static_cast<OQueryController*>(getController())->getParser()->getContext()), - sal_False, - pEntryField->GetFunctionType() != FKT_OTHER); - aWhereStr = aWhere; - delete pParseNode; - } - else - { - aWhereStr += aWork; - aWhereStr += aCriteria; - } - } - } - // nur einmal fr jedes Feld - else if(!i && pEntryField->GetFunctionType() == FKT_CONDITION) - { - if (!aWhereStr.getLength()) // noch keine Kriterien - aWhereStr += ::rtl::OUString('('); // Klammern - else - aWhereStr += C_AND; - aWhereStr += pEntryField->GetField(); - } - } - if (aWhereStr.getLength()) - { - aWhereStr += ::rtl::OUString(')'); // Klammern zu fuer 'AND' Zweig - if (rRetStr.getLength()) // schon Feldbedingungen ? - rRetStr += C_OR; - else // Klammern auf fuer 'OR' Zweig - rRetStr += ::rtl::OUString('('); - rRetStr += aWhereStr; - } - if (aHavingStr.getLength()) - { - aHavingStr += ::rtl::OUString(')'); // Klammern zu fuer 'AND' Zweig - if (rHavingStr.getLength()) // schon Feldbedingungen ? - rHavingStr += C_OR; - else // Klammern auf fuer 'OR' Zweig - rHavingStr += ::rtl::OUString('('); - rHavingStr += aHavingStr; - } - } - - if (rRetStr.getLength()) - rRetStr += ::rtl::OUString(')'); // Klammern zu fuer 'OR' Zweig - if (rHavingStr.getLength()) - rHavingStr += ::rtl::OUString(')'); // Klammern zu fuer 'OR' Zweig - } - catch(SQLException&) - { - OSL_ASSERT(!"Failure while building where clause!"); - } - return sal_True; -} - -//------------------------------------------------------------------------------ - -::rtl::OUString OQueryDesignView::GenerateOrder( OTableFields& _rFieldList,sal_Bool bMulti ) -{ - - ::rtl::OUString aRetStr, aColumnName; - String aWorkStr; - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(!xConnection.is()) - return aRetStr; - - try - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString(); - // * darf keine Filter enthalten : habe ich die entsprechende Warnung schon angezeigt ? - sal_Bool bCritsOnAsterikWarning = sal_False; // ** TMFS ** - OTableFields::iterator aIter = _rFieldList.begin(); - - for(;aIter != _rFieldList.end();++aIter) - { - OTableFieldDescRef pEntryField = *aIter; - EOrderDir eOrder = pEntryField->GetOrderDir(); - - // nur wenn eine Sortierung und ein Tabellenname vorhanden ist-> erzeugen - // sonst werden die Expressions vom Order By im GenerateCriteria mit erzeugt - if (eOrder != ORDER_NONE && pEntryField->GetTable().getLength()) - { - aColumnName = pEntryField->GetField(); - if(aColumnName.toChar() == '*') - { - // die entsprechende MessageBox nur beim ersten mal anzeigen - if (!bCritsOnAsterikWarning) - ErrorBox((OQueryDesignView*)this, ModuleRes( ERR_QRY_ORDERBY_ON_ASTERISK)).Execute(); - bCritsOnAsterikWarning = sal_True; - continue; - } - if(pEntryField->GetFunctionType() == FKT_NONE) - { - if (bMulti && pEntryField->GetAlias().getLength()) - { - aWorkStr += ::dbtools::quoteName(aQuote, ConvertAlias(pEntryField->GetAlias())).getStr(); - aWorkStr += String('.'); - } - aWorkStr += ::dbtools::quoteName(aQuote, aColumnName).getStr(); - } - else if(pEntryField->GetFieldAlias().getLength()) - { - aWorkStr += ::dbtools::quoteName(aQuote, pEntryField->GetFieldAlias()).getStr(); - } - else if(pEntryField->GetFunctionType() == FKT_AGGREGATE) - { - DBG_ASSERT(pEntryField->GetFunction().getLength(),"Functionname darf hier nicht leer sein! ;-("); - aWorkStr += pEntryField->GetFunction().getStr(); - aWorkStr += String('('); - if (bMulti && pEntryField->GetAlias().getLength()) - { - aWorkStr += ::dbtools::quoteName(aQuote, ConvertAlias(pEntryField->GetAlias())).getStr(); - aWorkStr += String('.'); - } - aWorkStr += ::dbtools::quoteName(aQuote, aColumnName).getStr(); - aWorkStr += String(')'); - } - else - { - if (bMulti && pEntryField->GetAlias().getLength()) - { - aWorkStr += ::dbtools::quoteName(aQuote, ConvertAlias(pEntryField->GetAlias())).getStr(); - aWorkStr += String('.'); - } - aWorkStr += ::dbtools::quoteName(aQuote, aColumnName).getStr(); - } - aWorkStr += String(' '); - aWorkStr += String::CreateFromAscii( ";ASC;DESC" ).GetToken( eOrder ); - aWorkStr += String(','); - } - } - - aWorkStr.EraseTrailingChars( ',' ); - - if( aWorkStr.Len() ) - { - sal_Int32 nMaxOrder = xMetaData->getMaxColumnsInOrderBy(); - if(nMaxOrder && nMaxOrder < aWorkStr.GetTokenCount(',')) - { - ErrorBox aBox( const_cast<OQueryDesignView*>(this), ModuleRes( ERR_QRY_TOO_LONG_STATEMENT ) ); - aBox.Execute(); - } - else - { - aRetStr = ::rtl::OUString::createFromAscii(" ORDER BY "); - aRetStr += aWorkStr; - } - } - } - catch(SQLException&) - { - OSL_ASSERT(!"Failure while building group by!"); - } - - return aRetStr; -} - -//------------------------------------------------------------------------------ - -::rtl::OUString OQueryDesignView::BuildACriteria( const ::rtl::OUString& _rVal, sal_Int32 aType ) -{ - - ::rtl::OUString aRetStr; - String aVal,rVal; - String aOpList;aOpList.AssignAscii("<>;>=;<=;<;>;=;LIKE"); - xub_StrLen nOpListCnt = aOpList.GetTokenCount(); - - String aToken; - for( xub_StrLen nIdx=0 ; nIdx < nOpListCnt ; nIdx++ ) - { - aToken = aOpList.GetToken(nIdx); - if (rVal.Search( aToken ) == 0) - { - aRetStr = ::rtl::OUString(' '); - aRetStr += aToken; - aRetStr += ::rtl::OUString(' '); - aVal = rVal.Copy( aToken.Len() ); - aVal.EraseLeadingChars( ' ' ); - if( aVal.Search( '\'' ) == STRING_NOTFOUND )//XXX O'Brien??? - { - aVal = QuoteField( aVal, aType ); - } - aRetStr += aVal; - break; - } - } - - if( !aRetStr.getLength()) // == 0 - { - aRetStr = rVal.Search( '%' ) == STRING_NOTFOUND ? ::rtl::OUString::createFromAscii(" = ") : ::rtl::OUString::createFromAscii(" LIKE "); - aVal = rVal; - if( aVal.Search( '\'' ) == STRING_NOTFOUND )//XXX O'Brien??? - { - aVal = QuoteField( aVal, aType ); - } - aRetStr += aVal; - } - - return aRetStr;//XXX -} -// ----------------------------------------------------------------------------- -sal_Int32 OQueryDesignView::GetColumnFormatKey(const ::connectivity::OSQLParseNode* pColumnRef) -{ - ::rtl::OUString aTableRange,aColumnName; - ::connectivity::OSQLParseTreeIterator& rParseIter = static_cast<OQueryController*>(getController())->getParseIterator(); - rParseIter.getColumnRange( pColumnRef, aColumnName, aTableRange ); - - OQueryTableWindow* pSTW = NULL; - if (aTableRange.getLength()) - pSTW = static_cast<OQueryTableView*>(m_pTableView)->FindTable( aTableRange ); - else if(m_pTableView->GetTabWinMap()->size()) - pSTW = static_cast<OQueryTableWindow*>(m_pTableView->GetTabWinMap()->begin()->second); - - sal_Int32 nFormatKey = 0; - if(pSTW) - { - try - { - Reference<XNameAccess> xColumns = pSTW->GetOriginalColumns(); - if(xColumns.is() && xColumns->hasByName(aColumnName)) - { - Reference<XPropertySet> xColumn; - ::cppu::extractInterface(xColumn,xColumns->getByName(aColumnName)); - OSL_ENSURE(xColumn.is(),"Column is null!"); - if(xColumn.is() && xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_NUMBERFORMAT)) - xColumn->getPropertyValue(PROPERTY_NUMBERFORMAT) >>= nFormatKey; - } - } - catch(Exception&) - { - OSL_ASSERT(!"Failure while get column format!"); - } - } - return nFormatKey; -} -//------------------------------------------------------------------------------ -sal_Bool OQueryDesignView::FillDragInfo(const ::connectivity::OSQLParseNode* pColumnRef,OTableFieldDescRef& _rDragInfo) -{ - - sal_Bool bErg = sal_False; - - ::rtl::OUString aTableRange,aColumnName; - sal_uInt16 nCntAccount; - ::connectivity::OSQLParseTreeIterator& rParseIter = static_cast<OQueryController*>(getController())->getParseIterator(); - rParseIter.getColumnRange( pColumnRef, aColumnName, aTableRange ); - - if (aTableRange.getLength()) - { - OQueryTableWindow* pSTW = static_cast<OQueryTableView*>(m_pTableView)->FindTable( aTableRange ); - if(pSTW && pSTW->ExistsField( aColumnName, _rDragInfo ) ) - bErg = sal_True; - } - if(!bErg) - bErg = static_cast<OQueryTableView*>(m_pTableView)->FindTableFromField(aColumnName, _rDragInfo, nCntAccount); - - return bErg; -} -// ----------------------------------------------------------------------------- -int OQueryDesignView::GetSelectionCriteria( const ::connectivity::OSQLParseNode* pNode, int& rLevel, sal_Bool bJoinWhere) -{ - - // Naechster freier Satz ... - int nRet = 0; - int nJoins=0; - - if (!SQL_ISRULE(pNode, select_statement)) - { - ErrorBox aBox( this, ModuleRes( ERR_QRY_NOSELECT ) ); - aBox.Execute(); - return 1; - } - - // nyi: mehr Pruefung auf korrekte Struktur! - pNode = pNode ? pNode->getChild(3)->getChild(1) : NULL; - // Keine WHERE-Klausel. - if (!pNode || pNode->isLeaf()) - return nRet; - - ::connectivity::OSQLParseNode * pCondition = pNode->getChild(1); - if (!pCondition) // kein where clause - return nRet; - - // jetzt die anderen Bedingungen eintragen - ::connectivity::OSQLParseNode::negateSearchCondition(pCondition); - - ::connectivity::OSQLParseNode *pNodeTmp = pNode->getChild(1); - ::connectivity::OSQLParseNode::disjunctiveNormalForm(pNodeTmp); - pNodeTmp = pNode->getChild(1); - ::connectivity::OSQLParseNode::absorptions(pNodeTmp); - pNodeTmp = pNode->getChild(1); - - // first extract the inner joins conditions - GetInnerJoinCriteria(pNodeTmp); - - // it could happen that pCondition is not more valid - nRet = GetORCriteria(pNodeTmp, rLevel); - - if (nRet != 0) // mindestens eine OR Verknuepfung - { - ErrorBox aBox( this, ModuleRes( ERR_QRY_TOOCOMPLEX ) ); - aBox.Execute(); - return 99; - } - return nRet; -} -//------------------------------------------------------------------------------ -sal_Bool OQueryDesignView::GetInnerJoinCriteria(const ::connectivity::OSQLParseNode *pCondition) -{ - sal_Bool bFoundInnerJoin = sal_False; - ::connectivity::OSQLParseNode *pTmp=NULL; - bFoundInnerJoin = InsertJoinConnection(pCondition, INNER_JOIN); - return bFoundInnerJoin; -} -//------------------------------------------------------------------------------ - -int OQueryDesignView::GetORCriteria(const ::connectivity::OSQLParseNode * pCondition, int& nLevel ,sal_Bool bHaving) -{ - - int nRet = 0; - - // Runde Klammern um den Ausdruck - if (pCondition->count() == 3 && - SQL_ISPUNCTUATION(pCondition->getChild(0),"(") && - SQL_ISPUNCTUATION(pCondition->getChild(2),")")) - { - nRet = GetORCriteria(pCondition->getChild(1),nLevel,bHaving); - } - // oder Verknuepfung - // a searchcondition can only look like this: search_condition SQL_TOKEN_OR boolean_term - else if (SQL_ISRULE(pCondition,search_condition)) - { - for (int i = 0; i < 3; i+=2) - { - // Ist das erste Element wieder eine OR-Verknuepfung? - // Dann rekursiv absteigen ... - //if (!i && SQL_ISRULE(pCondition->getChild(i),search_condition)) - if (SQL_ISRULE(pCondition->getChild(i),search_condition)) - { - nRet = GetORCriteria(pCondition->getChild(i),nLevel,bHaving); - } - else if (!nRet) - { - nRet = GetANDCriteria(pCondition->getChild(i), nLevel++,bHaving); - } - else - { - ErrorBox aBox( this, ModuleRes( ERR_QRY_TOOMANYCOND ) ); - aBox.Execute(); - return 1; - } - } - } - else - { - nRet = GetANDCriteria( pCondition, nLevel, bHaving ); - } - return nRet; -} - - -//-------------------------------------------------------------------------------------------------- -int OQueryDesignView::GetANDCriteria(const ::connectivity::OSQLParseNode * pCondition, const int nLevel,sal_Bool bHaving ) -{ - - // ich werde ein paar Mal einen gecasteten Pointer auf meinen ::com::sun::star::sdbcx::Container brauchen - int nRet = 0; - - // Runde Klammern - if (SQL_ISRULE(pCondition,boolean_primary)) - { - int nLevel2 = nLevel; - nRet = GetORCriteria(pCondition->getChild(1), nLevel2,bHaving ); - } - // Das erste Element ist (wieder) eine AND-Verknuepfung - else if ( SQL_ISRULE(pCondition,boolean_term) && pCondition->count() == 3 ) - { - nRet = GetANDCriteria(pCondition->getChild(0), nLevel,bHaving ); - if (!nRet) - nRet = GetANDCriteria(pCondition->getChild(2), nLevel,bHaving ); - } - else if (SQL_ISRULE( pCondition, comparison_predicate)) - { - nRet = ComparsionPredicate(pCondition,nLevel,bHaving); - } - else if((SQL_ISRULE(pCondition,like_predicate))) - { - ::rtl::OUString aCondition; - OTableFieldDescRef aDragLeft = new OTableFieldDesc(); - if(SQL_ISRULE(pCondition->getChild(0), column_ref )) - { - ::rtl::OUString aColumnName; - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(xConnection.is()) - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - // the international doesn't matter I have a string - pCondition->parseNodeToPredicateStr(aCondition, - xMetaData, - static_cast<OQueryController*>(getController())->getNumberFormatter(), - m_aLocale, - m_sDecimalSep.toChar(), - &static_cast<OQueryController*>(getController())->getParser()->getContext() - ); - - pCondition->getChild(0)->parseNodeToPredicateStr( - aColumnName, - xMetaData, - static_cast<OQueryController*>(getController())->getNumberFormatter(), - m_aLocale, - m_sDecimalSep.toChar(), - &static_cast<OQueryController*>(getController())->getParser()->getContext() - ); - - // don't display the column name - aCondition = aCondition.copy(aColumnName.getLength()); - aCondition = aCondition.trim(); - } - - if (FillDragInfo(pCondition->getChild(0),aDragLeft)) - m_pSelectionBox->AddCondition(aDragLeft, aCondition, nLevel); - else - { - ErrorBox( this, ModuleRes( ERR_QRY_SYNTAX ) ).Execute(); - nRet = 5; - } - } - else - { - ErrorBox( this, ModuleRes( ERR_QRY_SYNTAX ) ).Execute(); - nRet = 5; - } - } - else if((SQL_ISRULE(pCondition,test_for_null) || SQL_ISRULE(pCondition,in_predicate) || - SQL_ISRULE(pCondition,all_or_any_predicate) || SQL_ISRULE(pCondition,between_predicate))) - { - ::rtl::OUString aCondition; - OTableFieldDescRef aDragLeft = new OTableFieldDesc(); - if(SQL_ISRULE(pCondition->getChild(0), column_ref )) - { - // parse condition - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(xConnection.is()) - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - for(sal_uInt16 i=1;i< pCondition->count();i++) - pCondition->getChild(i)->parseNodeToPredicateStr(aCondition, - xMetaData, - static_cast<OQueryController*>(getController())->getNumberFormatter(), - m_aLocale, - m_sDecimalSep.toChar(), - &static_cast<OQueryController*>(getController())->getParser()->getContext() - ); - } - } - - if (FillDragInfo(pCondition->getChild(0),aDragLeft)) - m_pSelectionBox->AddCondition(aDragLeft, aCondition, nLevel); - else - { - ErrorBox( this, ModuleRes( ERR_QRY_SYNTAX ) ).Execute(); - nRet = 5; - } - } - else if((SQL_ISRULE(pCondition,existence_test) || SQL_ISRULE(pCondition,unique_test))) - { - ::rtl::OUString aCondition; - OTableFieldDescRef aDragLeft = new OTableFieldDesc(); - - // Funktions-Bedingung parsen - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(xConnection.is()) - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - for(sal_uInt16 i=0;i< pCondition->count();i++) - pCondition->getChild(i)->parseNodeToPredicateStr(aCondition, - xMetaData, - static_cast<OQueryController*>(getController())->getNumberFormatter(), - m_aLocale, - m_sDecimalSep.toChar(), - &static_cast<OQueryController*>(getController())->getParser()->getContext()); - } - - aDragLeft->SetField(aCondition); - aDragLeft->SetFunctionType(FKT_CONDITION); - - m_pSelectionBox->InsertField(aDragLeft,-1,sal_False,sal_True); - } - else - { - // Etwas anderes unterstuetzen wir (noch) nicht. Basta! - ErrorBox( this, ModuleRes( ERR_QRY_SYNTAX ) ).Execute(); - nRet = 5; - } - // Fehler einfach weiterreichen. - return nRet; -} -//------------------------------------------------------------------------------ -int OQueryDesignView::ComparsionPredicate(const ::connectivity::OSQLParseNode * pCondition, const int nLevel, sal_Bool bHaving ) -{ - - DBG_ASSERT(SQL_ISRULE( pCondition, comparison_predicate),"ComparsionPredicate: pCondition ist kein ComparsionPredicate"); - sal_uInt32 nRet = 0; - if(SQL_ISRULE(pCondition->getChild(0), column_ref ) || SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref )) - { - ::rtl::OUString aCondition; - OTableFieldDescRef aDragLeft = new OTableFieldDesc(); - sal_uInt32 nPos; - if(SQL_ISRULE(pCondition->getChild(0), column_ref ) && SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref )) - { - OTableFieldDescRef aDragRight = new OTableFieldDesc(); - if (!FillDragInfo(pCondition->getChild(0),aDragLeft) || - !FillDragInfo(pCondition->getChild(2),aDragRight)) - return nRet; - - OQueryTableConnection* pConn = static_cast<OQueryTableConnection*>(m_pTableView->GetTabConn(static_cast<OQueryTableWindow*>(aDragLeft->GetTabWindow()), - static_cast<OQueryTableWindow*>(aDragRight->GetTabWindow()))); - if(pConn) - { - OConnectionLineDataVec* pLineDataList = pConn->GetData()->GetConnLineDataList(); - OConnectionLineDataVec::iterator aIter = pLineDataList->begin(); - for(;aIter != pLineDataList->end();++aIter) - { - if((*aIter)->GetSourceFieldName() == aDragLeft->GetField() || - (*aIter)->GetDestFieldName() == aDragLeft->GetField() ) - break; - } - if(aIter != pLineDataList->end()) - return 0; - } - } - - if(SQL_ISRULE(pCondition->getChild(0), column_ref )) - { - nPos = 0; - sal_uInt32 i=1; - - // don't display the equal - if (pCondition->getChild(i)->getNodeType() == SQL_NODE_EQUAL) - i++; - - // International aInter(Shell()->BuildInternational(GetColumnFormatKey(pCondition->getChild(0)))); - // Bedingung parsen - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(xConnection.is()) - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - for(;i< pCondition->count();i++) - pCondition->getChild(i)->parseNodeToPredicateStr(aCondition, - xMetaData, - static_cast<OQueryController*>(getController())->getNumberFormatter(), - m_aLocale, - m_sDecimalSep.toChar(), - &static_cast<OQueryController*>(getController())->getParser()->getContext()); - } - } - else if(SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref )) - { - nPos = pCondition->count()-1; - - sal_uInt32 i = pCondition->count() - 2; - switch (pCondition->getChild(i)->getNodeType()) - { - case SQL_NODE_EQUAL: - // don't display the equal - i--; - break; - case SQL_NODE_LESS: - // take the opposite as we change the order - i--; - aCondition = aCondition + ::rtl::OUString::createFromAscii(">"); - break; - case SQL_NODE_LESSEQ: - // take the opposite as we change the order - i--; - aCondition = aCondition + ::rtl::OUString::createFromAscii(">="); - break; - case SQL_NODE_GREAT: - // take the opposite as we change the order - i--; - aCondition = aCondition + ::rtl::OUString::createFromAscii("<"); - break; - case SQL_NODE_GREATEQ: - // take the opposite as we change the order - i--; - aCondition = aCondition + ::rtl::OUString::createFromAscii("<="); - break; - } - // International aInter(Shell()->BuildInternational(GetColumnFormatKey(pCondition->getChild(pCondition->count()-1)))); - - // go backward - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(xConnection.is()) - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - for (; i >= 0; i--) - pCondition->getChild(i)->parseNodeToPredicateStr(aCondition, - xMetaData, - static_cast<OQueryController*>(getController())->getNumberFormatter(), - m_aLocale, - m_sDecimalSep.toChar(), - &static_cast<OQueryController*>(getController())->getParser()->getContext()); - } - } - if(FillDragInfo(pCondition->getChild(nPos),aDragLeft)) - { - if(bHaving) - aDragLeft->SetGroupBy(sal_True); - m_pSelectionBox->AddCondition(aDragLeft, aCondition, nLevel); - } - else - { - ErrorBox( this, ModuleRes( ERR_QRY_SYNTAX ) ).Execute(); - nRet = 5; - } - } - else if(SQL_ISRULE(pCondition->getChild(0), set_fct_spec ) || SQL_ISRULE(pCondition->getChild(0), general_set_fct )) - { - ::rtl::OUString aName, - aCondition; - OTableFieldDescRef aDragLeft = new OTableFieldDesc(); - - OSQLParseNode* pFunction = pCondition->getChild(0); - - ::rtl::OUString aColumnName; - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(xConnection.is()) - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - pCondition->parseNodeToPredicateStr(aCondition, - xMetaData, - static_cast<OQueryController*>(getController())->getNumberFormatter(), - m_aLocale, - m_sDecimalSep.toChar(), - &static_cast<OQueryController*>(getController())->getParser()->getContext()); - pFunction->parseNodeToPredicateStr(aColumnName, - xMetaData, - static_cast<OQueryController*>(getController())->getNumberFormatter(), - m_aLocale, - m_sDecimalSep.toChar(), - &static_cast<OQueryController*>(getController())->getParser()->getContext()); - // don't display the column name - aCondition = aCondition.copy(aColumnName.getLength()); - aCondition = aCondition.trim(); - if(aCondition.indexOf('=',0) == 1) // ignore the equal sign - aCondition = aCondition.copy(1); - - - if(SQL_ISRULE(pFunction, general_set_fct )) - { - if(!FillDragInfo(pFunction->getChild(pFunction->count()-2),aDragLeft)) - { - OSL_ENSURE(pFunction->count() > 3,"Invalid format for general_set_fct!"); - ::rtl::OUString sParameterValue; - pFunction->getChild(pFunction->count()-2)->parseNodeToPredicateStr(sParameterValue, - xMetaData, - static_cast<OQueryController*>(getController())->getNumberFormatter(), - m_aLocale, - m_sDecimalSep.toChar(), - &static_cast<OQueryController*>(getController())->getParser()->getContext()); - aDragLeft->SetField(sParameterValue); - } - aDragLeft->SetFunctionType(FKT_AGGREGATE); - if(bHaving) - aDragLeft->SetGroupBy(sal_True); - sal_Int32 nIndex = 0; - aDragLeft->SetFunction(aColumnName.getToken(0,'(',nIndex)); - } - else - { - // bei unbekannten Funktionen wird der gesamte Text in das Field gechrieben - aDragLeft->SetField(aColumnName); - if(bHaving) - aDragLeft->SetGroupBy(sal_True); - aDragLeft->SetFunctionType(FKT_OTHER); - } - m_pSelectionBox->AddCondition(aDragLeft, aCondition, nLevel); - } - } - else // kann sich nur um einen Expr. Ausdruck handeln - { - OTableFieldDescRef aDragLeft = new OTableFieldDesc(); - ::rtl::OUString aName,aCondition; - - ::connectivity::OSQLParseNode *pLhs = pCondition->getChild(0); - ::connectivity::OSQLParseNode *pRhs = pCondition->getChild(2); - // Feldnamen - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(xConnection.is()) - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - for(sal_uInt16 i=0;i< pLhs->count();i++) - pCondition->getChild(i)->parseNodeToStr(aName, - xMetaData, - &static_cast<OQueryController*>(getController())->getParser()->getContext(), - sal_True); - // Kriterium - aCondition = pCondition->getChild(1)->getTokenValue(); - for(i=0;i< pRhs->count();i++) - pCondition->getChild(i)->parseNodeToPredicateStr(aCondition, - xMetaData, - static_cast<OQueryController*>(getController())->getNumberFormatter(), - m_aLocale, - m_sDecimalSep.toChar(), - &static_cast<OQueryController*>(getController())->getParser()->getContext()); - } - - aDragLeft->SetField(aName); - aDragLeft->SetFunctionType(FKT_OTHER); - // und anh"angen - m_pSelectionBox->AddCondition(aDragLeft, aCondition, nLevel); - } - return nRet; -} -// ----------------------------------------------------------------------------- -::rtl::OUString OQueryDesignView::QuoteField( const ::rtl::OUString& rValue, sal_Int32 aType ) -{ - ::rtl::OUString rNewValue; - switch (rValue.toChar()) - { - case '?': - if (rValue.getLength() != 1) - break; - case '\'': // ::rtl::OUString Quotierung oder Datum - //case '#': // Datumsquotierung // jetengine - case ':': // Parameter - case '[': // Parameter - return rValue; - } - - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - Reference< XDatabaseMetaData > xMetaData; - if(xConnection.is()) - xMetaData = xConnection->getMetaData(); - ::rtl::OUString aQuote; - try - { - if(xMetaData.is()) - aQuote = xMetaData->getIdentifierQuoteString(); - - switch( aType ) - { - case DataType::DATE: - case DataType::TIME: - case DataType::TIMESTAMP: - if (rValue.toChar() != '{') // nur quoten, wenn kein Access Datum - rNewValue = ::dbtools::quoteName(aQuote,rValue); - else - rNewValue = rValue; - break; - case DataType::CHAR: - case DataType::VARCHAR: - case DataType::LONGVARCHAR: - rNewValue = ::dbtools::quoteName(aQuote,rValue); - break; - case DataType::DECIMAL: - case DataType::NUMERIC: - case DataType::TINYINT: - case DataType::SMALLINT: - case DataType::INTEGER: - case DataType::BIGINT: - case DataType::REAL: - case DataType::DOUBLE: - case DataType::BINARY: - case DataType::VARBINARY: - case DataType::LONGVARBINARY: - rNewValue = rValue; - break; - case DataType::BIT: - { - if(xMetaData.is()) - { - ::comphelper::UStringMixEqual bCase(xMetaData->storesMixedCaseQuotedIdentifiers()); - if (bCase(rValue, ::rtl::OUString(ModuleRes(STR_QUERY_TRUE)))) - rNewValue = ::rtl::OUString::createFromAscii("TRUE"); - else if (bCase(rValue, ::rtl::OUString(ModuleRes(STR_QUERY_FALSE)))) - rNewValue = ::rtl::OUString::createFromAscii("FALSE"); - else - rNewValue = rValue; - } - } - break; - default: - DBG_ERROR( "QuoteField: illegal type" ); - break; - } - } - catch(SQLException&) - { - DBG_ERROR( "QuoteField: Exception" ); - } - return rNewValue; -} // ----------------------------------------------------------------------------- -sal_Bool OQueryDesignView::InsertJoinConnection(const ::connectivity::OSQLParseNode *pNode, const EJoinType& _eJoinType) -{ - if (pNode->count() == 3 && // Ausdruck is geklammert - SQL_ISPUNCTUATION(pNode->getChild(0),"(") && - SQL_ISPUNCTUATION(pNode->getChild(2),")")) - { - return InsertJoinConnection(pNode->getChild(1), _eJoinType); - } - else if (SQL_ISRULE(pNode,search_condition) || - SQL_ISRULE(pNode,boolean_term) && // AND/OR-Verknuepfung: - pNode->count() == 3) - { - // nur AND Verknpfung zulassen - if (!SQL_ISTOKEN(pNode->getChild(1),AND)) - return sal_False; - else - return InsertJoinConnection(pNode->getChild(0), _eJoinType) && - InsertJoinConnection(pNode->getChild(2), _eJoinType); - } - else if (SQL_ISRULE(pNode,comparison_predicate)) - { - // Nur ein Vergleich auf Spalten ist erlaubt - DBG_ASSERT(pNode->count() == 3,"OQueryDesignView::InsertJoinConnection: Fehler im Parse Tree"); - if (!(SQL_ISRULE(pNode->getChild(0),column_ref) && - SQL_ISRULE(pNode->getChild(2),column_ref) && - pNode->getChild(1)->getNodeType() == SQL_NODE_EQUAL)) - return sal_False; - - OTableFieldDescRef aDragLeft = new OTableFieldDesc(); - OTableFieldDescRef aDragRight = new OTableFieldDesc(); - if (!FillDragInfo(pNode->getChild(0),aDragLeft) || - !FillDragInfo(pNode->getChild(2),aDragRight)) - return sal_False; - - OQueryTableConnection* pConn = static_cast<OQueryTableConnection*>( m_pTableView->GetTabConn(static_cast<OQueryTableWindow*>(aDragLeft->GetTabWindow()),static_cast<OQueryTableWindow*>(aDragRight->GetTabWindow()))); - if(!pConn) - { - OQueryTableConnectionData aInfoData; - aInfoData.InitFromDrag(aDragLeft, aDragRight); - aInfoData.SetJoinType(_eJoinType); - - OQueryTableConnection aInfo(static_cast<OQueryTableView*>(m_pTableView), &aInfoData); - // da ein OQueryTableConnection-Objekt nie den Besitz der uebergebenen Daten uebernimmt, sondern sich nur den Zeiger merkt, - // ist dieser Zeiger auf eine lokale Variable hier unkritisch, denn aInfoData und aInfo haben die selbe Lebensdauer - static_cast<OQueryTableView*>(m_pTableView)->NotifyTabConnection( aInfo ); - } - else - { - ::rtl::OUString aSourceFieldName(aDragLeft->GetField()); - ::rtl::OUString aDestFieldName(aDragRight->GetField()); - // the connection could point on the other side - if(pConn->GetSourceWin() == aDragRight->GetTabWindow()) - { - ::rtl::OUString aTmp(aSourceFieldName); - aSourceFieldName = aDestFieldName; - aDestFieldName = aTmp; - } - pConn->GetData()->AppendConnLine( aSourceFieldName,aDestFieldName); - pConn->UpdateLineList(); - // Modified-Flag - // SetModified(); - // und neu zeichnen - pConn->RecalcLines(); - // fuer das unten folgende Invalidate muss ich dieser neuen Connection erst mal die Moeglichkeit geben, - // ihr BoundingRect zu ermitteln - pConn->Invalidate(); - } - return sal_True; - } - return sal_False; -} // ----------------------------------------------------------------------------- void OQueryDesignView::setSlotEnabled(sal_Int32 _nSlotId,sal_Bool _bEnable) { @@ -2054,546 +2672,6 @@ sal_Bool OQueryDesignView::isSlotEnabled(sal_Int32 _nSlotId) return m_pSelectionBox->IsRowVisible(nRow); } // ----------------------------------------------------------------------------- -void OQueryDesignView::InitFromParseNode() -{ - m_pSelectionBox->PreFill(); - m_pSelectionBox->Fill(); - - ::connectivity::OSQLParseTreeIterator& aIterator = static_cast<OQueryController*>(getController())->getParseIterator(); - const ::connectivity::OSQLParseNode* pParseTree = aIterator.getParseTree(); - const ::connectivity::OSQLParseNode* pTableRefCommaList = 0; - - if (pParseTree) - { - if (!static_cast<OQueryController*>(getController())->isEsacpeProcessing()) - { - WarningBox( this, ModuleRes(WARN_QRY_NATIVE) ).Execute(); - } - else if (SQL_ISRULE(pParseTree,select_statement)) - { - - ::connectivity::OSQLParseNode* pTree = pParseTree->getChild(1); - - const OSQLTables& aMap = aIterator.getTables(); - ::comphelper::UStringMixLess aTmp(aMap.key_comp()); - ::comphelper::UStringMixEqual aKeyComp(static_cast< ::comphelper::UStringMixLess*>(&aTmp)->isCaseSensitive()); - - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(xConnection.is()) - { - sal_Int32 nMax = 0; - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - try - { - nMax = xMetaData->getMaxTablesInSelect(); - - if(!nMax || nMax >= (sal_Int32)aMap.size()) // Anzahl der Tabellen im Select-Statement "uberpr"ufen - { - ::rtl::OUString sComposedName; - ::rtl::OUString aQualifierName; - ::rtl::OUString sAlias; - - OSQLTables::const_iterator aIter = aMap.begin(); - for(;aIter != aMap.end();++aIter) - { - OSQLTable xTable = aIter->second; - ::dbaui::composeTableName(xMetaData,Reference<XPropertySet>(xTable,UNO_QUERY),sComposedName,sal_False); - sAlias = aIter->first; - if(aKeyComp(sComposedName,aIter->first)) - { - ::rtl::OUString sCatalog,sSchema,sTable; - ::dbtools::qualifiedNameComponents(xMetaData,sComposedName,sCatalog,sSchema,sTable); - sAlias = sTable; - } - - OQueryTableWindow* pExistentWin = static_cast<OQueryTableView*>(m_pTableView)->FindTable(sAlias); - if (!pExistentWin) - { - m_pTableView->AddTabWin(sComposedName, sAlias,sal_False);// don't create data here - } - else - { - // es existiert schon ein Fenster mit dem selben Alias ... - if (!aKeyComp(pExistentWin->GetData()->GetComposedName(),sComposedName)) - // ... aber anderem Tabellennamen -> neues Fenster - m_pTableView->AddTabWin(sComposedName, sAlias); - } - } - - // now delete the data for which we haven't any tablewindow - OJoinTableView::OTableWindowMap* pTableMap = m_pTableView->GetTabWinMap(); - OJoinTableView::OTableWindowMap::iterator aIterTableMap = pTableMap->begin(); - for(;aIterTableMap != pTableMap->end();++aIterTableMap) - { - if(aMap.find(aIterTableMap->second->GetComposedName()) == aMap.end() && - aMap.find(aIterTableMap->first) == aMap.end()) - m_pTableView->RemoveTabWin(aIterTableMap->second); - } - - FillOuterJoins(pParseTree->getChild(3)->getChild(0)->getChild(1)); - - // check if we have a distinct statement - if(SQL_ISTOKEN(pParseTree->getChild(1),DISTINCT)) - { - static_cast<OQueryController*>(getController())->setDistinct(sal_True); - static_cast<OQueryController*>(getController())->InvalidateFeature(ID_BROWSER_QUERY_DISTINCT_VALUES); - } - if (!InstallFields(pParseTree, m_pTableView->GetTabWinMap())) - { - // GetSelectionCriteria mu"s vor GetHavingCriteria aufgerufen werden - int nLevel=0; - - GetSelectionCriteria(pParseTree,nLevel,sal_True); - GetGroupCriteria(pParseTree); - GetHavingCriteria(pParseTree,nLevel); - GetOrderCriteria(pParseTree); - // now we have to insert the fields which aren't in the statement - OTableFields& rUnUsedFields = static_cast<OQueryController*>(getController())->getUnUsedFields(); - for(OTableFields::iterator aIter = rUnUsedFields.begin();aIter != rUnUsedFields.end();++aIter) - if(m_pSelectionBox->InsertField(*aIter,-1,sal_False,sal_False).isValid()) - (*aIter) = NULL; - OTableFields().swap( rUnUsedFields ); - } - } - else - { - ErrorBox aBox(this, ModuleRes( ERR_QRY_TOO_MANY_TABLES)); - aBox.Execute(); - } - } - catch(SQLException&) - { - OSL_ASSERT(!"getMaxTablesInSelect!"); - } - } - } - else - { - ErrorBox aBox(this, ModuleRes( ERR_QRY_NOSELECT)); - aBox.Execute(); - } - } - - // Durch das Neuerzeugen wurden wieder Undo-Actions in den Manager gestellt - static_cast<OQueryController*>(getController())->getUndoMgr()->Clear(); - m_pSelectionBox->Invalidate(); -} -// ----------------------------------------------------------------------------- -int OQueryDesignView::InstallFields(const ::connectivity::OSQLParseNode* pNode, OJoinTableView::OTableWindowMap* pTabList ) -{ - if( pNode==0 || !SQL_ISRULE(pNode,select_statement)) - { - ErrorBox aBox( this, ModuleRes( ERR_QRY_NOSELECT ) ); - aBox.Execute(); - return 1; - } - - ::connectivity::OSQLParseNode* pParseTree = pNode->getChild(2); - sal_Bool bFirstField = sal_True; // bei der Initialisierung mu auf alle Faelle das erste Feld neu aktiviert werden - - if(pParseTree->isRule() && SQL_ISPUNCTUATION(pParseTree->getChild(0),"*")) - { - // SELECT * ... - - OTableFieldDescRef aInfo = new OTableFieldDesc(); - OJoinTableView::OTableWindowMap::iterator aIter = pTabList->begin(); - for(;aIter != pTabList->end();++aIter) - { - OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second); - - if (pTabWin->ExistsField( ::rtl::OUString::createFromAscii("*"), aInfo )) - { - if(!InsertField(aInfo, sal_True, bFirstField)) - return 1; - bFirstField = sal_False; - } - } - - // Einfach alle Columns der Datei direkt uebernehmen: - } - else if (SQL_ISRULE(pParseTree,scalar_exp_commalist) ) - { - // SELECT column, ... - - ::rtl::OUString aColumnName,aTableRange; - for (sal_uInt32 i = 0; i < pParseTree->count(); i++) - { - ::connectivity::OSQLParseNode * pColumnRef = pParseTree->getChild(i); - - if (SQL_ISRULE(pColumnRef,select_sublist)) - { - OTableFieldDescRef aInfo = new OTableFieldDesc(); - OJoinTableView::OTableWindowMap::iterator aIter = pTabList->begin(); - for(;aIter != pTabList->end();++aIter) - { - OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second); - - if (pTabWin->ExistsField( ::rtl::OUString::createFromAscii("*"), aInfo )) - { - if(!InsertField(aInfo, sal_True, bFirstField)) - return 1; - - bFirstField = sal_False; - } - } - } - else if (SQL_ISRULE(pColumnRef,derived_column)) - { - Reference< XConnection> xConnection = static_cast<OQueryController*>(getController())->getConnection(); - if(xConnection.is()) - { - Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); - ::rtl::OUString aColumnAlias(static_cast<OQueryController*>(getController())->getParseIterator().getColumnAlias(pColumnRef)); // kann leer sein - pColumnRef = pColumnRef->getChild(0); - if (SQL_ISRULE(pColumnRef,column_ref)) - { - OTableFieldDescRef aInfo = new OTableFieldDesc(); - switch(InsertColumnRef(pColumnRef,aColumnName,aColumnAlias,aTableRange,aInfo,pTabList)) - { - case 5: - ErrorBox( this, ModuleRes( ERR_QRY_AMB_FIELD ) ).Execute(); - break; - default: - if(!InsertField(aInfo, sal_True, bFirstField)) - return 1; - bFirstField = sal_False; - } - } - else if(SQL_ISRULE(pColumnRef,general_set_fct) || SQL_ISRULE(pColumnRef,set_fct_spec) || - SQL_ISRULE(pColumnRef,position_exp) || SQL_ISRULE(pColumnRef,extract_exp) || - SQL_ISRULE(pColumnRef,length_exp) || SQL_ISRULE(pColumnRef,char_value_fct)) - { - OTableFieldDescRef aInfo = new OTableFieldDesc(); - ::rtl::OUString aColumns; - pColumnRef->parseNodeToStr( aColumns, - xMetaData, - &static_cast<OQueryController*>(getController())->getParser()->getContext(), - sal_True, - sal_True); // quote is to true because we need quoted elements inside the function - - ::connectivity::OSQLParseNode * pParamRef = pColumnRef->getChild(pColumnRef->count()-2); - if (SQL_ISRULE(pColumnRef,general_set_fct) - && SQL_ISRULE(pParamRef = pColumnRef->getChild(pColumnRef->count()-2),column_ref)) - { - // Parameter auf Columnref pr"ufen - switch(InsertColumnRef(pParamRef,aColumnName,aColumnAlias,aTableRange,aInfo,pTabList)) - { - case 5: - ErrorBox( this, ModuleRes( ERR_QRY_AMB_FIELD ) ).Execute(); - break; - } - } - else - { - if(pParamRef && pParamRef->getTokenValue().toChar() == '*') - { - OJoinTableView::OTableWindowMap::iterator aIter = pTabList->begin(); - for(;aIter != pTabList->end();++aIter) - { - OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second); - if (pTabWin->ExistsField( ::rtl::OUString::createFromAscii("*"), aInfo )) - { - aInfo->SetAlias(String()); - aInfo->SetTable(String()); - break; - } - } - } - else - { - aInfo->SetDataType(DataType::DOUBLE); - aInfo->SetFieldType(TAB_NORMAL_FIELD); - aInfo->SetField(aColumns); - - } - aInfo->SetTabWindow(NULL); - aInfo->SetFieldAlias(aColumnAlias); - } - - if(SQL_ISRULE(pColumnRef,general_set_fct)) - { - aInfo->SetFunctionType(FKT_AGGREGATE); - String aCol(aColumns); - aInfo->SetFunction(aCol.GetToken(0,'(').EraseTrailingChars(' ')); - } - else - aInfo->SetFunctionType(FKT_OTHER); - - if(!InsertField(aInfo, sal_True, bFirstField)) - return 1; - bFirstField = sal_False; - } - else //if(SQL_ISRULE(pColumnRef,num_value_exp) || SQL_ISRULE(pColumnRef,term)) - { - ::rtl::OUString aColumns; - pColumnRef->parseNodeToStr( aColumns, - xMetaData, - &static_cast<OQueryController*>(getController())->getParser()->getContext(), - sal_True,sal_False); - - OTableFieldDescRef aInfo = new OTableFieldDesc(); - aInfo->SetDataType(DataType::DOUBLE); - aInfo->SetFieldType(TAB_NORMAL_FIELD); - aInfo->SetTabWindow(NULL); - aInfo->SetField(aColumns); - aInfo->SetFieldAlias(aColumnAlias); - aInfo->SetFunctionType(FKT_OTHER); - - if(!InsertField(aInfo, sal_True, bFirstField)) - return 1; - bFirstField = sal_False; - } - } - } - } - } - else - { - ErrorBox( this, ModuleRes( ERR_QRY_SYNTAX ) ).Execute(); - return 4; - } - - return 0; -} -//------------------------------------------------------------------------------ -void OQueryDesignView::GetOrderCriteria(const ::connectivity::OSQLParseNode* pParseRoot ) -{ - if (!pParseRoot->getChild(3)->getChild(4)->isLeaf()) - { - ::connectivity::OSQLParseNode* pNode = pParseRoot->getChild(3)->getChild(4)->getChild(2); - ::connectivity::OSQLParseNode* pParamRef = NULL; - ::rtl::OUString aField, aAlias; - sal_uInt16 nPos = 0; - - EOrderDir eOrderDir; - OTableFieldDescRef aDragLeft = new OTableFieldDesc(); - for( sal_uInt32 i=0 ; i<pNode->count() ; i++ ) - { - eOrderDir = ORDER_ASC; - ::connectivity::OSQLParseNode* pChild = pNode->getChild( i ); - - if (SQL_ISTOKEN( pChild->getChild(1), DESC ) ) - eOrderDir = ORDER_DESC; - - if(SQL_ISRULE(pChild->getChild(0),column_ref)) - { - if(FillDragInfo(pChild->getChild(0),aDragLeft)) - m_pSelectionBox->AddOrder( aDragLeft, eOrderDir, nPos); - else // it could be a alias name for a field - { - ::rtl::OUString aTableRange,aColumnName; - ::connectivity::OSQLParseTreeIterator& rParseIter = static_cast<OQueryController*>(getController())->getParseIterator(); - rParseIter.getColumnRange( pChild->getChild(0), aColumnName, aTableRange ); - - OTableFields& aList = static_cast<OQueryController*>(getController())->getTableFieldDesc(); - OTableFields::iterator aIter = aList.begin(); - for(;aIter != aList.end();++aIter) - { - OTableFieldDescRef pEntry = *aIter; - if(pEntry.isValid() && pEntry->GetFieldAlias() == aColumnName.getStr()) - pEntry->SetOrderDir( eOrderDir ); - } - } - } - else if(SQL_ISRULE(pChild->getChild(0),general_set_fct) && - SQL_ISRULE(pParamRef = pChild->getChild(0)->getChild(pChild->getChild(0)->count()-2),column_ref) && - FillDragInfo(pParamRef,aDragLeft)) - m_pSelectionBox->AddOrder( aDragLeft, eOrderDir, nPos); - } - } -} -//------------------------------------------------------------------------------ -void OQueryDesignView::GetHavingCriteria(const ::connectivity::OSQLParseNode* pSelectRoot, int &rLevel ) -{ - if (!pSelectRoot->getChild(3)->getChild(3)->isLeaf()) - GetORCriteria(pSelectRoot->getChild(3)->getChild(3)->getChild(1),rLevel, sal_True); -} -//------------------------------------------------------------------------------ -void OQueryDesignView::GetGroupCriteria(const ::connectivity::OSQLParseNode* pSelectRoot ) -{ - if (!pSelectRoot->getChild(3)->getChild(2)->isLeaf()) - { - ::connectivity::OSQLParseNode* pGroupBy = pSelectRoot->getChild(3)->getChild(2)->getChild(2); - OTableFieldDescRef aDragInfo = new OTableFieldDesc(); - for( sal_uInt32 i=0 ; i < pGroupBy->count() ; i++ ) - { - ::connectivity::OSQLParseNode* pColumnRef = pGroupBy->getChild( i ); - if(SQL_ISRULE(pColumnRef,column_ref)) - { - if(FillDragInfo(pColumnRef,aDragInfo)) - { - aDragInfo->SetGroupBy(sal_True); - m_pSelectionBox->AddGroupBy(aDragInfo); - } - } - } - } -} -//------------------------------------------------------------------------------ -void OQueryDesignView::FillOuterJoins(const ::connectivity::OSQLParseNode* pTableRefList) -{ - sal_uInt32 ncount = pTableRefList->count(); - - if (ncount == 0) - { - ErrorBox( this, ModuleRes( ERR_QRY_ILLEGAL_JOIN ) ).Execute(); - return; - } - else - { - for (sal_uInt32 i=0; i < ncount; i++) - { - const ::connectivity::OSQLParseNode* pParseNode = pTableRefList->getChild(i); - if (SQL_ISRULE(pParseNode , qualified_join) || - SQL_ISRULE(pParseNode , joined_table)) - { - if (!InsertJoin(pParseNode)) - { - ErrorBox( this, ModuleRes( ERR_QRY_ILLEGAL_JOIN ) ).Execute(); - return; - } - } - else if(pParseNode->count() == 4 && SQL_ISPUNCTUATION(pParseNode->getChild(0),"{") && SQL_ISRULE(pParseNode,table_ref)) - { - if (!InsertJoin(pParseNode->getChild(2))) - { - ErrorBox( this, ModuleRes( ERR_QRY_ILLEGAL_JOIN ) ).Execute(); - return; - } - } - } - } -} -//------------------------------------------------------------------------------ -int OQueryDesignView::InsertColumnRef(const ::connectivity::OSQLParseNode * pColumnRef,::rtl::OUString& aColumnName,const ::rtl::OUString& aColumnAlias, - ::rtl::OUString& aTableRange,OTableFieldDescRef& _raInfo, OJoinTableView::OTableWindowMap* pTabList) -{ - - // Tabellennamen zusammen setzen - ::connectivity::OSQLParseTreeIterator& rParseIter = static_cast<OQueryController*>(getController())->getParseIterator(); - rParseIter.getColumnRange( pColumnRef, aColumnName, aTableRange ); - - DBG_ASSERT(aColumnName.getLength(),"Columnname darf nicht leer sein"); - if (!aTableRange.getLength()) - { - // SELECT column, ... - sal_Bool bFound(sal_False); - OJoinTableView::OTableWindowMap::iterator aIter = pTabList->begin(); - for(;aIter != pTabList->end();++aIter) - { - OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second); - if (pTabWin->ExistsField( aColumnName, _raInfo ) ) - { - if(aColumnName.toChar() != '*') - _raInfo->SetFieldAlias(aColumnAlias); - bFound = sal_True; - break; - } - } - if (!bFound) - { - _raInfo->SetTable(::rtl::OUString()); - _raInfo->SetAlias(::rtl::OUString()); - _raInfo->SetField(aColumnName); - _raInfo->SetFieldAlias(aColumnAlias); // nyi : hier ein fortlaufendes Expr_1, Expr_2 ... - _raInfo->SetFunctionType(FKT_OTHER); - } - } - else - { - // SELECT range.column, ... - OQueryTableWindow* pTabWin = static_cast<OQueryTableView*>(m_pTableView)->FindTable(aTableRange); - - if (pTabWin && pTabWin->ExistsField(aColumnName, _raInfo)) - { - if(aColumnName.toChar() != '*') - _raInfo->SetFieldAlias(aColumnAlias); - } - else - { - _raInfo->SetTable(::rtl::OUString()); - _raInfo->SetAlias(::rtl::OUString()); - _raInfo->SetField(aColumnName); - _raInfo->SetFieldAlias(aColumnAlias); // nyi : hier ein fortlaufendes Expr_1, Expr_2 ... - _raInfo->SetFunctionType(FKT_OTHER); - } - } - return 0; -} -//----------------------------------------------------------------------------- -sal_Bool OQueryDesignView::InsertJoin(const ::connectivity::OSQLParseNode *pNode) -{ - DBG_ASSERT(SQL_ISRULE(pNode, qualified_join) || SQL_ISRULE(pNode, joined_table), - "OQueryDesignView::InsertJoin: Fehler im Parse Tree"); - - if (SQL_ISRULE(pNode,joined_table)) - return InsertJoin(pNode->getChild(1)); - - if (SQL_ISRULE(pNode->getChild(0),qualified_join)) - { - if (!InsertJoin(pNode->getChild(0))) - return sal_False; - } - else if (SQL_ISRULE(pNode->getChild(0), joined_table)) - { - if (!InsertJoin(pNode->getChild(0)->getChild(1))) - return sal_False; - } - else if (!(SQL_ISRULE(pNode->getChild(0), table_ref) && ( - SQL_ISRULE(pNode->getChild(0)->getChild(0), catalog_name) || - SQL_ISRULE(pNode->getChild(0)->getChild(0), schema_name) || - SQL_ISRULE(pNode->getChild(0)->getChild(0), table_name)))) - return sal_False; - - // geschachtelter join? - if (SQL_ISRULE(pNode->getChild(3),qualified_join)) - { - if (!InsertJoin(pNode->getChild(3))) - return sal_False; - } - else if (SQL_ISRULE(pNode->getChild(3), joined_table)) - { - if (!InsertJoin(pNode->getChild(3)->getChild(1))) - return sal_False; - } - // sonst sollte es eine Tabelle sein - else if (!(SQL_ISRULE(pNode->getChild(3), table_ref) && ( - SQL_ISRULE(pNode->getChild(3)->getChild(0), catalog_name) || - SQL_ISRULE(pNode->getChild(3)->getChild(0), schema_name) || - SQL_ISRULE(pNode->getChild(3)->getChild(0), table_name)))) - return sal_False; - - // named column join wird spter vieleicht noch implementiert - // SQL_ISRULE(pNode->getChild(4),named_columns_join) - if (SQL_ISRULE(pNode->getChild(4),join_condition)) - { - EJoinType eJoinType; - ::connectivity::OSQLParseNode* pJoinType = pNode->getChild(1); // join_type - if (SQL_ISRULE(pJoinType,join_type) && SQL_ISTOKEN(pJoinType->getChild(0),INNER)) - { - eJoinType = INNER_JOIN; - } - else - { - if (SQL_ISRULE(pJoinType,join_type)) // eine Ebene tiefer - pJoinType = pJoinType->getChild(0); - - if (SQL_ISTOKEN(pJoinType->getChild(0),LEFT)) - eJoinType = LEFT_JOIN; - else if(SQL_ISTOKEN(pJoinType->getChild(0),RIGHT)) - eJoinType = RIGHT_JOIN; - else - eJoinType = FULL_JOIN; - } - if(!InsertJoinConnection(pNode->getChild(4)->getChild(1), eJoinType)) - return sal_False; - } - else - return sal_False; - - return sal_True; -} -// ----------------------------------------------------------------------------- void OQueryDesignView::zoomTableView(const Fraction& _rFraction) { m_pTableView->SetZoom(_rFraction); @@ -2710,4 +2788,14 @@ void OQueryDesignView::setNoneVisbleRow(sal_Int32 _nRows) m_pSelectionBox->SetNoneVisbleRow(_nRows); } // ----------------------------------------------------------------------------- +void OQueryDesignView::InitFromParseNode() +{ + InitFromParseNodeImpl(this,m_pSelectionBox); +} +// ----------------------------------------------------------------------------- +sal_Bool OQueryDesignView::HasTable() const +{ + return m_pTableView->GetTabWinMap()->size() != 0; +} +// ----------------------------------------------------------------------------- |