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