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