sl@0: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #ifndef __TOOLS2__ sl@0: #include <../include/d32dbms.h> sl@0: #else sl@0: #include <d32dbms.h> sl@0: #endif sl@0: #include <s32file.h> sl@0: #include <e32test.h> sl@0: #include <e32math.h> sl@0: sl@0: #include "D32TABLE.H" sl@0: sl@0: #include "crccheck.h" sl@0: sl@0: #undef __UHEAP_MARK sl@0: #define __UHEAP_MARK sl@0: #undef __UHEAP_MARKEND sl@0: #define __UHEAP_MARKEND sl@0: sl@0: LOCAL_D TDBMS_CRCChecks TheCrcChecker; sl@0: sl@0: #ifndef __linux__ //No CRC test on LINUX sl@0: #ifdef __TOOLS2__ sl@0: const TPtrC KCrcRecord=_L("\\epoc32\\winscw\\c\\dbms-tst\\T_INDEX.CRC"); sl@0: #else sl@0: const TPtrC KCrcRecord=_L("C:\\dbms-tst\\T_INDEX.CRC"); sl@0: #endif sl@0: #endif sl@0: sl@0: sl@0: // MSVC++ up to 5.0 has problems with expanding inline functions sl@0: // This disables the mad warnings for the whole project sl@0: #if defined(NDEBUG) && defined(__VC32__) && _MSC_VER<=1100 sl@0: #pragma warning(disable : 4710) // function not expanded. MSVC 5.0 is stupid sl@0: #endif sl@0: sl@0: LOCAL_D RTest test(_L("T_INDEX - Test DBMS indexing and ordering")); sl@0: LOCAL_D CTrapCleanup* TheTrapCleanup; sl@0: LOCAL_D RDbs TheDbs; sl@0: LOCAL_D RDbNamedDatabase TheDatabase; sl@0: LOCAL_D RDbTable TheTable; sl@0: LOCAL_D RDbView TheView; sl@0: LOCAL_D RFs TheFs; sl@0: LOCAL_D TBuf<0x200> TheBuf; sl@0: sl@0: const TInt KTestCleanupStack=0x20; sl@0: sl@0: #ifdef __TOOLS2__ sl@0: const TPtrC KTestDatabase=_L(".\\dbms-tst\\T_INDEX.DB"); sl@0: #else sl@0: const TPtrC KTestDatabase=_L("C:\\dbms-tst\\T_INDEX.DB"); sl@0: #endif sl@0: sl@0: const TPtrC KTableName(_S("Table")); sl@0: const TPtrC KIndexName(_S("index")); sl@0: const TPtrC KIndexTwo(_S("index_two")); sl@0: const TPtrC KColumnName(_S("column")); sl@0: const TPtrC KColumnTwo(_S("column2")); sl@0: sl@0: const TPtrC KSelectOrdered(_L("select column from table order by column")); sl@0: sl@0: #define elementsof(array) (sizeof(array)/sizeof(array[0])) sl@0: sl@0: sl@0: // sl@0: // Open the database (shared access) (SYMBIAN_REMOVE_TRIVIAL_ENCRYPTION version) sl@0: // sl@0: LOCAL_C void OpenDatabaseL() sl@0: { sl@0: TInt r=TheDatabase.Open(TheDbs,KTestDatabase); sl@0: test (r==KErrNone); sl@0: } sl@0: sl@0: // sl@0: // Create the database (SYMBIAN_REMOVE_TRIVIAL_ENCRYPTION version) sl@0: // sl@0: LOCAL_C void CreateDatabaseL() sl@0: { sl@0: TInt r=TheDatabase.Replace(TheFs,KTestDatabase); sl@0: test (r==KErrNone); sl@0: TheDatabase.Close(); sl@0: TheCrcChecker.GenerateCrcL(KTestDatabase); sl@0: OpenDatabaseL(); sl@0: } sl@0: sl@0: sl@0: LOCAL_C void CloseDatabaseL() sl@0: { sl@0: TheDatabase.Close(); sl@0: TheCrcChecker.GenerateCrcL(KTestDatabase); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0618 sl@0: @SYMTestCaseDesc Tests for RDbNamedDatabase functionality sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for RDbNamedDatabase::CreateIndex() sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void TestIndexBuild() sl@0: { sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0618 Create table ")); sl@0: TheDatabase.Begin(); sl@0: CDbColSet *cs=CDbColSet::NewLC(); sl@0: cs->AddL(TDbCol(KColumnName,EDbColInt32)); sl@0: cs->AddL(TDbCol(KColumnTwo,EDbColInt32)); sl@0: test(TheDatabase.CreateTable(KTableName,*cs)==KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: test.Next(_L("create indices")); sl@0: CDbKey *key=CDbKey::NewLC(); sl@0: key->AddL(TDbKeyCol(KColumnName)); sl@0: key->MakeUnique(); sl@0: test(TheDatabase.CreateIndex(KIndexName,KTableName,*key)==KErrNone); sl@0: key->Clear(); sl@0: key->AddL(TDbKeyCol(KColumnTwo)); sl@0: key->MakeUnique(); sl@0: test(TheDatabase.CreateIndex(KIndexTwo,KTableName,*key)==KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: test.Next(_L("Populate table")); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,1); sl@0: TheTable.SetColL(2,-1); sl@0: TheTable.PutL(); sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,2); sl@0: TheTable.SetColL(2,-2); sl@0: TheTable.PutL(); sl@0: test(TheDatabase.Commit()==KErrNone); sl@0: test.Next(_L("Check order")); sl@0: test(TheTable.SetNoIndex()==KErrNone); sl@0: test(TheTable.SetIndex(KIndexName)==KErrNone); sl@0: test(TheTable.CountL()==2); sl@0: test(TheTable.NextL()); sl@0: TheTable.GetL(); sl@0: test(TheTable.ColInt(1)==1); sl@0: test(TheTable.NextL()); sl@0: TheTable.GetL(); sl@0: test(TheTable.ColInt(1)==2); sl@0: test(!TheTable.NextL()); sl@0: test(TheTable.SetIndex(KIndexTwo)==KErrNone); sl@0: test(TheTable.CountL()==2); sl@0: test(TheTable.NextL()); sl@0: TheTable.GetL(); sl@0: test(TheTable.ColInt(1)==2); sl@0: test(TheTable.NextL()); sl@0: TheTable.GetL(); sl@0: test(TheTable.ColInt(1)==1); sl@0: test(!TheTable.NextL()); sl@0: test(TheTable.SetNoIndex()==KErrNone); sl@0: test(TheTable.CountL()==2); sl@0: test(TheTable.NextL()); sl@0: test(TheTable.NextL()); sl@0: test(!TheTable.NextL()); sl@0: TheTable.Close(); sl@0: test.Next(_L("Drop indices")); sl@0: test(TheDatabase.DropIndex(KIndexTwo,KTableName)==KErrNone); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: test(TheTable.SetIndex(KIndexName)==KErrNone); sl@0: test(TheTable.SetIndex(KIndexTwo)!=KErrNone); sl@0: TheTable.Close(); sl@0: test(TheDatabase.DropIndex(KIndexName,KTableName)==KErrNone); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: test(TheTable.SetIndex(KIndexName)!=KErrNone); sl@0: test(TheTable.SetIndex(KIndexTwo)!=KErrNone); sl@0: TheTable.Close(); sl@0: test(TheDatabase.DropTable(KTableName)==KErrNone); sl@0: test.End(); sl@0: } sl@0: sl@0: LOCAL_C TInt CountRowsL() sl@0: { sl@0: TInt count=0; sl@0: while (TheTable.NextL()) sl@0: ++count; sl@0: return count; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0619 sl@0: @SYMTestCaseDesc RDbNamedDatabase::Execute() function test sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for CREATE TABLE,CREATE INDEX and CREATE UNIQUE INDEX query sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void TestPersistence() sl@0: { sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0619 Create table ")); sl@0: TheDatabase.Begin(); sl@0: test(TheDatabase.Execute(_L("CREATE TABLE Table (column CHAR(120) NOT NULL)"))==KErrNone); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,_L("a")); sl@0: TheTable.PutL(); sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,_L("b")); sl@0: TheTable.PutL(); sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,_L("c")); sl@0: TheTable.PutL(); sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,_L("d")); sl@0: TheTable.PutL(); sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,_L("e")); sl@0: TheTable.PutL(); sl@0: TheTable.Close(); sl@0: test(TheDatabase.Commit()==KErrNone); sl@0: test.Next(_L("Build indices")); sl@0: test (TheDatabase.Execute(_L("CREATE INDEX index ON table (column ASC)"))==KErrNone); sl@0: test (TheDatabase.Execute(_L("CREATE UNIQUE INDEX index_two ON table (column DESC)"))==KErrNone); sl@0: test.Next(_L("Close and re-open database")); sl@0: CloseDatabaseL(); sl@0: OpenDatabaseL(); sl@0: test.Next(_L("Check indices")); sl@0: CDbKey* key=TheDatabase.KeyL(KIndexName,KTableName); sl@0: test (key->Count()==1); sl@0: test (key->Comparison()==EDbCompareNormal); sl@0: test (!key->IsUnique()); sl@0: test ((*key)[0].iName.CompareF(KColumnName)==0); sl@0: test ((*key)[0].iOrder==TDbKeyCol::EAsc); sl@0: delete key; sl@0: key=TheDatabase.KeyL(KIndexTwo,KTableName); sl@0: test (key->Count()==1); sl@0: test (key->Comparison()==EDbCompareNormal); sl@0: test (key->IsUnique()); sl@0: test ((*key)[0].iName.CompareF(KColumnName)==0); sl@0: test ((*key)[0].iOrder==TDbKeyCol::EDesc); sl@0: delete key; sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: test(TheTable.SetNoIndex()==KErrNone); sl@0: test(CountRowsL()==5); sl@0: test(TheTable.CountL()==5); sl@0: test(TheTable.SetIndex(KIndexName)==KErrNone); sl@0: test(TheTable.CountL()==5); sl@0: test(CountRowsL()==5); sl@0: test(TheTable.SetIndex(KIndexTwo)==KErrNone); sl@0: test(TheTable.CountL()==5); sl@0: test(CountRowsL()==5); sl@0: TheTable.Close(); sl@0: test.Next(_L("Drop indices")); sl@0: TheDatabase.Begin(); sl@0: test (TheDatabase.Execute(_L("DROP INDEX index_two FROM table"))==KErrNone); sl@0: test (TheDatabase.Execute(_L("DROP INDEX index FROM table"))==KErrNone); sl@0: test (TheDatabase.Execute(_L("DROP TABLE table"))==KErrNone); sl@0: test(TheDatabase.Commit()==KErrNone); sl@0: test.End(); sl@0: } sl@0: sl@0: LOCAL_C void BuildTableProlog(TDbColType aType,TInt aAttribs=0) sl@0: { sl@0: TheDatabase.Begin(); sl@0: CDbColSet *cs=CDbColSet::NewLC(); sl@0: TDbCol col(KColumnName,aType); sl@0: col.iAttributes=aAttribs; sl@0: cs->AddL(col); sl@0: test(TheDatabase.CreateTable(KTableName,*cs)==KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: } sl@0: sl@0: inline void SetColL(RDbRowSet& aSet,TDbColNo col,const TInt& aValue) sl@0: {aSet.SetColL(col,aValue);} sl@0: inline void SetColL(RDbRowSet& aSet,TDbColNo col,const TUint& aValue) sl@0: {aSet.SetColL(col,aValue);} sl@0: inline void SetColL(RDbRowSet& aSet,TDbColNo col,const TInt64& aValue) sl@0: {aSet.SetColL(col,aValue);} sl@0: inline void SetColL(RDbRowSet& aSet,TDbColNo col,const TReal32& aValue) sl@0: {aSet.SetColL(col,aValue);} sl@0: inline void SetColL(RDbRowSet& aSet,TDbColNo col,const TReal64& aValue) sl@0: {aSet.SetColL(col,aValue);} sl@0: inline void SetColL(RDbRowSet& aSet,TDbColNo col,const TTime& aValue) sl@0: {aSet.SetColL(col,aValue);} sl@0: inline void SetColL(RDbRowSet& aSet,TDbColNo col,const TPtrC& aValue) sl@0: {aSet.SetColL(col,aValue);} sl@0: sl@0: template <class T> sl@0: void BuildTable(TDbColType aType,TInt aAttribs,T aValues[],TInt aCount) sl@0: { sl@0: BuildTableProlog(aType,aAttribs); sl@0: for (TInt ii=0;ii<aCount;++ii) sl@0: { sl@0: TheTable.InsertL(); sl@0: SetColL(TheTable,1,aValues[ii]); sl@0: TheTable.PutL(); sl@0: } sl@0: test(TheDatabase.Commit()==KErrNone); sl@0: test (TheTable.CountL()==aCount); sl@0: TheTable.Close(); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0620 sl@0: @SYMTestCaseDesc Setting the specified index as the active index for a table test sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Create an index and set as active index for the table. sl@0: Tests for RDbNamedDatabase::CreateIndex(),RDbNamedDatabase::Commit() sl@0: RDbTable::Open(),RDbTable::SetIndex() functions. sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void BuildIndex(TDbTextComparison aComparison=EDbCompareNormal,TInt aLength=KDbUndefinedLength) sl@0: { sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0620 Test index order ")); sl@0: TheDatabase.Begin(); sl@0: CDbKey *key=CDbKey::NewLC(); sl@0: key->AddL(TDbKeyCol(KColumnName,aLength)); sl@0: key->MakeUnique(); sl@0: key->SetComparison(aComparison); sl@0: test(TheDatabase.CreateIndex(KIndexName,KTableName,*key)==KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: test (TheDatabase.Commit()==KErrNone); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: test(TheTable.SetIndex(KIndexName)==KErrNone); sl@0: } sl@0: sl@0: inline void GetCol(RDbRowSet& aSet,TDbColNo col,TInt& aValue) sl@0: {aValue=aSet.ColInt(col);} sl@0: inline void GetCol(RDbRowSet& aSet,TDbColNo col,TUint& aValue) sl@0: {aValue=aSet.ColUint(col);} sl@0: inline void GetCol(RDbRowSet& aSet,TDbColNo col,TInt64& aValue) sl@0: {aValue=aSet.ColInt64(col);} sl@0: inline void GetCol(RDbRowSet& aSet,TDbColNo col,TReal32& aValue) sl@0: {aValue=aSet.ColReal32(col);} sl@0: inline void GetCol(RDbRowSet& aSet,TDbColNo col,TReal64& aValue) sl@0: {aValue=aSet.ColReal64(col);} sl@0: inline void GetCol(RDbRowSet& aSet,TDbColNo col,TTime& aValue) sl@0: {aValue=aSet.ColTime(col);} sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0621 sl@0: @SYMTestCaseDesc RDbRowSet ordering test sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Reorder the row set data with RDbRowSet::GetL(),SetL() functions. sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: template <class T> sl@0: void TestOrdering(RDbRowSet& aSet,T,TInt aCount) sl@0: { sl@0: test.Next( _L( " @SYMTestCaseID:SYSLIB-DBMS-CT-0621 " ) ); sl@0: test(aSet.CountL()==aCount); sl@0: TInt count=0; sl@0: if (aSet.FirstL()) sl@0: { sl@0: ++count; sl@0: aSet.GetL(); sl@0: T last; sl@0: GetCol(aSet,1,last); sl@0: while (aSet.NextL()) sl@0: { sl@0: ++count; sl@0: aSet.GetL(); sl@0: T current; sl@0: GetCol(aSet,1,current); sl@0: test(last<current); sl@0: last=current; sl@0: } sl@0: } sl@0: test(count==aCount); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0622 sl@0: @SYMTestCaseDesc RDbTable::SeekL() function test sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for the retrieved column value sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: template <class T> sl@0: void TestSeek(RDbTable& aTable,T,const T aValues[],TInt aCount) sl@0: { sl@0: test.Next( _L( " @SYMTestCaseID:SYSLIB-DBMS-CT-0622 Test index seeking " ) ); sl@0: for (TInt ii=0;ii<aCount;++ii) sl@0: { sl@0: test(aTable.SeekL(aValues[ii])); sl@0: aTable.GetL(); sl@0: T val; sl@0: GetCol(aTable,1,val); sl@0: test(aValues[ii]==val); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: aVal argument is used in the test functions (TestType & TestOrdering) and has no meaning outside them. sl@0: It is used only to avoid some compiler varnings and to determine the correct template type sl@0: sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0623 sl@0: @SYMTestCaseDesc Tests for RDbTable,RDbRowSet classes sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Call up Test for table ordering and index seeking functions sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: template <class T> sl@0: void TestType( TDbColType aType, TInt aAttribs, const T aValues[], TInt aCount ) sl@0: { sl@0: test.Start( _L( " @SYMTestCaseID:SYSLIB-DBMS-CT-0623 Build table " ) ); sl@0: BuildTable( aType, aAttribs, aValues, aCount ); sl@0: T t(0); sl@0: // sl@0: test.Next( _L( "Test ORDER BY ordering" ) ); sl@0: test( TheView.Prepare( TheDatabase, KSelectOrdered ) == KErrNone ); sl@0: test( TheView.EvaluateAll() == KErrNone ); sl@0: TestOrdering( TheView, t, aCount ); sl@0: TheView.Close(); sl@0: // sl@0: test.Next( _L( "Test index ordering" ) ); sl@0: BuildIndex(); sl@0: TestOrdering( TheTable, t, aCount ); sl@0: // sl@0: test.Next( _L( "Test index seeking" ) ); sl@0: TestSeek( TheTable, t, aValues, aCount ); sl@0: TheTable.Close(); sl@0: // sl@0: test( TheDatabase.DropTable( KTableName ) == KErrNone ); sl@0: test.End(); sl@0: } sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-1322 sl@0: @SYMTestCaseDesc Text ordering test sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for RDbRowSet::Next(),RDbRowSet::GetL(),RDbRowSet::ColDes() functions sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: void TestTextOrdering(RDbRowSet& aSet,TInt aCount,const TTextOps& aComp) sl@0: { sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-1322 ")); sl@0: test(aSet.CountL()==aCount); sl@0: TInt count=0; sl@0: while (aSet.NextL()) sl@0: { sl@0: aSet.GetL(); sl@0: TPtrC current=aSet.ColDes(1); sl@0: if (count++>0) sl@0: test(aComp.Compare(TheBuf,current)<0); sl@0: TheBuf=current; sl@0: } sl@0: test(count==aCount); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-1323 sl@0: @SYMTestCaseDesc Tests for RDbView,RDbTable classes sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Wrapper function to call up for text ordering and text indexing tests sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: void TestText(const TPtrC aValues[],TInt aCount,TDbTextComparison aComparison,TInt aLength=KDbUndefinedLength) sl@0: { sl@0: const TTextOps& comp=TTextOps::Ops(aComparison); sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-1323 Build table ")); sl@0: BuildTable(EDbColText,0,aValues,aCount); sl@0: // sl@0: test.Next(_L("Test ORDER BY ordering")); sl@0: test (TheView.Prepare(TheDatabase,TDbQuery(KSelectOrdered,aComparison))==KErrNone); sl@0: test (TheView.EvaluateAll()==KErrNone); sl@0: TestTextOrdering(TheView,aCount,comp); sl@0: TheView.Close(); sl@0: // sl@0: test.Next(_L("Test index order")); sl@0: BuildIndex(aComparison,aLength); sl@0: test(TheTable.SetIndex(KIndexName)==KErrNone); sl@0: TestTextOrdering(TheTable,aCount,comp); sl@0: // sl@0: test.Next(_L("Test index seeking")); sl@0: for (TInt ii=0;ii<aCount;++ii) sl@0: { sl@0: test(TheTable.SeekL(aValues[ii])); sl@0: TheTable.GetL(); sl@0: test(comp.Compare(aValues[ii],TheTable.ColDes(1))==0); sl@0: } sl@0: // sl@0: TheTable.Close(); sl@0: test(TheDatabase.DropTable(KTableName)==KErrNone); sl@0: test.End(); sl@0: } sl@0: sl@0: void TestLongTextOrdering(RDbRowSet& aSet,TInt aCount,const TTextOps& aComp) sl@0: { sl@0: test(aSet.CountL()==aCount); sl@0: TInt count=0; sl@0: HBufC* prev=0; sl@0: while (aSet.NextL()) sl@0: { sl@0: aSet.GetL(); sl@0: TInt len=aSet.ColLength(1); sl@0: HBufC* buf=HBufC::NewL(len); sl@0: RDbColReadStream s; sl@0: s.OpenLC(aSet,1); sl@0: TPtr des(buf->Des()); sl@0: s.ReadL(des,len); sl@0: CleanupStack::PopAndDestroy(); sl@0: if (count++) sl@0: test (aComp.Compare(*buf,*prev)>=0); sl@0: delete prev; sl@0: prev=buf; sl@0: } sl@0: delete prev; sl@0: test(count==aCount); sl@0: } sl@0: sl@0: LOCAL_C void OrderByLongText(TInt aCount,TDbTextComparison aComparison) sl@0: { sl@0: test (TheView.Prepare(TheDatabase,TDbQuery(KSelectOrdered,aComparison))==KErrNone); sl@0: test (TheView.EvaluateAll()==KErrNone); sl@0: TestLongTextOrdering(TheView,aCount,TTextOps::Ops(aComparison)); sl@0: TheView.Close(); sl@0: } sl@0: sl@0: LOCAL_C void TestLongText(const TPtrC aValues[],TInt aCount,TDbTextComparison aComparison,TInt aLength=KDbUndefinedLength) sl@0: { sl@0: const TTextOps& comp=TTextOps::Ops(aComparison); sl@0: test.Start(_L("Build table")); sl@0: BuildTable(EDbColLongText,0,aValues,aCount); sl@0: // sl@0: test.Next(_L("Test ORDER BY ordering")); sl@0: OrderByLongText(aCount,aComparison); sl@0: // sl@0: test.Next(_L("Test index order")); sl@0: BuildIndex(aComparison,aLength); sl@0: test(TheTable.SetIndex(KIndexName)==KErrNone); sl@0: TestLongTextOrdering(TheTable,aCount,comp); sl@0: // sl@0: test.Next(_L("Test index seeking")); sl@0: for (TInt ii=0;ii<aCount;++ii) sl@0: { sl@0: test(TheTable.SeekL(aValues[ii])); sl@0: TheTable.GetL(); sl@0: RDbColReadStream strm; sl@0: strm.OpenLC(TheTable,1); sl@0: strm.ReadL(TheBuf,TheTable.ColLength(1)); sl@0: CleanupStack::PopAndDestroy(); sl@0: test(comp.Compare(aValues[ii],TheBuf)==0); sl@0: } sl@0: TheTable.Close(); sl@0: // sl@0: test(TheDatabase.DropTable(KTableName)==KErrNone); sl@0: test.End(); sl@0: } sl@0: sl@0: TUint const KBitValues[]={0,1}; sl@0: TInt const KInt8Values[]={0,KMinTInt8+1,1,KMaxTInt8,2,-3,-1,KMaxTInt8-1,KMinTInt8,-40}; sl@0: TInt const KInt16Values[]={0,KMinTInt16+1,1,KMaxTInt16,2,-3,-1,KMaxTInt16-1,KMinTInt16,-4000}; sl@0: TInt const KInt32Values[]={0,KMinTInt32+1,1,KMaxTInt32,2,-3,-1,KMaxTInt32-1,KMinTInt32,-40000000}; sl@0: TInt const KInt32Count=sizeof(KInt32Values)/sizeof(KInt32Values[0]); sl@0: TUint const KUint8Values[]={0,1,KMaxTUint8,2,(KMaxTUint8+1)/2,(KMaxTUint8-1)/2,KMaxTUint8-1,40}; sl@0: TUint const KUint16Values[]={0,1,KMaxTUint16,2,(KMaxTUint16+1)/2,(KMaxTUint16-1)/2,KMaxTUint16-1,4000}; sl@0: TUint const KUint32Values[]={0,1,KMaxTUint32,2,KMaxTUint32/2+1,KMaxTUint32/2,KMaxTUint32-1,40000000}; sl@0: //TReal32 const KReal32Values[]={0.0f,1.0f,KMaxTReal32,KMinTReal32,-1.0f,-KMaxTReal32,-4e20f,-KMinTReal32}; sl@0: //TReal64 const KReal64Values[]={0.0,1.0,KMaxTReal64,KMinTReal64,-1.0,-KMaxTReal64,-4e200,-KMinTReal64}; sl@0: TReal32 const KReal32Values[]={0.0f,1.0f,1e37f,1e-37f,-1.0f,-1e37f,-4e20f,-1e-37f}; sl@0: TReal64 const KReal64Values[]={0.0,1.0,KMaxTReal64,KMinTReal64,-1.0,-KMaxTReal64,-4e200,-KMinTReal64}; sl@0: TInt64 const KInt64Values[]= sl@0: { sl@0: 0, sl@0: MAKE_TINT64(0x80000000u,0x1u), sl@0: 1, sl@0: MAKE_TINT64(0x7fffffffu,0xffffffffu), sl@0: 2, sl@0: -3, sl@0: -1, sl@0: MAKE_TINT64(0x7fffffffu,0xfffffffeu), sl@0: MAKE_TINT64(0x80000000u,0x0u), sl@0: -40 sl@0: }; sl@0: TTime const KTimeValues[]= sl@0: { sl@0: Time::MaxTTime(), sl@0: TInt64(0), sl@0: TDateTime(1970,EJanuary,0,0,0,0,0), sl@0: Time::MinTTime(), sl@0: TDateTime(2049,EDecember,30,23,59,59,999999), sl@0: TDateTime(1996,EJuly,8,17,45,0,0) sl@0: }; sl@0: TPtrC const KTextValues[]= sl@0: { sl@0: _S(""), sl@0: _S("10"), sl@0: _S("zyx"), sl@0: _S("0"), sl@0: _S("abcd"), sl@0: _S("abcdefg"), sl@0: _S("ABCDE"), sl@0: _S("Z") sl@0: }; sl@0: TPtrC const KLongTextValues[]= sl@0: { sl@0: _S("this blob will be inlined"), sl@0: _S(""), sl@0: _S("that blob was null"), sl@0: _S("An example of an out-of-line blob in an index! LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8-LongText8") sl@0: }; sl@0: const TInt KLongTextLimit=30; sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0624 sl@0: @SYMTestCaseDesc Wrapper function testing for Indexing with different integer sizes and Text . sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for indexing sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void TestTypes() sl@0: { sl@0: #define ARRAY_SIZE(a) TInt(sizeof(a)/sizeof(a[0])) sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0624 Indexing Bit ")); sl@0: TestType(EDbColBit,TDbCol::ENotNull,KBitValues,ARRAY_SIZE(KBitValues)); sl@0: test.Next(_L("Indexing Int8")); sl@0: TestType(EDbColInt8,TDbCol::ENotNull,KInt8Values,ARRAY_SIZE(KInt8Values)); sl@0: test.Next(_L("Indexing Int16")); sl@0: TestType(EDbColInt16,TDbCol::ENotNull,KInt16Values,ARRAY_SIZE(KInt16Values)); sl@0: test.Next(_L("Indexing Int32")); sl@0: TestType(EDbColInt32,TDbCol::ENotNull,KInt32Values,ARRAY_SIZE(KInt32Values)); sl@0: test.Next(_L("Indexing Uint8")); sl@0: TestType(EDbColUint8,TDbCol::ENotNull,KUint8Values,ARRAY_SIZE(KUint8Values)); sl@0: test.Next(_L("Indexing Uint16")); sl@0: TestType(EDbColUint16,TDbCol::ENotNull,KUint16Values,ARRAY_SIZE(KUint16Values)); sl@0: test.Next(_L("Indexing Uint32")); sl@0: TestType(EDbColUint32,TDbCol::ENotNull,KUint32Values,ARRAY_SIZE(KUint32Values)); sl@0: test.Next(_L("Indexing Real32")); sl@0: TestType(EDbColReal32,TDbCol::ENotNull,KReal32Values,ARRAY_SIZE(KReal32Values)); sl@0: test.Next(_L("Indexing Real64")); sl@0: TestType(EDbColReal64,TDbCol::ENotNull,KReal64Values,ARRAY_SIZE(KReal64Values)); sl@0: test.Next(_L("Indexing Int64")); sl@0: TestType(EDbColInt64,TDbCol::ENotNull,KInt64Values,ARRAY_SIZE(KInt64Values)); sl@0: test.Next(_L("Indexing Time")); sl@0: TestType(EDbColDateTime,TDbCol::ENotNull,KTimeValues,ARRAY_SIZE(KTimeValues)); sl@0: test.Next(_L("Indexing Text (Normal)")); sl@0: TestText(KTextValues,ARRAY_SIZE(KTextValues),EDbCompareNormal); sl@0: test.Next(_L("Indexing Text (Folded)")); sl@0: TestText(KTextValues,ARRAY_SIZE(KTextValues),EDbCompareFolded); sl@0: test.Next(_L("Indexing Text (Collated)")); sl@0: TestText(KTextValues,ARRAY_SIZE(KTextValues),EDbCompareCollated); sl@0: test.Next(_L("Indexing Text (Normal, truncated)")); sl@0: TestText(KTextValues,ARRAY_SIZE(KTextValues),EDbCompareNormal,5); sl@0: test.Next(_L("Indexing LongText (Normal)")); sl@0: TestLongText(KLongTextValues,ARRAY_SIZE(KLongTextValues),EDbCompareNormal,KLongTextLimit); sl@0: test.Next(_L("Indexing LongText (Folded)")); sl@0: TestLongText(KLongTextValues,ARRAY_SIZE(KLongTextValues),EDbCompareFolded,KLongTextLimit); sl@0: test.Next(_L("Indexing LongText (Collated)")); sl@0: TestLongText(KLongTextValues,ARRAY_SIZE(KLongTextValues),EDbCompareCollated,KLongTextLimit); sl@0: test.End(); sl@0: } sl@0: sl@0: const TInt KBlobKeyTruncated=32/sizeof(TText); sl@0: const TInt KBlobKeyMaxInline=255/sizeof(TText); sl@0: const TInt KBlobKeyCompare=512/sizeof(TText); sl@0: sl@0: const TInt KMemoTestLengths[]= sl@0: { sl@0: 0, sl@0: 1, sl@0: KBlobKeyTruncated-1, sl@0: KBlobKeyTruncated, sl@0: KBlobKeyTruncated+1, sl@0: KBlobKeyMaxInline, sl@0: KBlobKeyMaxInline+1, sl@0: KBlobKeyCompare-1, sl@0: KBlobKeyCompare, sl@0: KBlobKeyCompare+1, sl@0: 5000 sl@0: }; sl@0: sl@0: void TestMemoTable(CDbColSet& aBaseSet) sl@0: { sl@0: test.Start(_L("create the table")); sl@0: aBaseSet.AddL(TDbCol(KColumnName,EDbColLongText)); sl@0: TheDatabase.Begin(); sl@0: TInt r=TheDatabase.CreateTable(KTableName,aBaseSet); sl@0: test (r==KErrNone); sl@0: // sl@0: test.Next(_L("add the rows")); sl@0: r=TheView.Prepare(TheDatabase,KSelectOrdered,RDbView::EInsertOnly); sl@0: test (r==KErrNone); sl@0: r=TheView.EvaluateAll(); sl@0: test (r==KErrNone); sl@0: HBufC* prev=0; sl@0: TInt count=0; sl@0: for (TUint ii=0;ii<elementsof(KMemoTestLengths);++ii) sl@0: { sl@0: TInt size=KMemoTestLengths[ii]; sl@0: HBufC* buf=HBufC::NewL(size); sl@0: if (size>0) sl@0: { sl@0: TPtr des(buf->Des()); sl@0: des.Copy(*prev); sl@0: des.AppendFill('b',size-prev->Length()); sl@0: delete prev; sl@0: TheView.InsertL(); sl@0: TheView.SetColL(1,*buf); sl@0: TheView.PutL(); sl@0: ++count; sl@0: des[size-1]='a'; sl@0: } sl@0: TheView.InsertL(); sl@0: TheView.SetColL(1,*buf); sl@0: TheView.PutL(); sl@0: ++count; sl@0: prev=buf; sl@0: } sl@0: delete prev; sl@0: TheView.Close(); sl@0: r=TheDatabase.Commit(); sl@0: test (r==KErrNone); sl@0: // sl@0: test.Next(_L("Normal order")); sl@0: OrderByLongText(count,EDbCompareNormal); sl@0: test.Next(_L("Folded order")); sl@0: OrderByLongText(count,EDbCompareFolded); sl@0: test.Next(_L("Collated order")); sl@0: OrderByLongText(count,EDbCompareCollated); sl@0: // sl@0: r=TheDatabase.DropTable(KTableName); sl@0: test (r==KErrNone); sl@0: test.End(); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0625 sl@0: @SYMTestCaseDesc Tests for ordering by longtext sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for CDbColSet sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void TestOrderByLongText() sl@0: { sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0625 Maximum Inline Limit ")); sl@0: CDbColSet* set=CDbColSet::NewLC(); sl@0: TestMemoTable(*set); sl@0: // sl@0: test.Next(_L("Reduced Inline limit [<32]")); sl@0: set->Clear(); sl@0: TDbCol col; sl@0: col.iType=EDbColText8; sl@0: col.iMaxLength=255; sl@0: col.iAttributes=0; sl@0: TDbColName name; sl@0: for (TInt ii=0;ii<32;++ii) sl@0: { sl@0: name.Format(_L("col%d"),ii); sl@0: col.iName=name; sl@0: if (ii==31) sl@0: col.iMaxLength=255-20; sl@0: set->AddL(col); sl@0: } sl@0: TestMemoTable(*set); sl@0: CleanupStack::PopAndDestroy(); sl@0: test.End(); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0626 sl@0: @SYMTestCaseDesc Tests for reverse ordering in indexes sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for reversing the indexes sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void TestReverse() sl@0: { sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0626 Create table and index ")); sl@0: TheDatabase.Begin(); sl@0: CDbColSet *cs=CDbColSet::NewLC(); sl@0: cs->AddL(TDbCol(KColumnName,EDbColInt32)); sl@0: test(TheDatabase.CreateTable(KTableName,*cs)==KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: CDbKey *key=CDbKey::NewLC(); sl@0: key->AddL(TDbKeyCol(KColumnName,TDbKeyCol::EDesc)); sl@0: key->MakeUnique(); sl@0: test(TheDatabase.CreateIndex(KIndexName,KTableName,*key)==KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: test(TheDatabase.Commit()==KErrNone); sl@0: test.Next(_L("Add records")); sl@0: TheDatabase.Begin(); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: for (TInt ii=0;ii<KInt32Count;++ii) sl@0: { sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,KInt32Values[ii]); sl@0: TheTable.PutL(); sl@0: } sl@0: test(TheDatabase.Commit()==KErrNone); sl@0: test(TheTable.CountL()==KInt32Count); sl@0: test.Next(_L("Check order")); sl@0: test(TheTable.SetIndex(KIndexName)==KErrNone); sl@0: test(TheTable.CountL()==KInt32Count); sl@0: TInt count=0; sl@0: if (TheTable.FirstL()) sl@0: { sl@0: ++count; sl@0: TheTable.GetL(); sl@0: TInt32 last=TheTable.ColInt(1); sl@0: while (TheTable.NextL()) sl@0: { sl@0: ++count; sl@0: TheTable.GetL(); sl@0: TInt32 current=TheTable.ColInt(1); sl@0: test(last>current); sl@0: last=current; sl@0: } sl@0: } sl@0: test(count==KInt32Count); sl@0: TheTable.Close(); sl@0: test(TheDatabase.DropTable(KTableName)==KErrNone); sl@0: test.End(); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0627 sl@0: @SYMTestCaseDesc Tests for multi-column keys sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for mutliple column keys sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void TestMulti() sl@0: { sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0627 Create table and index ")); sl@0: TheDatabase.Begin(); sl@0: CDbColSet *cs=CDbColSet::NewLC(); sl@0: TDbCol col(KColumnName,EDbColInt32); sl@0: col.iAttributes=TDbCol::ENotNull; sl@0: cs->AddL(col); sl@0: col.iName=KColumnTwo; sl@0: cs->AddL(col); sl@0: test(TheDatabase.CreateTable(KTableName,*cs)==KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: CDbKey *key=CDbKey::NewLC(); sl@0: key->AddL(TDbKeyCol(KColumnTwo)); sl@0: key->AddL(TDbKeyCol(KColumnName,TDbKeyCol::EDesc)); sl@0: key->MakeUnique(); sl@0: test(TheDatabase.CreateIndex(KIndexName,KTableName,*key)==KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: test(TheDatabase.Commit()==KErrNone); sl@0: test.Next(_L("Add records")); sl@0: TheDatabase.Begin(); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: for (TInt ii=0;ii<KInt32Count;++ii) sl@0: { sl@0: for (TInt jj=0;jj<KInt32Count;++jj) sl@0: { sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,KInt32Values[ii]); sl@0: TheTable.SetColL(2,KInt32Values[jj]); sl@0: TheTable.PutL(); sl@0: } sl@0: } sl@0: test(TheDatabase.Commit()==KErrNone); sl@0: test.Next(_L("Check order")); sl@0: test(TheTable.CountL()==KInt32Count*KInt32Count); sl@0: test(TheTable.SetIndex(KIndexName)==KErrNone); sl@0: test(TheTable.CountL()==KInt32Count*KInt32Count); sl@0: TInt count=0; sl@0: if (TheTable.FirstL()) sl@0: { sl@0: ++count; sl@0: TheTable.GetL(); sl@0: TInt32 lastOne=TheTable.ColInt(1); sl@0: TInt32 lastTwo=TheTable.ColInt(2); sl@0: while (TheTable.NextL()) sl@0: { sl@0: ++count; sl@0: TheTable.GetL(); sl@0: TInt32 currentOne=TheTable.ColInt(1); sl@0: TInt32 currentTwo=TheTable.ColInt(2); sl@0: test(lastTwo<currentTwo||(lastTwo==currentTwo&&lastOne>currentOne)); sl@0: lastOne=currentOne; sl@0: lastTwo=currentTwo; sl@0: } sl@0: } sl@0: test(count==KInt32Count*KInt32Count); sl@0: TheTable.Close(); sl@0: test(TheDatabase.DropTable(KTableName)==KErrNone); sl@0: test.End(); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0628 sl@0: @SYMTestCaseDesc Tests duplicates/unique constraints sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for adding duplicate entries sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void TestDuplicates() sl@0: { sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0628 Create table and indices ")); sl@0: BuildTable(EDbColInt32,TDbCol::ENotNull,KInt32Values,KInt32Count); sl@0: BuildIndex(); sl@0: TheTable.Close(); sl@0: CDbKey* key=CDbKey::NewLC(); sl@0: key->AddL(KColumnName); sl@0: test(TheDatabase.CreateIndex(KIndexTwo,KTableName,*key)==KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: test.Next(_L("Attempt to add/update duplicate entry")); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,0); sl@0: TRAPD(r,TheTable.PutL()); sl@0: test(r!=KErrNone); sl@0: TheTable.Cancel(); sl@0: TheTable.LastL(); sl@0: TheTable.UpdateL(); sl@0: TheTable.SetColL(1,0); sl@0: TRAP(r,TheTable.PutL()); sl@0: test(r!=KErrNone); sl@0: TheTable.Cancel(); sl@0: test.Next(_L("Remove unique index")); sl@0: TheTable.Close(); sl@0: test(TheDatabase.DropIndex(KIndexName,KTableName)==KErrNone); sl@0: test.Next(_L("Attempt to update/add duplicate entry")); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: TheTable.LastL(); sl@0: TheTable.UpdateL(); sl@0: TheTable.SetColL(1,0); sl@0: TRAP(r,TheTable.PutL()); sl@0: test(r==KErrNone); sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,0); sl@0: TRAP(r,TheTable.PutL()); sl@0: test(r==KErrNone); sl@0: test.Next(_L("Check order")); sl@0: test(TheTable.CountL()==KInt32Count+1); sl@0: test(TheTable.SetIndex(KIndexTwo)==KErrNone); sl@0: test(TheTable.CountL()==KInt32Count+1); sl@0: TInt count=0; sl@0: if (TheTable.FirstL()) sl@0: { sl@0: ++count; sl@0: TheTable.GetL(); sl@0: TInt32 last=TheTable.ColInt(1); sl@0: while (TheTable.NextL()) sl@0: { sl@0: ++count; sl@0: TheTable.GetL(); sl@0: TInt32 current=TheTable.ColInt(1); sl@0: test(last<=current); // duplicates present sl@0: last=current; sl@0: } sl@0: } sl@0: test(count==KInt32Count+1); sl@0: test.Next(_L("Try to create unique index")); sl@0: TheTable.Close(); sl@0: key=CDbKey::NewLC(); sl@0: key->AddL(KColumnName); sl@0: key->MakeUnique(); sl@0: test(TheDatabase.CreateIndex(KIndexName,KTableName,*key)!=KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: test(TheDatabase.DropTable(KTableName)==KErrNone); sl@0: test.End(); sl@0: } sl@0: sl@0: struct Pair { TInt i1,i2; }; sl@0: struct TSeekingTest sl@0: { sl@0: Pair iSeek; sl@0: Pair iResults[5]; sl@0: }; sl@0: sl@0: // seek pair: results for <,<=,=,>=,> sl@0: static TSeekingTest const SeekingTests[]= sl@0: { sl@0: {{0,0},{{-1,-1},{-1,-1},{-1,-1},{100,10},{100,10}}}, sl@0: {{0,-1},{{-1,-1},{-1,-1},{-1,-1},{100,10},{100,10}}}, sl@0: {{100,0},{{-1,-1},{-1,-1},{-1,-1},{100,10},{100,10}}}, sl@0: {{100,10},{{-1,-1},{100,10},{100,10},{100,10},{100,20}}}, sl@0: {{100,55},{{100,50},{100,50},{-1,-1},{100,60},{100,60}}}, sl@0: {{100,60},{{100,50},{100,60},{100,60},{100,60},{100,70}}}, sl@0: {{100,100},{{100,90},{100,100},{100,100},{100,100},{200,10}}}, sl@0: {{100,110},{{100,100},{100,100},{-1,-1},{200,10},{200,10}}}, sl@0: {{100,-1},{{-1,-1},{100,100},{100,10},{100,10},{200,10}}}, sl@0: {{500,-1},{{400,100},{500,100},{500,10},{500,10},{600,10}}}, sl@0: {{550,50},{{500,100},{500,100},{-1,-1},{600,10},{600,10}}}, sl@0: {{550,-1},{{500,100},{500,100},{-1,-1},{600,10},{600,10}}}, sl@0: {{1000,0},{{900,100},{900,100},{-1,-1},{1000,10},{1000,10}}}, sl@0: {{1000,10},{{900,100},{1000,10},{1000,10},{1000,10},{1000,20}}}, sl@0: {{1000,100},{{1000,90},{1000,100},{1000,100},{1000,100},{-1,-1}}}, sl@0: {{1000,110},{{1000,100},{1000,100},{-1,-1},{-1,-1},{-1,-1}}}, sl@0: {{1000,-1},{{900,100},{1000,100},{1000,10},{1000,10},{-1,-1}}}, sl@0: {{1100,0},{{1000,100},{1000,100},{-1,-1},{-1,-1},{-1,-1}}}, sl@0: {{1100,-1},{{1000,100},{1000,100},{-1,-1},{-1,-1},{-1,-1}}} sl@0: }; sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0629 sl@0: @SYMTestCaseDesc Tests for seeking on indexes sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for SeekL and GetL functions sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void TestSeeking() sl@0: { sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0629 Create table and index ")); sl@0: TheDatabase.Begin(); sl@0: CDbColSet *cs=CDbColSet::NewLC(); sl@0: TDbCol col(KColumnName,EDbColInt32); sl@0: col.iAttributes=TDbCol::ENotNull; sl@0: cs->AddL(col); sl@0: col.iName=KColumnTwo; sl@0: cs->AddL(col); sl@0: test(TheDatabase.CreateTable(KTableName,*cs)==KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: CDbKey *key=CDbKey::NewLC(); sl@0: key->AddL(KColumnName).AddL(KColumnTwo); sl@0: key->MakeUnique(); sl@0: test(TheDatabase.CreateIndex(KIndexName,KTableName,*key)==KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: test(TheDatabase.Commit()==KErrNone); sl@0: test.Next(_L("Add records")); sl@0: TheDatabase.Begin(); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: for (TInt ii=100;ii<=1000;ii+=100) sl@0: { sl@0: for (TInt jj=10;jj<=100;jj+=10) sl@0: { sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,ii); sl@0: TheTable.SetColL(2,jj); sl@0: TheTable.PutL(); sl@0: } sl@0: } sl@0: test(TheDatabase.Commit()==KErrNone); sl@0: test(TheTable.CountL()==100); sl@0: test(TheTable.SetIndex(KIndexName)==KErrNone); sl@0: test(TheTable.CountL()==100); sl@0: test.Next(_L("Seeking")); sl@0: const TSeekingTest* stest=SeekingTests; sl@0: const TSeekingTest* const end=stest+sizeof(SeekingTests)/sizeof(SeekingTests[0])-1; sl@0: for (;stest<=end;++stest) sl@0: { sl@0: TDbSeekMultiKey<2> key; sl@0: key.Add(stest->iSeek.i1); sl@0: if (stest->iSeek.i2>=0) sl@0: key.Add(stest->iSeek.i2); sl@0: const Pair* results=stest->iResults; sl@0: for (TInt ii=RDbTable::ELessThan;ii<=RDbTable::EGreaterThan;++results,++ii) sl@0: { sl@0: if (TheTable.SeekL(key,RDbTable::TComparison(ii))) sl@0: { sl@0: test(results->i1>=0); sl@0: TRAPD(errCode, TheTable.GetL()); sl@0: test(errCode==KErrNone); sl@0: test(TheTable.ColInt(1)==results->i1); sl@0: test(TheTable.ColInt(2)==results->i2); sl@0: } sl@0: else sl@0: test(results->i1<0); sl@0: } sl@0: } sl@0: TheTable.Close(); sl@0: test(TheDatabase.DropTable(KTableName)==KErrNone); sl@0: test.End(); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0630 sl@0: @SYMTestCaseDesc Tests for defect,index creation and set index operations sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for creating and setting index operations sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void TestInequalityError() sl@0: { sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0630 Create table ")); sl@0: TheDatabase.Begin(); sl@0: CDbColSet *cs=CDbColSet::NewLC(); sl@0: cs->AddL(TDbCol(KColumnName,EDbColInt32)); sl@0: test(TheDatabase.CreateTable(KTableName,*cs)==KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: // sl@0: test.Next(_L("create indices")); sl@0: CDbKey *key=CDbKey::NewLC(); sl@0: key->AddL(TDbKeyCol(KColumnName)); sl@0: test(TheDatabase.CreateIndex(KIndexName,KTableName,*key)==KErrNone); sl@0: CleanupStack::PopAndDestroy(); sl@0: // sl@0: test.Next(_L("Populate table")); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: for(TInt ii=0; ii<=130;++ii) sl@0: { sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,ii); sl@0: TheTable.PutL(); sl@0: } sl@0: // sl@0: test.Next(_L("Checks")); sl@0: test(TheTable.SetIndex(KIndexName)==KErrNone); sl@0: // sl@0: // We need to delete a row in this node to get to the correct inequality condition sl@0: test.Next(_L("Delete row 90")); sl@0: test(TheTable.SeekL(TDbSeekKey(90))); sl@0: TheTable.GetL(); sl@0: TheTable.DeleteL(); sl@0: // Now delete last row on node which should be 94 sl@0: test.Next(_L("Delete row 94")); sl@0: test(TheTable.SeekL(TDbSeekKey(94))); sl@0: TheTable.GetL(); sl@0: TheTable.DeleteL(); sl@0: TheTable.EndL(); sl@0: test(!TheTable.SeekL(TDbSeekKey(94))); sl@0: // sl@0: test.Next(_L("Insert row 94")); sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,94); sl@0: TheTable.PutL(); sl@0: // sl@0: test.Next(_L("now try and find it")); sl@0: test(TheTable.SeekL(TDbSeekKey(94))); //prior to defect fix this line failed. sl@0: // sl@0: TheTable.Close(); sl@0: test(TheDatabase.DropTable(KTableName)==KErrNone); sl@0: test.End(); sl@0: } sl@0: sl@0: // sl@0: // Test the database definition and enquiry functions sl@0: // sl@0: LOCAL_C void TestIndexes() sl@0: { sl@0: test.Start(_L("Create Database")); sl@0: CreateDatabaseL(); sl@0: test.Next(_L("Test index build and drop")); sl@0: TestIndexBuild(); sl@0: test.Next(_L("Test index persistence")); sl@0: TestPersistence(); sl@0: test.Next(_L("Testing index key types")); sl@0: TestTypes(); sl@0: test.Next(_L("Testing LongText ORDER BY")); sl@0: TestOrderByLongText(); sl@0: test.Next(_L("Testing reverse ordering")); sl@0: TestReverse(); sl@0: test.Next(_L("Testing multi column keys")); sl@0: TestMulti(); sl@0: test.Next(_L("Testing duplicate/unqiue")); sl@0: TestDuplicates(); sl@0: test.Next(_L("Testing seeking")); sl@0: TestSeeking(); sl@0: test.Next(_L("Testing incorrect inequaltiy condition in store btree")); sl@0: TestInequalityError(); sl@0: CloseDatabaseL(); sl@0: test.End(); sl@0: } sl@0: sl@0: // sl@0: // Prepare the test directory. sl@0: // sl@0: LOCAL_C void setupTestDirectory() sl@0: { sl@0: TInt r=TheFs.Connect(); sl@0: test(r==KErrNone); sl@0: // sl@0: r=TheFs.MkDir(KTestDatabase); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: } sl@0: sl@0: // sl@0: // Initialise the cleanup stack. sl@0: // sl@0: LOCAL_C void setupCleanup() sl@0: { sl@0: TheTrapCleanup=CTrapCleanup::New(); sl@0: test(TheTrapCleanup!=NULL); sl@0: TRAPD(r,\ sl@0: {\ sl@0: for (TInt i=KTestCleanupStack;i>0;i--)\ sl@0: CleanupStack::PushL((TAny*)0);\ sl@0: CleanupStack::Pop(KTestCleanupStack);\ sl@0: }); sl@0: test(r==KErrNone); sl@0: } sl@0: sl@0: LOCAL_C void DeleteDataFile(const TDesC& aFullName) sl@0: { sl@0: RFs fsSession; sl@0: TInt err = fsSession.Connect(); sl@0: if(err == KErrNone) sl@0: { sl@0: TEntry entry; sl@0: if(fsSession.Entry(aFullName, entry) == KErrNone) sl@0: { sl@0: RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName); sl@0: err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly); sl@0: if(err != KErrNone) sl@0: { sl@0: RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName); sl@0: } sl@0: err = fsSession.Delete(aFullName); sl@0: if(err != KErrNone) sl@0: { sl@0: RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName); sl@0: } sl@0: } sl@0: fsSession.Close(); sl@0: } sl@0: else sl@0: { sl@0: RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName); sl@0: } sl@0: } sl@0: sl@0: // sl@0: // Test streaming conversions. sl@0: // sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: test.Title(); sl@0: setupTestDirectory(); sl@0: setupCleanup(); sl@0: __UHEAP_MARK; sl@0: // sl@0: #ifndef __TOOLS2__ sl@0: TInt r=TheDbs.Connect(); sl@0: test (r==KErrNone); sl@0: TheDbs.ResourceMark(); sl@0: #else sl@0: TInt r; sl@0: #endif sl@0: test.Start(_L("Standard database")); sl@0: TRAP(r,TestIndexes();) sl@0: test(r==KErrNone); sl@0: test.Next(_L("Secure database")); sl@0: TRAP(r,TestIndexes();) sl@0: test(r==KErrNone); sl@0: sl@0: ::DeleteDataFile(KTestDatabase); //deletion of data files must be before call to end - DEF047652 sl@0: sl@0: #ifndef __linux__ sl@0: TInt err; sl@0: #ifndef __TOOLS2__ sl@0: TRAPD(lc, err = TheCrcChecker.DumpCrcRecordsL(KCrcRecord)); sl@0: test(err==KErrNone); sl@0: test(lc==KErrNone); sl@0: #else sl@0: TRAPD(lc, err = TheCrcChecker.ValidateCrcRecordsL(KCrcRecord)); sl@0: TPtrC errmsg; sl@0: TheCrcChecker.ErrorReportL(err, errmsg); sl@0: RDebug::Print(errmsg); sl@0: test(err==KErrNone || err==TDBMS_CRCChecks::ECrcCheckOk); sl@0: #endif sl@0: #endif sl@0: sl@0: test.End(); sl@0: #ifndef __TOOLS2__ sl@0: TheDbs.ResourceCheck(); sl@0: TheDbs.Close(); sl@0: #endif sl@0: sl@0: test.Printf(_L("Waiting for server exit\n")); sl@0: const TUint KExitDelay=6*0x100000; // ~6 seconds sl@0: User::After(KExitDelay); sl@0: sl@0: __UHEAP_MARKEND; sl@0: delete TheTrapCleanup; sl@0: sl@0: TheFs.Close(); sl@0: test.Close(); sl@0: return 0; sl@0: }