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