1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/dbms/tdbms/t_dbalter.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,697 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <d32dbms.h>
1.20 +#include <s32file.h>
1.21 +#include <e32test.h>
1.22 +
1.23 +LOCAL_D RTest test(_L("t_dbalter : Test AlterTable"));
1.24 +LOCAL_D CTrapCleanup* TheTrapCleanup;
1.25 +LOCAL_D CFileStore* TheStore;
1.26 +LOCAL_D RDbStoreDatabase TheDatabase;
1.27 +LOCAL_D RDbTable TheTable;
1.28 +LOCAL_D RFs TheFs;
1.29 +
1.30 +const TInt KTestCleanupStack=0x20;
1.31 +const TPtrC KTestDir=_L("C:\\DBMS-TST\\");
1.32 +const TPtrC KTestFile=_L("T_ALTER.DB");
1.33 +const TPtrC KTableName(_S("Table"));
1.34 +const TPtrC KTableName2(_S("Table2"));
1.35 +const TPtrC KIndexName(_S("Index"));
1.36 +
1.37 +TInt KRecords=100;
1.38 +
1.39 +const TUint KCol1Data=0;
1.40 +const TInt KCol2Data=2;
1.41 +const TPtrC KCol3Data=_L("three");
1.42 +const TUint8 _Col4Data[80]={4,4,4,4,0,0xff,2,2,1};
1.43 +const TPtrC8 KCol4Data(_Col4Data,sizeof(_Col4Data));
1.44 +const TUint KCol5Data=1;
1.45 +const TInt KCol6Data=5;
1.46 +const TPtrC KCol7Data=_L("six");
1.47 +const TPtrC KCol8Data=_L("column number eight = #8");
1.48 +const TUint8 _Col9Data[400]={1,2,3,4,5,6,7,8,9,10};
1.49 +const TPtrC8 KCol9Data(_Col9Data,sizeof(_Col9Data));
1.50 +
1.51 +const TText* const KColumn1=_S("c1");
1.52 +const TText* const KColumn2=_S("c2");
1.53 +const TText* const KColumn3=_S("c3");
1.54 +const TText* const KColumn4=_S("c4");
1.55 +const TText* const KColumn5=_S("c5");
1.56 +const TText* const KColumn6=_S("c6");
1.57 +const TText* const KColumn7=_S("c7");
1.58 +const TText* const KColumn8=_S("c8");
1.59 +const TText* const KColumn9=_S("c9");
1.60 +const TText* const KColumn10=_S("c10");
1.61 +const TText* const KColumn11=_S("c11");
1.62 +const TPtrC KColumns[]=
1.63 + {
1.64 + KColumn1,
1.65 + KColumn2,
1.66 + KColumn3,
1.67 + KColumn4,
1.68 + KColumn5,
1.69 + KColumn6,
1.70 + KColumn7,
1.71 + KColumn8,
1.72 + KColumn9
1.73 + };
1.74 +
1.75 +class Set
1.76 + {
1.77 +public:
1.78 + struct SColDef
1.79 + {
1.80 + const TText* iName;
1.81 + TDbColType iType;
1.82 + TInt iAttributes;
1.83 + TInt iMaxLength;
1.84 + };
1.85 + static SColDef const Basic[];
1.86 + static SColDef const Bad[];
1.87 + static SColDef const Incompatible1[];
1.88 + static SColDef const Incompatible2[];
1.89 + static SColDef const Incompatible3[];
1.90 + static SColDef const Different[];
1.91 + static SColDef const Extended[];
1.92 + static SColDef const LongerText[];
1.93 + static SColDef const TextToLongText[];
1.94 + static SColDef const Column3[];
1.95 + static SColDef const DropSome[];
1.96 + static SColDef const DropAndAdd[];
1.97 +public:
1.98 + static CDbColSet* CreateL(const SColDef* aDef);
1.99 + };
1.100 +// the basic column definition
1.101 +enum TCol {EBit,EInt,EText,ELong,EBitNull,EIntNull,ETextNull,ELongNull,EExtra};
1.102 +Set::SColDef const Set::Basic[]=
1.103 + {
1.104 + {KColumn1,EDbColBit,TDbCol::ENotNull,-1},
1.105 + {KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
1.106 + {KColumn3,EDbColText,TDbCol::ENotNull,-1},
1.107 + {KColumn4,EDbColLongBinary,TDbCol::ENotNull,-1},
1.108 + {KColumn5,EDbColBit,0,-1},
1.109 + {KColumn6,EDbColInt32,0,-1},
1.110 + {KColumn7,EDbColText,0,-1},
1.111 + {KColumn8,EDbColText,0,50},
1.112 + {0}
1.113 + };
1.114 +// a basically invalid set
1.115 +Set::SColDef const Set::Bad[]=
1.116 + {
1.117 + {KColumn9,EDbColInt32,0,-1},
1.118 + {KColumn9,EDbColInt32,0,-1},
1.119 + {0}
1.120 + };
1.121 +// an incompatible set with Basic
1.122 +Set::SColDef const Set::Incompatible1[]=
1.123 + {
1.124 + {KColumn1,EDbColInt32,TDbCol::ENotNull,-1}, // retype a column
1.125 + {0}
1.126 + };
1.127 +Set::SColDef const Set::Incompatible2[]=
1.128 + {
1.129 + {KColumn5,EDbColBit,TDbCol::ENotNull,-1}, // change attributes
1.130 + {0}
1.131 + };
1.132 +Set::SColDef const Set::Incompatible3[]=
1.133 + {
1.134 + {KColumn8,EDbColText,0,49}, // shrink a text column
1.135 + {0}
1.136 + };
1.137 +// a wildly different set
1.138 +Set::SColDef const Set::Different[]=
1.139 + {
1.140 + {KColumn11,EDbColInt32,0,-1},
1.141 + {KColumn4,EDbColLongBinary,TDbCol::ENotNull,-1},
1.142 + {KColumn10,EDbColBit,TDbCol::ENotNull,-1},
1.143 + {KColumn3,EDbColText,TDbCol::ENotNull,-1},
1.144 + {0}
1.145 + };
1.146 +// basic + 1 column
1.147 +Set::SColDef const Set::Extended[]=
1.148 + {
1.149 + {KColumn1,EDbColBit,TDbCol::ENotNull,-1},
1.150 + {KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
1.151 + {KColumn3,EDbColText,TDbCol::ENotNull,-1},
1.152 + {KColumn4,EDbColLongBinary,TDbCol::ENotNull,-1},
1.153 + {KColumn5,EDbColBit,0,-1},
1.154 + {KColumn6,EDbColInt32,0,-1},
1.155 + {KColumn7,EDbColText,0,-1},
1.156 + {KColumn8,EDbColText,0,50},
1.157 + {KColumn9,EDbColLongBinary,0,-1}, // add this column
1.158 + {0}
1.159 + };
1.160 +// Extended with a longer text column
1.161 +Set::SColDef const Set::LongerText[]=
1.162 + {
1.163 + {KColumn1,EDbColBit,TDbCol::ENotNull,-1},
1.164 + {KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
1.165 + {KColumn3,EDbColText,TDbCol::ENotNull,-1},
1.166 + {KColumn4,EDbColLongBinary,TDbCol::ENotNull,-1},
1.167 + {KColumn5,EDbColBit,0,-1},
1.168 + {KColumn6,EDbColInt32,0,-1},
1.169 + {KColumn7,EDbColText,0,-1},
1.170 + {KColumn8,EDbColText,0,51}, // longer definition
1.171 + {KColumn9,EDbColLongBinary,0,-1},
1.172 + {0}
1.173 + };
1.174 +// Extended with a text->LongText column
1.175 +Set::SColDef const Set::TextToLongText[]=
1.176 + {
1.177 + {KColumn1,EDbColBit,TDbCol::ENotNull,-1},
1.178 + {KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
1.179 + {KColumn3,EDbColText,TDbCol::ENotNull,-1},
1.180 + {KColumn4,EDbColLongBinary,TDbCol::ENotNull,-1},
1.181 + {KColumn5,EDbColBit,0,-1},
1.182 + {KColumn6,EDbColInt32,0,-1},
1.183 + {KColumn7,EDbColText,0,-1},
1.184 + {KColumn8,EDbColLongText,0,-1}, // longer still
1.185 + {KColumn9,EDbColLongBinary,0,-1},
1.186 + {0}
1.187 + };
1.188 +Set::SColDef const Set::Column3[]=
1.189 + {
1.190 + {KColumn3,EDbColText,TDbCol::ENotNull,-1},
1.191 + {0}
1.192 + };
1.193 +Set::SColDef const Set::DropSome[]=
1.194 + {
1.195 + {KColumn1,EDbColBit,TDbCol::ENotNull,-1},
1.196 + {KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
1.197 + {KColumn6,EDbColInt32,0,-1},
1.198 + {KColumn7,EDbColText,0,-1},
1.199 + {0}
1.200 + };
1.201 +Set::SColDef const Set::DropAndAdd[]=
1.202 + {
1.203 + {KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
1.204 + {KColumn7,EDbColText,0,-1},
1.205 + {KColumn10,EDbColBinary,0,-1},
1.206 + {0}
1.207 + };
1.208 +
1.209 +CDbColSet* Set::CreateL(const SColDef* aDef)
1.210 + {
1.211 + CDbColSet *set=CDbColSet::NewLC();
1.212 + for (;aDef->iName;++aDef)
1.213 + {
1.214 + TDbCol col(TPtrC(aDef->iName),aDef->iType);
1.215 + col.iAttributes=aDef->iAttributes;
1.216 + if (aDef->iMaxLength>=0)
1.217 + col.iMaxLength=aDef->iMaxLength;
1.218 + set->AddL(col);
1.219 + }
1.220 + CleanupStack::Pop();
1.221 + return set;
1.222 + }
1.223 +
1.224 +//
1.225 +// Create the database-in-a-store
1.226 +//
1.227 +LOCAL_C void CreateDatabaseL()
1.228 + {
1.229 + CFileStore* store=CPermanentFileStore::ReplaceLC(TheFs,KTestFile,EFileRead|EFileWrite);
1.230 + store->SetTypeL(KPermanentFileStoreLayoutUid);
1.231 + TStreamId id;
1.232 + id=TheDatabase.CreateL(store);
1.233 + store->SetRootL(id);
1.234 + store->CommitL();
1.235 + CleanupStack::Pop();
1.236 + TheStore=store;
1.237 + }
1.238 +
1.239 +//
1.240 +// Open the database-in-a-store
1.241 +//
1.242 +LOCAL_C void OpenDatabaseL()
1.243 + {
1.244 + CFileStore* store=CFileStore::OpenLC(TheFs,KTestFile,EFileRead|EFileWrite);
1.245 + TStreamId id=store->Root();
1.246 + TheDatabase.OpenL(store,id);
1.247 + CleanupStack::Pop();
1.248 + TheStore=store;
1.249 + }
1.250 +
1.251 +LOCAL_C void CloseDatabaseL()
1.252 + {
1.253 + TheDatabase.Close();
1.254 + delete TheStore;
1.255 + }
1.256 +
1.257 +LOCAL_C void DestroyDatabaseL()
1.258 + {
1.259 + TheDatabase.Destroy();
1.260 + TheStore->CommitL();
1.261 + delete TheStore;
1.262 + }
1.263 +
1.264 +LOCAL_C CDbColSet* TableDefinitionL(const TDesC& aTable)
1.265 + {
1.266 + RDbTable table;
1.267 + test(table.Open(TheDatabase,aTable,table.EReadOnly)==KErrNone);
1.268 + CDbColSet* cs=table.ColSetL();
1.269 + table.Close();
1.270 + return cs;
1.271 + }
1.272 +
1.273 +//
1.274 +// Compare two column sets
1.275 +//
1.276 +LOCAL_C void Compare(const CDbColSet& aLeft,const CDbColSet& aRight)
1.277 + {
1.278 + test(aLeft.Count()==aRight.Count());
1.279 + for (TDbColSetIter iter(aLeft);iter;++iter)
1.280 + {
1.281 + const TDbCol* pRight=aRight.Col(iter->iName);
1.282 + test(pRight!=NULL);
1.283 + test(iter->iType==pRight->iType);
1.284 + test(iter->iMaxLength==KDbUndefinedLength || pRight->iMaxLength==KDbUndefinedLength || iter->iMaxLength==pRight->iMaxLength);
1.285 + test((iter->iAttributes&pRight->iAttributes)==iter->iAttributes);
1.286 + }
1.287 + }
1.288 +
1.289 +/**
1.290 +@SYMTestCaseID SYSLIB-DBMS-CT-0575
1.291 +@SYMTestCaseDesc Store database test
1.292 + Test for altering the table with different column definitions
1.293 +@SYMTestPriority Medium
1.294 +@SYMTestActions Test for RDbStoreDatabase::AlterTable(),RDbStoreDatabase::DropIndex()
1.295 +@SYMTestExpectedResults Test must not fail
1.296 +@SYMREQ REQ0000
1.297 +*/
1.298 +LOCAL_C void TestEmptyTableL()
1.299 + {
1.300 + test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0575 Create table "));
1.301 + CreateDatabaseL();
1.302 + CDbColSet* set=Set::CreateL(Set::Basic);
1.303 + test(TheDatabase.CreateTable(KTableName,*set)==KErrNone);
1.304 + test.Next(_L("Alter non existant table"));
1.305 + test(TheDatabase.AlterTable(KTableName2,*set)==KErrNotFound);
1.306 + delete set;
1.307 +//
1.308 + test.Next(_L("Alter to bad definitions"));
1.309 + set=Set::CreateL(Set::Bad);
1.310 + test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
1.311 + delete set;
1.312 + set=Set::CreateL(Set::Incompatible1);
1.313 + test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
1.314 + delete set;
1.315 + set=Set::CreateL(Set::Incompatible2);
1.316 + test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
1.317 + delete set;
1.318 + set=Set::CreateL(Set::Incompatible3);
1.319 + test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
1.320 + delete set;
1.321 +//
1.322 + test.Next(_L("Drop an indexed column"));
1.323 + CDbKey* key=CDbKey::NewLC();
1.324 + key->AddL(TPtrC(KColumn2));
1.325 + key->MakeUnique();
1.326 + test(TheDatabase.CreateIndex(KIndexName,KTableName,*key)==KErrNone);
1.327 + CleanupStack::PopAndDestroy();
1.328 + set=TableDefinitionL(KTableName);
1.329 + set->Remove(TPtrC(KColumn2));
1.330 + test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
1.331 + test(TheDatabase.DropIndex(KIndexName,KTableName)==KErrNone);
1.332 + delete set;
1.333 +//
1.334 + test.Next(_L("Extend an indexed text column"));
1.335 + set=Set::CreateL(Set::Extended);
1.336 + test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
1.337 + delete set;
1.338 + key=CDbKey::NewLC();
1.339 + key->AddL(TPtrC(KColumn8));
1.340 + key->MakeUnique();
1.341 + test(TheDatabase.CreateIndex(KIndexName,KTableName,*key)==KErrNone);
1.342 + CleanupStack::PopAndDestroy();
1.343 + set=Set::CreateL(Set::LongerText);
1.344 + test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
1.345 + test(TheDatabase.DropIndex(KIndexName,KTableName)==KErrNone);
1.346 +//
1.347 + test.Next(_L("Extend a text column"));
1.348 + test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
1.349 + delete set;
1.350 +//
1.351 + test.Next(_L("Extend a text column to a LongText column"));
1.352 + set=Set::CreateL(Set::TextToLongText);
1.353 + test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
1.354 + delete set;
1.355 +//
1.356 + test.Next(_L("Alter to a very different set"));
1.357 + set=Set::CreateL(Set::Different);
1.358 + test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
1.359 + CloseDatabaseL();
1.360 + OpenDatabaseL();
1.361 + CDbColSet* def=TableDefinitionL(KTableName);
1.362 + Compare(*set,*def);
1.363 + delete def;
1.364 + delete set;
1.365 + test.End();
1.366 + test(TheDatabase.DropTable(KTableName)==KErrNone);
1.367 + DestroyDatabaseL();
1.368 + }
1.369 +
1.370 +class Map
1.371 + {
1.372 +public:
1.373 + Map();
1.374 + void Init(RDbRowSet& aSet);
1.375 + inline TDbColNo operator[](TInt aCol) const
1.376 + {return iMap[aCol];}
1.377 +private:
1.378 + TDbColNo iMap[EExtra+1];
1.379 + };
1.380 +
1.381 +Map::Map()
1.382 + {
1.383 + }
1.384 +
1.385 +void Map::Init(RDbRowSet& aSet)
1.386 + {
1.387 + CDbColSet* set=NULL;
1.388 + TRAPD(errCode, set=aSet.ColSetL());
1.389 + if(errCode != KErrNone)
1.390 + {
1.391 + return;
1.392 + }
1.393 + for (TInt ii=EBit;ii<=EExtra;++ii)
1.394 + iMap[ii]=set->ColNo(KColumns[ii]);
1.395 + if(set)
1.396 + delete set;
1.397 + }
1.398 +
1.399 +//
1.400 +// Build the table for Altering
1.401 +//
1.402 +LOCAL_C void BuildTableL(const Set::SColDef* aDef=Set::Basic)
1.403 + {
1.404 + CDbColSet* set=Set::CreateL(aDef);
1.405 + test(TheDatabase.CreateTable(KTableName,*set)==KErrNone);
1.406 + delete set;
1.407 + TheDatabase.Begin();
1.408 + test(TheTable.Open(TheDatabase,KTableName,TheTable.EInsertOnly)==KErrNone);
1.409 + Map map;
1.410 + map.Init(TheTable);
1.411 + for (TInt ii=0;ii<KRecords;++ii)
1.412 + {
1.413 + TheTable.InsertL();
1.414 + TheTable.SetColL(map[EBit],KCol1Data);
1.415 + TheTable.SetColL(map[EInt],KCol2Data);
1.416 + TheTable.SetColL(map[EText],KCol3Data);
1.417 + TheTable.SetColL(map[ELong],KCol4Data);
1.418 + if ((ii%EBitNull)==0)
1.419 + TheTable.SetColL(map[EBitNull],KCol5Data);
1.420 + if ((ii%EIntNull)==0)
1.421 + TheTable.SetColL(map[EIntNull],KCol6Data);
1.422 + if ((ii%ETextNull)==0)
1.423 + TheTable.SetColL(map[ETextNull],KCol7Data);
1.424 + if ((ii%ELongNull)==0)
1.425 + TheTable.SetColL(map[ELongNull],KCol8Data);
1.426 + if (map[EExtra] && (ii%EExtra)==0)
1.427 + TheTable.SetColL(map[EExtra],KCol9Data);
1.428 + TheTable.PutL();
1.429 + }
1.430 + TheTable.Close();
1.431 + test(TheDatabase.Commit()==KErrNone);
1.432 + }
1.433 +
1.434 +LOCAL_C void CheckBlobL(TDbColNo aCol,const TDesC8& aData)
1.435 + {
1.436 + test(TheTable.ColSize(aCol)==aData.Size());
1.437 + TBuf8<500> buf;
1.438 + __ASSERT_DEBUG(buf.MaxLength()>=aData.Length(),User::Invariant());
1.439 + RDbColReadStream str;
1.440 + str.OpenLC(TheTable,aCol);
1.441 + str.ReadL(buf,aData.Length());
1.442 + CleanupStack::PopAndDestroy();
1.443 + test(buf==aData);
1.444 + }
1.445 +
1.446 +#if defined(UNICODE)
1.447 +LOCAL_C void CheckBlobL(TDbColNo aCol,const TDesC16& aData)
1.448 + {
1.449 + test(TheTable.ColSize(aCol)==aData.Size());
1.450 + TBuf16<500> buf;
1.451 + __ASSERT_DEBUG(buf.MaxLength()>=aData.Length(),User::Invariant());
1.452 + RDbColReadStream str;
1.453 + str.OpenLC(TheTable,aCol);
1.454 + str.ReadL(buf,aData.Length());
1.455 + CleanupStack::PopAndDestroy();
1.456 + test(buf==aData);
1.457 + }
1.458 +#endif
1.459 +
1.460 +//
1.461 +// Check that the columns which still exist, still contain the same stuff
1.462 +// New columns should be Null
1.463 +//
1.464 +LOCAL_C void CheckTableL()
1.465 + {
1.466 + test(TheTable.Open(TheDatabase,KTableName,TheTable.EReadOnly)==KErrNone);
1.467 + Map map;
1.468 + map.Init(TheTable);
1.469 +
1.470 + for (TInt ii=0;ii<KRecords;++ii)
1.471 + {
1.472 + test(TheTable.NextL());
1.473 + TheTable.GetL();
1.474 + if (map[EBit])
1.475 + test(TheTable.ColUint(map[EBit])==KCol1Data);
1.476 + if (map[EInt])
1.477 + test(TheTable.ColInt(map[EInt])==KCol2Data);
1.478 + if (map[EText])
1.479 + test(TheTable.ColDes(map[EText])==KCol3Data);
1.480 + if (map[ELong])
1.481 + CheckBlobL(map[ELong],KCol4Data);
1.482 + for (TInt jj=EBitNull;jj<=EExtra;++jj)
1.483 + {
1.484 + if (!map[jj])
1.485 + continue;
1.486 + if (ii%jj)
1.487 + test(TheTable.IsColNull(map[jj]));
1.488 + else
1.489 + {
1.490 + switch (jj)
1.491 + {
1.492 + case EBitNull:
1.493 + test(TheTable.ColUint(map[EBitNull])==KCol5Data);
1.494 + break;
1.495 + case EIntNull:
1.496 + test(TheTable.ColInt(map[EIntNull])==KCol6Data);
1.497 + break;
1.498 + case ETextNull:
1.499 + test(TheTable.ColDes(map[ETextNull])==KCol7Data);
1.500 + break;
1.501 + case ELongNull:
1.502 + CheckBlobL(map[ELongNull],KCol8Data);
1.503 + break;
1.504 + case EExtra:
1.505 + CheckBlobL(map[EExtra],KCol9Data);
1.506 + break;
1.507 + }
1.508 + }
1.509 + }
1.510 + }
1.511 + TheTable.Close();
1.512 + }
1.513 +
1.514 +/**
1.515 +@SYMTestCaseID SYSLIB-DBMS-CT-0576
1.516 +@SYMTestCaseDesc Test a full table
1.517 +@SYMTestPriority Medium
1.518 +@SYMTestActions Tests for altering the table
1.519 +@SYMTestExpectedResults Test must not fail
1.520 +@SYMREQ REQ0000
1.521 +*/
1.522 +LOCAL_C void TestFullTableL()
1.523 + {
1.524 + test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0576 Create database "));
1.525 + CreateDatabaseL();
1.526 +//
1.527 + test.Next(_L("Add non-null column"));
1.528 + BuildTableL();
1.529 + CDbColSet* set=TableDefinitionL(KTableName);
1.530 + TDbCol col10=TDbCol(TPtrC(KColumn10),EDbColInt32);
1.531 + col10.iAttributes=TDbCol::ENotNull;
1.532 + set->AddL(col10);
1.533 + test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
1.534 +//
1.535 + test.Next(_L("Add nullable column"));
1.536 + set->Remove(col10.iName);
1.537 + col10.iAttributes=0;
1.538 + set->AddL(col10);
1.539 + test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
1.540 + CheckTableL();
1.541 +//
1.542 + test.Next(_L("Drop columns one by one"));
1.543 + while (set->Count()>1)
1.544 + {
1.545 + set->Remove((*set)[1].iName);
1.546 + test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
1.547 + CheckTableL();
1.548 + }
1.549 + delete set;
1.550 + test(TheDatabase.DropTable(KTableName)==KErrNone);
1.551 +//
1.552 + test.Next(_L("Extend a text column"));
1.553 + BuildTableL(Set::Extended);
1.554 + set=Set::CreateL(Set::LongerText);
1.555 + test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
1.556 + delete set;
1.557 + CheckTableL();
1.558 +//
1.559 + test.Next(_L("Extend it to a LongText column"));
1.560 + set=Set::CreateL(Set::TextToLongText);
1.561 + test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
1.562 + delete set;
1.563 + CheckTableL();
1.564 +//
1.565 + test.Next(_L("Drop all except one"));
1.566 + set=Set::CreateL(Set::Column3);
1.567 + test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
1.568 + delete set;
1.569 + CheckTableL();
1.570 + test(TheDatabase.DropTable(KTableName)==KErrNone);
1.571 + test.Next(_L("Drop single column"));
1.572 + for (TInt ii=EBit;ii<=EExtra;++ii)
1.573 + {
1.574 + BuildTableL(Set::Extended);
1.575 + CDbColSet* set=TableDefinitionL(KTableName);
1.576 + set->Remove(KColumns[ii]);
1.577 + test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
1.578 + delete set;
1.579 + CheckTableL();
1.580 + test(TheDatabase.DropTable(KTableName)==KErrNone);
1.581 + }
1.582 + test.Next(_L("Drop multiple columns"));
1.583 + BuildTableL();
1.584 + set=Set::CreateL(Set::DropSome);
1.585 + test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
1.586 + delete set;
1.587 + CheckTableL();
1.588 + test.Next(_L("Drop and add together"));
1.589 + set=Set::CreateL(Set::DropAndAdd);
1.590 + test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
1.591 + delete set;
1.592 + CheckTableL();
1.593 + test(TheDatabase.DropTable(KTableName)==KErrNone);
1.594 + test.End();
1.595 + DestroyDatabaseL();
1.596 + }
1.597 +
1.598 +LOCAL_C void Test()
1.599 + {
1.600 + __UHEAP_MARK;
1.601 +//
1.602 + test.Start(_L("Alter empty table"));
1.603 + TRAPD(r,TestEmptyTableL();)
1.604 + test(r==KErrNone);
1.605 + __UHEAP_CHECK(0);
1.606 + test.Next(_L("Alter full table"));
1.607 + TRAP(r,TestFullTableL();)
1.608 + test(r==KErrNone);
1.609 + test.End();
1.610 +//
1.611 + __UHEAP_MARKEND;
1.612 + }
1.613 +
1.614 +//
1.615 +// Prepare the test directory.
1.616 +//
1.617 +LOCAL_C void setupTestDirectory()
1.618 + {
1.619 + TInt r=TheFs.Connect();
1.620 + test(r==KErrNone);
1.621 +//
1.622 + r=TheFs.MkDir(KTestDir);
1.623 + test(r==KErrNone || r==KErrAlreadyExists);
1.624 + r=TheFs.SetSessionPath(KTestDir);
1.625 + test(r==KErrNone);
1.626 + }
1.627 +
1.628 +//
1.629 +// Initialise the cleanup stack.
1.630 +//
1.631 +LOCAL_C void setupCleanup()
1.632 + {
1.633 + TheTrapCleanup=CTrapCleanup::New();
1.634 + test(TheTrapCleanup!=NULL);
1.635 + TRAPD(r,\
1.636 + {\
1.637 + for (TInt i=KTestCleanupStack;i>0;i--)\
1.638 + CleanupStack::PushL((TAny*)0);\
1.639 + CleanupStack::Pop(KTestCleanupStack);\
1.640 + });
1.641 + test(r==KErrNone);
1.642 + }
1.643 +
1.644 +LOCAL_C void DeleteDataFile(const TDesC& aFullName)
1.645 + {
1.646 + RFs fsSession;
1.647 + TInt err = fsSession.Connect();
1.648 + if(err == KErrNone)
1.649 + {
1.650 + TEntry entry;
1.651 + if(fsSession.Entry(aFullName, entry) == KErrNone)
1.652 + {
1.653 + RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName);
1.654 + err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
1.655 + if(err != KErrNone)
1.656 + {
1.657 + RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
1.658 + }
1.659 + err = fsSession.Delete(aFullName);
1.660 + if(err != KErrNone)
1.661 + {
1.662 + RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
1.663 + }
1.664 + }
1.665 + fsSession.Close();
1.666 + }
1.667 + else
1.668 + {
1.669 + RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
1.670 + }
1.671 + }
1.672 +
1.673 +//
1.674 +// Test streaming conversions.
1.675 +//
1.676 +GLDEF_C TInt E32Main()
1.677 + {
1.678 + test.Title();
1.679 + setupTestDirectory();
1.680 + setupCleanup();
1.681 + __UHEAP_MARK;
1.682 +//
1.683 + test.Start(_L("Standard database"));
1.684 + Test();
1.685 + test.Next(_L("Secure database"));
1.686 + Test();
1.687 +
1.688 + // clean up data files used by this test - must be done before call to End() - DEF047652
1.689 + _LIT(KTestDbName, "C:\\DBMS-TST\\T_ALTER.DB");
1.690 + ::DeleteDataFile(KTestDbName);
1.691 +
1.692 + test.End();
1.693 +//
1.694 + __UHEAP_MARKEND;
1.695 + delete TheTrapCleanup;
1.696 +
1.697 + TheFs.Close();
1.698 + test.Close();
1.699 + return 0;
1.700 + }