diff options
author | Rüdiger Timm <rt@openoffice.org> | 2008-06-06 12:22:12 +0000 |
---|---|---|
committer | Rüdiger Timm <rt@openoffice.org> | 2008-06-06 12:22:12 +0000 |
commit | 96a73ad78830a4ec6a1ce49a00fdccaffa0bea66 (patch) | |
tree | 39205b1c4a5721b3558d4913a3bbc9bbdc89d5ac /connectivity | |
parent | 4843da38436996777789df68fdd58333b38febef (diff) |
INTEGRATION: CWS dba30c (1.101.10); FILE MERGED
2008/05/06 09:31:49 oj 1.101.10.2: stl problems under linux solved
2008/05/02 10:58:47 oj 1.101.10.1: #i53779# apply patch for distinct values
Diffstat (limited to 'connectivity')
-rw-r--r-- | connectivity/source/drivers/file/FResultSet.cxx | 324 |
1 files changed, 163 insertions, 161 deletions
diff --git a/connectivity/source/drivers/file/FResultSet.cxx b/connectivity/source/drivers/file/FResultSet.cxx index 73dd1873e5f8..1cafe49bc432 100644 --- a/connectivity/source/drivers/file/FResultSet.cxx +++ b/connectivity/source/drivers/file/FResultSet.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: FResultSet.cxx,v $ - * $Revision: 1.101 $ + * $Revision: 1.102 $ * * This file is part of OpenOffice.org. * @@ -1162,6 +1162,109 @@ Error: return sal_False; } // ------------------------------------------------------------------------- +void OResultSet::sortRows() +{ + if (!m_pSQLAnalyzer->hasRestriction() && m_aOrderbyColumnNumber.size() == 1) + { + // Ist nur ein Feld fuer die Sortierung angegeben + // Und diese Feld ist indiziert, dann den Index ausnutzen + Reference<XIndexesSupplier> xIndexSup; + m_pTable->queryInterface(::getCppuType((const Reference<XIndexesSupplier>*)0)) >>= xIndexSup; + // Reference<XIndexesSupplier> xIndexSup(m_pTable,UNO_QUERY); + Reference<XIndexAccess> xIndexes; + if(xIndexSup.is()) + { + xIndexes.set(xIndexSup->getIndexes(),UNO_QUERY); + Reference<XPropertySet> xColProp; + if(m_aOrderbyColumnNumber[0] < xIndexes->getCount()) + { + xColProp.set(xIndexes->getByIndex(m_aOrderbyColumnNumber[0]),UNO_QUERY); + // iterate through the indexes to find the matching column + const sal_Int32 nCount = xIndexes->getCount(); + for(sal_Int32 i=0; i < nCount;++i) + { + Reference<XColumnsSupplier> xIndex(xIndexes->getByIndex(i),UNO_QUERY); + Reference<XNameAccess> xIndexCols = xIndex->getColumns(); + if(xIndexCols->hasByName(comphelper::getString(xColProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME))))) + { + m_pFileSet = new OKeySet(); + + if(fillIndexValues(xIndex)) + return; + } + } + } + } + } + + OSortIndex::TKeyTypeVector eKeyType(m_aOrderbyColumnNumber.size()); + ::std::vector<sal_Int32>::iterator aOrderByIter = m_aOrderbyColumnNumber.begin(); + for (::std::vector<sal_Int16>::size_type i=0;aOrderByIter != m_aOrderbyColumnNumber.end(); ++aOrderByIter,++i) + { + OSL_ENSURE((sal_Int32)m_aRow->size() > *aOrderByIter,"Invalid Index"); + switch ((*(m_aRow->begin()+*aOrderByIter))->getValue().getTypeKind()) + { + case DataType::CHAR: + case DataType::VARCHAR: + eKeyType[i] = SQL_ORDERBYKEY_STRING; + break; + + case DataType::OTHER: + case DataType::TINYINT: + case DataType::SMALLINT: + case DataType::INTEGER: + case DataType::DECIMAL: + case DataType::NUMERIC: + case DataType::REAL: + case DataType::DOUBLE: + case DataType::DATE: + case DataType::TIME: + case DataType::TIMESTAMP: + case DataType::BIT: + eKeyType[i] = SQL_ORDERBYKEY_DOUBLE; + break; + + // Andere Typen sind nicht implementiert (und damit immer FALSE) + default: + eKeyType[i] = SQL_ORDERBYKEY_NONE; + OSL_ASSERT("OFILECursor::Execute: Datentyp nicht implementiert"); + break; + } + (*m_aEvaluateRow)[*aOrderByIter]->setBound(sal_True); + } + + m_pSortIndex = new OSortIndex(eKeyType,m_aOrderbyAscending); + + if (m_pEvaluationKeySet) + { + m_aEvaluateIter = m_pEvaluationKeySet->begin(); + + while (m_aEvaluateIter != m_pEvaluationKeySet->end()) + { + ExecuteRow(IResultSetHelper::BOOKMARK,(*m_aEvaluateIter),TRUE); + ++m_aEvaluateIter; + } + } + else + { + while (ExecuteRow(IResultSetHelper::NEXT,1,TRUE)) + { + } + } + + // Sortiertes Keyset erzeugen + // DELETEZ(m_pEvaluationKeySet); + m_pEvaluationKeySet = NULL; + m_pFileSet = NULL; + m_pFileSet = m_pSortIndex->CreateKeySet(); + // if(!bDistinct) + // SetRowCount(pFileSet->count()); + DELETEZ(m_pSortIndex); + // Nun kann ueber den Index sortiert zugegriffen werden. +} + + +// ------------------------------------------------------------------------- BOOL OResultSet::OpenImpl() { OSL_ENSURE(m_pSQLAnalyzer,"No analyzer set with setSqlAnalyzer!"); @@ -1262,122 +1365,29 @@ BOOL OResultSet::OpenImpl() BOOL bDistinct = FALSE; BOOL bWasSorted = FALSE; OSQLParseNode *pDistinct = m_pParseTree->getChild(1); + ::std::vector<sal_Int32> aOrderbyColumnNumberSave; + ::std::vector<TAscendingOrder> aOrderbyAscendingSave; + if (pDistinct && pDistinct->getTokenID() == SQL_TOKEN_DISTINCT ) { - if(!IsSorted()) + // Sort on all columns, saving original order for later + if(IsSorted()) { - m_aOrderbyColumnNumber.push_back(m_aColMapping[1]); - m_aOrderbyAscending.push_back(SQL_DESC); - } - else + aOrderbyColumnNumberSave = m_aOrderbyColumnNumber;// .assign(m_aOrderbyColumnNumber.begin(), m_aOrderbyColumnNumber.end()); + aOrderbyAscendingSave.assign(m_aOrderbyAscending.begin(), m_aOrderbyAscending.end()); bWasSorted = TRUE; - bDistinct = TRUE; - } - - OSortIndex::TKeyTypeVector eKeyType(m_aOrderbyColumnNumber.size()); - ::std::vector<sal_Int32>::iterator aOrderByIter = m_aOrderbyColumnNumber.begin(); - for (::std::vector<sal_Int16>::size_type i=0;aOrderByIter != m_aOrderbyColumnNumber.end(); ++aOrderByIter,++i) - { - OSL_ENSURE((sal_Int32)m_aRow->size() > *aOrderByIter,"Invalid Index"); - switch ((*(m_aRow->begin()+*aOrderByIter))->getValue().getTypeKind()) - { - case DataType::CHAR: - case DataType::VARCHAR: - eKeyType[i] = SQL_ORDERBYKEY_STRING; - break; - - case DataType::OTHER: - case DataType::TINYINT: - case DataType::SMALLINT: - case DataType::INTEGER: - case DataType::DECIMAL: - case DataType::NUMERIC: - case DataType::REAL: - case DataType::DOUBLE: - case DataType::DATE: - case DataType::TIME: - case DataType::TIMESTAMP: - case DataType::BIT: - eKeyType[i] = SQL_ORDERBYKEY_DOUBLE; - break; - - // Andere Typen sind nicht implementiert (und damit immer FALSE) - default: - eKeyType[i] = SQL_ORDERBYKEY_NONE; - OSL_ASSERT("OFILECursor::Execute: Datentyp nicht implementiert"); - break; } - (*m_aEvaluateRow)[*aOrderByIter]->setBound(sal_True); + + // the first column is the bookmark column + ::std::vector<sal_Int32>::iterator aColStart = (m_aColMapping.begin()+1); + ::std::copy(aColStart, m_aColMapping.end(),::std::back_inserter(m_aOrderbyColumnNumber)); +// m_aOrderbyColumnNumber.assign(aColStart, m_aColMapping.end()); + m_aOrderbyAscending.assign(m_aColMapping.size()-1, SQL_ASC); + bDistinct = TRUE; } - // Nur wenn Sortierung gewuenscht, ueber alle Datensaetze iterieren und - // dabei den "Key", nach dem sortiert werden soll, in den Index eintragen: if (IsSorted()) - { - if (!m_pSQLAnalyzer->hasRestriction() && m_aOrderbyColumnNumber.size() == 1) - { - // Ist nur ein Feld fuer die Sortierung angegeben - // Und diese Feld ist indiziert, dann den Index ausnutzen - Reference<XIndexesSupplier> xIndexSup; - m_pTable->queryInterface(::getCppuType((const Reference<XIndexesSupplier>*)0)) >>= xIndexSup; - // Reference<XIndexesSupplier> xIndexSup(m_pTable,UNO_QUERY); - Reference<XIndexAccess> xIndexes; - if(xIndexSup.is()) - { - xIndexes.set(xIndexSup->getIndexes(),UNO_QUERY); - Reference<XPropertySet> xColProp; - if(m_aOrderbyColumnNumber[0] < xIndexes->getCount()) - { - xColProp.set(xIndexes->getByIndex(m_aOrderbyColumnNumber[0]),UNO_QUERY); - // iterate through the indexes to find the matching column - const sal_Int32 nCount = xIndexes->getCount(); - for(sal_Int32 i=0; i < nCount;++i) - { - Reference<XColumnsSupplier> xIndex(xIndexes->getByIndex(i),UNO_QUERY); - Reference<XNameAccess> xIndexCols = xIndex->getColumns(); - if(xIndexCols->hasByName(comphelper::getString(xColProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME))))) - { - m_pFileSet = new OKeySet(); - - if(fillIndexValues(xIndex)) - goto DISTINCT; - } - } - } - } - } - - m_pSortIndex = new OSortIndex(eKeyType,m_aOrderbyAscending); - - sal_Bool bOK = sal_True; - if (m_pEvaluationKeySet) - { - if (m_pEvaluationKeySet->size()) - m_aEvaluateIter = m_pEvaluationKeySet->begin(); - - } - while (bOK) - { - if (m_pEvaluationKeySet) - { - ExecuteRow(IResultSetHelper::BOOKMARK,(*m_aEvaluateIter),TRUE); - ++m_aEvaluateIter; - bOK = m_aEvaluateIter == m_pEvaluationKeySet->end(); - } - else - bOK = ExecuteRow(IResultSetHelper::NEXT,1,TRUE); - } - - // Sortiertes Keyset erzeugen - // DELETEZ(m_pEvaluationKeySet); - m_pEvaluationKeySet = NULL; - m_pFileSet = NULL; - m_pFileSet = m_pSortIndex->CreateKeySet(); - // if(!bDistinct) - // SetRowCount(pFileSet->count()); - DELETEZ(m_pSortIndex); - // Nun kann ueber den Index sortiert zugegriffen werden. - } + sortRows(); if (!m_pFileSet.isValid()) { @@ -1395,7 +1405,8 @@ BOOL OResultSet::OpenImpl() } } OSL_ENSURE(m_pFileSet.isValid(),"Kein KeySet vorhanden! :-("); - DISTINCT: if(bDistinct && m_pFileSet.isValid()) // sicher ist sicher + + if(bDistinct && m_pFileSet.isValid()) // sicher ist sicher { OValueRow aSearchRow = new OValueVector(m_aRow->size()); OValueRefVector::iterator aRowIter = m_aRow->begin(); @@ -1405,66 +1416,47 @@ BOOL OResultSet::OpenImpl() ++aRowIter,++aSearchIter) aSearchIter->setBound((*aRowIter)->isBound()); - INT32 nPos; size_t nMaxRow = m_pFileSet->size(); + if (nMaxRow) { #if OSL_DEBUG_LEVEL > 1 INT32 nFound=0; #endif - ::std::vector<sal_Int16> nWasAllwaysFound(nMaxRow,0); - INT32 nPrev_i; - for( size_t j = nMaxRow; j > 0; ) + INT32 nPos; + INT32 nKey; + + for( size_t j = nMaxRow-1; j > 0; --j) { - --j; + nPos = (*m_pFileSet)[j]; + ExecuteRow(IResultSetHelper::BOOKMARK,nPos,FALSE); + m_pSQLAnalyzer->setSelectionEvaluationResult(m_aSelectRow,m_aColMapping); + { // copy row values + OValueRefVector::iterator copyFrom = m_aSelectRow->begin(); + OValueVector::iterator copyTo = aSearchRow->begin(); + for ( ++copyFrom,++copyTo; // the first column is the bookmark column + copyFrom != m_aSelectRow->end(); + ++copyFrom,++copyTo) + *copyTo = *(*copyFrom); + // *aSearchRow = *m_aRow; + } - nPos = (*m_pFileSet)[j]; // aktuell zu loeschender Key - if(!nWasAllwaysFound[j] && nPos) // nur falls noch nicht nach dieser Row gesucht wurde + // compare with next row + nKey = (*m_pFileSet)[j-1]; + ExecuteRow(IResultSetHelper::BOOKMARK,nKey,FALSE); + m_pSQLAnalyzer->setSelectionEvaluationResult(m_aSelectRow,m_aColMapping); + OValueRefVector::iterator loopInRow = m_aSelectRow->begin(); + OValueVector::iterator existentInSearchRow = aSearchRow->begin(); + for ( ++loopInRow,++existentInSearchRow; // the first column is the bookmark column + loopInRow != m_aSelectRow->end(); + ++loopInRow,++existentInSearchRow) { - ExecuteRow(IResultSetHelper::BOOKMARK,nPos,FALSE); - m_pSQLAnalyzer->setSelectionEvaluationResult(m_aSelectRow,m_aColMapping); - { // copy row values - OValueRefVector::iterator copyFrom = m_aSelectRow->begin(); - OValueVector::iterator copyTo = aSearchRow->begin(); - for ( ++copyFrom,++copyTo; // the first column is the bookmark column - copyFrom != m_aSelectRow->end(); - ++copyFrom,++copyTo) - *copyTo = *(*copyFrom); - // *aSearchRow = *m_aRow; - } - - // jetzt den Rest nach doppelten durchsuchen - INT32 nKey; - nPrev_i = j; - for(INT32 i = j-1; i >= 0 ;i--) - { - nKey = (*m_pFileSet)[i]; - ExecuteRow(IResultSetHelper::BOOKMARK,nKey,FALSE); - if(!nWasAllwaysFound[i]) - { - m_pSQLAnalyzer->setSelectionEvaluationResult(m_aSelectRow,m_aColMapping); - OValueRefVector::iterator loopInRow = m_aSelectRow->begin(); - OValueVector::iterator existentInSearchRow = aSearchRow->begin(); - for ( ++loopInRow,++existentInSearchRow; // the first column is the bookmark column - loopInRow != m_aSelectRow->end(); - ++loopInRow,++existentInSearchRow) - { - if ( (*loopInRow)->isBound() && !( *(*loopInRow) == *existentInSearchRow) ) - break; - } - if(loopInRow == m_aSelectRow->end()) - { - // gefunden - // Key an der Stelle 0 setzen. - (*m_pFileSet)[nPrev_i] = 0; - // und altes i merken - nPrev_i = i; - nPos = nKey; // auf naechste gueltige Position setzen - nWasAllwaysFound[i] = 1; - } - } - } + if ( (*loopInRow)->isBound() && !( *(*loopInRow) == *existentInSearchRow) ) + break; } + + if(loopInRow == m_aSelectRow->end()) + (*m_pFileSet)[j] = 0; // Rows match -- Mark for deletion by setting key to 0 #if OSL_DEBUG_LEVEL > 1 else nFound++; @@ -1475,7 +1467,17 @@ BOOL OResultSet::OpenImpl() ::std::bind2nd(::std::equal_to<sal_Int32>(),0)) ,m_pFileSet->end()); - if (!bWasSorted) + if (bWasSorted) + { + // Re-sort on original requested order + m_aOrderbyColumnNumber = aOrderbyColumnNumberSave; + m_aOrderbyAscending.assign(aOrderbyAscendingSave.begin(), aOrderbyAscendingSave.end()); + + TIntVector aEvaluationKeySet(*m_pFileSet); + m_pEvaluationKeySet = &aEvaluationKeySet; + sortRows(); + } + else { m_aOrderbyColumnNumber.clear(); m_aOrderbyAscending.clear(); |