sl@0: // Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "t_sqlcmdlineutil.h" sl@0: #include "SqlSrvStrings.h" sl@0: #include "sqlite3.h" sl@0: #include "SqliteSymbian.h" sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: RTest TheTest(_L("t_sqlperformance test")); sl@0: RFs TheFs; sl@0: TBuf<200> TheTestTitle; sl@0: TCmdLineParams TheCmdLineParams; sl@0: TBuf8<200> TheSqlConfigString; sl@0: sl@0: _LIT(KUtf8, "UTF8 "); sl@0: _LIT(KUtf16, "UTF16"); sl@0: sl@0: TFileName TheSecureDbName; sl@0: TFileName TheNonSecureDbName; sl@0: TFileName TheNonSecureDbName2; sl@0: TFileName TheNonSecureTmpDbName; sl@0: TFileName TheSglRecDbFileName; sl@0: sl@0: _LIT(KSqlServerPrivateDir, "\\private\\10281e17\\"); sl@0: sl@0: _LIT(KCreateDbScript, "z:\\test\\contacts_schema_to_vendors.sql"); sl@0: _LIT(KFillDbScript, "z:\\test\\add_simple_contacts.sql"); sl@0: sl@0: _LIT8(KCommitStr8, "COMMIT;"); sl@0: _LIT16(KCommitStr16, "COMMIT;"); sl@0: sl@0: _LIT8(KUpdateSql8, "UPDATE IDENTITYTABLE SET CM_FIRSTNAME=:V1, CM_LASTNAME=:V2,CM_COMPANYNAME=:V3 WHERE PARENT_CMID=:ID"); sl@0: _LIT16(KUpdateSql16, "UPDATE IDENTITYTABLE SET CM_FIRSTNAME=:V1, CM_LASTNAME=:V2,CM_COMPANYNAME=:V3 WHERE PARENT_CMID=:ID"); sl@0: sl@0: _LIT8(KUpdateSql2_8, "UPDATE IDENTITYTABLE SET CM_FIRSTNAME='%S%d',CM_LASTNAME='%S%d',CM_COMPANYNAME='%S%d' WHERE PARENT_CMID=%d"); sl@0: _LIT16(KUpdateSql2_16, "UPDATE IDENTITYTABLE SET CM_FIRSTNAME='%S%d',CM_LASTNAME='%S%d',CM_COMPANYNAME='%S%d' WHERE PARENT_CMID=%d"); sl@0: sl@0: _LIT8(KSelectSql8, "SELECT CM_FIRSTNAME, CM_LASTNAME, CM_COMPANYNAME FROM IDENTITYTABLE WHERE PARENT_CMID > 50"); sl@0: _LIT16(KSelectSql16, "SELECT CM_FIRSTNAME, CM_LASTNAME, CM_COMPANYNAME FROM IDENTITYTABLE WHERE PARENT_CMID > 50"); sl@0: sl@0: _LIT8(KDeleteSql8, "DELETE FROM IDENTITYTABLE WHERE PARENT_CMID > 50"); sl@0: _LIT16(KDeleteSql16, "DELETE FROM IDENTITYTABLE WHERE PARENT_CMID > 50"); sl@0: sl@0: extern TPtrC GetFirstSqlStmt(TPtr& aString); sl@0: sl@0: _LIT(KFirstName, "FirstName-"); sl@0: _LIT(KLastName, "LastName-"); sl@0: _LIT(KCompanyName, "CompanyName-"); sl@0: sl@0: _LIT(KFirstName2, "12345678-"); sl@0: _LIT(KLastName2, "ABCDEFGHIJK-"); sl@0: _LIT(KCompanyName2, "KKKKKKKKKK10-"); sl@0: sl@0: const char* KRawPrmName1 = ":V1"; sl@0: const char* KRawPrmName2 = ":V2"; sl@0: const char* KRawPrmName3 = ":V3"; sl@0: const char* KRawPrmName4 = ":ID"; sl@0: sl@0: _LIT(KPrmName1, ":V1"); sl@0: _LIT(KPrmName2, ":V2"); sl@0: _LIT(KPrmName3, ":V3"); sl@0: _LIT(KPrmName4, ":ID"); sl@0: sl@0: const TInt KTestTecordCount = 1000; sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: void TestEnvDestroy() sl@0: { sl@0: (void)RSqlDatabase::Delete(TheNonSecureTmpDbName); sl@0: (void)RSqlDatabase::Delete(TheNonSecureDbName2); sl@0: (void)RSqlDatabase::Delete(TheNonSecureDbName); sl@0: (void)RSqlDatabase::Delete(TheSecureDbName); sl@0: TheFs.Close(); sl@0: } sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: //Test macros and functions sl@0: void Check1(TInt aValue, TInt aLine) sl@0: { sl@0: if(!aValue) sl@0: { sl@0: TestEnvDestroy(); sl@0: TheTest.Printf(_L("*** Line %d\r\n"), aLine); sl@0: TheTest(EFalse, aLine); sl@0: } sl@0: } sl@0: void Check2(TInt aValue, TInt aExpected, TInt aLine) sl@0: { sl@0: if(aValue != aExpected) sl@0: { sl@0: TestEnvDestroy(); sl@0: TheTest.Printf(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue); sl@0: TheTest(EFalse, aLine); sl@0: } sl@0: } sl@0: #define TEST(arg) ::Check1((arg), __LINE__) sl@0: #define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__) sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: void TestEnvInit() sl@0: { sl@0: TInt err = TheFs.Connect(); sl@0: TEST2(err, KErrNone); sl@0: sl@0: err = TheFs.MkDir(TheNonSecureDbName); sl@0: TEST(err == KErrNone || err == KErrAlreadyExists); sl@0: } sl@0: sl@0: //Reads a SQL file and returns the file content as HBUFC string. sl@0: //The caller is responsible for destroying the returned HBUFC object. sl@0: template HBUFC* ReadSqlScript(const TDesC& aSqlFileName) sl@0: { sl@0: RFile file; sl@0: TEST2(file.Open(TheFs, aSqlFileName, EFileRead), KErrNone); sl@0: sl@0: TInt size = 0; sl@0: TEST2(file.Size(size), KErrNone); sl@0: sl@0: HBufC8* sql = HBufC8::New(size); sl@0: TEST(sql != NULL); sl@0: sl@0: TPtr8 ptr = sql->Des(); sl@0: TEST2(file.Read(ptr, size), KErrNone); sl@0: sl@0: file.Close(); sl@0: sl@0: HBUFC* sql2 = HBUFC::New(size + 1); sl@0: TEST(sql2 != NULL); sl@0: sql2->Des().Copy(sql->Des()); sl@0: sql2->Des().Append(TChar(0)); sl@0: delete sql; sl@0: sl@0: return sql2; sl@0: } sl@0: //Explicit ReadSqlScript() template instantiations. sl@0: template HBufC8* ReadSqlScript(const TDesC&); sl@0: template HBufC16* ReadSqlScript(const TDesC&); sl@0: sl@0: //Searches for the next aCommitStr appearance in aSqlScript string and returns a PTRC object holding sl@0: //the SQL strings from the beginning of aSqlScript till the aCommitStr (including it). sl@0: template PTRC GetNextTrans(PTRC& aSqlScript, const DESC& aCommitStr) sl@0: { sl@0: PTRC res(NULL, 0); sl@0: TInt pos = aSqlScript.FindF(aCommitStr); sl@0: if(pos >= 0) sl@0: { sl@0: pos += aCommitStr.Length(); sl@0: res.Set(aSqlScript.Left(pos)); sl@0: aSqlScript.Set(aSqlScript.Mid(pos)); sl@0: } sl@0: return res; sl@0: } sl@0: //Explicit GetNextTrans() template instantiations. sl@0: template TPtrC8 GetNextTrans(TPtrC8&, const TDesC8&); sl@0: template TPtrC16 GetNextTrans(TPtrC16&, const TDesC16&); sl@0: sl@0: //Prints aTicks parameter (converted to ms) sl@0: void PrintStats(TUint32 aStartTicks, TUint32 aEndTicks) sl@0: { sl@0: static TInt freq = 0; sl@0: if(freq == 0) sl@0: { sl@0: TEST2(HAL::Get(HAL::EFastCounterFrequency, freq), KErrNone); sl@0: } sl@0: TInt64 diffTicks = (TInt64)aEndTicks - (TInt64)aStartTicks; sl@0: if(diffTicks < 0) sl@0: { sl@0: diffTicks = KMaxTUint32 + diffTicks + 1; sl@0: } sl@0: const TInt KMicroSecIn1Sec = 1000000; sl@0: TInt32 us = (diffTicks * KMicroSecIn1Sec) / freq; sl@0: TheTest.Printf(_L("####Execution time: %d ms\r\n"), us / 1000); sl@0: } sl@0: sl@0: void PrintFileSize(const TDesC& aFileName) sl@0: { sl@0: TParse parse; sl@0: parse.Set(aFileName, &KSqlServerPrivateDir(), 0); sl@0: RFile file; sl@0: TInt err = file.Open(TheFs, parse.FullName(), EFileRead); sl@0: TEST2(err, KErrNone); sl@0: TInt size = 0; sl@0: err = file.Size(size); sl@0: TEST2(err, KErrNone); sl@0: TheTest.Printf(_L("####FileSize: %d\r\n"), size); sl@0: file.Close(); sl@0: } sl@0: sl@0: ////////////////////////////////////////////////////////////////////////////////////////////////////////////// sl@0: /////// SQL SERVER performance tests sl@0: ////////////////////////////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: enum TDbType {ENonSecureDb, ESecureDb}; sl@0: sl@0: //Template class offering Create() and Open() methods for creating/opening a RSqlDatabase object sl@0: template class TDbHelper sl@0: { sl@0: public: sl@0: static void Create(const TDesC& aDbName); sl@0: static RSqlDatabase Open(const TDesC& aDbName); sl@0: }; sl@0: sl@0: //Creates aDb database schema. sl@0: void CreateDbSchema(RSqlDatabase& aDb) sl@0: { sl@0: HBufC8* createDbScript = ReadSqlScript(KCreateDbScript()); sl@0: TInt err = aDb.Exec(createDbScript->Des()); sl@0: TEST(err >= 0); sl@0: delete createDbScript; sl@0: } sl@0: sl@0: //Explicit TDbHelper class specialization for creating/opening a nonsecure RSqlDatabase object sl@0: template <> class TDbHelper sl@0: { sl@0: public: sl@0: static void Create(const TDesC& aDbName) sl@0: { sl@0: RSqlDatabase::Delete(aDbName); sl@0: RSqlDatabase db; sl@0: TInt err = db.Create(aDbName, &TheSqlConfigString); sl@0: TEST2(err, KErrNone); sl@0: CreateDbSchema(db); sl@0: db.Close(); sl@0: } sl@0: static RSqlDatabase Open(const TDesC& aDbName) sl@0: { sl@0: RSqlDatabase db; sl@0: TInt err = db.Open(aDbName); sl@0: TEST2(err, KErrNone); sl@0: return db; sl@0: } sl@0: }; sl@0: sl@0: //Explicit TDbHelper class specialization for creating/opening a secure RSqlDatabase object sl@0: template <> class TDbHelper sl@0: { sl@0: public: sl@0: static void Create(const TDesC& aDbName) sl@0: { sl@0: RSqlDatabase::Delete(aDbName); sl@0: RSqlSecurityPolicy securityPolicy; sl@0: TInt err = securityPolicy.Create(TSecurityPolicy(TSecurityPolicy::EAlwaysPass)); sl@0: TEST2(err, KErrNone); sl@0: securityPolicy.SetDbPolicy(RSqlSecurityPolicy::ESchemaPolicy, TSecurityPolicy(ECapabilityReadUserData, ECapabilityWriteUserData)); sl@0: securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EWritePolicy, TSecurityPolicy(ECapabilityWriteUserData)); sl@0: securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EReadPolicy, TSecurityPolicy(ECapabilityReadUserData)); sl@0: RSqlDatabase db; sl@0: err = db.Create(aDbName, securityPolicy, &TheSqlConfigString); sl@0: TEST2(err, KErrNone); sl@0: securityPolicy.Close(); sl@0: CreateDbSchema(db); sl@0: db.Close(); sl@0: } sl@0: static RSqlDatabase Open(const TDesC& aDbName) sl@0: { sl@0: RSqlDatabase db; sl@0: TInt err = db.Open(aDbName); sl@0: TEST2(err, KErrNone); sl@0: return db; sl@0: } sl@0: }; sl@0: sl@0: //Executes SQL script sl@0: template void ExecuteSqlScript(RSqlDatabase& aDb, const TDesC& aScriptFileName, const DESC& aCommitStr) sl@0: { sl@0: HBUFC* fillDbScript = ReadSqlScript(aScriptFileName); sl@0: TUint32 start = User::FastCounter(); sl@0: PTRC ptr(fillDbScript->Des()); sl@0: PTRC sql(GetNextTrans(ptr, aCommitStr)); sl@0: while(sql.Length() > 0) sl@0: { sl@0: TInt err = aDb.Exec(sql); sl@0: if(err == KErrNoMemory) sl@0: { sl@0: TheTest.Printf(_L("###ERROR 'Out of memory'! The test cannot be completed!\r\n")); sl@0: return; sl@0: } sl@0: TEST(err > 0); sl@0: sql.Set(GetNextTrans(ptr, aCommitStr)); sl@0: } sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: delete fillDbScript; sl@0: } sl@0: //Explicit ExecuteSqlScript() template instantiations. sl@0: template void ExecuteSqlScript(RSqlDatabase&, const TDesC&, const TDesC8&); sl@0: template void ExecuteSqlScript(RSqlDatabase&, const TDesC&, const TDesC16&); sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: //"INSERT" test function sl@0: template void InsertTest(const TDesC& aDbFileName, const DESC& aCommitStr) sl@0: { sl@0: TheTest.Printf(_L("\"Insert\" test\r\n")); sl@0: RSqlDatabase db = TDbHelper::Open(aDbFileName); sl@0: ExecuteSqlScript(db, KFillDbScript, aCommitStr); sl@0: db.Close(); sl@0: } sl@0: //Explicit InsertTest() template instantiations. sl@0: template void InsertTest(const TDesC&, const TDesC8&); sl@0: template void InsertTest(const TDesC&, const TDesC8&); sl@0: template void InsertTest(const TDesC&, const TDesC16&); sl@0: template void InsertTest(const TDesC&, const TDesC16&); sl@0: sl@0: //"UPDATE" test function (parametrized update) sl@0: template void UpdateTest(const TDesC& aDbFileName, const DESC& aUpdateSql) sl@0: { sl@0: TheTest.Printf(_L("\"Update (parametrized)\" test\r\n")); sl@0: RSqlDatabase db = TDbHelper::Open(aDbFileName); sl@0: RSqlStatement stmt; sl@0: TInt err = stmt.Prepare(db, aUpdateSql); sl@0: TEST2(err, KErrNone); sl@0: sl@0: TInt firstNamePrmIdx = stmt.ParameterIndex(KPrmName1()); sl@0: TEST(firstNamePrmIdx >= 0); sl@0: TInt lastNamePrmIdx = stmt.ParameterIndex(KPrmName2()); sl@0: TEST(lastNamePrmIdx >= 0); sl@0: TInt companyNamePrmIdx = stmt.ParameterIndex(KPrmName3()); sl@0: TEST(companyNamePrmIdx >= 0); sl@0: TInt idIdx = stmt.ParameterIndex(KPrmName4()); sl@0: TEST(idIdx >= 0); sl@0: sl@0: TUint32 start = User::FastCounter(); sl@0: for(TInt id=1;id<=KTestTecordCount;++id) sl@0: { sl@0: TBuf<20> buf; sl@0: buf.Copy(KFirstName); sl@0: buf.AppendNum(id); sl@0: err = stmt.BindText(firstNamePrmIdx, buf); sl@0: TEST2(err, KErrNone); sl@0: buf.Copy(KLastName); sl@0: buf.AppendNum(id); sl@0: err = stmt.BindText(lastNamePrmIdx, buf); sl@0: TEST2(err, KErrNone); sl@0: buf.Copy(KCompanyName); sl@0: buf.AppendNum(id); sl@0: err = stmt.BindText(companyNamePrmIdx, buf); sl@0: TEST2(err, KErrNone); sl@0: err = stmt.BindInt(idIdx, id); sl@0: TEST2(err, KErrNone); sl@0: err = stmt.Exec(); sl@0: TEST(err > 0); sl@0: err = stmt.Reset(); sl@0: TEST2(err, KErrNone); sl@0: } sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: stmt.Close(); sl@0: db.Close(); sl@0: } sl@0: //Explicit UpdateTest() template instantiations. sl@0: template void UpdateTest(const TDesC&, const TDesC8&); sl@0: template void UpdateTest(const TDesC&, const TDesC8&); sl@0: template void UpdateTest(const TDesC&, const TDesC16&); sl@0: template void UpdateTest(const TDesC&, const TDesC16&); sl@0: sl@0: //"UPDATE" test function (without parameters) - SQL server sl@0: template void UpdateWPTest(const TDesC& aDbFileName, const DESC& aUpdateSql) sl@0: { sl@0: TheTest.Printf(_L("\"Update (without parameters)\" test\r\n")); sl@0: RSqlDatabase db = TDbHelper::Open(aDbFileName); sl@0: TBuf<200> fmtstr; sl@0: fmtstr.Copy(aUpdateSql); sl@0: sl@0: TUint32 start = User::FastCounter(); sl@0: for(TInt id=1;id<=KTestTecordCount;++id) sl@0: { sl@0: TBuf<200> buf; sl@0: buf.Format(fmtstr, &KFirstName2, id, &KLastName2, id, &KCompanyName2, id, id); sl@0: BUF sql; sl@0: sql.Copy(buf); sl@0: TInt err = db.Exec(sql); sl@0: TEST(err > 0); sl@0: } sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: db.Close(); sl@0: PrintFileSize(aDbFileName); sl@0: } sl@0: //Explicit UpdateWPTest() template instantiations. sl@0: template void UpdateWPTest, TDesC8, ENonSecureDb>(const TDesC&, const TDesC8&); sl@0: template void UpdateWPTest, TDesC8, ESecureDb>(const TDesC&, const TDesC8&); sl@0: template void UpdateWPTest, TDesC16, ENonSecureDb>(const TDesC&, const TDesC16&); sl@0: template void UpdateWPTest, TDesC16, ESecureDb>(const TDesC&, const TDesC16&); sl@0: sl@0: //"SELECT" test function sl@0: template void SelectTest(const TDesC& aDbFileName, const DESC& aSelectSql) sl@0: { sl@0: TheTest.Printf(_L("\"Select\" test\r\n")); sl@0: RSqlDatabase db = TDbHelper::Open(aDbFileName); sl@0: RSqlStatement stmt; sl@0: TInt err = stmt.Prepare(db, aSelectSql); sl@0: TEST2(err, KErrNone); sl@0: TUint32 start = User::FastCounter(); sl@0: while((err = stmt.Next()) == KSqlAtRow) sl@0: { sl@0: TBuf<20> buf; sl@0: err = stmt.ColumnText(0, buf); sl@0: TEST2(err, KErrNone); sl@0: TEST(buf.Length() > 0); sl@0: err = stmt.ColumnText(1, buf); sl@0: TEST2(err, KErrNone); sl@0: TEST(buf.Length() > 0); sl@0: err = stmt.ColumnText(2, buf); sl@0: TEST2(err, KErrNone); sl@0: TEST(buf.Length() > 0); sl@0: } sl@0: TEST2(err, KSqlAtEnd); sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: stmt.Close(); sl@0: db.Close(); sl@0: } sl@0: //Explicit SelectTest() template instantiations. sl@0: template void SelectTest(const TDesC&, const TDesC8&); sl@0: template void SelectTest(const TDesC&, const TDesC8&); sl@0: template void SelectTest(const TDesC&, const TDesC16&); sl@0: template void SelectTest(const TDesC&, const TDesC16&); sl@0: sl@0: //"DELETE" test function sl@0: template void DeleteTest(const TDesC& aDbFileName, const DESC& aDeleteSql) sl@0: { sl@0: TheTest.Printf(_L("\"Delete\" test\r\n")); sl@0: RSqlDatabase db = TDbHelper::Open(aDbFileName); sl@0: TUint32 start = User::FastCounter(); sl@0: TInt err = db.Exec(aDeleteSql); sl@0: TEST(err > 0); sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: db.Close(); sl@0: } sl@0: //Explicit SelectTest() template instantiations. sl@0: template void DeleteTest(const TDesC&, const TDesC8&); sl@0: template void DeleteTest(const TDesC&, const TDesC8&); sl@0: template void DeleteTest(const TDesC&, const TDesC16&); sl@0: template void DeleteTest(const TDesC&, const TDesC16&); sl@0: sl@0: //Performance test function: INSERT, UPDATE, SELECT sl@0: template void PerformanceTest(const TDesC& aDbFileName, sl@0: const DESC& aCommitStr, sl@0: const DESC& aUpdateSql, sl@0: const DESC& aSelectSql, sl@0: const DESC& aDeleteSql) sl@0: { sl@0: CFileMan* fm = NULL; sl@0: TRAPD(err, fm = CFileMan::NewL(TheFs)); sl@0: TEST2(err, KErrNone); sl@0: sl@0: TDbHelper::Create(aDbFileName); sl@0: InsertTest(aDbFileName, aCommitStr); sl@0: PrintFileSize(aDbFileName); sl@0: (void)fm->Copy(aDbFileName, TheNonSecureTmpDbName); sl@0: sl@0: UpdateTest(aDbFileName, aUpdateSql); sl@0: PrintFileSize(aDbFileName); sl@0: SelectTest(aDbFileName, aSelectSql); sl@0: sl@0: DeleteTest(aDbFileName, aDeleteSql); sl@0: PrintFileSize(aDbFileName); sl@0: sl@0: (void)fm->Copy(TheNonSecureTmpDbName, aDbFileName); sl@0: (void)fm->Delete(TheNonSecureTmpDbName); sl@0: delete fm; sl@0: } sl@0: //Explicit PerformanceTest() template instantiations. sl@0: template void PerformanceTest(const TDesC&, const TDesC8&, const TDesC8&, const TDesC8&, const TDesC8&); sl@0: template void PerformanceTest(const TDesC&, const TDesC8&, const TDesC8&, const TDesC8&, const TDesC8&); sl@0: template void PerformanceTest(const TDesC&, const TDesC16&, const TDesC16&, const TDesC16&, const TDesC16&); sl@0: template void PerformanceTest(const TDesC&, const TDesC16&, const TDesC16&, const TDesC16&, const TDesC16&); sl@0: sl@0: ////////////////////////////////////////////////////////////////////////////////////////////////////////////// sl@0: /////// SQLITE API used directly sl@0: ////////////////////////////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: //Template class offering Create() and Open() methods for creating/opening a sqlite3 handle. sl@0: template class TDbHelper2 sl@0: { sl@0: public: sl@0: static void Create(const TDesC& aDbName); sl@0: static sqlite3* Open(const TDesC& aDbName); sl@0: }; sl@0: sl@0: //If error - prints error message and panics the application sl@0: void PanicIfError(sqlite3* aDbHandle, TInt aErr) sl@0: { sl@0: if(aErr != SQLITE_OK && aErr != SQLITE_DONE && aErr != SQLITE_ROW) sl@0: { sl@0: if(aDbHandle) sl@0: { sl@0: TPtrC p((const TUint16*)sqlite3_errmsg16(aDbHandle)); sl@0: TheTest.Printf(_L("Database err %d, msg: %S\n\n"), aErr, &p); sl@0: (void)sqlite3_close(aDbHandle); sl@0: } sl@0: TEST(0); sl@0: } sl@0: } sl@0: sl@0: //If error - prints error message and returns zero sl@0: TInt ReportIfError(sqlite3* aDbHandle, TInt aErr) sl@0: { sl@0: if(aErr != SQLITE_OK && aErr != SQLITE_DONE && aErr != SQLITE_ROW) sl@0: { sl@0: if(aDbHandle) sl@0: { sl@0: TPtrC p((const TUint16*)sqlite3_errmsg16(aDbHandle)); sl@0: TheTest.Printf(_L("Database err %d, msg: %S\n\n"), aErr, &p); sl@0: } sl@0: return ETrue; sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: //Explicit TDbHelper2 class specialization for creating/opening a database with UTF8 default encoding sl@0: template <> class TDbHelper2 sl@0: { sl@0: public: sl@0: static void Create(const TDesC& aDbFileName) sl@0: { sl@0: (void)TheFs.Delete(aDbFileName); sl@0: HBufC8* dbName = HBufC8::New(aDbFileName.Length() + 1); sl@0: TEST(dbName != NULL); sl@0: dbName->Des().Copy(aDbFileName); sl@0: sqlite3* dbHandle = NULL; sl@0: TInt err = sqlite3_open((const char*)(dbName->Des().PtrZ()), &dbHandle); sl@0: delete dbName; sl@0: PanicIfError(dbHandle, err); sl@0: HBufC8* createDbScript = ReadSqlScript(KCreateDbScript()); sl@0: HBufC8* createDbScript2 = HBufC8::New(createDbScript->Des().Length() + 1); sl@0: TEST(createDbScript2 != NULL); sl@0: createDbScript2->Des().Copy(createDbScript->Des()); sl@0: delete createDbScript; sl@0: createDbScript2->Des().Append(TChar(0)); sl@0: err = sqlite3_exec(dbHandle, (const char*)createDbScript2->Des().Ptr(), NULL, 0, NULL); sl@0: PanicIfError(dbHandle, err); sl@0: delete createDbScript2; sl@0: (void)sqlite3_close(dbHandle); sl@0: } sl@0: static sqlite3* Open(const TDesC& aDbFileName) sl@0: { sl@0: HBufC8* dbName = HBufC8::New(aDbFileName.Length() + 1); sl@0: TEST(dbName != NULL); sl@0: dbName->Des().Copy(aDbFileName); sl@0: sqlite3* dbHandle = NULL; sl@0: TInt err = sqlite3_open((const char*)(dbName->Des().PtrZ()), &dbHandle); sl@0: delete dbName; sl@0: PanicIfError(dbHandle, err); sl@0: return dbHandle; sl@0: } sl@0: }; sl@0: sl@0: //Explicit TDbHelper2 class specialization for creating/opening a database with UTF16 default encoding sl@0: template <> class TDbHelper2 sl@0: { sl@0: public: sl@0: static void Create(const TDesC& aDbFileName) sl@0: { sl@0: (void)TheFs.Delete(aDbFileName); sl@0: HBufC16* dbName = HBufC16::New(aDbFileName.Length() + 1); sl@0: TEST(dbName != NULL); sl@0: dbName->Des().Copy(aDbFileName); sl@0: sqlite3* dbHandle = NULL; sl@0: TInt err = sqlite3_open16((const void*)(dbName->Des().PtrZ()), &dbHandle); sl@0: delete dbName; sl@0: PanicIfError(dbHandle, err); sl@0: HBufC8* createDbScript = ReadSqlScript(KCreateDbScript()); sl@0: HBufC8* createDbScript2 = HBufC8::New(createDbScript->Des().Length() + 1); sl@0: TEST(createDbScript2 != NULL); sl@0: createDbScript2->Des().Copy(createDbScript->Des()); sl@0: delete createDbScript; sl@0: createDbScript2->Des().Append(TChar(0)); sl@0: err = sqlite3_exec(dbHandle, (const char*)createDbScript2->Des().Ptr(), NULL, 0, NULL); sl@0: PanicIfError(dbHandle, err); sl@0: delete createDbScript2; sl@0: (void)sqlite3_close(dbHandle); sl@0: } sl@0: static sqlite3* Open(const TDesC& aDbFileName) sl@0: { sl@0: HBufC16* dbName = HBufC16::New(aDbFileName.Length() + 1); sl@0: TEST(dbName != NULL); sl@0: dbName->Des().Copy(aDbFileName); sl@0: sqlite3* dbHandle = NULL; sl@0: TInt err = sqlite3_open16((const void*)(dbName->Des().PtrZ()), &dbHandle); sl@0: delete dbName; sl@0: PanicIfError(dbHandle, err); sl@0: return dbHandle; sl@0: } sl@0: }; sl@0: sl@0: template void InsertTest2(sqlite3* aDbHandle, const TDesC& aScriptFileName, const DESC& aCommitStr); sl@0: sl@0: //Explicit InsertTest2() template specialization for UTF8 encoded SQL strings sl@0: template <> void InsertTest2(sqlite3* aDbHandle, const TDesC& aScriptFileName, const TDesC8& aCommitStr) sl@0: { sl@0: TheTest.Printf(_L("\"Insert\" test\r\n")); sl@0: HBufC8* fillDbScript = ReadSqlScript(aScriptFileName); sl@0: TUint32 start = User::FastCounter(); sl@0: TPtrC8 ptr(fillDbScript->Des()); sl@0: TPtrC8 sql(GetNextTrans(ptr, aCommitStr)); sl@0: while(sql.Length() > 0) sl@0: { sl@0: TUint8* p = (TUint8*)sql.Ptr(); sl@0: p[sql.Length() - 1] = 0; sl@0: TInt err = sqlite3_exec(aDbHandle, (const char*)sql.Ptr(), NULL, 0, NULL); sl@0: PanicIfError(aDbHandle, err); sl@0: sql.Set(GetNextTrans(ptr, aCommitStr)); sl@0: } sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: delete fillDbScript; sl@0: } sl@0: sl@0: //Explicit InsertTest2() template specialization for UTF16 encoded SQL strings sl@0: template <> void InsertTest2(sqlite3* aDbHandle, const TDesC& aScriptFileName, const TDesC16& aCommitStr) sl@0: { sl@0: TheTest.Printf(_L("\"Insert\" test\r\n")); sl@0: HBufC16* fillDbScript = ReadSqlScript(aScriptFileName); sl@0: TUint32 start = User::FastCounter(); sl@0: TPtrC16 ptr(fillDbScript->Des()); sl@0: TPtrC16 sql(GetNextTrans(ptr, aCommitStr)); sl@0: while(sql != KNullDesC16) sl@0: { sl@0: TPtr16 p((TUint16*)sql.Ptr(), sql.Length(), sql.Length()); sl@0: TPtrC16 current(KNullDesC16); sl@0: while(p.Length() > 1) //"> 1" because it is a zero terminated string sl@0: { sl@0: current.Set(GetFirstSqlStmt(p)); sl@0: sqlite3_stmt* stmtHandle = NULL; sl@0: const void* stmtTail = NULL; sl@0: TInt err = sqlite3_prepare16_v2(aDbHandle, current.Ptr(), -1, &stmtHandle, &stmtTail); sl@0: if(stmtHandle) //stmtHandle can be NULL for statements like this: ";". sl@0: { sl@0: if(err == SQLITE_OK) sl@0: { sl@0: while((err = sqlite3_step(stmtHandle)) == SQLITE_ROW) sl@0: { sl@0: } sl@0: } sl@0: TInt err2 = sqlite3_finalize(stmtHandle); sl@0: TEST2(err2, SQLITE_OK); sl@0: } sl@0: if(ReportIfError(aDbHandle, err)) sl@0: { sl@0: delete fillDbScript; sl@0: return; sl@0: } sl@0: }//while(p.Length() > 1) sl@0: sql.Set(GetNextTrans(ptr, aCommitStr)); sl@0: }//while(sql != KNullDesC16) sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: delete fillDbScript; sl@0: } sl@0: sl@0: template void UpdateTest2(sqlite3* aDbHandle, const DESC& aUpdateSql); sl@0: sl@0: //Explicit UpdateTest2() template specialization for UTF8 encoded SQL strings sl@0: template <> void UpdateTest2(sqlite3* aDbHandle, const TDesC8& aUpdateSql) sl@0: { sl@0: TheTest.Printf(_L("\"Update\" test\r\n")); sl@0: HBufC8* sql = HBufC8::New(aUpdateSql.Length() + 1); sl@0: TEST(sql != NULL); sl@0: sql->Des().Copy(aUpdateSql); sl@0: sql->Des().Append(TChar(0)); sl@0: sl@0: sqlite3_stmt* stmtHandle = NULL; sl@0: const char* stmtTail = NULL; sl@0: TInt err = sqlite3_prepare_v2(aDbHandle, (const char*)sql->Des().Ptr(), -1, &stmtHandle, &stmtTail); sl@0: delete sql; sl@0: PanicIfError(aDbHandle, err); sl@0: TInt firstNamePrmIdx = sqlite3_bind_parameter_index(stmtHandle, KRawPrmName1); sl@0: TEST(firstNamePrmIdx >= 0); sl@0: TInt lastNamePrmIdx = sqlite3_bind_parameter_index(stmtHandle, KRawPrmName2); sl@0: TEST(lastNamePrmIdx >= 0); sl@0: TInt companyNamePrmIdx = sqlite3_bind_parameter_index(stmtHandle, KRawPrmName3); sl@0: TEST(companyNamePrmIdx >= 0); sl@0: TInt idIdx = sqlite3_bind_parameter_index(stmtHandle, KRawPrmName4); sl@0: TEST(idIdx >= 0); sl@0: sl@0: TUint32 start = User::FastCounter(); sl@0: for(TInt id=1;id<=KTestTecordCount;++id) sl@0: { sl@0: TBuf8<20> buf1; sl@0: buf1.Copy(KFirstName); sl@0: buf1.AppendNum(id); sl@0: buf1.Append(TChar(0)); sl@0: err = sqlite3_bind_text(stmtHandle, firstNamePrmIdx, (const char*)buf1.Ptr(), -1, SQLITE_STATIC); sl@0: TEST2(err, SQLITE_OK); sl@0: TBuf8<20> buf2; sl@0: buf2.Copy(KLastName); sl@0: buf2.AppendNum(id); sl@0: buf2.Append(TChar(0)); sl@0: err = sqlite3_bind_text(stmtHandle, lastNamePrmIdx, (const char*)buf2.Ptr(), -1, SQLITE_STATIC); sl@0: TEST2(err, SQLITE_OK); sl@0: TBuf8<20> buf3; sl@0: buf3.Copy(KCompanyName); sl@0: buf3.AppendNum(id); sl@0: buf3.Append(TChar(0)); sl@0: err = sqlite3_bind_text(stmtHandle, companyNamePrmIdx, (const char*)buf3.Ptr(), -1, SQLITE_STATIC); sl@0: TEST2(err, SQLITE_OK); sl@0: err = sqlite3_bind_int(stmtHandle, idIdx, id); sl@0: TEST2(err, SQLITE_OK); sl@0: while((err = sqlite3_step(stmtHandle)) == SQLITE_ROW) sl@0: { sl@0: } sl@0: PanicIfError(aDbHandle, err); sl@0: err = sqlite3_reset(stmtHandle); sl@0: PanicIfError(aDbHandle, err); sl@0: } sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: err = sqlite3_finalize(stmtHandle); sl@0: TEST2(err, SQLITE_OK); sl@0: } sl@0: sl@0: //Explicit UpdateTest2() template specialization for UTF16 encoded SQL strings sl@0: template <> void UpdateTest2(sqlite3* aDbHandle, const TDesC16& aUpdateSql) sl@0: { sl@0: TheTest.Printf(_L("\"Update\" test\r\n")); sl@0: HBufC16* sql = HBufC16::New(aUpdateSql.Length() + 1); sl@0: TEST(sql != NULL); sl@0: sql->Des().Copy(aUpdateSql); sl@0: sql->Des().Append(TChar(0)); sl@0: sl@0: sqlite3_stmt* stmtHandle = NULL; sl@0: const void* stmtTail = NULL; sl@0: TInt err = sqlite3_prepare16_v2(aDbHandle, (const void*)sql->Des().Ptr(), -1, &stmtHandle, &stmtTail); sl@0: delete sql; sl@0: PanicIfError(aDbHandle, err); sl@0: TInt firstNamePrmIdx = sqlite3_bind_parameter_index(stmtHandle, KRawPrmName1); sl@0: TEST(firstNamePrmIdx >= 0); sl@0: TInt lastNamePrmIdx = sqlite3_bind_parameter_index(stmtHandle, KRawPrmName2); sl@0: TEST(lastNamePrmIdx >= 0); sl@0: TInt companyNamePrmIdx = sqlite3_bind_parameter_index(stmtHandle, KRawPrmName3); sl@0: TEST(companyNamePrmIdx >= 0); sl@0: TInt idIdx = sqlite3_bind_parameter_index(stmtHandle, KRawPrmName4); sl@0: TEST(idIdx >= 0); sl@0: sl@0: TUint32 start = User::FastCounter(); sl@0: for(TInt id=1;id<=KTestTecordCount;++id) sl@0: { sl@0: TBuf16<20> buf1; sl@0: buf1.Copy(KFirstName); sl@0: buf1.AppendNum(id); sl@0: buf1.Append(TChar(0)); sl@0: err = sqlite3_bind_text16(stmtHandle, firstNamePrmIdx, (const void*)buf1.Ptr(), -1, SQLITE_STATIC); sl@0: TEST2(err, SQLITE_OK); sl@0: TBuf16<20> buf2; sl@0: buf2.Copy(KLastName); sl@0: buf2.AppendNum(id); sl@0: buf2.Append(TChar(0)); sl@0: err = sqlite3_bind_text16(stmtHandle, lastNamePrmIdx, (const void*)buf2.Ptr(), -1, SQLITE_STATIC); sl@0: TEST2(err, SQLITE_OK); sl@0: TBuf16<20> buf3; sl@0: buf3.Copy(KCompanyName); sl@0: buf3.AppendNum(id); sl@0: buf3.Append(TChar(0)); sl@0: err = sqlite3_bind_text16(stmtHandle, companyNamePrmIdx, (const void*)buf3.Ptr(), -1, SQLITE_STATIC); sl@0: TEST2(err, SQLITE_OK); sl@0: err = sqlite3_bind_int(stmtHandle, idIdx, id); sl@0: TEST2(err, SQLITE_OK); sl@0: while((err = sqlite3_step(stmtHandle)) == SQLITE_ROW) sl@0: { sl@0: } sl@0: PanicIfError(aDbHandle, err); sl@0: err = sqlite3_reset(stmtHandle); sl@0: PanicIfError(aDbHandle, err); sl@0: } sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: err = sqlite3_finalize(stmtHandle); sl@0: TEST2(err, SQLITE_OK); sl@0: } sl@0: sl@0: //"UPDATE" test function (without parameters) - SQLITE sl@0: template void UpdateWPTest2(const TDesC& aDbName, const DESC& aUpdateSql); sl@0: sl@0: //Explicit UpdateWPTest2() template specialization for UTF8 encoded SQL strings sl@0: template <> void UpdateWPTest2(const TDesC& aDbName, const TDesC8& aUpdateSql) sl@0: { sl@0: TheTest.Printf(_L("\"Update (without parameters)\" test\r\n")); sl@0: TBuf<200> fmtstr; sl@0: fmtstr.Copy(aUpdateSql); sl@0: sl@0: sqlite3SymbianLibInit(); sl@0: sqlite3* dbHandle = TDbHelper2::Open(aDbName); sl@0: sl@0: TUint32 start = User::FastCounter(); sl@0: for(TInt id=1;id<=KTestTecordCount;++id) sl@0: { sl@0: TBuf<200> buf; sl@0: buf.Format(fmtstr, &KFirstName2, id, &KLastName2, id, &KCompanyName2, id, id); sl@0: TBuf8<200> sql; sl@0: sql.Copy(buf); sl@0: sql.Append(0); sl@0: TInt err = sqlite3_exec(dbHandle, (const char*)sql.Ptr(), 0, 0, 0); sl@0: TEST2(err, SQLITE_OK); sl@0: } sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: sl@0: TInt err2 = sqlite3_close(dbHandle); sl@0: TEST2(err2, SQLITE_OK); sl@0: sqlite3SymbianLibFinalize(); sl@0: CloseSTDLIB(); sl@0: } sl@0: sl@0: //Explicit UpdateWPTest2() template specialization for UTF16 encoded SQL strings sl@0: template <> void UpdateWPTest2(const TDesC& aDbName, const TDesC16& aUpdateSql) sl@0: { sl@0: TheTest.Printf(_L("\"Update (without parameters)\" test\r\n")); sl@0: sl@0: sqlite3SymbianLibInit(); sl@0: sqlite3* dbHandle = TDbHelper2::Open(aDbName); sl@0: sl@0: TUint32 start = User::FastCounter(); sl@0: for(TInt id=1;id<=KTestTecordCount;++id) sl@0: { sl@0: TBuf<200> sql; sl@0: sql.Format(aUpdateSql, &KFirstName2, id, &KLastName2, id, &KCompanyName2, id, id); sl@0: sql.Append(0); sl@0: sqlite3_stmt* stmtHandle = NULL; sl@0: const void* stmtTail = NULL; sl@0: TInt err = sqlite3_prepare16_v2(dbHandle, sql.Ptr(), -1, &stmtHandle, &stmtTail); sl@0: TEST2(err, SQLITE_OK); sl@0: if(stmtHandle) //stmtHandle can be NULL for statements like this: ";". sl@0: { sl@0: if(err == SQLITE_OK) sl@0: { sl@0: while((err = sqlite3_step(stmtHandle)) == SQLITE_ROW) sl@0: { sl@0: } sl@0: } sl@0: TInt err2 = sqlite3_finalize(stmtHandle); sl@0: TEST2(err2, SQLITE_OK); sl@0: TEST2(err, SQLITE_DONE); sl@0: } sl@0: } sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: sl@0: TInt err2 = sqlite3_close(dbHandle); sl@0: TEST2(err2, SQLITE_OK); sl@0: sqlite3SymbianLibFinalize(); sl@0: CloseSTDLIB(); sl@0: } sl@0: sl@0: template void SelectTest2(sqlite3* aDbHandle, const DESC& aSelectSql); sl@0: sl@0: //Explicit SelectTest2() template specialization for UTF8 encoded SQL strings sl@0: template <> void SelectTest2(sqlite3* aDbHandle, const TDesC8& aSelectSql) sl@0: { sl@0: TheTest.Printf(_L("\"Select\" test\r\n")); sl@0: HBufC8* sql = HBufC8::New(aSelectSql.Length() + 1); sl@0: TEST(sql != NULL); sl@0: sql->Des().Copy(aSelectSql); sl@0: sql->Des().Append(TChar(0)); sl@0: sl@0: sqlite3_stmt* stmtHandle = NULL; sl@0: const char* stmtTail = NULL; sl@0: TInt err = sqlite3_prepare_v2(aDbHandle, (const char*)sql->Des().Ptr(), -1, &stmtHandle, &stmtTail); sl@0: delete sql; sl@0: PanicIfError(aDbHandle, err); sl@0: sl@0: TUint32 start = User::FastCounter(); sl@0: while((err = sqlite3_step(stmtHandle)) == SQLITE_ROW) sl@0: { sl@0: TBuf8<20> buf; sl@0: const unsigned char* p = sqlite3_column_text(stmtHandle, 0); sl@0: buf.Copy(p, User::StringLength(p)); sl@0: TEST(buf.Length() > 0); sl@0: p = sqlite3_column_text(stmtHandle, 1); sl@0: buf.Copy(p, User::StringLength(p)); sl@0: TEST(buf.Length() > 0); sl@0: p = sqlite3_column_text(stmtHandle, 2); sl@0: buf.Copy(p, User::StringLength(p)); sl@0: TEST(buf.Length() > 0); sl@0: } sl@0: TEST2(err, SQLITE_DONE); sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: err = sqlite3_finalize(stmtHandle); sl@0: TEST2(err, SQLITE_OK); sl@0: } sl@0: sl@0: //Explicit SelectTest2() template specialization for UTF16 encoded SQL strings sl@0: template <> void SelectTest2(sqlite3* aDbHandle, const TDesC16& aSelectSql) sl@0: { sl@0: TheTest.Printf(_L("\"Select\" test\r\n")); sl@0: HBufC16* sql = HBufC16::New(aSelectSql.Length() + 1); sl@0: TEST(sql != NULL); sl@0: sql->Des().Copy(aSelectSql); sl@0: sql->Des().Append(TChar(0)); sl@0: sl@0: sqlite3_stmt* stmtHandle = NULL; sl@0: const void* stmtTail = NULL; sl@0: TInt err = sqlite3_prepare16_v2(aDbHandle, (const void*)sql->Des().Ptr(), -1, &stmtHandle, &stmtTail); sl@0: delete sql; sl@0: PanicIfError(aDbHandle, err); sl@0: sl@0: TUint32 start = User::FastCounter(); sl@0: while((err = sqlite3_step(stmtHandle)) == SQLITE_ROW) sl@0: { sl@0: TBuf16<20> buf; sl@0: const void* p = sqlite3_column_text16(stmtHandle, 0); sl@0: buf.Copy((const TUint16*)p, User::StringLength((const TUint16*)p)); sl@0: TEST(buf.Length() > 0); sl@0: p = sqlite3_column_text16(stmtHandle, 1); sl@0: buf.Copy((const TUint16*)p, User::StringLength((const TUint16*)p)); sl@0: TEST(buf.Length() > 0); sl@0: p = sqlite3_column_text16(stmtHandle, 2); sl@0: buf.Copy((const TUint16*)p, User::StringLength((const TUint16*)p)); sl@0: TEST(buf.Length() > 0); sl@0: } sl@0: TEST2(err, SQLITE_DONE); sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: err = sqlite3_finalize(stmtHandle); sl@0: TEST2(err, SQLITE_OK); sl@0: } sl@0: sl@0: template void DeleteTest2(sqlite3* aDbHandle, const DESC& aDeleteSql); sl@0: sl@0: //Explicit DeleteTest2() template specialization for UTF8 encoded SQL strings sl@0: template <> void DeleteTest2(sqlite3* aDbHandle, const TDesC8& aDeleteSql) sl@0: { sl@0: TheTest.Printf(_L("\"Delete\" test\r\n")); sl@0: HBufC8* sql = HBufC8::New(aDeleteSql.Length() + 1); sl@0: TEST(sql != NULL); sl@0: sql->Des().Copy(aDeleteSql); sl@0: sql->Des().Append(TChar(0)); sl@0: TUint32 start = User::FastCounter(); sl@0: TInt err = sqlite3_exec(aDbHandle, (const char*)sql->Des().Ptr(), 0, 0, 0); sl@0: TEST2(err, SQLITE_OK); sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: delete sql; sl@0: } sl@0: sl@0: //Explicit DeleteTest2() template specialization for UTF16 encoded SQL strings sl@0: template <> void DeleteTest2(sqlite3* aDbHandle, const TDesC16& aDeleteSql) sl@0: { sl@0: TheTest.Printf(_L("\"Delete\" test\r\n")); sl@0: HBufC16* sql = HBufC16::New(aDeleteSql.Length() + 1); sl@0: TEST(sql != NULL); sl@0: sql->Des().Copy(aDeleteSql); sl@0: sql->Des().Append(TChar(0)); sl@0: TUint32 start = User::FastCounter(); sl@0: sqlite3_stmt* stmtHandle = NULL; sl@0: const void* stmtTail = NULL; sl@0: TInt err = sqlite3_prepare16_v2(aDbHandle, sql->Des().Ptr(), -1, &stmtHandle, &stmtTail); sl@0: TEST2(err, SQLITE_OK); sl@0: if(stmtHandle) //stmtHandle can be NULL for statements like this: ";". sl@0: { sl@0: if(err == SQLITE_OK) sl@0: { sl@0: while((err = sqlite3_step(stmtHandle)) == SQLITE_ROW) sl@0: { sl@0: } sl@0: } sl@0: TInt err2 = sqlite3_finalize(stmtHandle); sl@0: TEST2(err2, SQLITE_OK); sl@0: TEST2(err, SQLITE_DONE); sl@0: } sl@0: TUint32 end = User::FastCounter(); sl@0: PrintStats(start, end); sl@0: delete sql; sl@0: } sl@0: sl@0: template void PerformanceTest2( sl@0: const TDesC& aDbFileName, sl@0: const DESC& aCommitStr, sl@0: const DESC& aUpdateSql, sl@0: const DESC& aSelectSql, sl@0: const DESC& aDeleteSql) sl@0: { sl@0: CFileMan* fm = NULL; sl@0: TRAPD(err, fm = CFileMan::NewL(TheFs)); sl@0: TEST2(err, KErrNone); sl@0: sl@0: sqlite3SymbianLibInit(); sl@0: TDbHelper2::Create(aDbFileName); sl@0: sl@0: sqlite3* dbHandle = TDbHelper2::Open(aDbFileName); sl@0: InsertTest2(dbHandle, KFillDbScript(), aCommitStr); sl@0: (void)sqlite3_close(dbHandle); dbHandle = NULL; sl@0: PrintFileSize(aDbFileName); sl@0: sl@0: dbHandle = TDbHelper2::Open(aDbFileName); sl@0: UpdateTest2(dbHandle, aUpdateSql); sl@0: (void)sqlite3_close(dbHandle); dbHandle = NULL; sl@0: sl@0: dbHandle = TDbHelper2::Open(aDbFileName); sl@0: SelectTest2(dbHandle, aSelectSql); sl@0: (void)sqlite3_close(dbHandle); dbHandle = NULL; sl@0: sl@0: (void)fm->Copy(aDbFileName, TheNonSecureTmpDbName); sl@0: sl@0: dbHandle = TDbHelper2::Open(aDbFileName); sl@0: DeleteTest2(dbHandle, aDeleteSql); sl@0: (void)sqlite3_close(dbHandle); dbHandle = NULL; sl@0: PrintFileSize(aDbFileName); sl@0: sl@0: sqlite3SymbianLibFinalize(); sl@0: CloseSTDLIB(); sl@0: sl@0: (void)fm->Copy(TheNonSecureTmpDbName, aDbFileName); sl@0: (void)fm->Delete(TheNonSecureTmpDbName); sl@0: delete fm; sl@0: } sl@0: //Explicit PerformanceTest2() template instantiations. sl@0: template void PerformanceTest2(const TDesC&, const TDesC8&, const TDesC8&, const TDesC8&, const TDesC8&); sl@0: template void PerformanceTest2(const TDesC&, const TDesC8&, const TDesC8&, const TDesC8&, const TDesC8&); sl@0: template void PerformanceTest2(const TDesC&, const TDesC16&, const TDesC16&, const TDesC16&, const TDesC16&); sl@0: template void PerformanceTest2(const TDesC&, const TDesC16&, const TDesC16&, const TDesC16&, const TDesC16&); sl@0: sl@0: void ColumnValueAccessTest() sl@0: { sl@0: _LIT(KColName1, "Column1"); sl@0: _LIT(KColName2, "Column2"); sl@0: _LIT(KColName3, "Column3"); sl@0: _LIT(KColName4, "Column4"); sl@0: const TInt KColCount = 4; sl@0: TPtrC colNames[KColCount] = {KColName1(), KColName2(), KColName3(), KColName4()}; sl@0: TBuf<100> sql; sl@0: sl@0: //Create a test database sl@0: RSqlDatabase db; sl@0: TInt err = db.Create(TheNonSecureDbName2, &TheSqlConfigString); sl@0: TEST2(err, KErrNone); sl@0: _LIT(KCreateSql, "CREATE TABLE A(%S INTEGER, %S INTEGER, %S INTEGER, %S INTEGER)"); sl@0: sql.Format(KCreateSql, &colNames[0], &colNames[1], &colNames[2], &colNames[3]); sl@0: err = db.Exec(sql); sl@0: TEST(err >= 0); sl@0: //Insert a record in the test database sl@0: _LIT(KInsertSql, "INSERT INTO A(%S, %S, %S, %S) VALUES(0, 1, 2, 3)"); sl@0: sql.Format(KInsertSql, &colNames[0], &colNames[1], &colNames[2], &colNames[3]); sl@0: err = db.Exec(sql); sl@0: TEST2(err, 1); sl@0: //Retrieve the record sl@0: RSqlStatement stmt; sl@0: err = stmt.Prepare(db, _L8("SELECT * FROM A")); sl@0: TEST2(err, KErrNone); sl@0: err = stmt.Next(); sl@0: TEST2(err, KSqlAtRow); sl@0: sl@0: //Init the random numbers generator sl@0: TInt64 seed = (TInt64)&ColumnValueAccessTest; sl@0: const TInt KTestCount = 20000; sl@0: TInt val; sl@0: sl@0: //Test 1: retrieve column values using the column index sl@0: TUint32 start = User::FastCounter(); sl@0: for(TInt i1=0;i1= 0); sl@0: sl@0: //Add 100 records to the table sl@0: for(TInt k=0;k<100;++k) sl@0: { sl@0: TBuf<100> sql; sl@0: sql.Format(_L("INSERT INTO A VALUES(%d, 'Dvorák')"), k + 1); sl@0: err = TheDb.Exec(sql); sl@0: TEST2(err, 1); sl@0: } sl@0: sl@0: //Update one record sl@0: err = TheDb.Exec(_L("UPDATE A SET Name='dvorak1' WHERE ID = 50")); sl@0: TEST2(err, 1); sl@0: sl@0: TUint32 start = User::FastCounter(); sl@0: sl@0: //Create a statement object and issue a SELECT SQL statement + LIKE clause sl@0: //Test case 1 = full name search with LIKE sl@0: RSqlStatement stmt; sl@0: err = stmt.Prepare(TheDb, _L("SELECT COUNT(*) FROM A WHERE Name LIKE 'DVORAK1'")); sl@0: TEST2(err, KErrNone); sl@0: err = stmt.Next(); sl@0: TEST2(err, KSqlAtRow); sl@0: TInt cnt = stmt.ColumnInt(0); sl@0: TEST2(cnt, 1); sl@0: sl@0: stmt.Close(); sl@0: sl@0: TUint32 end = User::FastCounter(); sl@0: TEST2(err, 1); sl@0: PrintStats(start, end); sl@0: sl@0: TheDb.Close(); sl@0: (void)RSqlDatabase::Delete(TheNonSecureDbName); sl@0: } sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////// sl@0: /////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-CT-1648 sl@0: @SYMTestCaseDesc SQL database performance tests. sl@0: Three test types used: "insert records", "update records" and "select records". sl@0: The tests are executed on: secure database, non-secure database, client side database. sl@0: Each test executed twice using UTF8 and UTF16 encoded SQL statements. sl@0: @SYMTestPriority High sl@0: @SYMTestActions SQL database performance tests. sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ5792 sl@0: REQ5793 sl@0: REQ5912 sl@0: REQ10273 sl@0: */ sl@0: void DoTests() sl@0: { sl@0: TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1648 SQL performance tests")); sl@0: sl@0: TheTest.Printf(_L("Single \"update\" test\r\n")); sl@0: SingleUpdateTest(); sl@0: sl@0: TheTest.Printf(_L("Single \"insert\" test\r\n")); sl@0: SingleInsertTest(); sl@0: sl@0: TheTest.Printf(_L("Single \"delete\" test\r\n")); sl@0: SingleDeleteTest(); sl@0: sl@0: TheTestTitle.Format(_L("SERVER, UTF8 SQL strings, non-secure, encoding: \"%S\", page size: %d\r\n"), sl@0: TheCmdLineParams.iDbEncoding == TCmdLineParams::EDbUtf16 ? &KUtf16 : &KUtf8, TheCmdLineParams.iPageSize); sl@0: TheTest.Printf(TheTestTitle); sl@0: PerformanceTest(TheNonSecureDbName, KCommitStr8(), KUpdateSql8(), KSelectSql8(), KDeleteSql8()); sl@0: sl@0: TheTestTitle.Format(_L("SERVER, UTF8 SQL strings, non-secure, update test (without parameters), encoding: \"%S\", page size: %d\r\n"), sl@0: TheCmdLineParams.iDbEncoding == TCmdLineParams::EDbUtf16 ? &KUtf16 : &KUtf8, TheCmdLineParams.iPageSize); sl@0: TheTest.Printf(TheTestTitle); sl@0: UpdateWPTest, TDesC8, ENonSecureDb>(TheNonSecureDbName, KUpdateSql2_8()); sl@0: sl@0: TheTestTitle.Format(_L("SERVER, UTF8 SQL strings, secure, encoding: \"%S\", page size: %d\r\n"), sl@0: TheCmdLineParams.iDbEncoding == TCmdLineParams::EDbUtf16 ? &KUtf16 : &KUtf8, TheCmdLineParams.iPageSize); sl@0: TheTest.Printf(TheTestTitle); sl@0: PerformanceTest(TheSecureDbName, KCommitStr8(), KUpdateSql8(), KSelectSql8(), KDeleteSql8()); sl@0: sl@0: TheTest.Printf(_L("SQLITE, UTF8 encoded database, UTF8 SQL strings\r\n")); sl@0: PerformanceTest2(TheNonSecureDbName, KCommitStr8(), KUpdateSql8(), KSelectSql8(), KDeleteSql8()); sl@0: sl@0: TheTest.Printf(_L("SQLITE, UTF8 encoded database, UTF8 SQL strings, update test (without parameters)\r\n")); sl@0: UpdateWPTest2(TheNonSecureDbName, KUpdateSql2_8()); sl@0: sl@0: TheTest.Printf(_L("SQLITE, UTF16 encoded database, UTF8 SQL strings\r\n")); sl@0: PerformanceTest2(TheNonSecureDbName, KCommitStr8(), KUpdateSql8(), KSelectSql8(), KDeleteSql8()); sl@0: sl@0: TheTestTitle.Format(_L("SERVER, UTF16 SQL strings, non-secure, encoding: \"%S\", page size: %d\r\n"), sl@0: TheCmdLineParams.iDbEncoding == TCmdLineParams::EDbUtf16 ? &KUtf16 : &KUtf8, TheCmdLineParams.iPageSize); sl@0: TheTest.Printf(TheTestTitle); sl@0: PerformanceTest(TheNonSecureDbName, KCommitStr16(), KUpdateSql16(), KSelectSql16(), KDeleteSql16()); sl@0: sl@0: TheTestTitle.Format(_L("SERVER, UTF16 SQL strings, non-secure, update test (without parameters), encoding: \"%S\", page size: %d\r\n"), sl@0: TheCmdLineParams.iDbEncoding == TCmdLineParams::EDbUtf16 ? &KUtf16 : &KUtf8, TheCmdLineParams.iPageSize); sl@0: TheTest.Printf(TheTestTitle); sl@0: UpdateWPTest, TDesC16, ENonSecureDb>(TheNonSecureDbName, KUpdateSql2_16()); sl@0: sl@0: TheTestTitle.Format(_L("SERVER, UTF16 SQL strings, secure, encoding: \"%S\", page size: %d\r\n"), sl@0: TheCmdLineParams.iDbEncoding == TCmdLineParams::EDbUtf16 ? &KUtf16 : &KUtf8, TheCmdLineParams.iPageSize); sl@0: TheTest.Printf(TheTestTitle); sl@0: PerformanceTest(TheSecureDbName, KCommitStr16(), KUpdateSql16(), KSelectSql16(), KDeleteSql16()); sl@0: sl@0: TheTest.Printf(_L("SQLITE, UTF8 encoded database, UTF16 SQL strings\r\n")); sl@0: PerformanceTest2(TheNonSecureDbName, KCommitStr16(), KUpdateSql16(), KSelectSql16(), KDeleteSql16()); sl@0: sl@0: TheTest.Printf(_L("SQLITE, UTF16 encoded database, UTF16 SQL strings\r\n")); sl@0: PerformanceTest2(TheNonSecureDbName, KCommitStr16(), KUpdateSql16(), KSelectSql16(), KDeleteSql16()); sl@0: sl@0: TheTest.Printf(_L("SQLITE, UTF16 encoded database, UTF16 SQL strings, update test (without parameters)\r\n")); sl@0: UpdateWPTest2(TheNonSecureDbName, KUpdateSql2_16()); sl@0: sl@0: TheTest.Printf(_L("Accessing column value by index or by name\r\n")); sl@0: ColumnValueAccessTest(); sl@0: sl@0: TheTest.Printf(_L("Retrieving data from UTF8 Database using SELECT LIKE statements\r\n")); sl@0: SelectLikeQueryPerfTest(); sl@0: sl@0: } sl@0: sl@0: TInt E32Main() sl@0: { sl@0: TheTest.Title(); sl@0: sl@0: CTrapCleanup* tc = CTrapCleanup::New(); sl@0: TheTest(tc != NULL); sl@0: sl@0: GetCmdLineParamsAndSqlConfigString(TheTest, _L("t_sqlperformance"), TheCmdLineParams, TheSqlConfigString); sl@0: _LIT(KSecureDbName, "c:[2121212A]t_perfdb.db"); sl@0: PrepareDbName(KSecureDbName, TheCmdLineParams.iDriveName, TheSecureDbName); sl@0: _LIT(KNonSecureDbName, "c:\\test\\t_perfdb.db"); sl@0: PrepareDbName(KNonSecureDbName, TheCmdLineParams.iDriveName, TheNonSecureDbName); sl@0: _LIT(KNonSecureDbName2, "c:\\test\\t_perfdb2.db"); sl@0: PrepareDbName(KNonSecureDbName2, TheCmdLineParams.iDriveName, TheNonSecureDbName2); sl@0: _LIT(KNonSecureTmpDbName, "c:\\test\\tmp.db"); sl@0: PrepareDbName(KNonSecureTmpDbName, TheCmdLineParams.iDriveName, TheNonSecureTmpDbName); sl@0: _LIT(KSglRecDbName, "c:\\test\\default_avacon.dbSQL"); sl@0: PrepareDbName(KSglRecDbName, TheCmdLineParams.iDriveName, TheSglRecDbFileName); sl@0: sl@0: TheTest.Printf(_L("==Databases: %S, %S, %S, %S, %S\r\n"), &TheSecureDbName, &TheNonSecureDbName, sl@0: &TheNonSecureDbName2, &TheNonSecureTmpDbName, sl@0: &TheSglRecDbFileName); sl@0: sl@0: __UHEAP_MARK; sl@0: sl@0: TestEnvInit(); sl@0: DoTests(); sl@0: TestEnvDestroy(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: sl@0: TheTest.End(); sl@0: TheTest.Close(); sl@0: sl@0: delete tc; sl@0: sl@0: User::Heap().Check(); sl@0: return KErrNone; sl@0: }