persistentstorage/dbms/tdbms/t_dblimit.cpp
changeset 0 08ec8eefde2f
child 55 44f437012c90
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/dbms/tdbms/t_dblimit.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,311 @@
+// 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:
+//
+
+// MSVC++ up to 5.0 has problems with expanding inline functions
+// This disables the mad warnings for the whole project
+#if defined(NDEBUG) && defined(__VC32__) && _MSC_VER<=1100
+#pragma warning(disable : 4710)			// function not expanded. MSVC 5.0 is stupid
+#endif
+
+#include <d32dbms.h>
+#include <e32test.h>
+#include <s32file.h>
+
+LOCAL_D CTrapCleanup* TheTrapCleanup;
+LOCAL_D RFs TheFs;
+LOCAL_D RDbs TheDbs;
+LOCAL_D RDbNamedDatabase TheDatabase;
+LOCAL_D RDbTable TheTable;
+LOCAL_D RDbView TheView;
+
+const TInt KTestCleanupStack=0x20;
+const TPtrC KTestDatabase=_L("C:\\DBMS-TST\\T_LIMIT.DB");
+const TPtrC KTableName(_S("TestTable"));
+
+const TPtrC KColFormat=_L("c%d");
+
+LOCAL_D RTest test(_L("t_dblimit - testing table limits"));
+
+const TInt KRecordLimit=8200;
+const TInt KMinInlineLimit=16;
+const TInt KMaxInlineLimit=255;
+
+// expected maxima for record structure
+const TInt KMaxColInt64NN=1025;
+const TInt KMaxColText8=32;
+const TInt KMaxColText16=16;
+const TInt KMaxColLongText8=504;
+
+
+LOCAL_C TBool FitBlob(TInt aCount)
+//
+// Matches heuristics in DBMS
+//
+	{
+	TInt used=(aCount*(2+(KMinInlineLimit<<3))+7)>>3;
+	return used<=KRecordLimit;
+	}
+
+LOCAL_C TInt InlineLimit(TInt aCount)
+//
+// Matches heuristics in DBMS
+//
+	{
+	TInt used=(aCount*(2+(KMinInlineLimit<<3))+7)>>3;
+	TInt space=(KRecordLimit-used);//>>1;
+	TInt inl=space/aCount+KMinInlineLimit-1;
+	return Min(inl,KMaxInlineLimit);
+	}
+
+LOCAL_C void OpenDatabase()
+//
+// Open the database
+//
+	{
+	test (TheDatabase.Open(TheDbs,KTestDatabase)==KErrNone);
+	}
+
+LOCAL_C void CloseDatabase()
+	{
+	TheDatabase.Close();
+	}
+
+LOCAL_C void CreateDatabase()
+//
+// Create the database-in-a-store
+//
+	{
+	test (TheDatabase.Replace(TheFs,KTestDatabase)==KErrNone);
+	CloseDatabase();
+	OpenDatabase();
+	}
+
+LOCAL_C void DestroyDatabase()
+	{
+	test (TheDatabase.Destroy()==KErrNone);
+	}
+
+LOCAL_C CDbColSet* SetLC(TDbCol& aCol,TInt aCount)
+	{
+	CDbColSet* set=CDbColSet::NewLC();
+	TDbColName name;
+	while (--aCount>=0)
+		{
+		name.Format(KColFormat,aCount);
+		aCol.iName=name;
+		set->AddL(aCol);
+		}
+	return set;
+	}
+
+LOCAL_C TBool TestL(TDbCol& aCol,TInt aCount)
+	{
+	test.Printf(_L("\rtesting %d    "),aCount);
+	CDbColSet* set=SetLC(aCol,aCount);
+	TInt r;
+	r=TheDatabase.CreateTable(KTableName,*set);
+	if (r==KErrNone)
+		{
+		CDbColSet* comp=TheDatabase.ColSetL(KTableName);
+		test (comp->Count()==aCount);
+		delete comp;
+		}
+	CleanupStack::PopAndDestroy();
+	if (r==KErrTooBig)
+		return EFalse;
+	test (r==KErrNone);
+	test (TheDatabase.DropTable(KTableName)==KErrNone);
+	return ETrue;
+	}
+
+/**
+See how many columns of this sort can be used
+
+@SYMTestCaseID          SYSLIB-DBMS-CT-0631
+@SYMTestCaseDesc        Tests for maximum limits on a Table
+@SYMTestPriority        Medium
+@SYMTestActions         Tests for creating a table with maximum number of columns
+@SYMTestExpectedResults Test must not fail
+@SYMREQ                 REQ0000
+*/
+LOCAL_C TInt TestTypeL(TDbCol& aCol)
+	{
+	CreateDatabase();
+	TInt ii=1;
+	for (;;)
+		{
+		if (!TestL(aCol,ii))
+			break;
+		ii<<=1;
+		}
+	TInt lim=ii>>=1;
+	test (lim>0);
+	while ((ii>>=1)>0)
+		{	// ok<=max<ok+ii*2
+		if (TestL(aCol,lim+ii))
+			lim+=ii;
+		}
+	DestroyDatabase();
+	test.Printf(_L("\r   create %d     \n"),lim);
+	return lim;
+	}
+
+LOCAL_C void StretchRecordL()
+	{
+	CreateDatabase();
+	TDbCol col;
+	col.iType=EDbColLongText8;
+	col.iMaxLength=KDbUndefinedLength;
+	col.iAttributes=0;
+	for (TInt ii=4;FitBlob(ii);ii+=4)
+		{
+		test.Printf(_L("\rtesting %d    "),ii);
+		CDbColSet* set=SetLC(col,ii);
+		if (ii==4)
+			test (TheDatabase.CreateTable(KTableName,*set)==KErrNone);
+		else
+			test (TheDatabase.AlterTable(KTableName,*set)==KErrNone);
+		CleanupStack::PopAndDestroy();
+		test (TheTable.Open(TheDatabase,KTableName)==KErrNone);
+		if (ii==4)
+			TheTable.InsertL();
+		else
+			{
+			TheTable.FirstL();
+			TheTable.UpdateL();
+			}
+		TBuf8<256> buf;
+		buf.Fill('-',InlineLimit(ii)/*>>1*/);
+		TPtrC8 ptr((const TUint8*)buf.Ptr(),buf.Size());
+		TheTable.SetColL(ii-3,ptr);
+		TheTable.SetColL(ii-2,ptr);
+		TheTable.SetColL(ii-1,ptr);
+		TheTable.SetColL(ii,ptr);
+		TheTable.PutL();
+		TheTable.Close();
+//		if ((ii&0x1c)==0)
+//			test (TheDatabase.Compact()==KErrNone);
+		}
+	test (TheDatabase.Compact()==KErrNone);
+	test.Printf(_L("\n"));
+	CloseDatabase();
+	}
+
+LOCAL_C void doMainL()
+	{
+	test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0631 TInt64 NOT NULL "));
+	TDbCol col;
+	col.iType=EDbColInt64;
+	col.iMaxLength=KDbUndefinedLength;
+	col.iAttributes=TDbCol::ENotNull;
+	test (TestTypeL(col)==KMaxColInt64NN);
+	test.Next(_L("Text8"));
+	col.iType=EDbColText8;
+	col.iAttributes=0;
+	test (TestTypeL(col)==KMaxColText8);
+	test.Next(_L("Text16"));
+	col.iType=EDbColText16;
+	test (TestTypeL(col)==KMaxColText16);
+	test.Next(_L("LongText8"));
+	col.iType=EDbColLongText8;
+	test (TestTypeL(col)==KMaxColLongText8);
+	test.Next(_L("Stretching the record"));
+	StretchRecordL();
+	}
+
+LOCAL_C void setupTestDirectory()
+//
+// Prepare the test directory.
+//
+    {
+	TInt r=TheFs.Connect();
+	test(r==KErrNone);
+//
+	r=TheFs.MkDir(KTestDatabase);
+	test(r==KErrNone || r==KErrAlreadyExists);
+	}
+
+LOCAL_C void setupCleanup()
+//
+// Initialise the cleanup stack.
+//
+    {
+	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);
+		}
+	}
+
+GLDEF_C TInt E32Main()
+//
+// Test streaming conversions.
+//
+    {
+	test.Title();
+	setupTestDirectory();
+	setupCleanup();
+	test (TheDbs.Connect()==KErrNone);
+	__UHEAP_MARK;
+//
+	TRAPD(r,doMainL();)
+	test(r==KErrNone);
+
+	::DeleteDataFile(KTestDatabase);	//deletion of data files must be done before call to end - DEF047652
+	test.End();
+//
+	__UHEAP_MARKEND;
+	delete TheTrapCleanup;
+
+
+
+	TheDbs.Close();
+	TheFs.Close();
+	test.Close();
+	return 0;
+    }