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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
24 #undef __UHEAP_MARKEND
25 #define __UHEAP_MARKEND
27 #define __UHEAP_CHECK(a)
29 LOCAL_D TDBMS_CRCChecks TheCrcChecker;
31 #ifndef __linux__ //No CRC test on LINUX
33 const TPtrC KCrcRecord=_L("\\epoc32\\winscw\\c\\dbms-tst\\T_ALTER.CRC");
35 const TPtrC KCrcRecord=_L("C:\\dbms-tst\\T_ALTER.CRC");
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;
46 const TInt KTestCleanupStack=0x20;
49 const TPtrC KTestDir=_L(".\\dbms-tst\\");
51 const TPtrC KTestDir=_L("C:\\dbms-tst\\");
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"));
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));
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[]=
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[];
120 static CDbColSet* CreateL(const SColDef* aDef);
122 // the basic column definition
123 enum TCol {EBit,EInt,EText,ELong,EBitNull,EIntNull,ETextNull,ELongNull,EExtra};
124 Set::SColDef const Set::Basic[]=
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},
136 // a basically invalid set
137 Set::SColDef const Set::Bad[]=
139 {KColumn9,EDbColInt32,0,-1},
140 {KColumn9,EDbColInt32,0,-1},
143 // an incompatible set with Basic
144 Set::SColDef const Set::Incompatible1[]=
146 {KColumn1,EDbColInt32,TDbCol::ENotNull,-1}, // retype a column
149 Set::SColDef const Set::Incompatible2[]=
151 {KColumn5,EDbColBit,TDbCol::ENotNull,-1}, // change attributes
154 Set::SColDef const Set::Incompatible3[]=
156 {KColumn8,EDbColText,0,49}, // shrink a text column
159 // a wildly different set
160 Set::SColDef const Set::Different[]=
162 {KColumn11,EDbColInt32,0,-1},
163 {KColumn4,EDbColLongBinary,TDbCol::ENotNull,-1},
164 {KColumn10,EDbColBit,TDbCol::ENotNull,-1},
165 {KColumn3,EDbColText,TDbCol::ENotNull,-1},
169 Set::SColDef const Set::Extended[]=
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
182 // Extended with a longer text column
183 Set::SColDef const Set::LongerText[]=
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},
196 // Extended with a text->LongText column
197 Set::SColDef const Set::TextToLongText[]=
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},
210 Set::SColDef const Set::Column3[]=
212 {KColumn3,EDbColText,TDbCol::ENotNull,-1},
215 Set::SColDef const Set::DropSome[]=
217 {KColumn1,EDbColBit,TDbCol::ENotNull,-1},
218 {KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
219 {KColumn6,EDbColInt32,0,-1},
220 {KColumn7,EDbColText,0,-1},
223 Set::SColDef const Set::DropAndAdd[]=
225 {KColumn2,EDbColInt32,TDbCol::ENotNull,-1},
226 {KColumn7,EDbColText,0,-1},
227 {KColumn10,EDbColBinary,0,-1},
231 CDbColSet* Set::CreateL(const SColDef* aDef)
233 CDbColSet *set=CDbColSet::NewLC();
234 for (;aDef->iName;++aDef)
236 TDbCol col(TPtrC(aDef->iName),aDef->iType);
237 col.iAttributes=aDef->iAttributes;
238 if (aDef->iMaxLength>=0)
239 col.iMaxLength=aDef->iMaxLength;
247 // Create the database-in-a-store
249 LOCAL_C void CreateDatabaseL()
251 CFileStore* store=CPermanentFileStore::ReplaceLC(TheFs,KTestFile,EFileRead|EFileWrite);
252 store->SetTypeL(KPermanentFileStoreLayoutUid);
254 id=TheDatabase.CreateL(store);
262 // Open the database-in-a-store
264 LOCAL_C void OpenDatabaseL()
266 CFileStore* store=CFileStore::OpenLC(TheFs,KTestFile,EFileRead|EFileWrite);
267 TStreamId id=store->Root();
268 TheDatabase.OpenL(store,id);
273 LOCAL_C void CloseDatabaseL()
277 TInt err = TheCrcChecker.GenerateCrcL(KTestFile);
281 LOCAL_C void DestroyDatabaseL()
283 TheDatabase.Destroy();
286 TInt err = TheCrcChecker.GenerateCrcL(KTestFile);
290 LOCAL_C CDbColSet* TableDefinitionL(const TDesC& aTable)
293 test(table.Open(TheDatabase,aTable,table.EReadOnly)==KErrNone);
294 CDbColSet* cs=table.ColSetL();
300 // Compare two column sets
302 LOCAL_C void Compare(const CDbColSet& aLeft,const CDbColSet& aRight)
304 test(aLeft.Count()==aRight.Count());
305 for (TDbColSetIter iter(aLeft);iter;++iter)
307 const TDbCol* pRight=aRight.Col(iter->iName);
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);
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
324 LOCAL_C void TestEmptyTable()
326 test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0575 Create table "));
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);
334 test.Next(_L("Alter to bad definitions"));
335 set=Set::CreateL(Set::Bad);
336 test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
338 set=Set::CreateL(Set::Incompatible1);
339 test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
341 set=Set::CreateL(Set::Incompatible2);
342 test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
344 set=Set::CreateL(Set::Incompatible3);
345 test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
348 test.Next(_L("Drop an indexed column"));
349 CDbKey* key=CDbKey::NewLC();
350 key->AddL(TPtrC(KColumn2));
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);
360 test.Next(_L("Extend an indexed text column"));
361 set=Set::CreateL(Set::Extended);
362 test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
365 key->AddL(TPtrC(KColumn8));
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);
373 test.Next(_L("Extend a text column"));
374 test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
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);
382 test.Next(_L("Alter to a very different set"));
383 set=Set::CreateL(Set::Different);
384 test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
387 CDbColSet* def=TableDefinitionL(KTableName);
392 test(TheDatabase.DropTable(KTableName)==KErrNone);
400 void Init(RDbRowSet& aSet);
401 inline TDbColNo operator[](TInt aCol) const
404 TDbColNo iMap[EExtra+1];
411 void Map::Init(RDbRowSet& aSet)
414 TRAPD(errCode, set=aSet.ColSetL());
415 if(errCode != KErrNone)
419 for (TInt ii=EBit;ii<=EExtra;++ii)
420 iMap[ii]=set->ColNo(KColumns[ii]);
426 // Build the table for Altering
428 LOCAL_C void BuildTable(const Set::SColDef* aDef=Set::Basic)
430 CDbColSet* set=Set::CreateL(aDef);
431 test(TheDatabase.CreateTable(KTableName,*set)==KErrNone);
434 test(TheTable.Open(TheDatabase,KTableName,TheTable.EInsertOnly)==KErrNone);
437 for (TInt ii=0;ii<KRecords;++ii)
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);
457 test(TheDatabase.Commit()==KErrNone);
460 LOCAL_C void CheckBlob(TDbColNo aCol,const TDesC8& aData)
462 test(TheTable.ColSize(aCol)==aData.Size());
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();
473 LOCAL_C void CheckBlob(TDbColNo aCol,const TDesC16& aData)
475 test(TheTable.ColSize(aCol)==aData.Size());
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();
487 // Check that the columns which still exist, still contain the same stuff
488 // New columns should be Null
490 LOCAL_C void CheckTable()
492 test(TheTable.Open(TheDatabase,KTableName,TheTable.EReadOnly)==KErrNone);
496 for (TInt ii=0;ii<KRecords;++ii)
498 test(TheTable.NextL());
501 test(TheTable.ColUint(map[EBit])==KCol1Data);
503 test(TheTable.ColInt(map[EInt])==KCol2Data);
505 test(TheTable.ColDes(map[EText])==KCol3Data);
507 CheckBlob(map[ELong],KCol4Data);
508 for (TInt jj=EBitNull;jj<=EExtra;++jj)
513 test(TheTable.IsColNull(map[jj]));
519 test(TheTable.ColUint(map[EBitNull])==KCol5Data);
522 test(TheTable.ColInt(map[EIntNull])==KCol6Data);
525 test(TheTable.ColDes(map[ETextNull])==KCol7Data);
528 CheckBlob(map[ELongNull],KCol8Data);
531 CheckBlob(map[EExtra],KCol9Data);
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
548 LOCAL_C void TestFullTable()
550 test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0576 Create database "));
553 test.Next(_L("Add non-null column"));
555 CDbColSet* set=TableDefinitionL(KTableName);
556 TDbCol col10=TDbCol(TPtrC(KColumn10),EDbColInt32);
557 col10.iAttributes=TDbCol::ENotNull;
559 test(TheDatabase.AlterTable(KTableName,*set)!=KErrNone);
561 test.Next(_L("Add nullable column"));
562 set->Remove(col10.iName);
565 test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
568 test.Next(_L("Drop columns one by one"));
569 while (set->Count()>1)
571 set->Remove((*set)[1].iName);
572 test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
576 test(TheDatabase.DropTable(KTableName)==KErrNone);
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);
585 test.Next(_L("Extend it to a LongText column"));
586 set=Set::CreateL(Set::TextToLongText);
587 test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
591 test.Next(_L("Drop all except one"));
592 set=Set::CreateL(Set::Column3);
593 test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
596 test(TheDatabase.DropTable(KTableName)==KErrNone);
597 test.Next(_L("Drop single column"));
598 for (TInt ii=EBit;ii<=EExtra;++ii)
600 BuildTable(Set::Extended);
601 CDbColSet* set=TableDefinitionL(KTableName);
602 set->Remove(KColumns[ii]);
603 test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
606 test(TheDatabase.DropTable(KTableName)==KErrNone);
608 test.Next(_L("Drop multiple columns"));
610 set=Set::CreateL(Set::DropSome);
611 test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
614 test.Next(_L("Drop and add together"));
615 set=Set::CreateL(Set::DropAndAdd);
616 test(TheDatabase.AlterTable(KTableName,*set)==KErrNone);
619 test(TheDatabase.DropTable(KTableName)==KErrNone);
628 test.Start(_L("Alter empty table"));
629 TRAPD(r,TestEmptyTable();)
632 test.Next(_L("Alter full table"));
633 TRAP(r,TestFullTable();)
641 // Prepare the test directory.
643 LOCAL_C void setupTestDirectory()
645 TInt r=TheFs.Connect();
648 r=TheFs.MkDir(KTestDir);
649 test(r==KErrNone || r==KErrAlreadyExists);
650 r=TheFs.SetSessionPath(KTestDir);
652 // On TOOLS2 - RFs::SetSessionPath() will affect all RFs Sessions,
653 // the two RFs need same session path anyway
655 r=TheCrcChecker.SetSessionPath(KTestDir);
661 // Initialise the cleanup stack.
663 LOCAL_C void setupCleanup()
665 TheTrapCleanup=CTrapCleanup::New();
666 test(TheTrapCleanup!=NULL);
669 for (TInt i=KTestCleanupStack;i>0;i--)\
670 CleanupStack::PushL((TAny*)0);\
671 CleanupStack::Pop(KTestCleanupStack);\
676 LOCAL_C void DeleteDataFile(const TDesC& aFullName)
679 TInt err = fsSession.Connect();
683 if(fsSession.Entry(aFullName, entry) == KErrNone)
685 RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName);
686 err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
689 RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
691 err = fsSession.Delete(aFullName);
694 RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
701 RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
706 // Test streaming conversions.
708 GLDEF_C TInt E32Main()
711 setupTestDirectory();
715 test.Start(_L("Standard database"));
717 test.Next(_L("Secure database"));
720 // clean up data files used by this test - must be done before call to End() - DEF047652
722 _LIT(KTestDbName, "C:\\dbms-tst\\T_ALTER.DB");
724 _LIT(KTestDbName, "T_ALTER.DB");
726 ::DeleteDataFile(KTestDbName);
731 TRAPD(lc, err = TheCrcChecker.DumpCrcRecordsL(KCrcRecord));
735 TRAPD(lc, err = TheCrcChecker.ValidateCrcRecordsL(KCrcRecord));
737 TheCrcChecker.ErrorReportL(err, errmsg);
738 RDebug::Print(errmsg);
739 test(err==KErrNone || err==TDBMS_CRCChecks::ECrcCheckOk);
746 delete TheTrapCleanup;