--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/dbms/utable/UT_TBSRC.CPP Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,309 @@
+// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "UT_STD.H"
+
+// Class CDbReverseIterator
+
+NONSHARABLE_CLASS(CDbReverseIter) : public CDbRecordIter
+ {
+public:
+ CDbReverseIter(CDbRecordIter* anIterator);
+ ~CDbReverseIter();
+private:
+ TInt Count() const;
+ TDbRecordId CurrentL();
+ TBool GotoL(TDbPosition aPosition);
+ TBool GotoL(TDbRecordId aRecordId,RDbTableRow& aBuffer);
+ TBool SeekL(const TDbLookupKey& aKey,RDbTable::TComparison aComparison);
+ TDeleted DoDeletedL(TDbPosition aPosition,TDbRecordId aRecordId,const RDbTableRow* aRow);
+private:
+ CDbRecordIter* iIter;
+ };
+
+CDbReverseIter::CDbReverseIter(CDbRecordIter* aIterator)
+ : CDbRecordIter(aIterator->Host()),iIter(aIterator)
+ {}
+
+CDbReverseIter::~CDbReverseIter()
+ {
+ delete iIter;
+ }
+
+TInt CDbReverseIter::Count() const
+ {
+ return iIter->Count();
+ }
+
+TDbRecordId CDbReverseIter::CurrentL()
+ {
+ return iIter->CurrentL();
+ }
+
+TBool CDbReverseIter::GotoL(TDbPosition aPosition)
+ {
+ return iIter->GotoL(TDbPosition(EDbLast-aPosition));
+ }
+
+TBool CDbReverseIter::GotoL(TDbRecordId aRecord,RDbTableRow& aRow)
+ {
+ return iIter->GotoL(aRecord,aRow);
+ }
+
+TBool CDbReverseIter::SeekL(const TDbLookupKey& aKey,RDbTable::TComparison aComparison)
+//
+// Reverse the comparison
+//
+ {
+ return iIter->SeekL(aKey,RDbTable::TComparison(RDbTable::EGreaterThan-aComparison));
+ }
+
+CDbReverseIter::TDeleted CDbReverseIter::DoDeletedL(TDbPosition aPosition,TDbRecordId aRecordId,const RDbTableRow* aRow)
+//
+// Need to invert the position.
+//
+ {
+ return iIter->DoDeletedL(TDbPosition(EDbLast-aPosition),aRecordId,aRow);
+ }
+
+// Class CDbTableSource
+
+CDbTableSource::CDbTableSource()
+ {}
+
+CDbTableSource::~CDbTableSource()
+ {
+ delete iIter;
+ iRow.Close();
+ }
+
+void CDbTableSource::Construct(CDbTable* aTable)
+//
+// We own the table pass in
+//
+ {
+ iIterMark.Construct(aTable->Generation());
+ iRow.Open(aTable);
+ }
+
+void CDbTableSource::ReverseIteratorL()
+//
+// Plug in a reverse iterator adaptor for the iterator
+//
+ {
+ iIter=new(ELeave) CDbReverseIter(iIter);
+ }
+
+TInt CDbTableSource::ColumnCount() const
+ {
+ return iRow.Table().Def().Columns().Count();
+ }
+
+const TDbColumnDef& CDbTableSource::ColumnDef(TDbColNo aCol) const
+ {
+ return iRow.Table().Def().Columns()[aCol];
+ }
+
+RDbRow* CDbTableSource::RowBuffer()
+ {
+ return &iRow;
+ }
+
+TDbColumn CDbTableSource::Column(TDbColNo aColNo)
+ {
+ return TDbColumn(iRow,aColNo);
+ }
+
+void CDbTableSource::Reset()
+ {
+ iReset=ETrue;
+ }
+
+TBool CDbTableSource::EvaluateL(TInt&,TDbRecordId&,TBool&)
+ {
+ return EFalse;
+ }
+
+TBool CDbTableSource::Unevaluated()
+ {
+ return EFalse;
+ }
+
+TInt CDbTableSource::CountL()
+//
+// Count the records
+//
+ {
+ if (iReset)
+ OpenIteratorL();
+ return iIter->Count();
+ }
+
+void CDbTableSource::OpenIteratorL()
+//
+// Re-open the iterator after a reset
+//
+ {
+ __ASSERT(iIter);
+ if (iIter->Host().OpenL())
+ __LEAVE(KErrCorrupt);
+ iReset=EFalse;
+ }
+
+CDbTableSource::TGoto CDbTableSource::GotoL(TInt& aWork,TDbPosition aPosition,TDbRecordId& aRecordId)
+//
+// Move to the position specified. If out of synch, try to resynch the iterator
+// using aRecordId
+//
+ {
+ __ASSERT(iIter);
+ TInt work=aWork;
+ if (work<0)
+ return EExhausted;
+ aWork=work-EWorkToIterate;
+ CDbRecordIter& iter=*iIter;
+ if (iIterMark.Changed())
+ { // two possible resaons for this
+ if (iReset)
+ OpenIteratorL();
+ if (aPosition==EDbNext || aPosition==EDbPrevious)
+ { // table modified
+ if (aRecordId==KDbNullRecordId)
+ return ESynchFailure;
+ if (!iter.GotoL(aRecordId,iRow))
+ { // record has been deleted
+ switch(iter.DeletedL(aPosition,aRecordId))
+ {
+ case CDbRecordIter::EAtRow: // found it
+ aRecordId=iter.CurrentL();
+ return ESuccess;
+ case CDbRecordIter::ENoRow: // no more rows
+ aRecordId=KDbNullRecordId;
+ return ENoRow;
+ case CDbRecordIter::ENotSupported: // couldn't re-snych
+ return ESynchFailure;
+ }
+ }
+ }
+ iIterMark.Mark();
+ }
+ if (iter.GotoL(aPosition))
+ {
+ aRecordId=iter.CurrentL();
+ return ESuccess;
+ }
+ else
+ {
+ aRecordId=KDbNullRecordId;
+ return ENoRow;
+ }
+ }
+
+TBool CDbTableSource::SynchL(TDbRecordId aRecordId)
+ {
+ if (iReset)
+ OpenIteratorL();
+ TBool found=iIter->GotoL(aRecordId,iRow);
+ iIterMark.Mark();
+ return found;
+ }
+
+TBool CDbTableSource::GotoL(TDbRecordId aRecordId)
+ {
+ return iRow.Table().ExistsL(aRecordId) ? SynchL(aRecordId) : EFalse;
+ }
+
+void CDbTableSource::ReadRowL(TDbRecordId aRecordId)
+ {
+ iRow.ReadL(aRecordId);
+ }
+
+void CDbTableSource::NewRowL(TDbRecordId aCopyRecord)
+ {
+ if (iIter!=NULL&&iReset)
+ OpenIteratorL();
+ iRow.NewL(aCopyRecord);
+ }
+
+void CDbTableSource::PrepareToWriteRowL(TWrite aWrite)
+ {
+ __ASSERT(aWrite==EReplace||aWrite==EAppend);
+ if (aWrite==EReplace)
+ iRow.PrepareReplaceL();
+ else
+ iRow.PrepareAppendL();
+ }
+
+TDbRecordId CDbTableSource::WriteRowL(TWrite aWrite,TSynch aSynch)
+ {
+ __ASSERT(aWrite==EReplace||aWrite==EAppend);
+ TDbRecordId id=aWrite==EReplace ? iRow.ReplaceL() : iRow.AppendL();
+ if (aSynch==ESynch)
+ {
+ __DEBUG(TBool dbgchk=) SynchL(id);
+ __ASSERT(dbgchk);
+ }
+ return id;
+ }
+
+CDbTableSource::TDelete CDbTableSource::DeleteRowL(TDbRecordId& aRecordId,TSynch aSynch)
+//
+// Remove the row from the table. Synchronise the iterator if required
+// When not synchronising, the return value is not significant
+//
+ {
+ // if the table has changed, we may need to re-synch the iterator before deleting
+ // this is important if neighbouring rows have been deleted by another view
+ if (aSynch==ESynch && iIterMark.Changed() && !SynchL(aRecordId))
+ __LEAVE(KErrNotFound); // it has been deleted already!
+ iRow.DeleteL(aRecordId);
+ if (aSynch==ESynch)
+ {
+ CDbRecordIter::TDeleted del=iIter->DeletedL(EDbNext,aRecordId,iRow);
+ __ASSERT(del!=CDbRecordIter::ENotSupported); // must always be able to synch with row data
+ iIterMark.Mark();
+ if (del==CDbRecordIter::EAtRow)
+ { // pass back the next record id
+ aRecordId=iIter->CurrentL();
+ return EDeletedAtNext;
+ }
+ }
+ return EDeletedAtEnd;
+ }
+
+void CDbTableSource::SetIndexL(const TDesC* anIndex)
+ {
+ CDbRecordIter* iter=anIndex ? iRow.Table().IteratorL(*anIndex) : iRow.Table().IteratorL();
+ delete iIter;
+ iIter=iter;
+ }
+
+TBool CDbTableSource::SeekL(const TDbLookupKey& aKey,RDbTable::TComparison aComparison,TDbRecordId& aRecordId)
+ {
+ if (iReset)
+ OpenIteratorL();
+ CDbRecordIter& iter=*iIter;
+ TBool atrow=iter.SeekL(aKey,aComparison);
+ aRecordId=atrow ? iter.CurrentL() : KDbNullRecordId;
+ iIterMark.Mark();
+ return atrow;
+ }
+
+CSqlSearchCondition* CDbTableSource::ParseConstraintLC(const TDesC& aCondition)
+ {
+ CSqlSearchCondition* sc=Sql::ParseSearchConditionLC(aCondition);
+ sc->BindL(iRow);
+ return sc;
+ }