os/persistentdata/persistentstorage/dbms/pcdbms/tdbms/src/t_alter.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include <d32dbms.h>
    17 #include <s32file.h>
    18 #include <e32test.h>
    19 
    20 #include "crccheck.h"
    21 
    22 #undef __UHEAP_MARK
    23 #define __UHEAP_MARK
    24 #undef __UHEAP_MARKEND
    25 #define __UHEAP_MARKEND
    26 #undef __UHEAP_CHECK
    27 #define __UHEAP_CHECK(a)
    28 
    29 LOCAL_D TDBMS_CRCChecks TheCrcChecker;
    30 
    31 #ifndef __linux__ //No CRC test on LINUX
    32 #ifdef __TOOLS2__
    33 const TPtrC	KCrcRecord=_L("\\epoc32\\winscw\\c\\dbms-tst\\T_ALTER.CRC");
    34 #else
    35 const TPtrC	KCrcRecord=_L("C:\\dbms-tst\\T_ALTER.CRC");
    36 #endif
    37 #endif
    38 
    39 LOCAL_D RTest test(_L("T_ALTER : Test AlterTable"));
    40 LOCAL_D CTrapCleanup* TheTrapCleanup;
    41 LOCAL_D CFileStore* TheStore;
    42 LOCAL_D RDbStoreDatabase TheDatabase;
    43 LOCAL_D RDbTable TheTable;
    44 LOCAL_D RFs TheFs;
    45 
    46 const TInt KTestCleanupStack=0x20;
    47 
    48 #ifdef __TOOLS2__
    49 const TPtrC KTestDir=_L(".\\dbms-tst\\");
    50 #else
    51 const TPtrC KTestDir=_L("C:\\dbms-tst\\");
    52 #endif
    53 
    54 const TPtrC KTestFile=_L("T_ALTER.DB");
    55 const TPtrC KTableName(_S("Table"));
    56 const TPtrC KTableName2(_S("Table2"));
    57 const TPtrC KIndexName(_S("Index"));
    58 
    59 TInt KRecords=100;
    60 
    61 const TUint KCol1Data=0;
    62 const TInt KCol2Data=2;
    63 const TPtrC KCol3Data=_L("three");
    64 const TUint8 _Col4Data[80]={4,4,4,4,0,0xff,2,2,1};
    65 const TPtrC8 KCol4Data(_Col4Data,sizeof(_Col4Data));
    66 const TUint KCol5Data=1;
    67 const TInt KCol6Data=5;
    68 const TPtrC KCol7Data=_L("six");
    69 const TPtrC KCol8Data=_L("column number eight = #8");
    70 const TUint8 _Col9Data[400]={1,2,3,4,5,6,7,8,9,10};
    71 const TPtrC8 KCol9Data(_Col9Data,sizeof(_Col9Data));
    72 
    73 const TText* const KColumn1=_S("c1");
    74 const TText* const KColumn2=_S("c2");
    75 const TText* const KColumn3=_S("c3");
    76 const TText* const KColumn4=_S("c4");
    77 const TText* const KColumn5=_S("c5");
    78 const TText* const KColumn6=_S("c6");
    79 const TText* const KColumn7=_S("c7");
    80 const TText* const KColumn8=_S("c8");
    81 const TText* const KColumn9=_S("c9");
    82 const TText* const KColumn10=_S("c10");
    83 const TText* const KColumn11=_S("c11");
    84 const TPtrC KColumns[]=
    85 	{
    86 	KColumn1,
    87 	KColumn2,
    88 	KColumn3,
    89 	KColumn4,
    90 	KColumn5,
    91 	KColumn6,
    92 	KColumn7,
    93 	KColumn8,
    94 	KColumn9
    95 	};
    96 
    97 class Set
    98 	{
    99 public:
   100 	struct SColDef
   101 		{
   102 		const TText* iName;
   103 		TDbColType iType;
   104 		TInt iAttributes;
   105 		TInt iMaxLength;
   106 		};
   107 	static SColDef const Basic[];
   108 	static SColDef const Bad[];
   109 	static SColDef const Incompatible1[];
   110 	static SColDef const Incompatible2[];
   111 	static SColDef const Incompatible3[];
   112 	static SColDef const Different[];
   113 	static SColDef const Extended[];
   114 	static SColDef const LongerText[];
   115 	static SColDef const TextToLongText[];
   116 	static SColDef const Column3[];
   117 	static SColDef const DropSome[];
   118 	static SColDef const DropAndAdd[];
   119 public:
   120 	static CDbColSet* CreateL(const SColDef* aDef);
   121 	};
   122 // the basic column definition
   123 enum TCol {EBit,EInt,EText,ELong,EBitNull,EIntNull,ETextNull,ELongNull,EExtra};
   124 Set::SColDef const Set::Basic[]=
   125 	{
   126 	{KColumn1,EDbColBit,TDbCol::ENotNull,-1},
   127 	{KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
   128 	{KColumn3,EDbColText,TDbCol::ENotNull,-1},
   129 	{KColumn4,EDbColLongBinary,TDbCol::ENotNull,-1},
   130 	{KColumn5,EDbColBit,0,-1},
   131 	{KColumn6,EDbColInt32,0,-1},
   132 	{KColumn7,EDbColText,0,-1},
   133 	{KColumn8,EDbColText,0,50},
   134 	{0}
   135 	};
   136 // a basically invalid set
   137 Set::SColDef const Set::Bad[]=
   138 	{
   139 	{KColumn9,EDbColInt32,0,-1},
   140 	{KColumn9,EDbColInt32,0,-1},
   141 	{0}
   142 	};
   143 // an incompatible set with Basic
   144 Set::SColDef const Set::Incompatible1[]=
   145 	{
   146 	{KColumn1,EDbColInt32,TDbCol::ENotNull,-1},	// retype a column
   147 	{0}
   148 	};
   149 Set::SColDef const Set::Incompatible2[]=
   150 	{
   151 	{KColumn5,EDbColBit,TDbCol::ENotNull,-1},	// change attributes
   152 	{0}
   153 	};
   154 Set::SColDef const Set::Incompatible3[]=
   155 	{
   156 	{KColumn8,EDbColText,0,49},	// shrink a text column
   157 	{0}
   158 	};
   159 // a wildly different set
   160 Set::SColDef const Set::Different[]=
   161 	{
   162 	{KColumn11,EDbColInt32,0,-1},
   163 	{KColumn4,EDbColLongBinary,TDbCol::ENotNull,-1},
   164 	{KColumn10,EDbColBit,TDbCol::ENotNull,-1},
   165 	{KColumn3,EDbColText,TDbCol::ENotNull,-1},
   166 	{0}
   167 	};
   168 // basic + 1 column
   169 Set::SColDef const Set::Extended[]=
   170 	{
   171 	{KColumn1,EDbColBit,TDbCol::ENotNull,-1},
   172 	{KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
   173 	{KColumn3,EDbColText,TDbCol::ENotNull,-1},
   174 	{KColumn4,EDbColLongBinary,TDbCol::ENotNull,-1},
   175 	{KColumn5,EDbColBit,0,-1},
   176 	{KColumn6,EDbColInt32,0,-1},
   177 	{KColumn7,EDbColText,0,-1},
   178 	{KColumn8,EDbColText,0,50},
   179 	{KColumn9,EDbColLongBinary,0,-1},		// add this column
   180 	{0}
   181 	};
   182 // Extended with a longer text column
   183 Set::SColDef const Set::LongerText[]=
   184 	{
   185 	{KColumn1,EDbColBit,TDbCol::ENotNull,-1},
   186 	{KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
   187 	{KColumn3,EDbColText,TDbCol::ENotNull,-1},
   188 	{KColumn4,EDbColLongBinary,TDbCol::ENotNull,-1},
   189 	{KColumn5,EDbColBit,0,-1},
   190 	{KColumn6,EDbColInt32,0,-1},
   191 	{KColumn7,EDbColText,0,-1},
   192 	{KColumn8,EDbColText,0,51},			// longer definition
   193 	{KColumn9,EDbColLongBinary,0,-1},
   194 	{0}
   195 	};
   196 // Extended with a text->LongText column
   197 Set::SColDef const Set::TextToLongText[]=
   198 	{
   199 	{KColumn1,EDbColBit,TDbCol::ENotNull,-1},
   200 	{KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
   201 	{KColumn3,EDbColText,TDbCol::ENotNull,-1},
   202 	{KColumn4,EDbColLongBinary,TDbCol::ENotNull,-1},
   203 	{KColumn5,EDbColBit,0,-1},
   204 	{KColumn6,EDbColInt32,0,-1},
   205 	{KColumn7,EDbColText,0,-1},
   206 	{KColumn8,EDbColLongText,0,-1},		// longer still
   207 	{KColumn9,EDbColLongBinary,0,-1},
   208 	{0}
   209 	};
   210 Set::SColDef const Set::Column3[]=
   211 	{
   212 	{KColumn3,EDbColText,TDbCol::ENotNull,-1},
   213 	{0}
   214 	};
   215 Set::SColDef const Set::DropSome[]=
   216 	{
   217 	{KColumn1,EDbColBit,TDbCol::ENotNull,-1},
   218 	{KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
   219 	{KColumn6,EDbColInt32,0,-1},
   220 	{KColumn7,EDbColText,0,-1},
   221 	{0}
   222 	};
   223 Set::SColDef const Set::DropAndAdd[]=
   224 	{
   225 	{KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
   226 	{KColumn7,EDbColText,0,-1},
   227 	{KColumn10,EDbColBinary,0,-1},
   228 	{0}
   229 	};
   230 
   231 CDbColSet* Set::CreateL(const SColDef* aDef)
   232 	{
   233 	CDbColSet *set=CDbColSet::NewLC();
   234 	for (;aDef->iName;++aDef)
   235 		{
   236 		TDbCol col(TPtrC(aDef->iName),aDef->iType);
   237 		col.iAttributes=aDef->iAttributes;
   238 		if (aDef->iMaxLength>=0)
   239 			col.iMaxLength=aDef->iMaxLength;
   240 		set->AddL(col);
   241 		}
   242 	CleanupStack::Pop();
   243 	return set;
   244 	}
   245 
   246 //
   247 // Create the database-in-a-store
   248 //
   249 LOCAL_C void CreateDatabaseL()
   250 	{
   251 	CFileStore* store=CPermanentFileStore::ReplaceLC(TheFs,KTestFile,EFileRead|EFileWrite);
   252 	store->SetTypeL(KPermanentFileStoreLayoutUid);
   253 	TStreamId id;
   254 	    id=TheDatabase.CreateL(store);
   255 	store->SetRootL(id);
   256 	store->CommitL();
   257 	CleanupStack::Pop();
   258 	TheStore=store;
   259 	}
   260 
   261 //
   262 // Open the database-in-a-store
   263 //
   264 LOCAL_C void OpenDatabaseL()
   265 	{
   266 	CFileStore* store=CFileStore::OpenLC(TheFs,KTestFile,EFileRead|EFileWrite);
   267 	TStreamId id=store->Root();
   268 	    TheDatabase.OpenL(store,id);
   269 	CleanupStack::Pop();
   270 	TheStore=store;
   271 	}
   272 
   273 LOCAL_C void CloseDatabaseL()
   274 	{
   275 	TheDatabase.Close();
   276 	delete TheStore;
   277 	TInt err = TheCrcChecker.GenerateCrcL(KTestFile);
   278 	test(err==KErrNone);
   279 	}
   280 
   281 LOCAL_C void DestroyDatabaseL()
   282 	{
   283 	TheDatabase.Destroy();
   284 	TheStore->CommitL();
   285 	delete TheStore;
   286 	TInt err = TheCrcChecker.GenerateCrcL(KTestFile);
   287 	test(err==KErrNone);
   288 	}
   289 
   290 LOCAL_C CDbColSet* TableDefinitionL(const TDesC& aTable)
   291 	{
   292 	RDbTable table;
   293 	test(table.Open(TheDatabase,aTable,table.EReadOnly)==KErrNone);
   294 	CDbColSet* cs=table.ColSetL();
   295 	table.Close();
   296 	return cs;
   297 	}
   298 
   299 //
   300 // Compare two column sets
   301 //
   302 LOCAL_C void Compare(const CDbColSet& aLeft,const CDbColSet& aRight)
   303 	{
   304 	test(aLeft.Count()==aRight.Count());
   305 	for (TDbColSetIter iter(aLeft);iter;++iter)
   306 		{
   307 		const TDbCol* pRight=aRight.Col(iter->iName);
   308 		test(pRight!=NULL);
   309 		test(iter->iType==pRight->iType);
   310 		test(iter->iMaxLength==KDbUndefinedLength || pRight->iMaxLength==KDbUndefinedLength || iter->iMaxLength==pRight->iMaxLength);
   311 		test((iter->iAttributes&pRight->iAttributes)==iter->iAttributes);
   312 		}
   313 	}
   314 
   315 /**
   316 @SYMTestCaseID          SYSLIB-DBMS-CT-0575
   317 @SYMTestCaseDesc        Store database test 
   318                         Test for altering the table with different column definitions  
   319 @SYMTestPriority        Medium
   320 @SYMTestActions        	Test for RDbStoreDatabase::AlterTable(),RDbStoreDatabase::DropIndex()
   321 @SYMTestExpectedResults Test must not fail
   322 @SYMREQ                 REQ0000
   323 */
   324 LOCAL_C void TestEmptyTable()
   325 	{
   326 	test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0575 Create table "));
   327 	CreateDatabaseL();
   328 	CDbColSet* set=Set::CreateL(Set::Basic);
   329 	test(TheDatabase.CreateTable(KTableName,*set)==KErrNone);
   330 	test.Next(_L("Alter non existant table"));
   331 	test(TheDatabase.AlterTable(KTableName2,*set)==KErrNotFound);
   332 	delete set;
   333 //
   334 	test.Next(_L("Alter to bad definitions"));
   335 	set=Set::CreateL(Set::Bad);
   336 	test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
   337 	delete set;
   338 	set=Set::CreateL(Set::Incompatible1);
   339 	test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
   340 	delete set;
   341 	set=Set::CreateL(Set::Incompatible2);
   342 	test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
   343 	delete set;
   344 	set=Set::CreateL(Set::Incompatible3);
   345 	test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
   346 	delete set;
   347 //
   348 	test.Next(_L("Drop an indexed column"));
   349 	CDbKey* key=CDbKey::NewLC();
   350 	key->AddL(TPtrC(KColumn2));
   351 	key->MakeUnique();
   352 	test(TheDatabase.CreateIndex(KIndexName,KTableName,*key)==KErrNone);
   353 	CleanupStack::PopAndDestroy();
   354 	set=TableDefinitionL(KTableName);
   355 	set->Remove(TPtrC(KColumn2));
   356 	test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
   357 	test(TheDatabase.DropIndex(KIndexName,KTableName)==KErrNone);
   358 	delete set;
   359 //
   360 	test.Next(_L("Extend an indexed text column"));
   361 	set=Set::CreateL(Set::Extended);
   362 	test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
   363 	delete set;
   364 	key=CDbKey::NewLC();
   365 	key->AddL(TPtrC(KColumn8));
   366 	key->MakeUnique();
   367 	test(TheDatabase.CreateIndex(KIndexName,KTableName,*key)==KErrNone);
   368 	CleanupStack::PopAndDestroy();
   369 	set=Set::CreateL(Set::LongerText);
   370 	test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
   371 	test(TheDatabase.DropIndex(KIndexName,KTableName)==KErrNone);
   372 //
   373 	test.Next(_L("Extend a text column"));
   374 	test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
   375 	delete set;
   376 //
   377 	test.Next(_L("Extend a text column to a LongText column"));
   378 	set=Set::CreateL(Set::TextToLongText);
   379 	test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
   380 	delete set;
   381 //
   382 	test.Next(_L("Alter to a very different set"));
   383 	set=Set::CreateL(Set::Different);
   384 	test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
   385 	CloseDatabaseL();
   386 	OpenDatabaseL();
   387 	CDbColSet* def=TableDefinitionL(KTableName);
   388 	Compare(*set,*def);
   389 	delete def;
   390 	delete set;
   391 	test.End();
   392 	test(TheDatabase.DropTable(KTableName)==KErrNone);
   393 	DestroyDatabaseL();
   394 	}
   395 
   396 class Map
   397 	{
   398 public:
   399 	Map();
   400 	void Init(RDbRowSet& aSet);
   401 	inline TDbColNo operator[](TInt aCol) const
   402 		{return iMap[aCol];}
   403 private:
   404 	TDbColNo iMap[EExtra+1];
   405 	};
   406 
   407 Map::Map()
   408 	{
   409 	}
   410 
   411 void Map::Init(RDbRowSet& aSet)
   412 	{
   413 	CDbColSet* set=NULL;
   414 	TRAPD(errCode, set=aSet.ColSetL());
   415 	if(errCode != KErrNone)
   416 		{
   417 		return;
   418 		}
   419 	for (TInt ii=EBit;ii<=EExtra;++ii)
   420 		iMap[ii]=set->ColNo(KColumns[ii]);
   421 	if(set)
   422 		delete set;
   423 	}
   424 
   425 //
   426 // Build the table for Altering
   427 //
   428 LOCAL_C void BuildTable(const Set::SColDef* aDef=Set::Basic)
   429 	{
   430 	CDbColSet* set=Set::CreateL(aDef);
   431 	test(TheDatabase.CreateTable(KTableName,*set)==KErrNone);
   432 	delete set;
   433 	TheDatabase.Begin();
   434 	test(TheTable.Open(TheDatabase,KTableName,TheTable.EInsertOnly)==KErrNone);
   435 	Map map;
   436 	map.Init(TheTable);
   437 	for (TInt ii=0;ii<KRecords;++ii)
   438 		{
   439 		TheTable.InsertL();
   440 		TheTable.SetColL(map[EBit],KCol1Data);
   441 		TheTable.SetColL(map[EInt],KCol2Data);
   442 		TheTable.SetColL(map[EText],KCol3Data);
   443 		TheTable.SetColL(map[ELong],KCol4Data);
   444 		if ((ii%EBitNull)==0)
   445 			TheTable.SetColL(map[EBitNull],KCol5Data);
   446 		if ((ii%EIntNull)==0)
   447 			TheTable.SetColL(map[EIntNull],KCol6Data);
   448 		if ((ii%ETextNull)==0)
   449 			TheTable.SetColL(map[ETextNull],KCol7Data);
   450 		if ((ii%ELongNull)==0)
   451 			TheTable.SetColL(map[ELongNull],KCol8Data);
   452 		if (map[EExtra] && (ii%EExtra)==0)
   453 			TheTable.SetColL(map[EExtra],KCol9Data);
   454 		TheTable.PutL();
   455 		}
   456 	TheTable.Close();
   457 	test(TheDatabase.Commit()==KErrNone);
   458 	}
   459 
   460 LOCAL_C void CheckBlob(TDbColNo aCol,const TDesC8& aData)
   461 	{
   462 	test(TheTable.ColSize(aCol)==aData.Size());
   463 	TBuf8<500> buf;
   464 	__ASSERT_DEBUG(buf.MaxLength()>=aData.Length(),User::Invariant());
   465 	RDbColReadStream str;
   466 	str.OpenLC(TheTable,aCol);
   467 	str.ReadL(buf,aData.Length());
   468 	CleanupStack::PopAndDestroy();
   469 	test(buf==aData);
   470 	}
   471 
   472 #if defined(UNICODE)
   473 LOCAL_C void CheckBlob(TDbColNo aCol,const TDesC16& aData)
   474 	{
   475 	test(TheTable.ColSize(aCol)==aData.Size());
   476 	TBuf16<500> buf;
   477 	__ASSERT_DEBUG(buf.MaxLength()>=aData.Length(),User::Invariant());
   478 	RDbColReadStream str;
   479 	str.OpenLC(TheTable,aCol);
   480 	str.ReadL(buf,aData.Length());
   481 	CleanupStack::PopAndDestroy();
   482 	test(buf==aData);
   483 	}
   484 #endif
   485 
   486 //
   487 // Check that the columns which still exist, still contain the same stuff
   488 // New columns should be Null
   489 //
   490 LOCAL_C void CheckTable()
   491 	{
   492 	test(TheTable.Open(TheDatabase,KTableName,TheTable.EReadOnly)==KErrNone);
   493 	Map map;
   494 	map.Init(TheTable);
   495 
   496 	for (TInt ii=0;ii<KRecords;++ii)
   497 		{
   498 		test(TheTable.NextL());
   499 		TheTable.GetL();
   500 		if (map[EBit])
   501 			test(TheTable.ColUint(map[EBit])==KCol1Data);
   502 		if (map[EInt])
   503 			test(TheTable.ColInt(map[EInt])==KCol2Data);
   504 		if (map[EText])
   505 			test(TheTable.ColDes(map[EText])==KCol3Data);
   506 		if (map[ELong])
   507 			CheckBlob(map[ELong],KCol4Data);
   508 		for (TInt jj=EBitNull;jj<=EExtra;++jj)
   509 			{
   510 			if (!map[jj])
   511 				continue;
   512 			if (ii%jj)
   513 				test(TheTable.IsColNull(map[jj]));
   514 			else
   515 				{
   516 				switch (jj)
   517 					{
   518 				case EBitNull:
   519 					test(TheTable.ColUint(map[EBitNull])==KCol5Data);
   520 					break;
   521 				case EIntNull:
   522 					test(TheTable.ColInt(map[EIntNull])==KCol6Data);
   523 					break;
   524 				case ETextNull:
   525 					test(TheTable.ColDes(map[ETextNull])==KCol7Data);
   526 					break;
   527 				case ELongNull:
   528 					CheckBlob(map[ELongNull],KCol8Data);
   529 					break;
   530 				case EExtra:
   531 					CheckBlob(map[EExtra],KCol9Data);
   532 					break;
   533 					}
   534 				}
   535 			}
   536 		}
   537 	TheTable.Close();
   538 	}
   539 
   540 /**
   541 @SYMTestCaseID          SYSLIB-DBMS-CT-0576
   542 @SYMTestCaseDesc        Test a full table
   543 @SYMTestPriority        Medium
   544 @SYMTestActions        	Tests for altering the table 
   545 @SYMTestExpectedResults Test must not fail
   546 @SYMREQ                 REQ0000
   547 */
   548 LOCAL_C void TestFullTable()
   549 	{
   550 	test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0576 Create database "));
   551 	CreateDatabaseL();
   552 //
   553 	test.Next(_L("Add non-null column"));
   554 	BuildTable();
   555 	CDbColSet* set=TableDefinitionL(KTableName);
   556 	TDbCol col10=TDbCol(TPtrC(KColumn10),EDbColInt32);
   557 	col10.iAttributes=TDbCol::ENotNull;
   558 	set->AddL(col10);
   559 	test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
   560 //
   561 	test.Next(_L("Add nullable column"));
   562 	set->Remove(col10.iName);
   563 	col10.iAttributes=0;
   564 	set->AddL(col10);
   565 	test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
   566 	CheckTable();
   567 //
   568 	test.Next(_L("Drop columns one by one"));
   569 	while (set->Count()>1)
   570 		{
   571 		set->Remove((*set)[1].iName);
   572 		test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
   573 		CheckTable();
   574 		}
   575 	delete set;
   576 	test(TheDatabase.DropTable(KTableName)==KErrNone);
   577 //
   578 	test.Next(_L("Extend a text column"));
   579 	BuildTable(Set::Extended);
   580 	set=Set::CreateL(Set::LongerText);
   581 	test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
   582 	delete set;
   583 	CheckTable();
   584 //
   585 	test.Next(_L("Extend it to a LongText column"));
   586 	set=Set::CreateL(Set::TextToLongText);
   587 	test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
   588 	delete set;
   589 	CheckTable();
   590 //
   591 	test.Next(_L("Drop all except one"));
   592 	set=Set::CreateL(Set::Column3);
   593 	test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
   594 	delete set;
   595 	CheckTable();
   596 	test(TheDatabase.DropTable(KTableName)==KErrNone);
   597 	test.Next(_L("Drop single column"));
   598 	for (TInt ii=EBit;ii<=EExtra;++ii)
   599 		{
   600 		BuildTable(Set::Extended);
   601 		CDbColSet* set=TableDefinitionL(KTableName);
   602 		set->Remove(KColumns[ii]);
   603 		test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
   604 		delete set;
   605 		CheckTable();
   606 		test(TheDatabase.DropTable(KTableName)==KErrNone);
   607 		}
   608 	test.Next(_L("Drop multiple columns"));
   609 	BuildTable();
   610 	set=Set::CreateL(Set::DropSome);
   611 	test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
   612 	delete set;
   613 	CheckTable();
   614 	test.Next(_L("Drop and add together"));
   615 	set=Set::CreateL(Set::DropAndAdd);
   616 	test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
   617 	delete set;
   618 	CheckTable();
   619 	test(TheDatabase.DropTable(KTableName)==KErrNone);
   620 	test.End();
   621 	DestroyDatabaseL();
   622 	}
   623 
   624 LOCAL_C void Test()
   625 	{
   626 	__UHEAP_MARK;
   627 //
   628 	test.Start(_L("Alter empty table"));
   629 	TRAPD(r,TestEmptyTable();)
   630 	test(r==KErrNone);
   631 	__UHEAP_CHECK(0);
   632 	test.Next(_L("Alter full table"));
   633 	TRAP(r,TestFullTable();)
   634 	test(r==KErrNone);
   635 	test.End();
   636 //
   637 	__UHEAP_MARKEND;
   638 	}
   639 
   640 //
   641 // Prepare the test directory.
   642 //
   643 LOCAL_C void setupTestDirectory()
   644     {
   645 	TInt r=TheFs.Connect();
   646 	test(r==KErrNone);
   647 //
   648 	r=TheFs.MkDir(KTestDir);
   649 	test(r==KErrNone || r==KErrAlreadyExists);
   650 	r=TheFs.SetSessionPath(KTestDir);
   651 	test(r==KErrNone);
   652 // On TOOLS2 - RFs::SetSessionPath() will affect all RFs Sessions, 
   653 // the two RFs need same session path anyway
   654 #ifdef __WINSCW__ 
   655 	r=TheCrcChecker.SetSessionPath(KTestDir);
   656 	test(r==KErrNone);
   657 #endif
   658 	}
   659 
   660 //
   661 // Initialise the cleanup stack.
   662 //
   663 LOCAL_C void setupCleanup()
   664     {
   665 	TheTrapCleanup=CTrapCleanup::New();
   666 	test(TheTrapCleanup!=NULL);
   667 	TRAPD(r,\
   668 		{\
   669 		for (TInt i=KTestCleanupStack;i>0;i--)\
   670 			CleanupStack::PushL((TAny*)0);\
   671 		CleanupStack::Pop(KTestCleanupStack);\
   672 		});
   673 	test(r==KErrNone);
   674 	}
   675 
   676 LOCAL_C void DeleteDataFile(const TDesC& aFullName)
   677 	{
   678 	RFs fsSession;
   679 	TInt err = fsSession.Connect();
   680 	if(err == KErrNone)
   681 		{
   682 		TEntry entry;
   683 		if(fsSession.Entry(aFullName, entry) == KErrNone)
   684 			{
   685 			RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName);
   686 			err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
   687 			if(err != KErrNone) 
   688 				{
   689 				RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
   690 				}
   691 			err = fsSession.Delete(aFullName);
   692 			if(err != KErrNone) 
   693 				{
   694 				RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
   695 				}
   696 			}
   697 		fsSession.Close();
   698 		}
   699 	else
   700 		{
   701 		RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
   702 		}
   703 	}
   704 
   705 //
   706 // Test streaming conversions.
   707 //
   708 GLDEF_C TInt E32Main()
   709     {
   710 	test.Title();
   711 	setupTestDirectory();
   712 	setupCleanup();
   713 	__UHEAP_MARK;
   714 
   715 	test.Start(_L("Standard database"));
   716 	Test();
   717 	test.Next(_L("Secure database"));
   718 	Test();
   719 	
   720 	// clean up data files used by this test - must be done before call to End() - DEF047652
   721 #ifndef __TOOLS2__
   722 	_LIT(KTestDbName, "C:\\dbms-tst\\T_ALTER.DB");
   723 #else
   724 	_LIT(KTestDbName, "T_ALTER.DB");
   725 #endif
   726 	::DeleteDataFile(KTestDbName);
   727 
   728 #ifndef __linux__
   729 	TInt err;
   730 #ifndef __TOOLS2__
   731 	TRAPD(lc, err = TheCrcChecker.DumpCrcRecordsL(KCrcRecord));
   732 	test(err==KErrNone);
   733 	test(lc==KErrNone);
   734 #else
   735 	TRAPD(lc, err = TheCrcChecker.ValidateCrcRecordsL(KCrcRecord));
   736 	TPtrC errmsg;
   737 	TheCrcChecker.ErrorReportL(err, errmsg);
   738 	RDebug::Print(errmsg);
   739 	test(err==KErrNone || err==TDBMS_CRCChecks::ECrcCheckOk);
   740 #endif // TOOLS2
   741 #endif // linux
   742 	
   743 	test.End();
   744 
   745 	__UHEAP_MARKEND;
   746 	delete TheTrapCleanup;
   747 
   748 	TheFs.Close();
   749 	test.Close();
   750 	return 0;
   751     }