persistentstorage/dbms/tdbms/t_dbwindow.cpp
changeset 0 08ec8eefde2f
child 55 44f437012c90
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/dbms/tdbms/t_dbwindow.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,516 @@
+// 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 <d32dbms.h>
+#include <s32file.h>
+#include <e32test.h>
+
+LOCAL_D RTest test(_L("t_dbwindow: Testing the 'window' stage"));
+LOCAL_D CTrapCleanup* TheTrapCleanup;
+LOCAL_D CFileStore* TheStore;
+LOCAL_D RDbStoreDatabase TheDatabase;
+LOCAL_D RDbView TheView;
+LOCAL_D RFs TheFs;
+
+const TInt KTestCleanupStack=0x20;
+const TPtrC KTestDir=_S("C:\\DBMS-TST\\");
+const TPtrC KTestFile=_S("T_WINDOW.DB");
+const TPtrC KTableName=_S("TestTable");
+const TPtrC KColumnID=_S("id");
+const TPtrC KIndexName=_S("TestIndex");
+const TInt KRecords=10;
+const TPtrC KCreateTable=_L("CREATE TABLE TestTable (id INTEGER NOT NULL)");
+const TPtrC KCreateIndex=_L("CREATE UNIQUE INDEX TestIndex ON TestTable (id)");
+const TPtrC KEmptyQuery=_L("select * from TestTable where id is null");
+const TPtrC KOrderQuery=_L("select * from TestTable order by id");
+const TDbWindow KSingleSlotWindow(0,0);
+const TDbWindow KSmallWindow(2,2);
+const TDbWindow KLargeWindow(20,0);
+
+//
+// Create the database-in-a-store
+//
+LOCAL_C void CreateDatabaseL()
+	{
+	CFileStore* store=CPermanentFileStore::ReplaceLC(TheFs,KTestFile,EFileRead|EFileWrite);
+	store->SetTypeL(KPermanentFileStoreLayoutUid);
+	TStreamId id;
+		id=TheDatabase.CreateL(store);
+	store->SetRootL(id);
+	store->CommitL();
+	CleanupStack::Pop();
+	TheStore=store;
+	}
+
+LOCAL_C void CloseDatabaseL()
+	{
+	// cannot evaluate size info for store database
+	RDbDatabase::TSize size=TheDatabase.Size();
+	test (size.iSize<0);
+	test (size.iUsage<0);
+	test (TheDatabase.UpdateStats()==KErrNone);
+	size=TheDatabase.Size();
+	test (size.iSize<0);
+	test (size.iUsage<0);
+	TheDatabase.Close();
+	delete TheStore;
+	}
+
+LOCAL_C void CreateTableL()
+	{
+	TheDatabase.Begin();
+	test(TheDatabase.Execute(KCreateTable)==KErrNone);
+	RDbTable table;
+	test(table.Open(TheDatabase,KTableName,table.EInsertOnly)==KErrNone);
+	for (TInt ii=0;ii<KRecords;++ii)
+		{
+		table.InsertL();
+		table.SetColL(1,ii);
+		table.PutL();
+		}
+	table.Close();
+	test(TheDatabase.Execute(KCreateIndex)==KErrNone);
+	test (TheDatabase.Commit()==KErrNone);
+	}
+
+LOCAL_C void InitL()
+	{
+	CreateDatabaseL();
+	CreateTableL();
+	}
+
+/**
+@SYMTestCaseID          SYSLIB-DBMS-CT-0638
+@SYMTestCaseDesc        Tests for navigation
+@SYMTestPriority        Medium
+@SYMTestActions         Tests for navigation in an empty window
+@SYMTestExpectedResults Test must not fail
+@SYMREQ                 REQ0000
+*/
+LOCAL_C void TestEmptyL()
+	{
+	test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0638 Unevaluated "));
+	test(TheView.Prepare(TheDatabase,KEmptyQuery,TDbWindow::EUnlimited)==KErrNone);
+	test(TheView.CountL(TheView.EQuick)==0);
+	test(!TheView.FirstL());
+	test(TheView.AtEnd());
+	test(!TheView.PreviousL());
+	test(TheView.AtBeginning());
+	test(!TheView.LastL());
+	test(TheView.AtBeginning());
+	test(!TheView.NextL());
+	test(TheView.AtEnd());
+	test.Next(_L("Evaluated"));
+	test(TheView.EvaluateAll()==KErrNone);
+	test(TheView.CountL()==0);
+	test(!TheView.FirstL());
+	test(TheView.AtEnd());
+	test(!TheView.PreviousL());
+	test(TheView.AtBeginning());
+	test(!TheView.LastL());
+	test(TheView.AtBeginning());
+	test(!TheView.NextL());
+	test(TheView.AtEnd());
+	test.End();
+	TheView.Close();
+	}
+
+/**
+@SYMTestCaseID          SYSLIB-DBMS-CT-0639
+@SYMTestCaseDesc        Tests for navigation
+@SYMTestPriority        Medium
+@SYMTestActions         Tests for the unlimited (dynaset) window
+@SYMTestExpectedResults Test must not fail
+@SYMREQ                 REQ0000
+*/
+LOCAL_C void TestUnlimitedL()
+	{
+	test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0639 EvaluateAll "));
+	test(TheView.Prepare(TheDatabase,KOrderQuery,TDbWindow::EUnlimited)==KErrNone);
+	test(TheView.EvaluateAll()==KErrNone);
+	test(!TheView.Unevaluated());
+	test(TheView.CountL()==KRecords);
+	TInt cc=0;
+	for (TheView.BeginningL();TheView.NextL();)
+		++cc;
+	test(cc==KRecords);
+	for (TheView.EndL();TheView.PreviousL();)
+		--cc;
+	test(cc==0);
+	test(!TheView.Unevaluated());
+	test.Next(_L("Incremental evaluate"));
+	TheView.Reset();
+	cc=TheView.CountL(TheView.EQuick);
+	test(cc==0);
+	test(!TheView.FirstL());
+	while (TheView.Unevaluated())
+		{
+		test(TheView.Evaluate()>=KErrNone);
+		TInt ii=TheView.CountL()-cc;
+		test(ii>=0);
+		cc+=ii;
+		while (--ii>=0)
+			{
+			test(TheView.AtRow());
+			TheView.NextL();
+			}
+		test(!TheView.AtRow());
+		}
+	test(cc==KRecords);
+	test.Next(_L("Insert"));
+// The new records should go on the end of the set
+	TheView.InsertL();
+	TheView.SetColL(1,TInt(-1));
+	TheView.PutL();
+	test(TheView.CountL()==KRecords+1);
+	test(TheView.LastL());
+	TheView.GetL();
+	test(TheView.ColInt(1)==-1);
+// because of order, it should appear at beginning on re-evaluation
+	TheView.Reset();
+	test(TheView.EvaluateAll()==KErrNone);
+	test(TheView.CountL()==KRecords+1);
+	test(TheView.FirstL());
+	TheView.GetL();
+	test(TheView.ColInt(1)==-1);
+	test.Next(_L("Update"));
+// updated records should not move (or disappear) in the set
+	TheView.UpdateL();
+	TheView.SetColL(1,KRecords);
+	TheView.PutL();
+	test(TheView.CountL()==KRecords+1);
+	test(TheView.FirstL());
+	TheView.GetL();
+	test(TheView.ColInt(1)==KRecords);
+// because of order, it should appear at end on re-evaluation
+	TheView.Reset();
+	test(TheView.EvaluateAll()==KErrNone);
+	test(TheView.CountL()==KRecords+1);
+	test(TheView.LastL());
+	TheView.GetL();
+	test(TheView.ColInt(1)==KRecords);
+	test.Next(_L("Bookmarks"));
+	TDbBookmark mark=TheView.Bookmark();
+	TheView.BeginningL();
+	TRAPD(r,TheView.GotoL(mark));
+	test(r==KErrNone);
+	TheView.GetL();
+	test(TheView.ColInt(1)==KRecords);
+	test(!TheView.NextL());
+	test(TheView.PreviousL());
+	test.Next(_L("Delete"));
+// should disappear from the set
+	TheView.DeleteL();
+	test(TheView.CountL()==KRecords);
+	for (TheView.BeginningL();TheView.NextL();)
+		{
+		TheView.GetL();
+		test(TheView.ColInt(1)!=KRecords);
+		}
+	TRAP(r,TheView.GotoL(mark));
+	test(r!=KErrNone);
+	TheView.Reset();
+	test(TheView.EvaluateAll()==KErrNone);
+	test(TheView.CountL()==KRecords);
+	for (TheView.BeginningL();TheView.NextL();)
+		{
+		TheView.GetL();
+		test(TheView.ColInt(1)!=KRecords);
+		}
+	TRAP(r,TheView.GotoL(mark));
+	test(r!=KErrNone);
+	test.End();
+	TheView.Close();
+	}
+
+//
+// do as much incremental evaluation as possible
+//
+LOCAL_C void Evaluate()
+	{
+	test(TheView.EvaluateAll()==KErrNone);
+	}
+
+//
+// get to the true end of set
+//
+LOCAL_C void GotoEndL()
+	{
+	for (;;)
+		{
+		while (TheView.AtRow())
+			TheView.NextL();
+		if (!TheView.Unevaluated())
+			break;
+		Evaluate();
+		}
+	}
+
+LOCAL_C void CheckWindowL(TInt forward,TInt back)
+	{
+	TInt ii;
+	for (ii=0;ii<forward;++ii)
+		test(TheView.NextL());
+	test(!TheView.NextL());
+	for (ii=0;ii<forward+back+1;++ii)
+		test(TheView.PreviousL());
+	test(!TheView.PreviousL());
+	for (ii=0;ii<back+1;++ii)
+		test(TheView.NextL());
+	}
+
+/**
+@SYMTestCaseID          SYSLIB-DBMS-CT-0640
+@SYMTestCaseDesc        Tests for RDbView
+@SYMTestPriority        Medium
+@SYMTestActions         Tests for a restricted sized window
+@SYMTestExpectedResults Test must not fail
+@SYMREQ                 REQ0000
+*/
+LOCAL_C void TestRestrictedL()
+	{
+	test.Start(_L("	@SYMTestCaseID:SYSLIB-DBMS-CT-0640 Behaviour at start of set "));
+	test(TheView.Prepare(TheDatabase,KOrderQuery,KSingleSlotWindow)==KErrNone);
+	test(TheView.EvaluateAll()==KErrNone);
+	test(TheView.CountL()==1);
+	test(!TheView.Unevaluated());
+	test(TheView.NextL());
+	test(!TheView.Unevaluated());
+	TheView.GetL();
+	TInt id=TheView.ColInt(1);
+	test(!TheView.NextL());
+	test(TheView.Unevaluated());
+	Evaluate();
+	test(TheView.CountL()==1);
+	test(TheView.AtRow());
+	test(!TheView.PreviousL());
+	test(TheView.Unevaluated());
+	Evaluate();
+	test(TheView.CountL()==1);
+	test(TheView.AtRow());
+	TheView.GetL();
+	test(TheView.ColInt(1)==id);
+	test(!TheView.PreviousL());
+	test(TheView.Unevaluated());
+	Evaluate();
+	test(TheView.CountL()==1);
+	test(TheView.AtBeginning());
+	test(TheView.NextL());
+	TheView.GetL();
+	test(TheView.ColInt(1)==id);
+	test(!TheView.Unevaluated());
+	test.Next(_L("Behaviour at end of set"));
+	GotoEndL();
+	test(TheView.LastL());
+	test(!TheView.Unevaluated());
+	TheView.GetL();
+	id=TheView.ColInt(1);
+	test(!TheView.PreviousL());
+	test(TheView.Unevaluated());
+	Evaluate();
+	test(TheView.CountL()==1);
+	test(TheView.AtRow());
+	test(!TheView.NextL());
+	test(TheView.Unevaluated());
+	Evaluate();
+	test(TheView.CountL()==1);
+	test(TheView.AtRow());
+	TheView.GetL();
+	test(TheView.ColInt(1)==id);
+	test(!TheView.NextL());
+	test(TheView.Unevaluated());
+	Evaluate();
+	test(TheView.CountL()==1);
+	test(TheView.AtEnd());
+	test(TheView.PreviousL());
+	TheView.GetL();
+	test(TheView.ColInt(1)==id);
+	test(!TheView.Unevaluated());
+	TheView.Close();
+//
+	test.Next(_L("Forward and backwards slots"));
+	test(TheView.Prepare(TheDatabase,KOrderQuery,KSmallWindow)==KErrNone);
+	test(TheView.EvaluateAll()==KErrNone);
+	test(TheView.CountL()==5);
+	test(TheView.FirstL());
+	CheckWindowL(4,0);
+	test(TheView.NextL());
+	test(TheView.NextL());		// now on preferred slot (id=2)
+	test(!TheView.Unevaluated());
+	test(TheView.NextL());
+	test(TheView.Unevaluated());
+	Evaluate();
+	CheckWindowL(2,2);
+	test(TheView.LastL());		// id=5
+	Evaluate();
+	test(TheView.LastL());		// id=7
+	Evaluate();					// should now have last five rows
+	CheckWindowL(2,2);
+	test(TheView.LastL());		// id=9
+	Evaluate();					// no more rows
+	CheckWindowL(0,4);			// all behind us now
+	TheView.GetL();
+	test(TheView.ColInt(1)==9);
+	TheView.FirstL();			// id=5
+	Evaluate();
+	TheView.FirstL();			// id=3
+	Evaluate();
+	TheView.FirstL();			// id=1
+	Evaluate();
+	CheckWindowL(3,1);
+//
+	test.Next(_L("Bookmarks"));
+	TDbBookmark mark=TheView.Bookmark();
+	test(TheView.NextL());
+	test(TheView.NextL());
+	test(TheView.NextL());
+	Evaluate();
+	TRAPD(r,TheView.GotoL(mark));
+	test(r!=KErrNone);
+	TheView.FirstL();
+	Evaluate();
+	TRAP(r,TheView.GotoL(mark));
+	test(r==KErrNone);
+	test.Next(_L("Delete"));
+	test(TheView.FirstL());
+	TheView.GetL();
+	test(TheView.ColInt(1)==0);
+	TheView.DeleteL();
+	test(TheView.CountL()==4);
+	TheView.FirstL();
+	CheckWindowL(3,0);
+	test.Next(_L("Insert"));
+	TheView.InsertL();
+	TheView.SetColL(1,TInt(0));
+	TheView.PutL();
+	test(TheView.CountL()==4);
+	TheView.FirstL();
+	TheView.GetL();
+	test(TheView.ColInt(1)==1);
+	TheView.Reset();
+	test(TheView.EvaluateAll()==KErrNone);
+	test(TheView.FirstL());
+	TheView.GetL();
+	test(TheView.ColInt(1)==0);
+//
+	test.End();
+	TheView.Close();
+	}
+
+LOCAL_C void TestL()
+	{
+	__UHEAP_MARK;
+	test.Start(_L("Setting up test table"));
+	TRAPD(r,InitL();)
+	test(r==KErrNone);
+	test.Next(_L("Empty Window"));
+	TRAP(r,TestEmptyL();)
+	test(r==KErrNone);
+	test.Next(_L("Unlimited Window"));
+	TRAP(r,TestUnlimitedL();)
+	test(r==KErrNone);
+	test.Next(_L("Sized window"));
+	TRAP(r,TestRestrictedL();)
+	test(r==KErrNone);
+	test.Next(_L("Cleanup"));
+	TRAP(r,CloseDatabaseL();)
+	test(r==KErrNone);
+	test.End();
+	__UHEAP_MARKEND;
+	}
+
+//
+// Prepare the test directory.
+//
+LOCAL_C void setupTestDirectory()
+    {
+	TInt r=TheFs.Connect();
+	test(r==KErrNone);
+//
+	r=TheFs.MkDir(KTestDir);
+	test(r==KErrNone || r==KErrAlreadyExists);
+	r=TheFs.SetSessionPath(KTestDir);
+	test(r==KErrNone);
+	}
+
+//
+// Initialise the cleanup stack.
+//
+LOCAL_C void setupCleanup()
+    {
+	TheTrapCleanup=CTrapCleanup::New();
+	test(TheTrapCleanup!=NULL);
+	TRAPD(r,\
+		{\
+		for (TInt i=KTestCleanupStack;i>0;i--)\
+			CleanupStack::PushL((TAny*)0);\
+		CleanupStack::Pop(KTestCleanupStack);\
+		});
+	test(r==KErrNone);
+	}
+
+LOCAL_C void DeleteDataFile(const TDesC& aFullName)
+	{
+	RFs fsSession;
+	TInt err = fsSession.Connect();
+	if(err == KErrNone)
+		{
+		TEntry entry;
+		if(fsSession.Entry(aFullName, entry) == KErrNone)
+			{
+			RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName);
+			err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
+			if(err != KErrNone)
+				{
+				RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
+				}
+			err = fsSession.Delete(aFullName);
+			if(err != KErrNone)
+				{
+				RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
+				}
+			}
+		fsSession.Close();
+		}
+	else
+		{
+		RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
+		}
+	}
+
+//
+// Test streaming conversions.
+//
+GLDEF_C TInt E32Main()
+    {
+	test.Title();
+	setupTestDirectory();
+	setupCleanup();
+//
+	test.Start(_L("TDbWindow - database test"));
+	TRAPD(err, TestL());
+	test(err == KErrNone);
+
+	//deletion of data files must be done before call to end - DEF047652
+	_LIT(KTestDbName, "C:\\DBMS-TST\\T_WINDOW.DB");
+	::DeleteDataFile(KTestDbName);
+	test.End();
+//
+
+	delete TheTrapCleanup;
+	TheFs.Close();
+	test.Close();
+	return 0;
+    }