|
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 } |