// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).+ −
// All rights reserved.+ −
// This component and the accompanying materials are made available+ −
// under the terms of "Eclipse Public License v1.0"+ −
// which accompanies this distribution, and is available+ −
// at the URL "http://www.eclipse.org/legal/epl-v10.html".+ −
//+ −
// Initial Contributors:+ −
// Nokia Corporation - initial contribution.+ −
//+ −
// Contributors:+ −
//+ −
// Description:+ −
//+ −
+ −
#include <d32dbms.h>+ −
#include <e32math.h>+ −
#include <e32test.h>+ −
#include <f32file.h>+ −
#include <s32buf.h>+ −
+ −
LOCAL_D RTest TheTest (_L ("t_dbdefect"));+ −
LOCAL_D CTrapCleanup* TheTrapCleanup = NULL;+ −
LOCAL_D RSemaphore TheWaitToStartSem;+ −
LOCAL_D RSemaphore TheWaitForThreadsReadySem;+ −
LOCAL_D RFs TheFs;+ −
LOCAL_D RDbs TheDbs1, TheDbs2;+ −
LOCAL_D RDbNamedDatabase TheDb1, TheDb2;+ −
+ −
_LIT (KName, "ConnectTestThread_");+ −
_LIT (KStart, "Starting thread %x.\n");+ −
_LIT (KConnect, "Thread %x: Waiting to connect...\n");+ −
_LIT (KConSuccess, "Thread %x: Connection succeeded.\n");+ −
_LIT (KConFailed, "Thread %x: Connection failed. Error %d.\n");+ −
_LIT (KStatus, "Status of thread %x is %d.\n");+ −
+ −
+ −
_LIT(KTable, "TABLE");+ −
_LIT(KColName, "Fld");+ −
_LIT(KCol2Name, "Fld2");+ −
_LIT(KDbName, "C:\\DBMS-TST\\TESTDB22.DB");+ −
_LIT(KSQLInsert1, "INSERT INTO TABLE (Fld, Fld2) VALUES ('ACDC\\','BLAH')");+ −
_LIT(KSQLInsert2, "INSERT INTO TABLE (Fld) VALUES ('ABCDEFGH')");+ −
_LIT(KSQLInsert3, "INSERT INTO TABLE (Fld) VALUES ('A?CDEFGH')");+ −
_LIT(KSQLInsert4, "INSERT INTO TABLE (Fld) VALUES ('A?*?CDEFGH')");+ −
_LIT(KSQLInsert5, "INSERT INTO TABLE (Fld) VALUES ('A*CDEFGH')");+ −
_LIT(KSQLInsert6, "INSERT INTO TABLE (Fld, Fld2) VALUES ('ADCDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOP','ADCB')");+ −
_LIT(KSQLInsert7, "INSERT INTO TABLE (Fld) VALUES ('XZD\\FZX')");+ −
+ −
_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'");+ −
+ −
_LIT(KText16Name, "text16");+ −
_LIT(KTableName, "test");+ −
_LIT(KIndexName, "test_index");+ −
_LIT(KMaxStringFormat, "%0256d");+ −
+ −
void TestCleanup()+ −
{+ −
TheDb2.Close();+ −
TheDb1.Close();+ −
TheDbs2.Close();+ −
TheDbs1.Close();+ −
(void)TheFs.Delete(KDbName);+ −
TheFs.Close();+ −
}+ −
+ −
//-----------------------------------------------------------------------------+ −
//+ −
// Test macros and functions.+ −
//+ −
//-----------------------------------------------------------------------------+ −
// If (!aValue) then the test will be panicked, the test data files will be+ −
// deleted.+ −
LOCAL_C void Check(TInt aValue, TInt aLine)+ −
{+ −
if(!aValue)+ −
{+ −
TestCleanup();+ −
TheTest(EFalse, aLine);+ −
}+ −
}+ −
+ −
+ −
// If (aValue != aExpected) then the test will be panicked, the test data files+ −
// will be deleted.+ −
LOCAL_C void Check(TInt aValue, TInt aExpected, TInt aLine)+ −
{+ −
if(aValue != aExpected)+ −
{+ −
RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);+ −
TestCleanup();+ −
TheTest(EFalse, aLine);+ −
}+ −
}+ −
+ −
+ −
//Use these to test conditions.+ −
#define TEST(arg) ::Check((arg), __LINE__)+ −
#define TEST2(aValue, aExpected) ::Check((aValue), (aExpected), __LINE__)+ −
//-----------------------------------------------------------------------------+ −
//-----------------------------------------------------------------------------+ −
+ −
struct TTest+ −
{+ −
const TText* result;+ −
const TText* query;+ −
};+ −
+ −
const TTest KQuery[]=+ −
{+ −
{_S("ACDC\\"),_S("SELECT Fld FROM TABLE WHERE Fld LIKE 'ACDC\\' AND Fld2 LIKE '*BL*'")},+ −
{_S("A*CDEFGH"),_S("SELECT * FROM TABLE WHERE Fld LIKE '*A\\*C*' ESCAPE '\\'")},+ −
{_S("A?CDEFGH"),_S("SELECT * FROM TABLE WHERE Fld LIKE '*A\\?C*' ESCAPE '\\'")},+ −
{_S("A?*?CDEFGH"),_S("SELECT * FROM TABLE WHERE Fld LIKE '*A\\?\\*\\?C*' ESCAPE '\\'")},+ −
{_S("ADCDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOP"),_S("SELECT * FROM TABLE WHERE Fld LIKE '*1234*'")},+ −
{_S("BLAH"),_S("SELECT Fld2 FROM TABLE WHERE Fld LIKE '*AC*' AND Fld2 LIKE '?LA?'")},+ −
{_S("BLAH"),_S("SELECT Fld2 FROM TABLE WHERE Fld LIKE 'NOTINTABLE' OR Fld2 LIKE '?LA?'")},+ −
{_S("ADCDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOPQRSTUVWXYZ123456789ACDEFGHIJKLMNOP"),_S("SELECT * FROM TABLE WHERE Fld LIKE '*ADC*' AND Fld2 LIKE 'ADC?'")},+ −
{_S("A*CDEFGH"),_S("SELECT Fld FROM TABLE WHERE Fld LIKE '*\\*C*' ESCAPE '\\'")},+ −
{_S("XZD\\FZX"),_S("SELECT Fld FROM TABLE WHERE Fld LIKE '*D\\\\*' ESCAPE '\\'")}+ −
};+ −
+ −
const TTest KBadQuery[]=+ −
{+ −
{_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE 'A?C' ESCAPE '\\'")},+ −
{_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE 'A*C' ESCAPE '\\'")},+ −
{_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE '?A\\?C' ESCAPE '\\'")},+ −
{_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE '?A\\?C?' ESCAPE '\\'")},+ −
{_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE '*A\\??\\?C*' ESCAPE '\\'")},+ −
{_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE '*A*\\*C*' ESCAPE '\\'")},+ −
{_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE 'ABC' ESCAPE '\\'")},+ −
{_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE 'ABC*' ESCAPE '\\'")},+ −
{_S(""),_S("SELECT * FROM TABLE WHERE Fld LIKE '*ABC' ESCAPE '\\'")}+ −
};+ −
+ −
const TInt KNumQueries = 10;+ −
const TInt KNumBadQueries = 9;+ −
const TInt KThreadCount = 3;+ −
const TInt KOneSecond = 1000000;+ −
const TInt KDbNameLen = 255;+ −
const TInt KMaxColName = 32;+ −
+ −
static void DoDbmsConnectThreadSubFunctionL (TInt aThreadNumber)+ −
{+ −
// The session+ −
RDbs TheDbSession;+ −
CleanupClosePushL (TheDbSession);+ −
+ −
RDebug::Print (KStart (), aThreadNumber);+ −
RDebug::Print (KConnect (), aThreadNumber);+ −
+ −
// Signal the main thread to continue+ −
TheWaitForThreadsReadySem.Signal (1);+ −
+ −
// Wait until we are signalled+ −
TheWaitToStartSem.Wait ();+ −
+ −
// Connect to Dbms+ −
TInt r = TheDbSession.Connect ();+ −
+ −
if (r == KErrNone)+ −
{+ −
RDebug::Print (KConSuccess (), aThreadNumber);+ −
TheDbSession.Close ();+ −
}+ −
else+ −
{+ −
RDebug::Print (KConFailed (), aThreadNumber, r);+ −
User::Leave (r);+ −
}+ −
+ −
CleanupStack::PopAndDestroy (1); // session+ −
}+ −
+ −
static TInt DoDbmsConnectThread (TAny* aThreadNumber)+ −
{+ −
__UHEAP_MARK;+ −
+ −
CTrapCleanup* trapCleanup = CTrapCleanup::New ();+ −
__ASSERT_ALWAYS (trapCleanup!=NULL, User::Invariant ());+ −
+ −
TInt* threadNumber = static_cast <TInt*> (aThreadNumber);+ −
TRAPD (err, DoDbmsConnectThreadSubFunctionL (*threadNumber));+ −
+ −
delete trapCleanup;+ −
+ −
__UHEAP_MARKEND;+ −
+ −
return err;+ −
}+ −
+ −
/**+ −
@SYMTestCaseID SYSLIB-DBMS-CT-0644+ −
@SYMTestCaseDesc Test for defect no 44697+ −
@SYMTestPriority Medium+ −
@SYMTestActions Test for defect fixes+ −
@SYMTestExpectedResults Test must not fail+ −
@SYMREQ REQ0000+ −
*/+ −
LOCAL_C void Defect_DEF44697L ()+ −
{+ −
TheTest.Next (_L (" @SYMTestCaseID:SYSLIB-DBMS-CT-0644 Defect_DEF44697L "));+ −
+ −
__UHEAP_MARK;+ −
+ −
// find out the number of open handles+ −
TInt startProcessHandleCount;+ −
TInt startThreadHandleCount;+ −
RThread ().HandleCount (startProcessHandleCount, startThreadHandleCount);+ −
+ −
/////////////////////+ −
// The Test Begins...+ −
+ −
// Create semaphores+ −
::CleanupClosePushL (::TheWaitForThreadsReadySem);+ −
User::LeaveIfError (::TheWaitForThreadsReadySem.CreateLocal (0));+ −
+ −
::CleanupClosePushL (::TheWaitToStartSem);+ −
User::LeaveIfError (::TheWaitToStartSem.CreateLocal (0));+ −
+ −
// Create the threads.+ −
RThread createTestThread_1;+ −
RThread createTestThread_2;+ −
RThread createTestThread_3;+ −
+ −
TBuf<100> thread_name;+ −
TInt KThreadNumber1 = 1;+ −
TInt KThreadNumber2 = 2;+ −
TInt KThreadNumber3 = 3;+ −
+ −
// Create the first test thread______________________________+ −
thread_name = KName ();+ −
thread_name.AppendNum (KThreadNumber1);+ −
+ −
User::LeaveIfError (+ −
createTestThread_1.Create (thread_name,+ −
(TThreadFunction) DoDbmsConnectThread,+ −
KDefaultStackSize,+ −
KMinHeapSize,+ −
KMinHeapSize,+ −
&KThreadNumber1));+ −
+ −
// Default priority of Main thread is EPriorityNormal+ −
createTestThread_1.SetPriority(EPriorityMore);+ −
+ −
TheTest.Printf (_L ("%S thread started\n"), &thread_name);+ −
+ −
// Request notification when the thread dies.+ −
TRequestStatus threadStatus_1;+ −
createTestThread_1.Logon (threadStatus_1);+ −
+ −
//___________________________________________________________+ −
+ −
// Create the second test thread______________________________+ −
thread_name = KName ();+ −
thread_name.AppendNum (KThreadNumber2);+ −
+ −
User::LeaveIfError (+ −
createTestThread_2.Create (thread_name,+ −
(TThreadFunction) DoDbmsConnectThread,+ −
KDefaultStackSize,+ −
KMinHeapSize,+ −
KMinHeapSize,+ −
&KThreadNumber2));+ −
+ −
// Default priority of Main thread is EPriorityNormal+ −
createTestThread_2.SetPriority(EPriorityMore);+ −
+ −
TheTest.Printf (_L ("%S thread started\n"), &thread_name);+ −
+ −
// Request notification when the tread dies.+ −
TRequestStatus threadStatus_2;+ −
createTestThread_2.Logon (threadStatus_2);+ −
+ −
//___________________________________________________________+ −
+ −
// Create the third test thread______________________________+ −
thread_name = KName ();+ −
thread_name.AppendNum (KThreadNumber3);+ −
+ −
User::LeaveIfError (+ −
createTestThread_3.Create (thread_name,+ −
(TThreadFunction) DoDbmsConnectThread,+ −
KDefaultStackSize,+ −
KMinHeapSize,+ −
KMinHeapSize,+ −
&KThreadNumber3));+ −
+ −
// Default priority of Main thread is EPriorityNormal+ −
createTestThread_3.SetPriority(EPriorityMore);+ −
+ −
TheTest.Printf (_L ("%S thread started\n"), &thread_name);+ −
+ −
// Request notification when the tread dies.+ −
TRequestStatus threadStatus_3;+ −
createTestThread_3.Logon (threadStatus_3);+ −
+ −
//___________________________________________________________+ −
+ −
TheTest (threadStatus_1.Int () == KRequestPending);+ −
TheTest (threadStatus_2.Int () == KRequestPending);+ −
TheTest (threadStatus_3.Int () == KRequestPending);+ −
+ −
// Make threads eligible for execution+ −
createTestThread_1.Resume ();+ −
createTestThread_2.Resume ();+ −
createTestThread_3.Resume ();+ −
+ −
// The way this works is that the main thread blocks until all+ −
// the test threads are ready (semaphore 1) and then signals them+ −
// (semaphore 2).+ −
//+ −
// 1: Main thread Waits for ALL test threads to become ready.+ −
// 2: Main thread Signals ALL test threads to run.+ −
//+ −
// 1: Test thread Signals Main thread+ −
// 2: Test thread Waits for Main thread+ −
//+ −
// There is still a slight race condition between the+ −
// test thread signalling (semaphore 1) and then waiting+ −
// (semaphore 2) which is why we use both higher priority test+ −
// threads and a timer.+ −
//+ −
// The problems come with the way Time slicing works due to+ −
// other threads of higher priority being run.+ −
//+ −
// Higher priority: Ensures the test thread runs before the+ −
// the main thread.+ −
//+ −
// Timer: Safeguards when multiple core processors are being used.+ −
//+ −
// The Higher priority fixes the problem on single core processors+ −
// and multiple cores processors (SMP) where each core can run a+ −
// thread.+ −
//+ −
// It should also ensure that if the system is so busy that it+ −
// affects the test thread execution, the test thread will still+ −
// get to the Wait state before the Main thread can Signal.+ −
//+ −
// However, on multiple cores the Main thread may run at the same+ −
// time as the test thread, so we need to make sure that when the+ −
// test thread Signals it can acheive its Wait state before the+ −
// Main thread Signals. For example, if the timer has elapsed on the+ −
// Main thread and the sytem is busy, the test thread should still+ −
// run before the Main thread due to it higher priority.+ −
//+ −
// We also have to think about things like priority inheritance+ −
// where a thread that has a handle on a Mutex inherits the same+ −
// priority as a thread Waiting on it. This shouldn't happen for+ −
// Semaphores as there is no one handle, i.e. no critical section.+ −
//+ −
// This higher priority inheritance will take affect when a low+ −
// priority thread that has a handle on the Mutex blocks because of+ −
// another medium priority running thread. So in effect a high+ −
// priority thread Waiting on this Mutex is also blocked.+ −
//+ −
// It is also worth noting that on EKA1 emulator, scheduling is+ −
// performed by windows. On EKA2 emulator scheduling is performed+ −
// by Symbian so that it is the same as hardware.+ −
+ −
TheWaitForThreadsReadySem.Wait();+ −
TheWaitForThreadsReadySem.Wait();+ −
TheWaitForThreadsReadySem.Wait();+ −
+ −
// Sleep for a while to allow threads to block on the semaphore+ −
User::After (KOneSecond<<2); // 4 seconds+ −
+ −
// Signal all the threads to continue+ −
TheWaitToStartSem.Signal (KThreadCount);+ −
+ −
// Wait for all threads to complete, don't care on the order.+ −
User::WaitForRequest (threadStatus_1);+ −
User::WaitForRequest (threadStatus_2);+ −
User::WaitForRequest (threadStatus_3);+ −
+ −
TheTest.Printf (KStatus, KThreadNumber1, threadStatus_1.Int ());+ −
TheTest.Printf (KStatus, KThreadNumber2, threadStatus_2.Int ());+ −
TheTest.Printf (KStatus, KThreadNumber3, threadStatus_3.Int ());+ −
+ −
TheTest (threadStatus_1.Int () == KErrNone);+ −
TheTest (threadStatus_2.Int () == KErrNone);+ −
TheTest (threadStatus_3.Int () == KErrNone);+ −
+ −
CleanupStack::PopAndDestroy (&::TheWaitToStartSem);+ −
CleanupStack::PopAndDestroy (&::TheWaitForThreadsReadySem);+ −
+ −
// The Test Ends...+ −
/////////////////////+ −
+ −
// check that no handles have leaked+ −
TInt endProcessHandleCount;+ −
TInt endThreadHandleCount;+ −
RThread ().HandleCount (endProcessHandleCount, endThreadHandleCount);+ −
+ −
TheTest (startThreadHandleCount == endThreadHandleCount);+ −
+ −
__UHEAP_MARKEND;+ −
}+ −
+ −
+ −
+ −
// Test for LIKE Predicate for EDbColLongText16+ −
LOCAL_C void LikePredicateDbColLongText16TestL()+ −
{+ −
TheTest.Next (_L ("LikePredicateDbColLongText16TestL"));+ −
//Creating database+ −
+ −
RFs fsSession;+ −
User::LeaveIfError(fsSession.Connect());+ −
CleanupClosePushL(fsSession);+ −
RDbNamedDatabase database;+ −
User::LeaveIfError(database.Replace(fsSession, KDbName));+ −
CleanupClosePushL(database);+ −
+ −
//Create table+ −
+ −
CDbColSet* columns= CDbColSet::NewLC();+ −
+ −
TDbCol name(KColName,EDbColLongText16,KDbNameLen);+ −
name.iAttributes = TDbCol::ENotNull;+ −
+ −
TDbCol name2(KCol2Name,EDbColLongText16,KDbNameLen);+ −
+ −
columns->AddL(name);+ −
columns->AddL(name2);+ −
User::LeaveIfError (database.CreateTable (KTable, *columns));+ −
CleanupStack::PopAndDestroy(); // columns+ −
+ −
// Insert values into table+ −
TInt error = database.Execute(KSQLInsert1);+ −
TheTest(error>=0);+ −
error =database.Execute(KSQLInsert2);+ −
TheTest(error>=0);+ −
error =database.Execute(KSQLInsert3);+ −
TheTest(error>=0);+ −
error = database.Execute(KSQLInsert4);+ −
TheTest(error>=0);+ −
error = database.Execute(KSQLInsert5);+ −
TheTest(error>=0);+ −
error = database.Execute(KSQLInsert6);+ −
TheTest(error>=0);+ −
error = database.Execute(KSQLInsert7);+ −
TheTest(error>=0);+ −
+ −
+ −
TheTest.Next(_L("Test for valid LIKE predicate queries"));+ −
+ −
+ −
for(TInt i =0;i<KNumQueries;++i)+ −
{+ −
RDebug::Print(_L("Executing statement: %s \n"),(KQuery[i].query));+ −
RDbView view;+ −
view.Prepare(database, TDbQuery(TPtrC(KQuery[i].query), EDbCompareFolded), view.EReadOnly);+ −
view.EvaluateAll();+ −
view.FirstL();+ −
typedef TBuf<256> TScriptLine;+ −
TInt count =0;+ −
while (view.AtRow())+ −
{+ −
view.GetL();+ −
count++;+ −
RDbColReadStream rd;+ −
rd.OpenLC(view,1);+ −
TScriptLine text;+ −
rd.ReadL(text,view.ColLength(1));+ −
CleanupStack::PopAndDestroy();+ −
RDebug::Print(_L("Expected result: %s Actual Result: %S\n"),(KQuery[i].result),&text);+ −
TInt err = text.Compare(TPtrC(KQuery[i].result));+ −
TheTest(err ==0);+ −
view.NextL();+ −
}+ −
view.Close();+ −
}+ −
+ −
+ −
// test for illegal statements, check they return KErrArgument+ −
TheTest.Next(_L("Test that illegal queries return KErrArgument"));+ −
+ −
+ −
for(TInt j =0;j<KNumBadQueries;++j)+ −
{+ −
RDebug::Print(_L("Executing illegal statement: %s \n"),(KBadQuery[j].query));+ −
RDbView view;+ −
TInt prepErr = view.Prepare(database, TDbQuery(TPtrC(KBadQuery[j].query), EDbCompareFolded), view.EReadOnly);+ −
TheTest(prepErr==KErrArgument);+ −
view.Close();+ −
}+ −
+ −
CleanupStack::PopAndDestroy(&database); // database+ −
CleanupStack::PopAndDestroy(&fsSession); // fsSession+ −
}+ −
+ −
+ −
+ −
// for LIKE Predicate for EDbColLongText8+ −
LOCAL_C void LikePredicateDbColLongText8TestL()+ −
{+ −
TheTest.Next (_L ("LikePredicate DbColLongText8 TestL"));+ −
+ −
//Creating database+ −
+ −
RFs fsSession;+ −
User::LeaveIfError(fsSession.Connect());+ −
CleanupClosePushL(fsSession);+ −
RDbNamedDatabase database;+ −
User::LeaveIfError(database.Replace(fsSession, KDbName));+ −
CleanupClosePushL(database);+ −
+ −
//Create table+ −
+ −
CDbColSet* columns= CDbColSet::NewLC();+ −
+ −
TDbCol name(KColName,EDbColLongText8,KDbNameLen);+ −
name.iAttributes = TDbCol::ENotNull;+ −
+ −
TDbCol name2(KCol2Name,EDbColLongText8,KDbNameLen);+ −
+ −
columns->AddL(name);+ −
columns->AddL(name2);+ −
+ −
User::LeaveIfError (database.CreateTable (KTable, *columns));+ −
CleanupStack::PopAndDestroy(); // columns+ −
+ −
// Insert values into the table+ −
TInt error = database.Execute(KSQLInsert1);+ −
TheTest(error>=0);+ −
error =database.Execute(KSQLInsert2);+ −
TheTest(error>=0);+ −
error =database.Execute(KSQLInsert3);+ −
TheTest(error>=0);+ −
error = database.Execute(KSQLInsert4);+ −
TheTest(error>=0);+ −
error = database.Execute(KSQLInsert5);+ −
TheTest(error>=0);+ −
error = database.Execute(KSQLInsert6);+ −
TheTest(error>=0);+ −
error = database.Execute(KSQLInsert7);+ −
TheTest(error>=0);+ −
+ −
TheTest.Next(_L("Test for valid LIKE predicate queries"));+ −
+ −
+ −
for(TInt i =0;i<KNumQueries;++i)+ −
{+ −
RDebug::Print(_L("Executing statement: %s \n"),(KQuery[i].query));+ −
RDbView view;+ −
TInt prepErr = view.Prepare(database, TDbQuery(TPtrC(KQuery[i].query), EDbCompareFolded), view.EReadOnly);+ −
TheTest(prepErr>=0);+ −
TInt evErr = view.EvaluateAll();+ −
TheTest(evErr==0);+ −
TBuf8<256> result;+ −
TBuf8<256> colname;+ −
result.Copy(TPtrC(KQuery[i].result));+ −
view.FirstL();+ −
+ −
while (view.AtRow())+ −
{+ −
view.GetL();+ −
RDbColReadStream rd;+ −
rd.OpenLC(view,1);+ −
rd.ReadL(colname,view.ColLength(1));+ −
CleanupStack::PopAndDestroy();+ −
RDebug::Print(_L("Expected result: %S Actual Result: %S\n"),&result,&colname);+ −
TInt err = colname.CompareF(result);+ −
TheTest(err ==0);+ −
+ −
view.NextL();+ −
}+ −
+ −
view.Close();+ −
}+ −
+ −
// test for illegal statements, check they return KErrArgument+ −
TheTest.Next(_L("Test that illegal queries return KErrArgument"));+ −
+ −
+ −
+ −
for(TInt j =0;j<KNumBadQueries;++j)+ −
{+ −
RDebug::Print(_L("Executing illegal statement: %s \n"),(KBadQuery[j].query));+ −
RDbView view;+ −
TInt prepErr = view.Prepare(database, TDbQuery(TPtrC(KBadQuery[j].query), EDbCompareFolded), view.EReadOnly);+ −
TheTest(prepErr==KErrArgument);+ −
+ −
view.Close();+ −
}+ −
+ −
CleanupStack::PopAndDestroy(&database); // database+ −
CleanupStack::PopAndDestroy(&fsSession); // fsSession+ −
}+ −
+ −
+ −
+ −
// Test for LIKE Predicate for EDbColText+ −
LOCAL_C void LikePredicateDbColTextTestL()+ −
{+ −
TheTest.Next (_L ("LikePredicate DbColText TestL"));+ −
//Creating database+ −
+ −
RFs fsSession;+ −
User::LeaveIfError(fsSession.Connect());+ −
CleanupClosePushL(fsSession);+ −
RDbNamedDatabase database;+ −
User::LeaveIfError(database.Replace(fsSession, KDbName));+ −
CleanupClosePushL(database);+ −
+ −
//Create table+ −
+ −
CDbColSet* columns= CDbColSet::NewLC();+ −
+ −
TDbCol name(KColName,EDbColText,KDbNameLen);+ −
name.iAttributes = TDbCol::ENotNull;+ −
+ −
TDbCol name2(KCol2Name,EDbColText,KDbNameLen);+ −
+ −
columns->AddL(name);+ −
columns->AddL(name2);+ −
+ −
User::LeaveIfError (database.CreateTable (KTable, *columns));+ −
CleanupStack::PopAndDestroy(); // columns+ −
+ −
// Insert values into the table+ −
TInt error = database.Execute(KSQLInsert1);+ −
TheTest(error>=0);+ −
error =database.Execute(KSQLInsert2);+ −
TheTest(error>=0);+ −
error =database.Execute(KSQLInsert3);+ −
TheTest(error>=0);+ −
error = database.Execute(KSQLInsert4);+ −
TheTest(error>=0);+ −
error = database.Execute(KSQLInsert5);+ −
TheTest(error>=0);+ −
error = database.Execute(KSQLInsert6);+ −
TheTest(error>=0);+ −
error = database.Execute(KSQLInsert7);+ −
TheTest(error>=0);+ −
+ −
+ −
TheTest.Next(_L("Test for valid LIKE predicate queries"));+ −
+ −
+ −
for(TInt i =0;i<KNumQueries;++i)+ −
{+ −
RDebug::Print(_L("Executing statement: %s \n"),(KQuery[i].query));+ −
RDbView view;+ −
TInt prepErr = view.Prepare(database, TDbQuery(TPtrC(KQuery[i].query), EDbCompareFolded), view.EReadOnly);+ −
if(TPtrC(KQuery[i].result).Length() == 0)+ −
{+ −
TheTest(prepErr != KErrNone);+ −
continue;+ −
}+ −
+ −
view.EvaluateAll();+ −
TBufC<256> colname;+ −
TBufC<256> res;+ −
view.FirstL();+ −
while (view.AtRow())+ −
{+ −
view.GetL();+ −
colname = view.ColDes(1);+ −
res= KQuery[i].result;+ −
RDebug::Print(_L("Expected result: %s Actual Result: %S\n"),(KQuery[i].result),&colname);+ −
TInt err = colname.Compare(TPtrC(KQuery[i].result));+ −
TheTest(err ==0);+ −
view.NextL();+ −
}+ −
view.Close();+ −
}+ −
+ −
// test for illegal statements, check they return KErrArgument+ −
TheTest.Next(_L("Test that illegal queries return KErrArgument"));+ −
+ −
for(TInt j =0;j<KNumBadQueries;++j)+ −
{+ −
RDebug::Print(_L("Executing illegal statement: %s \n"),(KBadQuery[j].query));+ −
RDbView view;+ −
TInt prepErr = view.Prepare(database, TDbQuery(TPtrC(KBadQuery[j].query), EDbCompareFolded), view.EReadOnly);+ −
TheTest(prepErr==KErrArgument);+ −
view.Close();+ −
}+ −
+ −
CleanupStack::PopAndDestroy(&database); // database+ −
CleanupStack::PopAndDestroy(&fsSession); // fsSession+ −
}+ −
+ −
+ −
+ −
/**+ −
@SYMTestCaseID SYSLIB-DBMS-UT-1592+ −
@SYMTestCaseDesc Testing limited-ESCAPE-clause+ −
@SYMTestPriority High+ −
@SYMTestActions Execute DBMS query with ESCAPE-clause+ −
@SYMTestExpectedResults The test should not fail.+ −
@SYMDEF INC076370+ −
*/+ −
LOCAL_C void Defect_INC076370L()+ −
{+ −
TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-1592 Defect INC076370 "));+ −
LikePredicateDbColTextTestL(); //EDbColText+ −
LikePredicateDbColLongText16TestL(); //EDbColLongText16+ −
LikePredicateDbColLongText8TestL(); //EDbColLongText8+ −
}+ −
+ −
/**+ −
@SYMTestCaseID SYSLIB-DBMS-UT-1667+ −
@SYMTestCaseDesc Testing RdbRowSet::DeleteL() with EDbColLongText16 type columns+ −
@SYMTestPriority High+ −
@SYMTestActions Create a table with a EDbColLongText16 type column and then use+ −
RdbRowSet::DeleteL() to delete the current row.+ −
@SYMTestExpectedResults The test should not fail.+ −
@SYMDEF INC083027+ −
*/+ −
LOCAL_C void Defect_INC083027L()+ −
{+ −
TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-1667 Defect INC083027 "));+ −
RFs fs;+ −
CleanupClosePushL(fs);+ −
User::LeaveIfError(fs.Connect());+ −
+ −
// create database+ −
RDbNamedDatabase database;+ −
CleanupClosePushL(database);+ −
User::LeaveIfError(database.Replace(fs, _L("c:\\test.db")));+ −
+ −
CDbColSet* columns = CDbColSet::NewLC();+ −
const TInt maxTextLength = 256;+ −
TDbCol text16Col(KText16Name, EDbColLongText16, maxTextLength);+ −
columns->AddL(text16Col);+ −
+ −
TBuf<KMaxColName> targetColName;+ −
targetColName = KText16Name;+ −
+ −
// create table+ −
User::LeaveIfError(database.CreateTable(KTableName, *columns));+ −
+ −
//create index+ −
CDbKey* key = CDbKey::NewLC();+ −
TInt keyLength = 122;+ −
TDbKeyCol keyCol(targetColName, keyLength);+ −
key->AddL(keyCol);+ −
User::LeaveIfError(database.CreateIndex(KIndexName, KTableName, *key));+ −
CleanupStack::PopAndDestroy(2); // key and columns+ −
+ −
//insert rows+ −
HBufC* sqlQueryBuf = HBufC::NewLC(512);+ −
TPtr sqlQuery(sqlQueryBuf->Des());+ −
_LIT(KSQLInsertFormat, "SELECT %S FROM %S");+ −
sqlQuery.Format(KSQLInsertFormat, &targetColName, &KTableName);+ −
+ −
RDbView insertview;+ −
User::LeaveIfError(insertview.Prepare(database, TDbQuery(sqlQuery), RDbView::EInsertOnly));+ −
+ −
HBufC* tmpBuf = HBufC::NewLC(maxTextLength);+ −
TPtr maxString(tmpBuf->Des());+ −
maxString.Format(KMaxStringFormat, 0);+ −
insertview.InsertL();+ −
insertview.SetColL(1, maxString);+ −
insertview.PutL();+ −
insertview.Close();+ −
+ −
//delete the row+ −
RDbView deleteview;+ −
User::LeaveIfError(deleteview.Prepare(database, TDbQuery(sqlQuery), RDbView::EUpdatable));+ −
User::LeaveIfError(deleteview.EvaluateAll());+ −
+ −
while (deleteview.NextL())+ −
{+ −
deleteview.GetL();+ −
TRAPD(err , deleteview.DeleteL());+ −
TheTest(err==KErrNone);+ −
}+ −
deleteview.Close();+ −
+ −
CleanupStack::PopAndDestroy(2); // tmpBuf, sqlQueryBuf+ −
CleanupStack::PopAndDestroy(&database); // database+ −
CleanupStack::PopAndDestroy(&fs); // fs+ −
}+ −
+ −
/**+ −
@SYMTestCaseID SYSLIB-DBMS-UT-1894+ −
@SYMTestCaseDesc Testing memory handling in CSqlMultiNode::Concatenate()+ −
@SYMTestPriority Medium+ −
@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+ −
@SYMTestExpectedResults The test should not fail or panic.+ −
@SYMDEF INC093657+ −
*/+ −
LOCAL_C void Defect_INC093657L ()+ −
{+ −
TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-1894 Defect INC093657 "));+ −
RFs fs;+ −
CleanupClosePushL(fs);+ −
User::LeaveIfError(fs.Connect());+ −
+ −
// create database+ −
RDbNamedDatabase database;+ −
CleanupClosePushL(database);+ −
User::LeaveIfError(database.Replace(fs, _L("c:\\test.db")));+ −
+ −
CDbColSet* columns = CDbColSet::NewLC();+ −
const TInt maxTextLength = 256;+ −
TDbCol column(KColName, EDbColLongText16, maxTextLength);+ −
columns->AddL(column);+ −
+ −
// create table+ −
User::LeaveIfError(database.CreateTable(KTableName, *columns));+ −
CleanupStack::PopAndDestroy(); // columns+ −
+ −
//execute a pointless request that is intended to detect subtle memory corruptions in CSqlMultiNode::Concatenate+ −
RDbView view;+ −
TInt err = view.Prepare(database, TDbQuery(KSqlRequestGranularity));+ −
+ −
TheTest(err==KErrNone);+ −
+ −
view.Close();+ −
database.Destroy();+ −
+ −
CleanupStack::PopAndDestroy(&database); // database+ −
CleanupStack::PopAndDestroy(&fs); // fs+ −
}+ −
+ −
/**+ −
@SYMTestCaseID SYSLIB-DBMS-UT-3467+ −
@SYMTestCaseDesc Test for DEF105615 "DBMS, CDbColSet::operator[](TDbColNo) operator may access an invalid memory".+ −
The test creates a table with 3 coluumns and a multi-column key (3 columns). The column+ −
names length is such that when RDbRowSet::ColSetL() is called for retrieving the column+ −
names, the CDbColSet array data member will make just a single memory allocation, where+ −
all TDbCol elements will be stored. Then the test repeats 100 times, the following statements:+ −
<retrieve a colset>;+ −
<create a copy of colset's last TDbCol element using TDbCol's copy constructor>;+ −
<create a copy of colset's last TDbCol element using TDbCol's "=" operator>;+ −
If the test uses the compiler generated TDbCol's copy constructor and "=" operator,+ −
the test crashes at some iteration, because an invalid memory region is accessed and+ −
the crash is: KERN-EXEC 3.+ −
The same test is repeated for TDbKeyCol's copy constructor and "=" operator.+ −
@SYMTestPriority High+ −
@SYMTestActions Test for DEF105615 "DBMS, CDbColSet::operator[](TDbColNo) operator may access an invalid memory".+ −
@SYMTestExpectedResults The test must not fail+ −
@SYMREQ DEF105615+ −
*/+ −
void DEF105615L()+ −
{+ −
TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-3467 DEF105615 DBMS, CDbColSet::operator[](TDbColNo) operator may access an invalid memory"));+ −
RFs fs;+ −
TInt err = fs.Connect();+ −
TheTest(err == KErrNone);+ −
+ −
RDbNamedDatabase db;+ −
err = db.Replace(fs, KDbName);+ −
TheTest(err == KErrNone);+ −
+ −
const TInt KColCnt = 3;+ −
+ −
err = db.Execute(_L("CREATE TABLE A(A1234567890 INTEGER, B1234567890 INTEGER, C12345 INTEGER)"));+ −
TheTest(err == KErrNone);+ −
err = db.Execute(_L("CREATE INDEX I1 ON A(A1234567890, B1234567890, C12345)"));+ −
TheTest(err == KErrNone);+ −
+ −
RDbTable tbl;+ −
err = tbl.Open(db, _L("A"));+ −
TheTest(err == KErrNone);+ −
+ −
//It is very hard to reproduce the problem, because the memory region after the memory, occupied by+ −
//CDbColSet's array, may be valid. That is the reason the test is repeated in a loop KTestCnt times,+ −
//where every ColSetL() call will allocate a new block of memory for its array and at some point TDbCol's+ −
//copy constructor and "=" operator may try to access an invalid memory area, if the compiler generated+ −
//ones are used.+ −
const TInt KTestCnt = 100;+ −
TInt i;+ −
CDbColSet* colset[KTestCnt];+ −
for(i=0;i<KTestCnt;++i)+ −
{+ −
TRAP(err, colset[i] = tbl.ColSetL());+ −
TheTest(err == KErrNone);+ −
TDbCol lastCol = (*colset[i])[KColCnt]; //copy constructor+ −
lastCol = (*colset[i])[KColCnt]; //"=" operator+ −
}+ −
for(i=0;i<KTestCnt;++i)+ −
{+ −
delete colset[i];+ −
}+ −
+ −
tbl.Close();+ −
+ −
//The same test is repeated for TDbKeyCol's copy constructor and "=" operator+ −
CDbKey* key[KTestCnt];+ −
for(i=0;i<KTestCnt;++i)+ −
{+ −
TRAP(err, key[i] = db.KeyL(_L("I1"), _L("A")));+ −
TheTest(err == KErrNone);+ −
TDbKeyCol lastKeyCol = (*key[i])[KColCnt - 1]; //copy constructor+ −
lastKeyCol = (*key[i])[KColCnt - 1]; //"=" operator+ −
}+ −
for(i=0;i<KTestCnt;++i)+ −
{+ −
delete key[i];+ −
}+ −
+ −
db.Close();+ −
err = fs.Delete(KDbName);+ −
TheTest(err == KErrNone);+ −
fs.Close();+ −
}+ −
+ −
/**+ −
@SYMTestCaseID SYSLIB-DBMS-UT-3469+ −
@SYMTestCaseDesc Test for DEF105615 "DBMS, CDbColSet::operator[](TDbColNo) operator may access an invalid memory".+ −
The test creates TDbCol and TDbKeyCol objects, creates their copies using copy constructors+ −
and "=" operators and checks that the copies were constructed correctly,+ −
@SYMTestPriority High+ −
@SYMTestActions Test for DEF105615 "DBMS, CDbColSet::operator[](TDbColNo) operator may access an invalid memory".+ −
@SYMTestExpectedResults The test must not fail+ −
@SYMREQ DEF105615+ −
*/+ −
void DEF105615_2()+ −
{+ −
TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-3469 DEF105615 DBMS, CDbColSet::operator[](TDbColNo) operator may access an invalid memory - 2 "));+ −
+ −
const TDbColType KColType = EDbColText16;+ −
const TInt KMaxColLen = 73;+ −
const TInt KColAttributes = TDbCol::ENotNull;+ −
_LIT(KColName, "Name");+ −
+ −
TDbCol srcDbCol(KColName, EDbColText16, KMaxColLen);+ −
srcDbCol.iAttributes = KColAttributes;+ −
+ −
//TDbCol - copy constructor+ −
TDbCol dbColCopy1(srcDbCol);+ −
TheTest(dbColCopy1.iType == srcDbCol.iType && dbColCopy1.iType == KColType);+ −
TheTest(dbColCopy1.iMaxLength == srcDbCol.iMaxLength && dbColCopy1.iMaxLength == KMaxColLen);+ −
TheTest(dbColCopy1.iAttributes == srcDbCol.iAttributes && dbColCopy1.iAttributes == KColAttributes);+ −
TheTest(dbColCopy1.iName == srcDbCol.iName && dbColCopy1.iName == KColName);+ −
+ −
//TDbCol - "=" operator+ −
TDbCol dbColCopy2;+ −
dbColCopy2 = srcDbCol;+ −
TheTest(dbColCopy2.iType == srcDbCol.iType && dbColCopy2.iType == KColType);+ −
TheTest(dbColCopy2.iMaxLength == srcDbCol.iMaxLength && dbColCopy2.iMaxLength == KMaxColLen);+ −
TheTest(dbColCopy2.iAttributes == srcDbCol.iAttributes && dbColCopy2.iAttributes == KColAttributes);+ −
TheTest(dbColCopy2.iName == srcDbCol.iName && dbColCopy2.iName == KColName);+ −
+ −
//TDbCol - self assignment+ −
srcDbCol = srcDbCol;+ −
TheTest(srcDbCol.iType == KColType);+ −
TheTest(srcDbCol.iMaxLength == KMaxColLen);+ −
TheTest(srcDbCol.iAttributes == KColAttributes);+ −
TheTest(srcDbCol.iName == KColName);+ −
+ −
const TInt KKeyLen = 29;+ −
const TDbKeyCol::TOrder KKeyOrder = TDbKeyCol::EDesc;+ −
_LIT(KKeyName, "Name22");+ −
+ −
TDbKeyCol srcDbKeyCol(KKeyName, KKeyLen, KKeyOrder);+ −
+ −
//TDbKeyCol - copy constructor+ −
TDbKeyCol dbKeyColCopy1(srcDbKeyCol);+ −
TheTest(dbKeyColCopy1.iOrder == srcDbKeyCol.iOrder && dbKeyColCopy1.iOrder == KKeyOrder);+ −
TheTest(dbKeyColCopy1.iLength == srcDbKeyCol.iLength && dbKeyColCopy1.iLength == KKeyLen);+ −
TheTest(dbKeyColCopy1.iName == srcDbKeyCol.iName && dbKeyColCopy1.iName == KKeyName);+ −
+ −
//TDbKeyCol - "=" operator+ −
TDbKeyCol dbKeyColCopy2;+ −
dbKeyColCopy2 = srcDbKeyCol;+ −
TheTest(dbKeyColCopy2.iOrder == srcDbKeyCol.iOrder && dbKeyColCopy2.iOrder == KKeyOrder);+ −
TheTest(dbKeyColCopy2.iLength == srcDbKeyCol.iLength && dbKeyColCopy2.iLength == KKeyLen);+ −
TheTest(dbKeyColCopy2.iName == srcDbKeyCol.iName && dbKeyColCopy2.iName == KKeyName);+ −
+ −
//TDbKeyCol - self assignment+ −
srcDbKeyCol = srcDbKeyCol;+ −
TheTest(srcDbKeyCol.iOrder == KKeyOrder);+ −
TheTest(srcDbKeyCol.iLength == KKeyLen);+ −
TheTest(srcDbKeyCol.iName == KKeyName);+ −
}+ −
+ −
/**+ −
@SYMTestCaseID SYSLIB-DBMS-UT-3413+ −
@SYMTestCaseDesc Testing that "incremental update" operations running in one connection does not+ −
interfere with database operations executed from a second connection+ −
@SYMTestPriority High+ −
@SYMTestActions Create a test database with one table and insert some records there (> 100).+ −
Create 2 database connections.+ −
Open that database from connection 1 and execute an incremental update operation+ −
in a transaction. At the same time try to open and close the same table from+ −
connection 2, mixing these operations with the RDbUpdate::Next() calls from+ −
connection 1. So the call pattern should be:+ −
@code+ −
RDbUpdate dbUpdate;+ −
....+ −
while((err = dbUpdate.Next()) > 0) //from "Conenction 1"+ −
{+ −
RDbTable tbl;+ −
err = tbl.Open(TheDb2, _L("A")); //from "Conenction 2"+ −
...+ −
}+ −
@endcode+ −
@SYMTestExpectedResults The test should not fail or panic.+ −
@SYMDEF INC101720+ −
*/+ −
void Defect_INC101720()+ −
{+ −
TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-3413 "));+ −
//Create the test database+ −
TInt err = TheDb1.Replace(TheFs, KDbName);+ −
TEST2(err, KErrNone);+ −
TheDb1.Close();+ −
//Establish the first database connection+ −
err = TheDbs1.Connect();+ −
TEST2(err, KErrNone);+ −
err = TheDb1.Open(TheDbs1, KDbName);+ −
TEST2(err, KErrNone);+ −
//Create a test table and fill the table with enough test records (> 100)+ −
err = TheDb1.Execute(_L("CREATE TABLE A(Id COUNTER, Id2 INTEGER, Name LONG VARCHAR)"));+ −
TEST2(err, KErrNone);+ −
const TInt KTestRecCount = 200;+ −
err = TheDb1.Begin();+ −
TEST2(err, KErrNone);+ −
for(TInt i=0;i<KTestRecCount;++i)+ −
{+ −
_LIT(KSqlFmtStr, "INSERT INTO A(Id2, Name) VALUES(%d, 'TestNameString')");+ −
TBuf<100> sql;+ −
TUint32 id = Math::Random() % KTestRecCount;+ −
sql.Format(KSqlFmtStr, id + 1);+ −
err = TheDb1.Execute(sql);+ −
TEST2(err, 1);+ −
}+ −
err = TheDb1.Commit();+ −
TEST2(err, KErrNone);+ −
//Establish a second connection with the same test database+ −
err = TheDbs2.Connect();+ −
TEST2(err, KErrNone);+ −
err = TheDb2.Open(TheDbs2, KDbName);+ −
TEST2(err, KErrNone);+ −
//The test: Conenction 1 - "incremental update" operation.+ −
// Connection 2 - "open table/close table" operations mixed with the incremental Next-s.+ −
//Expectation: The test must not fail.+ −
err = TheDb1.Begin();+ −
TEST2(err, KErrNone);+ −
RDbUpdate dbUpdate;+ −
err = dbUpdate.Execute(TheDb1, _L("UPDATE A SET Name = 'ModifiedNameString' WHERE Id2 > 10"));+ −
TEST2(err, KErrNone);+ −
TInt step = 0;+ −
while((err = dbUpdate.Next()) > 0)+ −
{+ −
++step;+ −
RDbTable tbl;+ −
err = tbl.Open(TheDb2, _L("A"));+ −
TEST2(err, KErrNone);+ −
tbl.Close();+ −
}+ −
TEST(step > 1);//just to be sure that the test executes dbUpdate.Next() more than once+ −
TEST2(err, KErrNone);+ −
dbUpdate.Close();+ −
err = TheDb1.Commit();+ −
TEST2(err, KErrNone);+ −
//Cleanup+ −
TheDb2.Close();+ −
TheDbs2.Close();+ −
TheDb1.Close();+ −
TheDbs1.Close();+ −
}+ −
+ −
/**+ −
@SYMTestCaseID SYSLIB-DBMS-UT-3484+ −
@SYMTestCaseDesc DBMS Hindi collation doesn't work on long text fields.+ −
@SYMTestPriority Medium+ −
@SYMTestActions This test is to check that DBMS correctly sorts columns using Collation, when+ −
the columns are of type EDbColLongText16. Previous implementations split the+ −
strings to be compared into chunks, however this could cause it to be sorted+ −
incorrectly if it was split on a combining or accent character. This fault+ −
occurs on the default locale as well as Hindi. Test steps:+ −
* Create a database table and adds several unicode strings to EDbColLongText16+ −
column in table. One set of strings have an ascii character followed by+ −
an accent (e + ') and the other set have the combined equivilant ascii+ −
character (è). These should have the same sort order,however if are split+ −
then will compare differently.+ −
* Sort the columns using EDbCompareCollated+ −
* Check that the columns were sorted in the correct order+ −
@SYMTestExpectedResults The columns should get sorted into ascending order correctly+ −
@SYMDEF INC107268+ −
*/+ −
void Defect_INC107268L()+ −
{+ −
TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-3484 Defect INC107268 - DBMS Hindi collation doesn't work on long text fields"));+ −
+ −
// some unicode characters+ −
const TChar Ka(0x0061); // a+ −
const TChar Kb(0x0062); // b+ −
const TChar Ke(0x0065); // e+ −
const TChar Kgrave(0x0060); // ' (grave)+ −
const TChar Kegrave(0x00e8); // e with grave+ −
const TChar K1(0x0031); // 1+ −
const TChar K2(0x0032); // 2+ −
+ −
// the maximum characters in a EDbColLongText16 string before dbms stops storing+ −
// the string inline, and we need to read it from a stream (see TBlobKey).+ −
const TInt KInlineLimit = 127;+ −
+ −
// maximum number of characters buffered in TBlobKey when string stored out of line.+ −
// (see TBlobKey::ETruncSize which is in bytes)+ −
const TInt KTruncLimit = 16;+ −
+ −
const TInt KMaxStringSize = 256;+ −
+ −
TBuf<KMaxStringSize> inLineBoundryA;+ −
TBuf<KMaxStringSize> inLineBoundryB;+ −
TBuf<KMaxStringSize> truncBoundryA;+ −
TBuf<KMaxStringSize> truncBoundryB;+ −
TBuf<KMaxStringSize> padding;+ −
+ −
// this string will be stored inline. It should sort to be < stringB+ −
inLineBoundryA.Fill(Ka, KInlineLimit-2);+ −
inLineBoundryA.Append(Kegrave);+ −
inLineBoundryA.Append(K1);+ −
+ −
// this string is just over the break point, so *is* truncated.+ −
// this is expected to get sorted incorrecly as combining character is split off (negative test case)+ −
inLineBoundryB.Fill(Ka, KInlineLimit-2);+ −
inLineBoundryB.Append(Ke);+ −
inLineBoundryB.Append(Kgrave);+ −
inLineBoundryB.Append(K2);+ −
+ −
padding.Fill(Kb, KInlineLimit);+ −
+ −
// this string is longger that KInlineLimit so is stored out of line+ −
truncBoundryA.Fill(Kb, KTruncLimit-2);+ −
truncBoundryA.Append(Kegrave);+ −
truncBoundryA.Append(K1);+ −
truncBoundryA.Append(padding);+ −
+ −
// this string has combining characters that fall on boundry of ETruncSize value (32 bytes)+ −
truncBoundryB.Fill(Kb, KTruncLimit-2);+ −
truncBoundryB.Append(Ke);+ −
truncBoundryB.Append(Kgrave);+ −
truncBoundryB.Append(K2);+ −
truncBoundryB.Append(padding);+ −
+ −
+ −
// e and '(grave) characters seperately+ −
TBuf<3> e_grave;+ −
e_grave.Append( Ke );+ −
e_grave.Append( Kgrave );+ −
+ −
// e with grave character - this should sort the same as e_grave+ −
TBuf<3> egrave;+ −
egrave.Append( Kegrave );+ −
+ −
TBuf<1> nullString;+ −
+ −
e_grave.Append(K2); // make e_grave sort second+ −
egrave.Append(K1); // make egrave sort first+ −
+ −
// Check with database+ −
_LIT(KPosLmLandmarkTable, "lmt_landmark");+ −
_LIT(KPosLmLandmarkIdCol, "lmc_lmid");+ −
_LIT(KPosLmNameCol, "lmc_name");+ −
+ −
TInt err = TheDb1.Replace( TheFs, KDbName );+ −
TEST2 (err, KErrNone);+ −
CleanupClosePushL(TheDb1);+ −
+ −
CDbColSet* columns = CDbColSet::NewLC();+ −
TDbCol idField( KPosLmLandmarkIdCol, EDbColUint32 );+ −
idField.iAttributes |= TDbCol::EAutoIncrement;+ −
columns->AddL( idField );+ −
columns->AddL( TDbCol( KPosLmNameCol, EDbColLongText16 ) ); // Works with EDbColText16. Defect only for EDbColLongText16.+ −
+ −
err = TheDb1.CreateTable( KPosLmLandmarkTable, *columns );+ −
TEST2 (err, KErrNone);+ −
CleanupStack::PopAndDestroy(columns);+ −
+ −
RDbTable table;+ −
err = table.Open( TheDb1, KPosLmLandmarkTable );+ −
TEST2 (err, KErrNone);+ −
CleanupClosePushL(table);+ −
+ −
// add rows to table+ −
table.InsertL();+ −
table.SetColL( 2, egrave); // row 0 - sorted 8th+ −
table.PutL();+ −
+ −
table.InsertL();+ −
table.SetColL( 2, e_grave ); // row 1 - sorted 9th+ −
table.PutL();+ −
+ −
table.InsertL();+ −
table.SetColL( 2, inLineBoundryA ); // row 2 - sorted 3rd (incorrectly - negative test case)+ −
table.PutL();+ −
+ −
table.InsertL();+ −
table.SetColL( 2, inLineBoundryB ); // row 3 - sorted 2nd (incorrectly - negative test case)+ −
table.PutL();+ −
+ −
table.InsertL();+ −
table.SetColL( 2, nullString ); // row 4 - sorted 1st+ −
table.PutL();+ −
+ −
table.InsertL();+ −
table.SetColL( 2, truncBoundryB ); // row 5 - sorted 5th+ −
table.PutL();+ −
+ −
table.InsertL();+ −
table.SetColL( 2, truncBoundryA ); // row 6 - sorted 4th+ −
table.PutL();+ −
+ −
+ −
CleanupStack::PopAndDestroy(); // table.close()+ −
+ −
// do an sql select with Order By to sort columns+ −
_LIT(KPosLmSqlSelectOrderByString, "SELECT %S, %S FROM %S ORDER BY %S");+ −
TBuf<200> sql;+ −
sql.Format( KPosLmSqlSelectOrderByString,+ −
&KPosLmLandmarkIdCol,+ −
&KPosLmNameCol,+ −
&KPosLmLandmarkTable,+ −
&KPosLmNameCol);+ −
+ −
RDbView view;+ −
CleanupClosePushL(view);+ −
err = view.Prepare( TheDb1, TDbQuery( sql, EDbCompareCollated ) );+ −
TEST2 (err, KErrNone);+ −
err = view.EvaluateAll();+ −
TEST2 (err, KErrNone);+ −
+ −
// Now check that view is ordered correctly+ −
const TUint32 ExpectedOrder[] = {4,3,2,6,5,0,1};+ −
TInt x = 0;+ −
while (view.NextL())+ −
{+ −
view.GetL();+ −
TEST2(view.ColUint32(1), ExpectedOrder[x]); // check we got the expected order+ −
x++;+ −
}+ −
TEST2(x, 7); // check we got the right number of values+ −
CleanupStack::PopAndDestroy(2); // TheDb1.Close(); view.Close()+ −
}+ −
+ −
+ −
/**+ −
@SYMTestCaseID PDS-DBMS-UT-4001+ −
@SYMTestCaseDesc INC128224 SQL statement with ESCAPE panics in DBMS.+ −
@SYMTestPriority High+ −
@SYMTestActions The test verifies that SELECT statement with a LIKE redicate with an ESCAPE clause + −
followed by another LIKE predicate does not causes a crash in DBMS.+ −
The test creates a test database, inserts some records and then runs a SELECT+ −
statement that has one LIKE predicate with an ESCAPE followed by another LIKE.+ −
@SYMTestExpectedResults The test should pass and should not crash the DBMS+ −
@SYMDEF INC128224+ −
*/+ −
void INC128224L()+ −
{+ −
TheTest.Next(_L(" @SYMTestCaseID:PDS-DBMS-UT-4001 INC128224 SQL statement with ESCAPE panics in DBMS"));+ −
+ −
TInt err = TheDb1.Replace(TheFs, KDbName);+ −
TEST2(err, KErrNone);+ −
+ −
err = TheDb1.Execute(_L("CREATE TABLE A(T1 VARCHAR(100),T2 VARCHAR(150))"));+ −
TEST2(err, KErrNone);+ −
err = TheDb1.Execute(_L("INSERT INTO A(T1,T2) VALUES('AAAAAA','HGS')"));+ −
TEST2(err, 1);+ −
err = TheDb1.Execute(_L("INSERT INTO A(T1,T2) VALUES('BBBBBB','RRR')"));+ −
TEST2(err, 1);+ −
err = TheDb1.Execute(_L("INSERT INTO A(T1,T2) VALUES('C*CCCCC','AAQWWT')"));+ −
TEST2(err, 1);+ −
err = TheDb1.Execute(_L("INSERT INTO A(T1,T2) VALUES('DDDDDD','TUQQPQQQQSSS')"));+ −
TEST2(err, 1);+ −
err = TheDb1.Execute(_L("INSERT INTO A(T1,T2) VALUES('C*CABS','IAAAIAAAIA')"));+ −
TEST2(err, 1);+ −
+ −
RDbView view;+ −
err = view.Prepare(TheDb1, _L("SELECT * FROM A WHERE (T1 LIKE '*C\\*C*' ESCAPE '\\') AND (T2 LIKE 'I?A*')"));+ −
TEST2(err, KErrNone);+ −
TInt cnt = 0;+ −
while(view.NextL())+ −
{+ −
view.GetL();+ −
TPtrC t1 = view.ColDes(1);+ −
TPtrC t2 = view.ColDes(2);+ −
RDebug::Print(_L("T1=\"%S\", T2=\"%S\"\r\n"), &t1, &t2);+ −
++cnt;+ −
}+ −
view.Close();+ −
TEST2(cnt, 1);+ −
+ −
TheDb1.Close();+ −
(void)TheFs.Delete(KDbName);+ −
}+ −
+ −
LOCAL_C void DoTestsL ()+ −
{+ −
__UHEAP_MARK;+ −
CleanupClosePushL(TheFs);+ −
Defect_INC076370L();+ −
Defect_INC083027L();+ −
Defect_DEF44697L ();+ −
Defect_INC093657L();+ −
Defect_INC101720();+ −
DEF105615L();+ −
DEF105615_2();+ −
Defect_INC107268L();+ −
INC128224L();+ −
CleanupStack::PopAndDestroy(); // TheFs.Close()+ −
__UHEAP_MARKEND;+ −
}+ −
+ −
+ −
GLDEF_C TInt E32Main ()+ −
{+ −
__UHEAP_MARK;+ −
TheTest.Title ();+ −
TheTest.Start (_L ("Verify Defect Fixes"));+ −
+ −
TheTrapCleanup = CTrapCleanup::New ();+ −
__ASSERT_ALWAYS (TheTrapCleanup!=NULL, User::Invariant ());+ −
+ −
TInt err = TheFs.Connect();+ −
TheTest(err == KErrNone);+ −
+ −
TRAP (err,DoTestsL ());+ −
TheTest (err==KErrNone);+ −
+ −
delete TheTrapCleanup;+ −
+ −
//Wait some time, because DBMS server won't be destroyed right after the last DBMS session+ −
//being clossed.+ −
TheTest.Printf(_L("Wait DBMS server shutdown...\n"));+ −
const TInt KExitDelay = 6000000;+ −
User::After(KExitDelay);+ −
+ −
TheTest.End ();+ −
TheTest.Close ();+ −
+ −
__UHEAP_MARKEND;+ −
return (0);+ −
}+ −