1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/dbms/pcdbms/tdbms/src/t_defect.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1349 @@
1.4 +// Copyright (c) 2004-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 <e32math.h>
1.21 +#include <e32test.h>
1.22 +#include <f32file.h>
1.23 +#include <s32buf.h>
1.24 +
1.25 +#include "crccheck.h"
1.26 +
1.27 +#undef __UHEAP_MARK
1.28 +#undef __UHEAP_MARKEND
1.29 +#define __UHEAP_MARK
1.30 +#define __UHEAP_MARKEND
1.31 +
1.32 +LOCAL_D TDBMS_CRCChecks TheCrcChecker;
1.33 +
1.34 +#ifndef __linux__ //No CRC test on LINUX
1.35 +#ifdef __TOOLS2__
1.36 +const TPtrC KCrcRecord=_L("\\epoc32\\winscw\\c\\dbms-tst\\T_DEFECT.CRC");
1.37 +#else
1.38 +const TPtrC KCrcRecord=_L("C:\\dbms-tst\\T_DEFECT.CRC");
1.39 +#endif
1.40 +#endif
1.41 +
1.42 +
1.43 +LOCAL_D RTest TheTest (_L ("t_defect.exe"));
1.44 +LOCAL_D CTrapCleanup* TheTrapCleanup = NULL;
1.45 +#ifndef __TOOLS2__
1.46 +LOCAL_D RSemaphore TheWaitToStartSem;
1.47 +LOCAL_D RSemaphore TheWaitForThreadsReadySem;
1.48 +#endif
1.49 +LOCAL_D RFs TheFs;
1.50 +LOCAL_D RDbs TheDbs1, TheDbs2;
1.51 +LOCAL_D RDbNamedDatabase TheDb1, TheDb2;
1.52 +
1.53 +_LIT (KName, "ConnectTestThread_");
1.54 +_LIT (KStart, "Starting thread %x.\n");
1.55 +_LIT (KConnect, "Thread %x: Waiting to connect...\n");
1.56 +_LIT (KConSuccess, "Thread %x: Connection succeeded.\n");
1.57 +_LIT (KConFailed, "Thread %x: Connection failed. Error %d.\n");
1.58 +_LIT (KStatus, "Status of thread %x is %d.\n");
1.59 +
1.60 +
1.61 +_LIT(KTable, "TABLE");
1.62 +_LIT(KColName, "Fld");
1.63 +_LIT(KCol2Name, "Fld2");
1.64 +
1.65 +#ifndef __TOOLS2__
1.66 +const TPtrC KDbName=_L("C:\\dbms-tst\\TESTDB22.DB");
1.67 +#else
1.68 +const TPtrC KDbName=_L(".\\dbms-tst\\TESTDB22.DB");
1.69 +#endif
1.70 +
1.71 +_LIT(KSQLInsert1, "INSERT INTO TABLE (Fld, Fld2) VALUES ('ACDC\\','BLAH')");
1.72 +_LIT(KSQLInsert2, "INSERT INTO TABLE (Fld) VALUES ('ABCDEFGH')");
1.73 +_LIT(KSQLInsert3, "INSERT INTO TABLE (Fld) VALUES ('A?CDEFGH')");
1.74 +_LIT(KSQLInsert4, "INSERT INTO TABLE (Fld) VALUES ('A?*?CDEFGH')");
1.75 +_LIT(KSQLInsert5, "INSERT INTO TABLE (Fld) VALUES ('A*CDEFGH')");
1.76 +_LIT(KSQLInsert6, "INSERT INTO TABLE (Fld, Fld2) VALUES ('ADCDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOP','ADCB')");
1.77 +_LIT(KSQLInsert7, "INSERT INTO TABLE (Fld) VALUES ('XZD\\FZX')");
1.78 +
1.79 +_LIT(KSqlRequestGranularity, "SELECT Fld FROM test WHERE (Fld LIKE '1' AND Fld LIKE '2') AND Fld LIKE '3' AND Fld LIKE '4' AND Fld LIKE '5' AND Fld LIKE '6'");
1.80 +
1.81 +_LIT(KText16Name, "text16");
1.82 +_LIT(KTableName, "test");
1.83 +_LIT(KIndexName, "test_index");
1.84 +_LIT(KMaxStringFormat, "%0256d");
1.85 +
1.86 +void TestCleanup()
1.87 + {
1.88 + TheDb2.Close();
1.89 + TheDb1.Close();
1.90 +#ifndef __TOOLS2__
1.91 + TheDbs2.Close();
1.92 + TheDbs1.Close();
1.93 +#endif
1.94 + (void)TheFs.Delete(KDbName);
1.95 + TheFs.Close();
1.96 + TheCrcChecker.GenerateCrcL(KDbName);
1.97 + }
1.98 +
1.99 +//-----------------------------------------------------------------------------
1.100 +//
1.101 +// Test macros and functions.
1.102 +//
1.103 +//-----------------------------------------------------------------------------
1.104 +// If (!aValue) then the test will be panicked, the test data files will be
1.105 +// deleted.
1.106 +LOCAL_C void Check(TInt aValue, TInt aLine)
1.107 + {
1.108 + if(!aValue)
1.109 + {
1.110 + TestCleanup();
1.111 + TheTest(EFalse, aLine);
1.112 + }
1.113 + }
1.114 +
1.115 +
1.116 +// If (aValue != aExpected) then the test will be panicked, the test data files
1.117 +// will be deleted.
1.118 +LOCAL_C void Check(TInt aValue, TInt aExpected, TInt aLine)
1.119 + {
1.120 + if(aValue != aExpected)
1.121 + {
1.122 + RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
1.123 + TestCleanup();
1.124 + TheTest(EFalse, aLine);
1.125 + }
1.126 + }
1.127 +
1.128 +
1.129 +//Use these to test conditions.
1.130 +#define TEST(arg) ::Check((arg), __LINE__)
1.131 +#define TEST2(aValue, aExpected) ::Check((aValue), (aExpected), __LINE__)
1.132 +//-----------------------------------------------------------------------------
1.133 +//-----------------------------------------------------------------------------
1.134 +
1.135 +struct TTest
1.136 + {
1.137 + const TText* result;
1.138 + const TText* query;
1.139 + };
1.140 +
1.141 +const TTest KQuery[]=
1.142 + {
1.143 + {_S("ACDC\\"),_S("SELECT Fld FROM TABLE WHERE Fld LIKE 'ACDC\\' AND Fld2 LIKE '*BL*'")},
1.144 + {_S("A*CDEFGH"),_S("SELECT * FROM TABLE WHERE Fld LIKE '*A\\*C*' ESCAPE '\\'")},
1.145 + {_S("A?CDEFGH"),_S("SELECT * FROM TABLE WHERE Fld LIKE '*A\\?C*' ESCAPE '\\'")},
1.146 + {_S("A?*?CDEFGH"),_S("SELECT * FROM TABLE WHERE Fld LIKE '*A\\?\\*\\?C*' ESCAPE '\\'")},
1.147 + {_S("ADCDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOP"),_S("SELECT * FROM TABLE WHERE Fld LIKE '*1234*'")},
1.148 + {_S("BLAH"),_S("SELECT Fld2 FROM TABLE WHERE Fld LIKE '*AC*' AND Fld2 LIKE '?LA?'")},
1.149 + {_S("BLAH"),_S("SELECT Fld2 FROM TABLE WHERE Fld LIKE 'NOTINTABLE' OR Fld2 LIKE '?LA?'")},
1.150 + {_S("ADCDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOP"),_S("SELECT * FROM TABLE WHERE Fld LIKE '*ADC*' AND Fld2 LIKE 'ADC?'")},
1.151 + {_S("A*CDEFGH"),_S("SELECT Fld FROM TABLE WHERE Fld LIKE '*\\*C*' ESCAPE '\\'")},
1.152 + {_S("XZD\\FZX"),_S("SELECT Fld FROM TABLE WHERE Fld LIKE '*D\\\\*' ESCAPE '\\'")}
1.153 + };
1.154 +
1.155 +const TTest KBadQuery[]=
1.156 + {
1.157 + {_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE 'A?C' ESCAPE '\\'")},
1.158 + {_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE 'A*C' ESCAPE '\\'")},
1.159 + {_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE '?A\\?C' ESCAPE '\\'")},
1.160 + {_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE '?A\\?C?' ESCAPE '\\'")},
1.161 + {_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE '*A\\??\\?C*' ESCAPE '\\'")},
1.162 + {_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE '*A*\\*C*' ESCAPE '\\'")},
1.163 + {_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE 'ABC' ESCAPE '\\'")},
1.164 + {_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE 'ABC*' ESCAPE '\\'")},
1.165 + {_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE '*ABC' ESCAPE '\\'")}
1.166 + };
1.167 +
1.168 +const TInt KNumQueries = 10;
1.169 +const TInt KNumBadQueries = 9;
1.170 +const TInt KThreadCount = 3;
1.171 +const TInt KOneSecond = 1000000;
1.172 +const TInt KDbNameLen = 255;
1.173 +const TInt KMaxColName = 32;
1.174 +
1.175 +#ifndef __TOOLS2__
1.176 +static void DoDbmsConnectThreadSubFunctionL (TInt aThreadNumber)
1.177 + {
1.178 + // The session
1.179 + RDbs TheDbSession;
1.180 + CleanupClosePushL (TheDbSession);
1.181 +
1.182 + RDebug::Print (KStart (), aThreadNumber);
1.183 + RDebug::Print (KConnect (), aThreadNumber);
1.184 +
1.185 + // Signal the main thread to continue
1.186 + TheWaitForThreadsReadySem.Signal (1);
1.187 +
1.188 + // Wait until we are signalled
1.189 + TheWaitToStartSem.Wait ();
1.190 +
1.191 + // Connect to Dbms
1.192 + TInt r = TheDbSession.Connect ();
1.193 +
1.194 + if (r == KErrNone)
1.195 + {
1.196 + RDebug::Print (KConSuccess (), aThreadNumber);
1.197 + TheDbSession.Close ();
1.198 + }
1.199 + else
1.200 + {
1.201 + RDebug::Print (KConFailed (), aThreadNumber, r);
1.202 + User::Leave (r);
1.203 + }
1.204 +
1.205 + CleanupStack::PopAndDestroy (1); // session
1.206 + }
1.207 +
1.208 +static TInt DoDbmsConnectThread (TAny* aThreadNumber)
1.209 + {
1.210 + __UHEAP_MARK;
1.211 +
1.212 + CTrapCleanup* trapCleanup = CTrapCleanup::New ();
1.213 + __ASSERT_ALWAYS (trapCleanup!=NULL, User::Invariant ());
1.214 +
1.215 + TInt* threadNumber = static_cast <TInt*> (aThreadNumber);
1.216 + TRAPD (err, DoDbmsConnectThreadSubFunctionL (*threadNumber));
1.217 +
1.218 + delete trapCleanup;
1.219 +
1.220 + __UHEAP_MARKEND;
1.221 +
1.222 + return err;
1.223 + }
1.224 +#endif
1.225 +
1.226 +#ifndef TOOLS2_VARIANT
1.227 +/**
1.228 +@SYMTestCaseID SYSLIB-DBMS-CT-0644
1.229 +@SYMTestCaseDesc Test for defect no 44697
1.230 +@SYMTestPriority Medium
1.231 +@SYMTestActions Test for defect fixes
1.232 +@SYMTestExpectedResults Test must not fail
1.233 +@SYMREQ REQ0000
1.234 +*/
1.235 +LOCAL_C void Defect_DEF44697L ()
1.236 + {
1.237 + TheTest.Next (_L (" @SYMTestCaseID:SYSLIB-DBMS-CT-0644 Defect_DEF44697L "));
1.238 +
1.239 + __UHEAP_MARK;
1.240 +
1.241 + // find out the number of open handles
1.242 + TInt startProcessHandleCount;
1.243 + TInt startThreadHandleCount;
1.244 + RThread ().HandleCount (startProcessHandleCount, startThreadHandleCount);
1.245 +
1.246 + /////////////////////
1.247 + // The Test Begins...
1.248 +
1.249 + // Create semaphores
1.250 + ::CleanupClosePushL (::TheWaitForThreadsReadySem);
1.251 + User::LeaveIfError (::TheWaitForThreadsReadySem.CreateLocal (0));
1.252 +
1.253 + ::CleanupClosePushL (::TheWaitToStartSem);
1.254 + User::LeaveIfError (::TheWaitToStartSem.CreateLocal (0));
1.255 +
1.256 + // Create the threads.
1.257 + RThread createTestThread_1;
1.258 + RThread createTestThread_2;
1.259 + RThread createTestThread_3;
1.260 +
1.261 + TBuf<100> thread_name;
1.262 + TInt KThreadNumber1 = 1;
1.263 + TInt KThreadNumber2 = 2;
1.264 + TInt KThreadNumber3 = 3;
1.265 +
1.266 + // Create the first test thread______________________________
1.267 + thread_name = KName ();
1.268 + thread_name.AppendNum (KThreadNumber1);
1.269 +
1.270 + User::LeaveIfError (
1.271 + createTestThread_1.Create (thread_name,
1.272 + (TThreadFunction) DoDbmsConnectThread,
1.273 + KDefaultStackSize,
1.274 + KMinHeapSize,
1.275 + KMinHeapSize,
1.276 + &KThreadNumber1));
1.277 +
1.278 + // Default priority of Main thread is EPriorityNormal
1.279 + createTestThread_1.SetPriority(EPriorityMore);
1.280 +
1.281 + TheTest.Printf (_L ("%S thread started\n"), &thread_name);
1.282 +
1.283 + // Request notification when the thread dies.
1.284 + TRequestStatus threadStatus_1;
1.285 + createTestThread_1.Logon (threadStatus_1);
1.286 +
1.287 + //___________________________________________________________
1.288 +
1.289 + // Create the second test thread______________________________
1.290 + thread_name = KName ();
1.291 + thread_name.AppendNum (KThreadNumber2);
1.292 +
1.293 + User::LeaveIfError (
1.294 + createTestThread_2.Create (thread_name,
1.295 + (TThreadFunction) DoDbmsConnectThread,
1.296 + KDefaultStackSize,
1.297 + KMinHeapSize,
1.298 + KMinHeapSize,
1.299 + &KThreadNumber2));
1.300 +
1.301 + // Default priority of Main thread is EPriorityNormal
1.302 + createTestThread_2.SetPriority(EPriorityMore);
1.303 +
1.304 + TheTest.Printf (_L ("%S thread started\n"), &thread_name);
1.305 +
1.306 + // Request notification when the tread dies.
1.307 + TRequestStatus threadStatus_2;
1.308 + createTestThread_2.Logon (threadStatus_2);
1.309 +
1.310 + //___________________________________________________________
1.311 +
1.312 + // Create the third test thread______________________________
1.313 + thread_name = KName ();
1.314 + thread_name.AppendNum (KThreadNumber3);
1.315 +
1.316 + User::LeaveIfError (
1.317 + createTestThread_3.Create (thread_name,
1.318 + (TThreadFunction) DoDbmsConnectThread,
1.319 + KDefaultStackSize,
1.320 + KMinHeapSize,
1.321 + KMinHeapSize,
1.322 + &KThreadNumber3));
1.323 +
1.324 + // Default priority of Main thread is EPriorityNormal
1.325 + createTestThread_3.SetPriority(EPriorityMore);
1.326 +
1.327 + TheTest.Printf (_L ("%S thread started\n"), &thread_name);
1.328 +
1.329 + // Request notification when the tread dies.
1.330 + TRequestStatus threadStatus_3;
1.331 + createTestThread_3.Logon (threadStatus_3);
1.332 +
1.333 + //___________________________________________________________
1.334 +
1.335 + TheTest (threadStatus_1.Int () == KRequestPending);
1.336 + TheTest (threadStatus_2.Int () == KRequestPending);
1.337 + TheTest (threadStatus_3.Int () == KRequestPending);
1.338 +
1.339 + // Make threads eligible for execution
1.340 + createTestThread_1.Resume ();
1.341 + createTestThread_2.Resume ();
1.342 + createTestThread_3.Resume ();
1.343 +
1.344 + // The way this works is that the main thread blocks until all
1.345 + // the test threads are ready (semaphore 1) and then signals them
1.346 + // (semaphore 2).
1.347 + //
1.348 + // 1: Main thread Waits for ALL test threads to become ready.
1.349 + // 2: Main thread Signals ALL test threads to run.
1.350 + //
1.351 + // 1: Test thread Signals Main thread
1.352 + // 2: Test thread Waits for Main thread
1.353 + //
1.354 + // There is still a slight race condition between the
1.355 + // test thread signalling (semaphore 1) and then waiting
1.356 + // (semaphore 2) which is why we use both higher priority test
1.357 + // threads and a timer.
1.358 + //
1.359 + // The problems come with the way Time slicing works due to
1.360 + // other threads of higher priority being run.
1.361 + //
1.362 + // Higher priority: Ensures the test thread runs before the
1.363 + // the main thread.
1.364 + //
1.365 + // Timer: Safeguards when multiple core processors are being used.
1.366 + //
1.367 + // The Higher priority fixes the problem on single core processors
1.368 + // and multiple cores processors (SMP) where each core can run a
1.369 + // thread.
1.370 + //
1.371 + // It should also ensure that if the system is so busy that it
1.372 + // affects the test thread execution, the test thread will still
1.373 + // get to the Wait state before the Main thread can Signal.
1.374 + //
1.375 + // However, on multiple cores the Main thread may run at the same
1.376 + // time as the test thread, so we need to make sure that when the
1.377 + // test thread Signals it can acheive its Wait state before the
1.378 + // Main thread Signals. For example, if the timer has elapsed on the
1.379 + // Main thread and the sytem is busy, the test thread should still
1.380 + // run before the Main thread due to it higher priority.
1.381 + //
1.382 + // We also have to think about things like priority inheritance
1.383 + // where a thread that has a handle on a Mutex inherits the same
1.384 + // priority as a thread Waiting on it. This shouldn't happen for
1.385 + // Semaphores as there is no one handle, i.e. no critical section.
1.386 + //
1.387 + // This higher priority inheritance will take affect when a low
1.388 + // priority thread that has a handle on the Mutex blocks because of
1.389 + // another medium priority running thread. So in effect a high
1.390 + // priority thread Waiting on this Mutex is also blocked.
1.391 + //
1.392 + // It is also worth noting that on EKA1 emulator, scheduling is
1.393 + // performed by windows. On EKA2 emulator scheduling is performed
1.394 + // by Symbian so that it is the same as hardware.
1.395 +
1.396 + TheWaitForThreadsReadySem.Wait();
1.397 + TheWaitForThreadsReadySem.Wait();
1.398 + TheWaitForThreadsReadySem.Wait();
1.399 +
1.400 + // Sleep for a while to allow threads to block on the semaphore
1.401 + User::After (KOneSecond<<2); // 4 seconds
1.402 +
1.403 + // Signal all the threads to continue
1.404 + TheWaitToStartSem.Signal (KThreadCount);
1.405 +
1.406 + // Wait for all threads to complete, don't care on the order.
1.407 + User::WaitForRequest (threadStatus_1);
1.408 + User::WaitForRequest (threadStatus_2);
1.409 + User::WaitForRequest (threadStatus_3);
1.410 +
1.411 + TheTest.Printf (KStatus, KThreadNumber1, threadStatus_1.Int ());
1.412 + TheTest.Printf (KStatus, KThreadNumber2, threadStatus_2.Int ());
1.413 + TheTest.Printf (KStatus, KThreadNumber3, threadStatus_3.Int ());
1.414 +
1.415 + TheTest (threadStatus_1.Int () == KErrNone);
1.416 + TheTest (threadStatus_2.Int () == KErrNone);
1.417 + TheTest (threadStatus_3.Int () == KErrNone);
1.418 +
1.419 + CleanupStack::PopAndDestroy (&::TheWaitToStartSem);
1.420 + CleanupStack::PopAndDestroy (&::TheWaitForThreadsReadySem);
1.421 +
1.422 + // The Test Ends...
1.423 + /////////////////////
1.424 +
1.425 + // check that no handles have leaked
1.426 + TInt endProcessHandleCount;
1.427 + TInt endThreadHandleCount;
1.428 + RThread ().HandleCount (endProcessHandleCount, endThreadHandleCount);
1.429 +
1.430 + TheTest (startThreadHandleCount == endThreadHandleCount);
1.431 +
1.432 + __UHEAP_MARKEND;
1.433 + }
1.434 +#endif // !TOOLS2_VARIANT
1.435 +
1.436 +
1.437 +
1.438 +// Test for LIKE Predicate for EDbColLongText16
1.439 +LOCAL_C void LikePredicateDbColLongText16TestL()
1.440 + {
1.441 + TheTest.Next (_L ("LikePredicateDbColLongText16TestL"));
1.442 + //Creating database
1.443 +
1.444 + RFs fsSession;
1.445 + User::LeaveIfError(fsSession.Connect());
1.446 + CleanupClosePushL(fsSession);
1.447 + RDbNamedDatabase database;
1.448 + User::LeaveIfError(database.Replace(fsSession, KDbName));
1.449 + CleanupClosePushL(database);
1.450 +
1.451 + //Create table
1.452 +
1.453 + CDbColSet* columns= CDbColSet::NewLC();
1.454 +
1.455 + TDbCol name(KColName,EDbColLongText16,KDbNameLen);
1.456 + name.iAttributes = TDbCol::ENotNull;
1.457 +
1.458 + TDbCol name2(KCol2Name,EDbColLongText16,KDbNameLen);
1.459 +
1.460 + columns->AddL(name);
1.461 + columns->AddL(name2);
1.462 + User::LeaveIfError (database.CreateTable (KTable, *columns));
1.463 + CleanupStack::PopAndDestroy(); // columns
1.464 +
1.465 + // Insert values into table
1.466 + TInt error = database.Execute(KSQLInsert1);
1.467 + TheTest(error>=0);
1.468 + error =database.Execute(KSQLInsert2);
1.469 + TheTest(error>=0);
1.470 + error =database.Execute(KSQLInsert3);
1.471 + TheTest(error>=0);
1.472 + error = database.Execute(KSQLInsert4);
1.473 + TheTest(error>=0);
1.474 + error = database.Execute(KSQLInsert5);
1.475 + TheTest(error>=0);
1.476 + error = database.Execute(KSQLInsert6);
1.477 + TheTest(error>=0);
1.478 + error = database.Execute(KSQLInsert7);
1.479 + TheTest(error>=0);
1.480 +
1.481 +
1.482 + TheTest.Next(_L("Test for valid LIKE predicate queries"));
1.483 +
1.484 +
1.485 + for(TInt i =0;i<KNumQueries;++i)
1.486 + {
1.487 + RDebug::Print(_L("Executing statement: %s \n"),(KQuery[i].query));
1.488 + RDbView view;
1.489 + view.Prepare(database, TDbQuery(TPtrC(KQuery[i].query), EDbCompareFolded), view.EReadOnly);
1.490 + view.EvaluateAll();
1.491 + view.FirstL();
1.492 + typedef TBuf<256> TScriptLine;
1.493 + TInt count =0;
1.494 + while (view.AtRow())
1.495 + {
1.496 + view.GetL();
1.497 + count++;
1.498 + RDbColReadStream rd;
1.499 + rd.OpenLC(view,1);
1.500 + TScriptLine text;
1.501 + rd.ReadL(text,view.ColLength(1));
1.502 + CleanupStack::PopAndDestroy();
1.503 + RDebug::Print(_L("Expected result: %s Actual Result: %S\n"),(KQuery[i].result),&text);
1.504 + TInt err = text.Compare(TPtrC(KQuery[i].result));
1.505 + TheTest(err ==0);
1.506 + view.NextL();
1.507 + }
1.508 + view.Close();
1.509 + }
1.510 +
1.511 +
1.512 + // test for illegal statements, check they return KErrArgument
1.513 + TheTest.Next(_L("Test that illegal queries return KErrArgument"));
1.514 +
1.515 +
1.516 + for(TInt j =0;j<KNumBadQueries;++j)
1.517 + {
1.518 + RDebug::Print(_L("Executing illegal statement: %s \n"),(KBadQuery[j].query));
1.519 + RDbView view;
1.520 + TInt prepErr = view.Prepare(database, TDbQuery(TPtrC(KBadQuery[j].query), EDbCompareFolded), view.EReadOnly);
1.521 + TheTest(prepErr==KErrArgument);
1.522 + view.Close();
1.523 + }
1.524 +
1.525 + CleanupStack::PopAndDestroy(&database); // database
1.526 + CleanupStack::PopAndDestroy(&fsSession); // fsSession
1.527 + }
1.528 +
1.529 +
1.530 +
1.531 + // for LIKE Predicate for EDbColLongText8
1.532 +LOCAL_C void LikePredicateDbColLongText8TestL()
1.533 + {
1.534 + TheTest.Next (_L ("LikePredicate DbColLongText8 TestL"));
1.535 +
1.536 + //Creating database
1.537 +
1.538 + RFs fsSession;
1.539 + User::LeaveIfError(fsSession.Connect());
1.540 + CleanupClosePushL(fsSession);
1.541 + RDbNamedDatabase database;
1.542 + User::LeaveIfError(database.Replace(fsSession, KDbName));
1.543 + CleanupClosePushL(database);
1.544 +
1.545 + //Create table
1.546 +
1.547 + CDbColSet* columns= CDbColSet::NewLC();
1.548 +
1.549 + TDbCol name(KColName,EDbColLongText8,KDbNameLen);
1.550 + name.iAttributes = TDbCol::ENotNull;
1.551 +
1.552 + TDbCol name2(KCol2Name,EDbColLongText8,KDbNameLen);
1.553 +
1.554 + columns->AddL(name);
1.555 + columns->AddL(name2);
1.556 +
1.557 + User::LeaveIfError (database.CreateTable (KTable, *columns));
1.558 + CleanupStack::PopAndDestroy(); // columns
1.559 +
1.560 + // Insert values into the table
1.561 + TInt error = database.Execute(KSQLInsert1);
1.562 + TheTest(error>=0);
1.563 + error =database.Execute(KSQLInsert2);
1.564 + TheTest(error>=0);
1.565 + error =database.Execute(KSQLInsert3);
1.566 + TheTest(error>=0);
1.567 + error = database.Execute(KSQLInsert4);
1.568 + TheTest(error>=0);
1.569 + error = database.Execute(KSQLInsert5);
1.570 + TheTest(error>=0);
1.571 + error = database.Execute(KSQLInsert6);
1.572 + TheTest(error>=0);
1.573 + error = database.Execute(KSQLInsert7);
1.574 + TheTest(error>=0);
1.575 +
1.576 + TheTest.Next(_L("Test for valid LIKE predicate queries"));
1.577 +
1.578 +
1.579 + for(TInt i =0;i<KNumQueries;++i)
1.580 + {
1.581 + RDebug::Print(_L("Executing statement: %s \n"),(KQuery[i].query));
1.582 + RDbView view;
1.583 + TInt prepErr = view.Prepare(database, TDbQuery(TPtrC(KQuery[i].query), EDbCompareFolded), view.EReadOnly);
1.584 + TheTest(prepErr>=0);
1.585 + TInt evErr = view.EvaluateAll();
1.586 + TheTest(evErr==0);
1.587 + TBuf8<256> result;
1.588 + TBuf8<256> colname;
1.589 + result.Copy(TPtrC(KQuery[i].result));
1.590 + view.FirstL();
1.591 +
1.592 + while (view.AtRow())
1.593 + {
1.594 + view.GetL();
1.595 + RDbColReadStream rd;
1.596 + rd.OpenLC(view,1);
1.597 + rd.ReadL(colname,view.ColLength(1));
1.598 + CleanupStack::PopAndDestroy();
1.599 + RDebug::Print(_L("Expected result: %S Actual Result: %S\n"),&result,&colname);
1.600 + TInt err = colname.CompareF(result);
1.601 + TheTest(err ==0);
1.602 +
1.603 + view.NextL();
1.604 + }
1.605 +
1.606 + view.Close();
1.607 + }
1.608 +
1.609 + // test for illegal statements, check they return KErrArgument
1.610 + TheTest.Next(_L("Test that illegal queries return KErrArgument"));
1.611 +
1.612 +
1.613 +
1.614 + for(TInt j =0;j<KNumBadQueries;++j)
1.615 + {
1.616 + RDebug::Print(_L("Executing illegal statement: %s \n"),(KBadQuery[j].query));
1.617 + RDbView view;
1.618 + TInt prepErr = view.Prepare(database, TDbQuery(TPtrC(KBadQuery[j].query), EDbCompareFolded), view.EReadOnly);
1.619 + TheTest(prepErr==KErrArgument);
1.620 +
1.621 + view.Close();
1.622 + }
1.623 +
1.624 + CleanupStack::PopAndDestroy(&database); // database
1.625 + CleanupStack::PopAndDestroy(&fsSession); // fsSession
1.626 + }
1.627 +
1.628 +
1.629 +
1.630 +// Test for LIKE Predicate for EDbColText
1.631 +LOCAL_C void LikePredicateDbColTextTestL()
1.632 + {
1.633 + TheTest.Next (_L ("LikePredicate DbColText TestL"));
1.634 + //Creating database
1.635 +
1.636 + RFs fsSession;
1.637 + User::LeaveIfError(fsSession.Connect());
1.638 + CleanupClosePushL(fsSession);
1.639 + RDbNamedDatabase database;
1.640 + User::LeaveIfError(database.Replace(fsSession, KDbName));
1.641 + CleanupClosePushL(database);
1.642 +
1.643 + //Create table
1.644 +
1.645 + CDbColSet* columns= CDbColSet::NewLC();
1.646 +
1.647 + TDbCol name(KColName,EDbColText,KDbNameLen);
1.648 + name.iAttributes = TDbCol::ENotNull;
1.649 +
1.650 + TDbCol name2(KCol2Name,EDbColText,KDbNameLen);
1.651 +
1.652 + columns->AddL(name);
1.653 + columns->AddL(name2);
1.654 +
1.655 + User::LeaveIfError (database.CreateTable (KTable, *columns));
1.656 + CleanupStack::PopAndDestroy(); // columns
1.657 +
1.658 + // Insert values into the table
1.659 + TInt error = database.Execute(KSQLInsert1);
1.660 + TheTest(error>=0);
1.661 + error =database.Execute(KSQLInsert2);
1.662 + TheTest(error>=0);
1.663 + error =database.Execute(KSQLInsert3);
1.664 + TheTest(error>=0);
1.665 + error = database.Execute(KSQLInsert4);
1.666 + TheTest(error>=0);
1.667 + error = database.Execute(KSQLInsert5);
1.668 + TheTest(error>=0);
1.669 + error = database.Execute(KSQLInsert6);
1.670 + TheTest(error>=0);
1.671 + error = database.Execute(KSQLInsert7);
1.672 + TheTest(error>=0);
1.673 +
1.674 +
1.675 + TheTest.Next(_L("Test for valid LIKE predicate queries"));
1.676 +
1.677 +
1.678 + for(TInt i =0;i<KNumQueries;++i)
1.679 + {
1.680 + RDebug::Print(_L("Executing statement: %s \n"),(KQuery[i].query));
1.681 + RDbView view;
1.682 + TInt prepErr = view.Prepare(database, TDbQuery(TPtrC(KQuery[i].query), EDbCompareFolded), view.EReadOnly);
1.683 + if(TPtrC(KQuery[i].result).Length() == 0)
1.684 + {
1.685 + TheTest(prepErr != KErrNone);
1.686 + continue;
1.687 + }
1.688 +
1.689 + view.EvaluateAll();
1.690 + TBufC<256> colname;
1.691 + TBufC<256> res;
1.692 + view.FirstL();
1.693 + while (view.AtRow())
1.694 + {
1.695 + view.GetL();
1.696 + colname = view.ColDes(1);
1.697 + res= KQuery[i].result;
1.698 + RDebug::Print(_L("Expected result: %s Actual Result: %S\n"),(KQuery[i].result),&colname);
1.699 + TInt err = colname.Compare(TPtrC(KQuery[i].result));
1.700 + TheTest(err ==0);
1.701 + view.NextL();
1.702 + }
1.703 + view.Close();
1.704 + }
1.705 +
1.706 + // test for illegal statements, check they return KErrArgument
1.707 + TheTest.Next(_L("Test that illegal queries return KErrArgument"));
1.708 +
1.709 + for(TInt j =0;j<KNumBadQueries;++j)
1.710 + {
1.711 + RDebug::Print(_L("Executing illegal statement: %s \n"),(KBadQuery[j].query));
1.712 + RDbView view;
1.713 + TInt prepErr = view.Prepare(database, TDbQuery(TPtrC(KBadQuery[j].query), EDbCompareFolded), view.EReadOnly);
1.714 + TheTest(prepErr==KErrArgument);
1.715 + view.Close();
1.716 + }
1.717 +
1.718 + CleanupStack::PopAndDestroy(&database); // database
1.719 + CleanupStack::PopAndDestroy(&fsSession); // fsSession
1.720 + }
1.721 +
1.722 +
1.723 +
1.724 + /**
1.725 +@SYMTestCaseID SYSLIB-DBMS-UT-1592
1.726 +@SYMTestCaseDesc Testing limited-ESCAPE-clause
1.727 +@SYMTestPriority High
1.728 +@SYMTestActions Execute DBMS query with ESCAPE-clause
1.729 +@SYMTestExpectedResults The test should not fail.
1.730 +@SYMDEF INC076370
1.731 +*/
1.732 +LOCAL_C void Defect_INC076370 ()
1.733 + {
1.734 + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-1592 Defect INC076370 "));
1.735 + LikePredicateDbColTextTestL(); //EDbColText
1.736 + LikePredicateDbColLongText16TestL(); //EDbColLongText16
1.737 + LikePredicateDbColLongText8TestL(); //EDbColLongText8
1.738 + }
1.739 +
1.740 + /**
1.741 +@SYMTestCaseID SYSLIB-DBMS-UT-1667
1.742 +@SYMTestCaseDesc Testing RdbRowSet::DeleteL() with EDbColLongText16 type columns
1.743 +@SYMTestPriority High
1.744 +@SYMTestActions Create a table with a EDbColLongText16 type column and then use
1.745 + RdbRowSet::DeleteL() to delete the current row.
1.746 +@SYMTestExpectedResults The test should not fail.
1.747 +@SYMDEF INC083027
1.748 +*/
1.749 +LOCAL_C void Defect_INC083027 ()
1.750 + {
1.751 + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-1667 Defect INC083027 "));
1.752 + RFs fs;
1.753 + CleanupClosePushL(fs);
1.754 + User::LeaveIfError(fs.Connect());
1.755 +
1.756 + // create database
1.757 + RDbNamedDatabase database;
1.758 + CleanupClosePushL(database);
1.759 + User::LeaveIfError(database.Replace(fs, _L("c:\\test.db")));
1.760 +
1.761 + CDbColSet* columns = CDbColSet::NewLC();
1.762 + const TInt maxTextLength = 256;
1.763 + TDbCol text16Col(KText16Name, EDbColLongText16, maxTextLength);
1.764 + columns->AddL(text16Col);
1.765 +
1.766 + TBuf<KMaxColName> targetColName;
1.767 + targetColName = KText16Name;
1.768 +
1.769 + // create table
1.770 + User::LeaveIfError(database.CreateTable(KTableName, *columns));
1.771 +
1.772 + //create index
1.773 + CDbKey* key = CDbKey::NewLC();
1.774 + TInt keyLength = 122;
1.775 + TDbKeyCol keyCol(targetColName, keyLength);
1.776 + key->AddL(keyCol);
1.777 + User::LeaveIfError(database.CreateIndex(KIndexName, KTableName, *key));
1.778 + CleanupStack::PopAndDestroy(2); // key and columns
1.779 +
1.780 + //insert rows
1.781 + HBufC* sqlQueryBuf = HBufC::NewLC(512);
1.782 + TPtr sqlQuery(sqlQueryBuf->Des());
1.783 + _LIT(KSQLInsertFormat, "SELECT %S FROM %S");
1.784 + sqlQuery.Format(KSQLInsertFormat, &targetColName, &KTableName);
1.785 +
1.786 + RDbView insertview;
1.787 + User::LeaveIfError(insertview.Prepare(database, TDbQuery(sqlQuery), RDbView::EInsertOnly));
1.788 +
1.789 + HBufC* tmpBuf = HBufC::NewLC(maxTextLength);
1.790 + TPtr maxString(tmpBuf->Des());
1.791 + maxString.Format(KMaxStringFormat, 0);
1.792 + insertview.InsertL();
1.793 + insertview.SetColL(1, maxString);
1.794 + insertview.PutL();
1.795 + insertview.Close();
1.796 +
1.797 + //delete the row
1.798 + RDbView deleteview;
1.799 + User::LeaveIfError(deleteview.Prepare(database, TDbQuery(sqlQuery), RDbView::EUpdatable));
1.800 + User::LeaveIfError(deleteview.EvaluateAll());
1.801 +
1.802 + while (deleteview.NextL())
1.803 + {
1.804 + deleteview.GetL();
1.805 + TRAPD(err , deleteview.DeleteL());
1.806 + TheTest(err==KErrNone);
1.807 + }
1.808 + deleteview.Close();
1.809 +
1.810 + CleanupStack::PopAndDestroy(2); // tmpBuf, sqlQueryBuf
1.811 + CleanupStack::PopAndDestroy(&database); // database
1.812 + CleanupStack::PopAndDestroy(&fs); // fs
1.813 + }
1.814 +
1.815 + /**
1.816 +@SYMTestCaseID SYSLIB-DBMS-UT-1894
1.817 +@SYMTestCaseDesc Testing memory handling in CSqlMultiNode::Concatenate()
1.818 +@SYMTestPriority Medium
1.819 +@SYMTestActions Execute a special request to a database which will trigger CSqlMultiNode::Concatenate(), and the size of one of the SQL nodes will be divisible by the CSqlMultiNode granularity
1.820 +@SYMTestExpectedResults The test should not fail or panic.
1.821 +@SYMDEF INC093657
1.822 +*/
1.823 +LOCAL_C void Defect_INC093657L ()
1.824 + {
1.825 + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-1894 Defect INC093657 "));
1.826 + RFs fs;
1.827 + CleanupClosePushL(fs);
1.828 + User::LeaveIfError(fs.Connect());
1.829 +
1.830 + // create database
1.831 + RDbNamedDatabase database;
1.832 + CleanupClosePushL(database);
1.833 + User::LeaveIfError(database.Replace(fs, _L("c:\\test.db")));
1.834 +
1.835 + CDbColSet* columns = CDbColSet::NewLC();
1.836 + const TInt maxTextLength = 256;
1.837 + TDbCol column(KColName, EDbColLongText16, maxTextLength);
1.838 + columns->AddL(column);
1.839 +
1.840 + // create table
1.841 + User::LeaveIfError(database.CreateTable(KTableName, *columns));
1.842 + CleanupStack::PopAndDestroy(); // columns
1.843 +
1.844 + //execute a pointless request that is intended to detect subtle memory corruptions in CSqlMultiNode::Concatenate
1.845 + RDbView view;
1.846 + TInt err = view.Prepare(database, TDbQuery(KSqlRequestGranularity));
1.847 +
1.848 + TheTest(err==KErrNone);
1.849 +
1.850 + view.Close();
1.851 + database.Destroy();
1.852 +
1.853 + CleanupStack::PopAndDestroy(&database); // database
1.854 + CleanupStack::PopAndDestroy(&fs); // fs
1.855 + }
1.856 +
1.857 +/**
1.858 +@SYMTestCaseID SYSLIB-DBMS-UT-3467
1.859 +@SYMTestCaseDesc Test for DEF105615 "DBMS, CDbColSet::operator[](TDbColNo) operator may access an invalid memory".
1.860 + The test creates a table with 3 coluumns and a multi-column key (3 columns). The column
1.861 + names length is such that when RDbRowSet::ColSetL() is called for retrieving the column
1.862 + names, the CDbColSet array data member will make just a single memory allocation, where
1.863 + all TDbCol elements will be stored. Then the test repeats 100 times, the following statements:
1.864 + <retrieve a colset>;
1.865 + <create a copy of colset's last TDbCol element using TDbCol's copy constructor>;
1.866 + <create a copy of colset's last TDbCol element using TDbCol's "=" operator>;
1.867 + If the test uses the compiler generated TDbCol's copy constructor and "=" operator,
1.868 + the test crashes at some iteration, because an invalid memory region is accessed and
1.869 + the crash is: KERN-EXEC 3.
1.870 + The same test is repeated for TDbKeyCol's copy constructor and "=" operator.
1.871 +@SYMTestPriority High
1.872 +@SYMTestActions Test for DEF105615 "DBMS, CDbColSet::operator[](TDbColNo) operator may access an invalid memory".
1.873 +@SYMTestExpectedResults The test must not fail
1.874 +@SYMDEF DEF105615
1.875 +*/
1.876 +void DEF105615()
1.877 + {
1.878 + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-3467 DEF105615 DBMS, CDbColSet::operator[](TDbColNo) operator may access an invalid memory"));
1.879 + RFs fs;
1.880 + TInt err = fs.Connect();
1.881 + TheTest(err == KErrNone);
1.882 +
1.883 + RDbNamedDatabase db;
1.884 + err = db.Replace(fs, KDbName);
1.885 + TheTest(err == KErrNone);
1.886 +
1.887 + const TInt KColCnt = 3;
1.888 +
1.889 + err = db.Execute(_L("CREATE TABLE A(A1234567890 INTEGER, B1234567890 INTEGER, C12345 INTEGER)"));
1.890 + TheTest(err == KErrNone);
1.891 + err = db.Execute(_L("CREATE INDEX I1 ON A(A1234567890, B1234567890, C12345)"));
1.892 + TheTest(err == KErrNone);
1.893 +
1.894 + RDbTable tbl;
1.895 + err = tbl.Open(db, _L("A"));
1.896 + TheTest(err == KErrNone);
1.897 +
1.898 + //It is very hard to reproduce the problem, because the memory region after the memory, occupied by
1.899 + //CDbColSet's array, may be valid. That is the reason the test is repeated in a loop KTestCnt times,
1.900 + //where every ColSetL() call will allocate a new block of memory for its array and at some point TDbCol's
1.901 + //copy constructor and "=" operator may try to access an invalid memory area, if the compiler generated
1.902 + //ones are used.
1.903 + const TInt KTestCnt = 100;
1.904 + TInt i;
1.905 + CDbColSet* colset[KTestCnt];
1.906 + for(i=0;i<KTestCnt;++i)
1.907 + {
1.908 + TRAP(err, colset[i] = tbl.ColSetL());
1.909 + TheTest(err == KErrNone);
1.910 + TDbCol lastCol = (*colset[i])[KColCnt]; //copy constructor
1.911 + lastCol = (*colset[i])[KColCnt]; //"=" operator
1.912 + }
1.913 + for(i=0;i<KTestCnt;++i)
1.914 + {
1.915 + delete colset[i];
1.916 + }
1.917 +
1.918 + tbl.Close();
1.919 +
1.920 + //The same test is repeated for TDbKeyCol's copy constructor and "=" operator
1.921 + CDbKey* key[KTestCnt];
1.922 + for(i=0;i<KTestCnt;++i)
1.923 + {
1.924 + TRAP(err, key[i] = db.KeyL(_L("I1"), _L("A")));
1.925 + TheTest(err == KErrNone);
1.926 + TDbKeyCol lastKeyCol = (*key[i])[KColCnt - 1]; //copy constructor
1.927 + lastKeyCol = (*key[i])[KColCnt - 1]; //"=" operator
1.928 + }
1.929 + for(i=0;i<KTestCnt;++i)
1.930 + {
1.931 + delete key[i];
1.932 + }
1.933 +
1.934 + db.Close();
1.935 + err = fs.Delete(KDbName);
1.936 + TheTest(err == KErrNone);
1.937 + fs.Close();
1.938 + }
1.939 +
1.940 +/**
1.941 +@SYMTestCaseID SYSLIB-DBMS-UT-3469
1.942 +@SYMTestCaseDesc Test for DEF105615 "DBMS, CDbColSet::operator[](TDbColNo) operator may access an invalid memory".
1.943 + The test creates TDbCol and TDbKeyCol objects, creates their copies using copy constructors
1.944 + and "=" operators and checks that the copies were constructed correctly,
1.945 +@SYMTestPriority High
1.946 +@SYMTestActions Test for DEF105615 "DBMS, CDbColSet::operator[](TDbColNo) operator may access an invalid memory".
1.947 +@SYMTestExpectedResults The test must not fail
1.948 +@SYMDEF DEF105615
1.949 +*/
1.950 +void DEF105615_2()
1.951 + {
1.952 + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-3469 DEF105615 DBMS, CDbColSet::operator[](TDbColNo) operator may access an invalid memory - 2 "));
1.953 +
1.954 + const TDbColType KColType = EDbColText16;
1.955 + const TInt KMaxColLen = 73;
1.956 + const TUint KColAttributes = TDbCol::ENotNull;
1.957 + _LIT(KColName, "Name");
1.958 +
1.959 + TDbCol srcDbCol(KColName, EDbColText16, KMaxColLen);
1.960 + srcDbCol.iAttributes = KColAttributes;
1.961 +
1.962 + //TDbCol - copy constructor
1.963 + TDbCol dbColCopy1(srcDbCol);
1.964 + TheTest(dbColCopy1.iType == srcDbCol.iType && dbColCopy1.iType == KColType);
1.965 + TheTest(dbColCopy1.iMaxLength == srcDbCol.iMaxLength && dbColCopy1.iMaxLength == KMaxColLen);
1.966 + TheTest(dbColCopy1.iAttributes == srcDbCol.iAttributes && dbColCopy1.iAttributes == KColAttributes);
1.967 + TheTest(dbColCopy1.iName == srcDbCol.iName && dbColCopy1.iName == KColName);
1.968 +
1.969 + //TDbCol - "=" operator
1.970 + TDbCol dbColCopy2;
1.971 + dbColCopy2 = srcDbCol;
1.972 + TheTest(dbColCopy2.iType == srcDbCol.iType && dbColCopy2.iType == KColType);
1.973 + TheTest(dbColCopy2.iMaxLength == srcDbCol.iMaxLength && dbColCopy2.iMaxLength == KMaxColLen);
1.974 + TheTest(dbColCopy2.iAttributes == srcDbCol.iAttributes && dbColCopy2.iAttributes == KColAttributes);
1.975 + TheTest(dbColCopy2.iName == srcDbCol.iName && dbColCopy2.iName == KColName);
1.976 +
1.977 + //TDbCol - self assignment
1.978 + srcDbCol = srcDbCol;
1.979 + TheTest(srcDbCol.iType == KColType);
1.980 + TheTest(srcDbCol.iMaxLength == KMaxColLen);
1.981 + TheTest(srcDbCol.iAttributes == KColAttributes);
1.982 + TheTest(srcDbCol.iName == KColName);
1.983 +
1.984 + const TInt KKeyLen = 29;
1.985 + const TDbKeyCol::TOrder KKeyOrder = TDbKeyCol::EDesc;
1.986 + _LIT(KKeyName, "Name22");
1.987 +
1.988 + TDbKeyCol srcDbKeyCol(KKeyName, KKeyLen, KKeyOrder);
1.989 +
1.990 + //TDbKeyCol - copy constructor
1.991 + TDbKeyCol dbKeyColCopy1(srcDbKeyCol);
1.992 + TheTest(dbKeyColCopy1.iOrder == srcDbKeyCol.iOrder && dbKeyColCopy1.iOrder == KKeyOrder);
1.993 + TheTest(dbKeyColCopy1.iLength == srcDbKeyCol.iLength && dbKeyColCopy1.iLength == KKeyLen);
1.994 + TheTest(dbKeyColCopy1.iName == srcDbKeyCol.iName && dbKeyColCopy1.iName == KKeyName);
1.995 +
1.996 + //TDbKeyCol - "=" operator
1.997 + TDbKeyCol dbKeyColCopy2;
1.998 + dbKeyColCopy2 = srcDbKeyCol;
1.999 + TheTest(dbKeyColCopy2.iOrder == srcDbKeyCol.iOrder && dbKeyColCopy2.iOrder == KKeyOrder);
1.1000 + TheTest(dbKeyColCopy2.iLength == srcDbKeyCol.iLength && dbKeyColCopy2.iLength == KKeyLen);
1.1001 + TheTest(dbKeyColCopy2.iName == srcDbKeyCol.iName && dbKeyColCopy2.iName == KKeyName);
1.1002 +
1.1003 + //TDbKeyCol - self assignment
1.1004 + srcDbKeyCol = srcDbKeyCol;
1.1005 + TheTest(srcDbKeyCol.iOrder == KKeyOrder);
1.1006 + TheTest(srcDbKeyCol.iLength == KKeyLen);
1.1007 + TheTest(srcDbKeyCol.iName == KKeyName);
1.1008 + }
1.1009 +
1.1010 +/**
1.1011 +@SYMTestCaseID SYSLIB-DBMS-UT-3413
1.1012 +@SYMTestCaseDesc Testing that "incremental update" operations running in one connection does not
1.1013 + interfere with database operations executed from a second connection
1.1014 +@SYMTestPriority High
1.1015 +@SYMTestActions Create a test database with one table and insert some records there (> 100).
1.1016 + Create 2 database connections.
1.1017 + Open that database from connection 1 and execute an incremental update operation
1.1018 + in a transaction. At the same time try to open and close the same table from
1.1019 + connection 2, mixing these operations with the RDbUpdate::Next() calls from
1.1020 + connection 1. So the call pattern should be:
1.1021 + @code
1.1022 + RDbUpdate dbUpdate;
1.1023 + ....
1.1024 + while((err = dbUpdate.Next()) > 0) //from "Conenction 1"
1.1025 + {
1.1026 + RDbTable tbl;
1.1027 + err = tbl.Open(TheDb2, _L("A")); //from "Conenction 2"
1.1028 + ...
1.1029 + }
1.1030 + @endcode
1.1031 +@SYMTestExpectedResults The test should not fail or panic.
1.1032 +@SYMDEF INC101720
1.1033 +*/
1.1034 +void Defect_INC101720()
1.1035 + {
1.1036 + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-3413 "));
1.1037 + //Create the test database
1.1038 + TInt err = TheDb1.Replace(TheFs, KDbName);
1.1039 + TEST2(err, KErrNone);
1.1040 + TheDb1.Close();
1.1041 + TheCrcChecker.GenerateCrcL(KDbName);
1.1042 +
1.1043 + //Establish the first database connection
1.1044 +#ifndef __TOOLS2__
1.1045 + err = TheDbs1.Connect();
1.1046 + TEST2(err, KErrNone);
1.1047 +#endif
1.1048 + err = TheDb1.Open(TheDbs1, KDbName);
1.1049 + TEST2(err, KErrNone);
1.1050 + //Create a test table and fill the table with enough test records (> 100)
1.1051 + err = TheDb1.Execute(_L("CREATE TABLE A(Id COUNTER, Id2 INTEGER, Name LONG VARCHAR)"));
1.1052 + TEST2(err, KErrNone);
1.1053 + const TInt KTestRecCount = 200;
1.1054 + err = TheDb1.Begin();
1.1055 + TEST2(err, KErrNone);
1.1056 + for(TInt i=0;i<KTestRecCount;++i)
1.1057 + {
1.1058 + _LIT(KSqlFmtStr, "INSERT INTO A(Id2, Name) VALUES(%d, 'TestNameString')");
1.1059 + TBuf<100> sql;
1.1060 + // We can't use this because Math::Random() may return different numbers on
1.1061 + // different platform, which will lead to different output that result in
1.1062 + // CRC test failing.
1.1063 + // TUint32 id = Math::Random() % KTestRecCount;
1.1064 + TUint32 id = (i^0x55555555) % KTestRecCount;
1.1065 +
1.1066 + sql.Format(KSqlFmtStr, id + 1);
1.1067 + err = TheDb1.Execute(sql);
1.1068 + TEST2(err, 1);
1.1069 + }
1.1070 + err = TheDb1.Commit();
1.1071 + TEST2(err, KErrNone);
1.1072 + //Establish a second connection with the same test database
1.1073 +#ifndef __TOOLS2__
1.1074 + err = TheDbs2.Connect();
1.1075 + TEST2(err, KErrNone);
1.1076 +#endif
1.1077 + err = TheDb2.Open(TheDbs2, KDbName);
1.1078 + TEST2(err, KErrNone);
1.1079 + //The test: Conenction 1 - "incremental update" operation.
1.1080 + // Connection 2 - "open table/close table" operations mixed with the incremental Next-s.
1.1081 + //Expectation: The test must not fail.
1.1082 + err = TheDb1.Begin();
1.1083 + TEST2(err, KErrNone);
1.1084 + RDbUpdate dbUpdate;
1.1085 + err = dbUpdate.Execute(TheDb1, _L("UPDATE A SET Name = 'ModifiedNameString' WHERE Id2 > 10"));
1.1086 + TEST2(err, KErrNone);
1.1087 + TInt step = 0;
1.1088 + while((err = dbUpdate.Next()) > 0)
1.1089 + {
1.1090 + ++step;
1.1091 + RDbTable tbl;
1.1092 + err = tbl.Open(TheDb2, _L("A"));
1.1093 + TEST2(err, KErrNone);
1.1094 + tbl.Close();
1.1095 + }
1.1096 + TEST(step > 1);//just to be sure that the test executes dbUpdate.Next() more than once
1.1097 + TEST2(err, KErrNone);
1.1098 + dbUpdate.Close();
1.1099 + err = TheDb1.Commit();
1.1100 + TEST2(err, KErrNone);
1.1101 + //Cleanup
1.1102 + TheDb2.Close();
1.1103 +#ifndef __TOOLS2__
1.1104 + TheDbs2.Close();
1.1105 +#endif
1.1106 + TheDb1.Close();
1.1107 +#ifndef __TOOLS2__
1.1108 + TheDbs1.Close();
1.1109 +#endif
1.1110 + TheCrcChecker.GenerateCrcL(KDbName);
1.1111 + }
1.1112 +
1.1113 +/**
1.1114 +@SYMTestCaseID SYSLIB-DBMS-UT-3484
1.1115 +@SYMTestCaseDesc DBMS Hindi collation doesn't work on long text fields.
1.1116 +@SYMTestPriority Medium
1.1117 +@SYMTestActions This test is to check that DBMS correctly sorts columns using Collation, when
1.1118 + the columns are of type EDbColLongText16. Previous implementations split the
1.1119 + strings to be compared into chunks, however this could cause it to be sorted
1.1120 + incorrectly if it was split on a combining or accent character. This fault
1.1121 + occurs on the default locale as well as Hindi. Test steps:
1.1122 + * Create a database table and adds several unicode strings to EDbColLongText16
1.1123 + column in table. One set of strings have an ascii character followed by
1.1124 + an accent (e + ') and the other set have the combined equivilant ascii
1.1125 + character (è). These should have the same sort order,however if are split
1.1126 + then will compare differently.
1.1127 + * Sort the columns using EDbCompareCollated
1.1128 + * Check that the columns were sorted in the correct order
1.1129 +@SYMTestExpectedResults The columns should get sorted into ascending order correctly
1.1130 +@SYMDEF INC107268
1.1131 +*/
1.1132 +void Defect_INC107268L()
1.1133 + {
1.1134 + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-3484 Defect INC107268 - DBMS Hindi collation doesn't work on long text fields"));
1.1135 +
1.1136 + // some unicode characters
1.1137 + const TChar Ka(0x0061); // a
1.1138 + const TChar Kb(0x0062); // b
1.1139 + const TChar Ke(0x0065); // e
1.1140 + const TChar Kgrave(0x0060); // ' (grave)
1.1141 + const TChar Kegrave(0x00e8); // e with grave
1.1142 + const TChar K1(0x0031); // 1
1.1143 + const TChar K2(0x0032); // 2
1.1144 +
1.1145 + // the maximum characters in a EDbColLongText16 string before dbms stops storing
1.1146 + // the string inline, and we need to read it from a stream (see TBlobKey).
1.1147 + const TInt KInlineLimit = 127;
1.1148 +
1.1149 + // maximum number of characters buffered in TBlobKey when string stored out of line.
1.1150 + // (see TBlobKey::ETruncSize which is in bytes)
1.1151 + const TInt KTruncLimit = 16;
1.1152 +
1.1153 + const TInt KMaxStringSize = 256;
1.1154 +
1.1155 + TBuf<KMaxStringSize> inLineBoundryA;
1.1156 + TBuf<KMaxStringSize> inLineBoundryB;
1.1157 + TBuf<KMaxStringSize> truncBoundryA;
1.1158 + TBuf<KMaxStringSize> truncBoundryB;
1.1159 + TBuf<KMaxStringSize> padding;
1.1160 +
1.1161 + // this string will be stored inline. It should sort to be < stringB
1.1162 + inLineBoundryA.Fill(Ka, KInlineLimit-2);
1.1163 + inLineBoundryA.Append(Kegrave);
1.1164 + inLineBoundryA.Append(K1);
1.1165 +
1.1166 + // this string is just over the break point, so *is* truncated.
1.1167 + // this is expected to get sorted incorrecly as combining character is split off (negative test case)
1.1168 + inLineBoundryB.Fill(Ka, KInlineLimit-2);
1.1169 + inLineBoundryB.Append(Ke);
1.1170 + inLineBoundryB.Append(Kgrave);
1.1171 + inLineBoundryB.Append(K2);
1.1172 +
1.1173 + padding.Fill(Kb, KInlineLimit);
1.1174 +
1.1175 + // this string is longger that KInlineLimit so is stored out of line
1.1176 + truncBoundryA.Fill(Kb, KTruncLimit-2);
1.1177 + truncBoundryA.Append(Kegrave);
1.1178 + truncBoundryA.Append(K1);
1.1179 + truncBoundryA.Append(padding);
1.1180 +
1.1181 + // this string has combining characters that fall on boundry of ETruncSize value (32 bytes)
1.1182 + truncBoundryB.Fill(Kb, KTruncLimit-2);
1.1183 + truncBoundryB.Append(Ke);
1.1184 + truncBoundryB.Append(Kgrave);
1.1185 + truncBoundryB.Append(K2);
1.1186 + truncBoundryB.Append(padding);
1.1187 +
1.1188 +
1.1189 + // e and '(grave) characters seperately
1.1190 + TBuf<3> e_grave;
1.1191 + e_grave.Append( Ke );
1.1192 + e_grave.Append( Kgrave );
1.1193 +
1.1194 + // e with grave character - this should sort the same as e_grave
1.1195 + TBuf<3> egrave;
1.1196 + egrave.Append( Kegrave );
1.1197 +
1.1198 + TBuf<1> nullString;
1.1199 +
1.1200 + e_grave.Append(K2); // make e_grave sort second
1.1201 + egrave.Append(K1); // make egrave sort first
1.1202 +
1.1203 + // Check with database
1.1204 + _LIT(KPosLmLandmarkTable, "lmt_landmark");
1.1205 + _LIT(KPosLmLandmarkIdCol, "lmc_lmid");
1.1206 + _LIT(KPosLmNameCol, "lmc_name");
1.1207 +
1.1208 + TInt err = TheDb1.Replace( TheFs, KDbName );
1.1209 + TEST2 (err, KErrNone);
1.1210 + CleanupClosePushL(TheDb1);
1.1211 +
1.1212 + CDbColSet* columns = CDbColSet::NewLC();
1.1213 + TDbCol idField( KPosLmLandmarkIdCol, EDbColUint32 );
1.1214 + idField.iAttributes |= TDbCol::EAutoIncrement;
1.1215 + columns->AddL( idField );
1.1216 + columns->AddL( TDbCol( KPosLmNameCol, EDbColLongText16 ) ); // Works with EDbColText16. Defect only for EDbColLongText16.
1.1217 +
1.1218 + err = TheDb1.CreateTable( KPosLmLandmarkTable, *columns );
1.1219 + TEST2 (err, KErrNone);
1.1220 + CleanupStack::PopAndDestroy(columns);
1.1221 +
1.1222 + RDbTable table;
1.1223 + err = table.Open( TheDb1, KPosLmLandmarkTable );
1.1224 + TEST2 (err, KErrNone);
1.1225 + CleanupClosePushL(table);
1.1226 +
1.1227 + // add rows to table
1.1228 + table.InsertL();
1.1229 + table.SetColL( 2, egrave); // row 0 - sorted 8th
1.1230 + table.PutL();
1.1231 +
1.1232 + table.InsertL();
1.1233 + table.SetColL( 2, e_grave ); // row 1 - sorted 9th
1.1234 + table.PutL();
1.1235 +
1.1236 + table.InsertL();
1.1237 + table.SetColL( 2, inLineBoundryA ); // row 2 - sorted 3rd (incorrectly - negative test case)
1.1238 + table.PutL();
1.1239 +
1.1240 + table.InsertL();
1.1241 + table.SetColL( 2, inLineBoundryB ); // row 3 - sorted 2nd (incorrectly - negative test case)
1.1242 + table.PutL();
1.1243 +
1.1244 + table.InsertL();
1.1245 + table.SetColL( 2, nullString ); // row 4 - sorted 1st
1.1246 + table.PutL();
1.1247 +
1.1248 + table.InsertL();
1.1249 + table.SetColL( 2, truncBoundryB ); // row 5 - sorted 5th
1.1250 + table.PutL();
1.1251 +
1.1252 + table.InsertL();
1.1253 + table.SetColL( 2, truncBoundryA ); // row 6 - sorted 4th
1.1254 + table.PutL();
1.1255 +
1.1256 +
1.1257 + CleanupStack::PopAndDestroy(); // table.close()
1.1258 +
1.1259 + // do an sql select with Order By to sort columns
1.1260 + _LIT(KPosLmSqlSelectOrderByString, "SELECT %S, %S FROM %S ORDER BY %S");
1.1261 + TBuf<200> sql;
1.1262 + sql.Format( KPosLmSqlSelectOrderByString,
1.1263 + &KPosLmLandmarkIdCol,
1.1264 + &KPosLmNameCol,
1.1265 + &KPosLmLandmarkTable,
1.1266 + &KPosLmNameCol);
1.1267 +
1.1268 + RDbView view;
1.1269 + CleanupClosePushL(view);
1.1270 + err = view.Prepare( TheDb1, TDbQuery( sql, EDbCompareCollated ) );
1.1271 + TEST2 (err, KErrNone);
1.1272 + err = view.EvaluateAll();
1.1273 + TEST2 (err, KErrNone);
1.1274 +
1.1275 + // Now check that view is ordered correctly
1.1276 + const TUint32 ExpectedOrder[] = {4,3,2,6,5,0,1};
1.1277 + TInt x = 0;
1.1278 + while (view.NextL())
1.1279 + {
1.1280 + view.GetL();
1.1281 + TEST2(view.ColUint32(1), ExpectedOrder[x]); // check we got the expected order
1.1282 + x++;
1.1283 + }
1.1284 + TEST2(x, 7); // check we got the right number of values
1.1285 + CleanupStack::PopAndDestroy(2); // TheDb1.Close(); view.Close()
1.1286 + TheCrcChecker.GenerateCrcL(KDbName);
1.1287 +
1.1288 + }
1.1289 +
1.1290 +
1.1291 +LOCAL_C void DoTestsL ()
1.1292 + {
1.1293 + __UHEAP_MARK;
1.1294 + CleanupClosePushL(TheFs);
1.1295 + Defect_INC076370();
1.1296 + Defect_INC083027();
1.1297 +
1.1298 +// Defect_DEF44697L (); // Use of three RThreads, not possible for tools2.
1.1299 +
1.1300 + Defect_INC093657L();
1.1301 + Defect_INC101720();
1.1302 +// These two tests don't work on 9.3.
1.1303 + DEF105615();
1.1304 + DEF105615_2();
1.1305 +
1.1306 + Defect_INC107268L();
1.1307 + CleanupStack::PopAndDestroy(); // TheFs.Close()
1.1308 + __UHEAP_MARKEND;
1.1309 + }
1.1310 +
1.1311 +GLDEF_C TInt E32Main ()
1.1312 + {
1.1313 + __UHEAP_MARK;
1.1314 + TheTest.Title ();
1.1315 + TheTest.Start (_L ("Verify Defect Fixes"));
1.1316 +
1.1317 + TheTrapCleanup = CTrapCleanup::New ();
1.1318 + __ASSERT_ALWAYS (TheTrapCleanup!=NULL, User::Invariant ());
1.1319 +
1.1320 + TInt err = TheFs.Connect();
1.1321 + TheTest(err == KErrNone);
1.1322 +
1.1323 + TRAP (err,DoTestsL ());
1.1324 + TheTest (err==KErrNone);
1.1325 +
1.1326 + //Wait some time, because DBMS server won't be destroyed right after the last DBMS session
1.1327 + //being clossed.
1.1328 + TheTest.Printf(_L("Wait DBMS server shutdown...\n"));
1.1329 + User::After(7000000);
1.1330 +
1.1331 +#ifndef __linux__
1.1332 +#ifndef __TOOLS2__
1.1333 + TRAPD(lc, err = TheCrcChecker.DumpCrcRecordsL(KCrcRecord));
1.1334 + TheTest(err==KErrNone);
1.1335 + TheTest(lc==KErrNone);
1.1336 +#else
1.1337 + TRAPD(lc, err = TheCrcChecker.ValidateCrcRecordsL(KCrcRecord));
1.1338 + TPtrC errmsg;
1.1339 + TheCrcChecker.ErrorReportL(err, errmsg);
1.1340 + RDebug::Print(errmsg);
1.1341 + TheTest(err==KErrNone || err==TDBMS_CRCChecks::ECrcCheckOk);
1.1342 +#endif
1.1343 +#endif
1.1344 +
1.1345 + delete TheTrapCleanup;
1.1346 +
1.1347 + TheTest.End ();
1.1348 + TheTest.Close ();
1.1349 +
1.1350 + __UHEAP_MARKEND;
1.1351 + return (0);
1.1352 + }