persistentstorage/sql/SRC/Server/SqlSrvResourceProfiler.cpp
changeset 0 08ec8eefde2f
child 11 211563e4b919
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/sql/SRC/Server/SqlSrvResourceProfiler.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,1032 @@
+// Copyright (c) 2008-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 <e32std.h>
+#include <e32debug.h>
+#include <f32file.h>
+#include "SqlPanic.h"
+#include "SqlSrvResourceProfiler.h"
+#include "SqlResourceProfiler.h"
+#include "SqliteSymbian.h"
+#include <hal.h>
+
+#ifdef _SQLPROFILER
+
+///////////////////////////////// Heap max alloc /////////////////////////////////////
+
+/**
+If true the max alloc profiling is enabled.
+@internalComponent
+*/
+TBool TheSqlSrvProfilerMaxAllocEnabled = EFalse;
+/**
+The size of the biggest memory block ever allocated by the SQL server.
+Set only if compiled with _SQLPROFILER macro.
+@internalComponent
+*/
+TInt  TheSqlSrvProfilerMaxAllocSize = 0;
+
+////////////////////////// IPC & SQL tracing related //////////////////////////////////
+
+/**
+If true the tracing is enabled (IPC calls & SQL statements).
+@internalComponent
+*/
+static TBool TheSqlSrvProfilerTraceEnabled = EFalse;
+/**
+Trace level:
+ - 0: no IPC calls traced (default);
+ - 1: only the 10 most important IPC calls traced - SQL statement execution, ....
+ - 2: all IPC calls traced; 
+@internalComponent
+*/
+static TInt TheSqlSrvProfilerTraceLevel = 0;
+/**
+If true the SQL statement tracing is enabled.
+@internalComponent
+*/
+static TBool TheSqlSrvProfilerSqlTraceEnabled = EFalse;
+
+/**
+When the SQL server boots, TheSqlSrvStartTime will be initialized with the current time then. 
+@internalComponent
+*/
+TTime TheSqlSrvStartTime = 0;
+
+/**
+When KSqlSrvProfilerDbName is with non-zero length, then only traces coming from database identified by
+KSqlSrvProfilerDbName name are printed out. 
+@internalComponent
+*/
+//_LIT(KSqlSrvProfilerDbName, "default_avacon.dbSQL");
+_LIT(KSqlSrvProfilerDbName, "");
+static TUint TheSqlSrvProfilerHandle = 0;
+
+//File "read", "write", "sync" and "set size" counters, incremented inside the OS porting layer.
+TInt TheSqlSrvProfilerFileRead = 0;
+TInt TheSqlSrvProfilerFileWrite = 0;
+TInt TheSqlSrvProfilerFileSync = 0;
+TInt TheSqlSrvProfilerFileSetSize = 0;
+
+static TInt TheSqlSrvProfilerFileRead1 = 0;
+static TInt TheSqlSrvProfilerFileWrite1 = 0;
+static TInt TheSqlSrvProfilerFileSync1 = 0;
+static TInt TheSqlSrvProfilerFileSetSize1 = 0;
+
+//Set it to true if you want traces to be stored into a file.
+static TBool TheSqlSrvProfilerTraceToFile = EFalse;
+
+//"Prepared" and "Executed" SQL statement counters
+static TInt TheSqlSrvProfilerPreparedCnt8;
+static TInt TheSqlSrvProfilerPreparedCnt16;
+static TInt TheSqlSrvProfilerExecutedCnt8;
+static TInt TheSqlSrvProfilerExecutedCnt16;
+
+///////////////////////////////// IPC counters ///////////////////////////////////////
+
+/**
+If true the IPC profiling is enabled.
+@internalComponent
+*/
+TBool TheSqlSrvProfilerIpcEnabled = EFalse;
+/**
+IPC requests, read and write counters.
+@internalComponent
+*/
+TInt  TheSqlSrvProfilerIpc[ESqlIpcLast] = {0};
+/**
+IPC read and write - bytes.
+@internalComponent
+*/
+TInt64 TheSqlSrvProfilerIpcBytes[ESqlIpcLast] = {0};
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+/**
+Starts the specified profiling counter.
+
+@leave KErrNotSupported, The requested profiling type is not supported;
+                 		 The function may also leave with some other system-wide error codes.
+
+Usage of the IPC call arguments:
+ - Arg 0: [in]  profiling counter type, one of the TSqlResourceProfiler::TSqlCounter enum item values.
+ - Arg 1: [in]  the length of the additional profiling parameters.
+ - Arg 2: [in]  additional profiling parameters.
+*/
+void TSqlSrvResourceProfiler::StartL(const RMessage2& aMessage)
+	{
+	const TSqlResourceProfiler::TSqlCounter KCounterType = static_cast <TSqlResourceProfiler::TSqlCounter> (aMessage.Int0());
+	TInt err = KErrNone;
+	switch(KCounterType)
+		{
+		case TSqlResourceProfiler::ESqlCounterFileIO:
+		case TSqlResourceProfiler::ESqlCounterOsCall:
+		case TSqlResourceProfiler::ESqlCounterOsCallTime:
+		case TSqlResourceProfiler::ESqlCounterOsCallDetails:
+			err = sqlite3SymbianProfilerStart(KCounterType);
+			break;
+		case TSqlResourceProfiler::ESqlCounterIpc:
+			TheSqlSrvProfilerIpcEnabled = ETrue;
+			break;
+		case TSqlResourceProfiler::ESqlCounterMemory:
+			err = sqlite3SymbianProfilerStart(KCounterType);
+			break;
+		case TSqlResourceProfiler::ESqlCounterMaxAlloc:
+			TheSqlSrvProfilerMaxAllocEnabled = ETrue;
+			err = sqlite3SymbianProfilerStart(KCounterType);
+			break;
+		case TSqlResourceProfiler::ESqlCounterTrace:
+		    {
+			TheSqlSrvProfilerTraceEnabled = ETrue;
+		    TInt len = aMessage.Int1();
+		    __SQLPANIC_CLIENT((TUint)len < 64, aMessage, ESqlPanicBadArgument);
+		    if(len > 0)
+		        {
+                TBuf8<64> prmBuf;
+                aMessage.ReadL(2, prmBuf);
+                prmBuf.UpperCase();
+                TPtrC8 ptr(prmBuf);
+                _LIT8(KLevel0, "L0");
+                _LIT8(KLevel1, "L1");
+                _LIT8(KLevel2, "L2");
+                _LIT8(KSqlStmtTraceOff, "S0");
+                _LIT8(KSqlStmtTraceOn, "S1");
+                while(ptr.Length() > 0)
+                    {
+                    TInt pos = ptr.Locate(TChar(';'));
+                    TPtrC8 str = ptr;
+                    if(pos >= 0)
+                        {
+                        str.Set(ptr.Left(pos));
+                        }
+                    if(str == KLevel0)
+                        {
+                        TheSqlSrvProfilerTraceLevel = 0;
+                        }
+                    else if(str == KLevel1)
+                        {
+                        TheSqlSrvProfilerTraceLevel = 1;
+                        }
+                    else if(str == KLevel2)
+                        {
+                        TheSqlSrvProfilerTraceLevel = 2;
+                        }
+                    else if(str == KSqlStmtTraceOff)
+                        {
+                        TheSqlSrvProfilerSqlTraceEnabled = EFalse;
+                        }
+                    else if(str == KSqlStmtTraceOn)
+                        {
+                        TheSqlSrvProfilerSqlTraceEnabled = ETrue;
+                        }
+                    if((TUint)pos > (ptr.Length() - 1))
+                        {
+                        break;
+                        }
+                    ptr.Set(ptr.Mid(pos + 1));
+                    }
+		        }
+		    }
+			break;
+		default:
+			err = KErrNotSupported;
+			break;
+		}
+	__SQLLEAVE_IF_ERROR(err);
+	}
+	
+/**
+Stops the specified profiling counter.
+
+@leave KErrNotSupported, The requested profiling type is not supported;
+                 		 The function may also leave with some other system-wide error codes.
+
+Usage of the IPC call arguments:
+ - Arg 0: [in]  profiling counter type, one of the TSqlResourceProfiler::TSqlCounter enum item values.
+*/
+void TSqlSrvResourceProfiler::StopL(const RMessage2& aMessage)
+	{
+	const TSqlResourceProfiler::TSqlCounter KCounterType = static_cast <TSqlResourceProfiler::TSqlCounter> (aMessage.Int0());
+	TInt err = KErrNone;
+	switch(KCounterType)
+		{
+		case TSqlResourceProfiler::ESqlCounterFileIO:
+		case TSqlResourceProfiler::ESqlCounterOsCall:
+		case TSqlResourceProfiler::ESqlCounterOsCallTime:
+		case TSqlResourceProfiler::ESqlCounterOsCallDetails:
+			err = sqlite3SymbianProfilerStop(KCounterType);
+			break;
+		case TSqlResourceProfiler::ESqlCounterIpc:
+			TheSqlSrvProfilerIpcEnabled = EFalse;
+			break;
+		case TSqlResourceProfiler::ESqlCounterMemory:
+			err = sqlite3SymbianProfilerStop(KCounterType);
+			break;
+		case TSqlResourceProfiler::ESqlCounterMaxAlloc:
+			TheSqlSrvProfilerMaxAllocEnabled = EFalse;
+			err = sqlite3SymbianProfilerStop(KCounterType);
+			break;
+        case TSqlResourceProfiler::ESqlCounterTrace:
+            TheSqlSrvProfilerTraceEnabled = EFalse;
+            TheSqlSrvProfilerSqlTraceEnabled = EFalse;
+            TheSqlSrvProfilerTraceLevel = 0;
+            TheSqlSrvProfilerHandle = 0;
+            break;
+		default:
+			err = KErrNotSupported;
+			break;
+		}
+	__SQLLEAVE_IF_ERROR(err);
+	}
+	
+/**
+Resets the specified profiling counter.
+
+@leave KErrNotSupported, The requested profiling type is not supported;
+                 		 The function may also leave with some other system-wide error codes.
+
+Usage of the IPC call arguments:
+ - Arg 0: [in]  profiling counter type, one of the TSqlResourceProfiler::TSqlCounter enum item values.
+*/
+void TSqlSrvResourceProfiler::ResetL(const RMessage2& aMessage)
+	{
+	const TSqlResourceProfiler::TSqlCounter KCounterType = static_cast <TSqlResourceProfiler::TSqlCounter> (aMessage.Int0());
+	TInt err = KErrNone;
+	switch(KCounterType)
+		{
+		case TSqlResourceProfiler::ESqlCounterFileIO:
+		case TSqlResourceProfiler::ESqlCounterOsCall:
+		case TSqlResourceProfiler::ESqlCounterOsCallTime:
+		case TSqlResourceProfiler::ESqlCounterOsCallDetails:
+			err = sqlite3SymbianProfilerReset(KCounterType);
+			break;
+		case TSqlResourceProfiler::ESqlCounterIpc:
+			Mem::FillZ(TheSqlSrvProfilerIpc, sizeof(TheSqlSrvProfilerIpc));
+			Mem::FillZ(TheSqlSrvProfilerIpcBytes, sizeof(TheSqlSrvProfilerIpcBytes));
+			break;
+		case TSqlResourceProfiler::ESqlCounterMemory:
+			err = sqlite3SymbianProfilerReset(KCounterType);
+			break;
+		case TSqlResourceProfiler::ESqlCounterMaxAlloc:
+			TheSqlSrvProfilerMaxAllocSize = 0;
+			err = sqlite3SymbianProfilerReset(KCounterType);
+			break;
+        case TSqlResourceProfiler::ESqlCounterTrace:
+            break;
+		default:
+			err = KErrNotSupported;
+			break;
+		}
+	__SQLLEAVE_IF_ERROR(err);
+	}
+	
+/**
+Retrieves the counter values for the specified profiling counter.
+
+@leave KErrNotSupported, The requested profiling type is not supported;
+                 		 The function may also leave with some other system-wide error codes.
+
+@see TSqlResourceProfiler
+
+Usage of the IPC call arguments:
+ - Arg 0: [in]  profiling counter type, one of the TSqlResourceProfiler::TSqlCounter enum item values.
+ - Arg 1: [in]  the size of the buffer for the profiling counter values.
+ - Arg 2: [out] the buffer for the profiling counter values.
+*/
+void TSqlSrvResourceProfiler::QueryL(const RMessage2& aMessage)
+	{
+	const TSqlResourceProfiler::TSqlCounter KCounterType = static_cast <TSqlResourceProfiler::TSqlCounter> (aMessage.Int0());
+	const TInt KIpcBufLen = 300;
+	TBuf8<KIpcBufLen> ipcBuf;
+	TInt err = KErrNone;
+	switch(KCounterType)
+		{
+		case TSqlResourceProfiler::ESqlCounterFileIO:
+		case TSqlResourceProfiler::ESqlCounterOsCall:
+		case TSqlResourceProfiler::ESqlCounterOsCallTime:
+		case TSqlResourceProfiler::ESqlCounterOsCallDetails:
+			err = sqlite3SymbianProfilerQuery(KCounterType, ipcBuf);
+			break;
+		case TSqlResourceProfiler::ESqlCounterIpc:
+			ipcBuf.AppendNum(TheSqlSrvProfilerIpc[ESqlIpcRq]);
+			ipcBuf.Append(TChar(';'));
+			ipcBuf.AppendNum(TheSqlSrvProfilerIpc[ESqlIpcRead]);
+			ipcBuf.Append(TChar(';'));
+			ipcBuf.AppendNum(TheSqlSrvProfilerIpc[ESqlIpcWrite]);
+			ipcBuf.Append(TChar(';'));
+			ipcBuf.AppendNum(TheSqlSrvProfilerIpcBytes[ESqlIpcRead]);
+			ipcBuf.Append(TChar(';'));
+			ipcBuf.AppendNum(TheSqlSrvProfilerIpcBytes[ESqlIpcWrite]);
+			ipcBuf.Append(TChar(';'));
+			break;
+		case TSqlResourceProfiler::ESqlCounterMemory:
+			{
+			TInt totalAllocCells = 0;
+			TInt totalAllocSize = 0;
+			TInt totalFreeSpace = 0;
+			TInt biggestBlockSize = 0;
+			RHeap& heap = User::Heap();;
+			totalAllocCells = heap.AllocSize(totalAllocSize);
+			totalFreeSpace = heap.Available(biggestBlockSize);
+			ipcBuf.AppendNum(totalAllocCells);
+			ipcBuf.Append(TChar(';'));
+			ipcBuf.AppendNum(totalAllocSize);
+			ipcBuf.Append(TChar(';'));
+			ipcBuf.AppendNum(totalFreeSpace);
+			ipcBuf.Append(TChar(';'));
+			ipcBuf.AppendNum(biggestBlockSize);
+			ipcBuf.Append(TChar(';'));
+			err = sqlite3SymbianProfilerQuery(KCounterType, ipcBuf);
+			}
+			break;
+		case TSqlResourceProfiler::ESqlCounterMaxAlloc:
+			ipcBuf.AppendNum(TheSqlSrvProfilerMaxAllocSize);
+			ipcBuf.Append(TChar(';'));
+			err = sqlite3SymbianProfilerQuery(KCounterType, ipcBuf);
+			break;
+        case TSqlResourceProfiler::ESqlCounterTrace:
+            break;
+		default:
+			err = KErrNotSupported;
+			break;
+		}
+	__SQLLEAVE_IF_ERROR(err);
+	aMessage.WriteL(2, ipcBuf);
+	}
+	
+////////////////////////// IPC tracing related ////////////////////////////////////////
+
+//Max trace line length
+const TInt KSqlTraceMaxLength = 220;
+//Trace buffer.
+static TBuf<KSqlTraceMaxLength> TheSqlTraceBuf;
+
+//IPC calls names - begin
+_LIT(KSqlSrvDbCreate, "DbCreate");
+_LIT(KSqlSrvDbCreateSecure, "DbCreateSecure");
+_LIT(KSqlSrvDbOpen, "DbOpen");
+_LIT(KSqlSrvDbOpenFromHandle, "DbOpenFromHandle");
+_LIT(KSqlSrvDbClose, "DbClose");
+_LIT(KSqlSrvDbCopy, "DbCopy");
+_LIT(KSqlSrvDbDelete, "DbDelete");
+_LIT(KSqlSrvLastErrorMsg, "LastErrorMsg");
+_LIT(KSqlSrvDbExec8, "DbExec8");
+_LIT(KSqlSrvDbExec16, "DbExec16");
+_LIT(KSqlSrvDbSetIsolationLevel, "DbSetIsolationLevel");
+_LIT(KSqlSrvDbGetSecurityPolicy, "DbGetSecurityPolicy");
+_LIT(KSqlSrvDbAttach, "DbAttach");
+_LIT(KSqlSrvDbAttachFromHandle, "DbAttachFromHandle");
+_LIT(KSqlSrvDbDetach, "DbDetach");
+_LIT(KSqlSrvDbScalarFullSelect8, "DbScalarFullSelect8");
+_LIT(KSqlSrvDbScalarFullSelect16, "DbScalarFullSelect16");
+_LIT(KSqlSrvDbInTransaction, "DbInTransaction");
+_LIT(KSqlSrvDbSize, "DbSize");
+_LIT(KSqlSrvDbSize2, "DbSize2");
+_LIT(KSqlSrvDbBlobSource, "DbBlobSource");
+_LIT(KSqlSrvDbLastInsertedRowId, "DbLastInsertedRowId");
+_LIT(KSqlSrvDbCompact, "DbCompact");
+_LIT(KSqlSrvDbReserveDriveSpace, "DbReserveDriveSpace");
+_LIT(KSqlSrvDbFreeReservedSpace, "DbFreeReservedSpace");
+_LIT(KSqlSrvDbGetReserveAccess, "DbGetReserveAccess");
+_LIT(KSqlSrvDbReleaseReserveAccess, "DbReleaseReserveAccess");
+_LIT(KSqlSrvStmtPrepare8, "StmtPrepare8");
+_LIT(KSqlSrvStmtPrepare16, "StmtPrepare16");
+_LIT(KSqlSrvStmtClose, "StmtClose");
+_LIT(KSqlSrvStmtReset, "StmtReset");
+_LIT(KSqlSrvStmtExec, "StmtExec");
+_LIT(KSqlSrvStmtAsyncExec, "StmtAsyncExec");
+_LIT(KSqlSrvStmtBindExec, "StmtBindExec");
+_LIT(KSqlSrvStmtAsyncBindExec, "StmtAsyncBindExec");
+_LIT(KSqlSrvStmtNext, "StmtNext");
+_LIT(KSqlSrvStmtBindNext, "StmtBindNext");
+_LIT(KSqlSrvStmtColumnNames, "StmtColumnNames");
+_LIT(KSqlSrvStmtParamNames, "StmtParamNames");
+_LIT(KSqlSrvStmtColumnSource, "StmtColumnSource");
+_LIT(KSqlSrvStmtBinParamSink, "StmtBinParamSink");
+_LIT(KSqlSrvStmtTxtParamSink16, "StmtTxtParamSink16");
+_LIT(KSqlSrvStmtBufFlat, "StmtBufFlat");
+_LIT(KSqlSrvStmtColumnValue, "StmtColumnValue");
+_LIT(KSqlSrvStmtDeclColumnTypes, "StmtDeclColumnTypes");
+_LIT(KSqlSrvStreamRead, "StreamRead");
+_LIT(KSqlSrvStreamWrite, "StreamWrite");
+_LIT(KSqlSrvStreamSize, "StreamSize");
+_LIT(KSqlSrvStreamSynch, "StreamSynch");
+_LIT(KSqlSrvStreamClose, "StreamClose");
+//IPC calls names - end
+
+//Gets as an argument the IPC call type in "aCode" parameter.
+//Returns: 
+// 0 or positive integer: the IPC call is one of the 10 most important IPC calls (trace level 0).
+// KErrNotFound         : the IPC call is some of the other possible call types (trace level 1).
+// KErrNotSupported     : unknown IPC call type.
+//
+// aIpcCallName will always be set to IPC call name descriptor.
+static TInt SqlIpcTraceIdxAndName(TSqlSrvFunction aCode, TPtrC& aIpcCallName)
+    {
+    TInt rc = KErrNotFound;
+    switch(aCode)
+        {
+        case ESqlSrvDbCreate:
+            aIpcCallName.Set(KSqlSrvDbCreate);
+            break;
+        case ESqlSrvDbCreateSecure:
+            aIpcCallName.Set(KSqlSrvDbCreateSecure);
+            break;
+        case ESqlSrvDbOpen:
+            aIpcCallName.Set(KSqlSrvDbOpen);
+            break;
+        case ESqlSrvDbOpenFromHandle:
+            aIpcCallName.Set(KSqlSrvDbOpenFromHandle);
+            break;
+        case ESqlSrvDbClose:
+            aIpcCallName.Set(KSqlSrvDbClose);
+            break;
+        case ESqlSrvDbCopy:
+            aIpcCallName.Set(KSqlSrvDbCopy);
+            break;
+        case ESqlSrvDbDelete:
+            aIpcCallName.Set(KSqlSrvDbDelete);
+            break;
+        case ESqlSrvLastErrorMsg:
+            aIpcCallName.Set(KSqlSrvLastErrorMsg);
+            break;
+        case ESqlSrvDbExec8:
+            aIpcCallName.Set(KSqlSrvDbExec8);
+            rc = 0;
+            break;
+        case ESqlSrvDbExec16:
+            aIpcCallName.Set(KSqlSrvDbExec16);
+            rc = 1;
+            break;
+        case ESqlSrvDbSetIsolationLevel:
+            aIpcCallName.Set(KSqlSrvDbSetIsolationLevel);
+            break;
+        case ESqlSrvDbGetSecurityPolicy:
+            aIpcCallName.Set(KSqlSrvDbGetSecurityPolicy);
+            break;
+        case ESqlSrvDbAttach:
+            aIpcCallName.Set(KSqlSrvDbAttach);
+            break;
+        case ESqlSrvDbAttachFromHandle:
+            aIpcCallName.Set(KSqlSrvDbAttachFromHandle);
+            break;
+        case ESqlSrvDbDetach:
+            aIpcCallName.Set(KSqlSrvDbDetach);
+            break;
+        case ESqlSrvDbScalarFullSelect8:
+            aIpcCallName.Set(KSqlSrvDbScalarFullSelect8);
+            rc = 2;
+            break;
+        case ESqlSrvDbScalarFullSelect16:
+            aIpcCallName.Set(KSqlSrvDbScalarFullSelect16);
+            rc = 3;
+            break;
+        case ESqlSrvDbInTransaction:
+            aIpcCallName.Set(KSqlSrvDbInTransaction);
+            break;
+        case ESqlSrvDbSize:
+            aIpcCallName.Set(KSqlSrvDbSize);
+            break;
+        case ESqlSrvDbSize2:
+            aIpcCallName.Set(KSqlSrvDbSize2);
+            break;
+        case ESqlSrvDbBlobSource:
+            aIpcCallName.Set(KSqlSrvDbBlobSource);
+            break;
+        case ESqlSrvDbLastInsertedRowId:
+            aIpcCallName.Set(KSqlSrvDbLastInsertedRowId);
+            break;
+        case ESqlSrvDbCompact:
+            aIpcCallName.Set(KSqlSrvDbCompact);
+            break;
+        case ESqlSrvDbReserveDriveSpace:
+            aIpcCallName.Set(KSqlSrvDbReserveDriveSpace);
+            break;
+        case ESqlSrvDbFreeReservedSpace:
+            aIpcCallName.Set(KSqlSrvDbFreeReservedSpace);
+            break;
+        case ESqlSrvDbGetReserveAccess:
+            aIpcCallName.Set(KSqlSrvDbGetReserveAccess);
+            break;
+        case ESqlSrvDbReleaseReserveAccess:
+            aIpcCallName.Set(KSqlSrvDbReleaseReserveAccess);
+            break;
+        case ESqlSrvStmtPrepare8:
+            aIpcCallName.Set(KSqlSrvStmtPrepare8);
+            break;
+        case ESqlSrvStmtPrepare16:
+            aIpcCallName.Set(KSqlSrvStmtPrepare16);
+            break;
+        case ESqlSrvStmtClose:
+            aIpcCallName.Set(KSqlSrvStmtClose);
+            break;
+        case ESqlSrvStmtReset:
+            aIpcCallName.Set(KSqlSrvStmtReset);
+            break;
+        case ESqlSrvStmtExec:
+            aIpcCallName.Set(KSqlSrvStmtExec);
+            rc = 4;
+            break;
+        case ESqlSrvStmtAsyncExec:
+            aIpcCallName.Set(KSqlSrvStmtAsyncExec);
+            rc = 5;
+            break;
+        case ESqlSrvStmtBindExec:
+            aIpcCallName.Set(KSqlSrvStmtBindExec);
+            rc = 6;
+            break;
+        case ESqlSrvStmtAsyncBindExec:
+            aIpcCallName.Set(KSqlSrvStmtAsyncBindExec);
+            rc = 7;
+            break;
+        case ESqlSrvStmtNext:
+            aIpcCallName.Set(KSqlSrvStmtNext);
+            rc = 8;
+            break;
+        case ESqlSrvStmtBindNext:
+            aIpcCallName.Set(KSqlSrvStmtBindNext);
+            rc = 9;
+            break;
+        case ESqlSrvStmtColumnNames:
+            aIpcCallName.Set(KSqlSrvStmtColumnNames);
+            break;
+        case ESqlSrvStmtParamNames:
+            aIpcCallName.Set(KSqlSrvStmtParamNames);
+            break;
+        case ESqlSrvStmtColumnSource:
+            aIpcCallName.Set(KSqlSrvStmtColumnSource);
+            break;
+        case ESqlSrvStmtBinParamSink:
+            aIpcCallName.Set(KSqlSrvStmtBinParamSink);
+            break;
+        case ESqlSrvStmtTxtParamSink16:
+            aIpcCallName.Set(KSqlSrvStmtTxtParamSink16);
+            break;
+        case ESqlSrvStmtBufFlat:
+            aIpcCallName.Set(KSqlSrvStmtBufFlat);
+            break;
+        case ESqlSrvStmtColumnValue:
+            aIpcCallName.Set(KSqlSrvStmtColumnValue);
+            break;
+        case ESqlSrvStmtDeclColumnTypes:
+            aIpcCallName.Set(KSqlSrvStmtDeclColumnTypes);
+            break;
+        case ESqlSrvStreamRead:
+            aIpcCallName.Set(KSqlSrvStreamRead);
+            break;
+        case ESqlSrvStreamWrite:
+            aIpcCallName.Set(KSqlSrvStreamWrite);
+            break;
+        case ESqlSrvStreamSize:
+            aIpcCallName.Set(KSqlSrvStreamSize);
+            break;
+        case ESqlSrvStreamSynch:
+            aIpcCallName.Set(KSqlSrvStreamSynch);
+            break;
+        case ESqlSrvStreamClose:
+            aIpcCallName.Set(KSqlSrvStreamClose);
+            break;
+        default:
+            return KErrNotSupported;
+        };
+    __SQLASSERT((TUint)rc < KIpcTraceTypeCount || rc == KErrNotFound, ESqlPanicInternalError);
+    return rc;
+    }
+
+//Calculates and returns the time difference between aStartTicks and aEndTicks in microseconds.  
+static TInt SqlConvertTicks2Us(TUint32 aStartTicks, TUint32 aEndTicks)
+    {
+    static TInt freq = 0;
+    if(freq == 0)
+        {
+        TInt err = HAL::Get(HAL::EFastCounterFrequency, freq);
+        if(err != KErrNone)
+            {
+            SqlPanic((TSqlPanic)err);
+            }
+        }
+    TInt64 diffTicks = (TInt64)aEndTicks - (TInt64)aStartTicks;
+    if(diffTicks < 0)
+        {
+        diffTicks = KMaxTUint32 + diffTicks + 1;
+        }
+    const TInt KMicroSecIn1Sec = 1000000;
+    TInt32 us = (diffTicks * KMicroSecIn1Sec) / freq;
+    return us;
+    }
+
+//Calculates the time since the SQL server boot in microseconds.
+static TInt64 SqlTimeFromStartUs()
+    {
+    TTime time;
+    time.UniversalTime();
+    TTimeIntervalMicroSeconds us = time.MicroSecondsFrom(TheSqlSrvStartTime);
+    if(us.Int64() < 0)
+        {
+        TheSqlSrvStartTime = time;
+        us = 0;
+        }
+    return us.Int64();
+    }
+
+
+//Tracing data buffer
+const TInt KSqlSrvProfilePrnBufSize = 230;
+static TBuf<KSqlSrvProfilePrnBufSize> TheSqlSrvProfileTraceBuf;
+static TBuf8<KSqlSrvProfilePrnBufSize> TheSqlSrvProfileTraceBuf8;
+
+static RFs TheSqlSrvTraceFs;
+static RFile TheTheSqlSrvTraceFile;
+_LIT(KSqlSrvTraceFileName, "C:\\SQLTRACE");
+
+//Prints out a time stamp
+static void SqlSrvProfileTimePrintf()
+    {
+    static TInt64 prevTimeDiff = 0;;
+    TInt64 timeDiff = SqlTimeFromStartUs();
+    const TInt64 KTimeInterval = 1000000; 
+    if((timeDiff - prevTimeDiff) >= KTimeInterval || timeDiff < prevTimeDiff)
+        {
+        prevTimeDiff = timeDiff;
+        TTime time;
+        time.UniversalTime();
+        TDateTime dt = time.DateTime();
+        TheSqlSrvProfileTraceBuf8.Format(_L8("%08X¬%012ld¬TME¬%02d:%02d:%02d.%06d¬Prep8=%08d¬Prep16=%08d¬Ex8=%08d¬Ex16=%08d"),
+                0, timeDiff, dt.Hour(), dt.Minute(), dt.Second(), dt.MicroSecond(),
+                TheSqlSrvProfilerPreparedCnt8, TheSqlSrvProfilerPreparedCnt16, 
+                TheSqlSrvProfilerExecutedCnt8, TheSqlSrvProfilerExecutedCnt16);
+        if(TheSqlSrvProfilerTraceToFile)
+            {
+            TheSqlSrvProfileTraceBuf8.Append(_L8("\r\n"));
+            (void)TheTheSqlSrvTraceFile.Write(TheSqlSrvProfileTraceBuf8);
+            }
+        else
+            {
+            TheSqlSrvProfileTraceBuf8.Append(_L8("\n"));
+            RDebug::RawPrint(TheSqlSrvProfileTraceBuf8);
+            }
+        }
+    }
+
+//Trace types
+enum TSqlSrvProfilerTraceType
+    {
+    ESqlSrvProfilerNonSqlTrace,
+    ESqlSrvProfilerMiddleLineSqlTrace,
+    ESqlSrvProfilerLastLineSqlTrace
+    };
+
+//Prints out the data that is in TheSqlSrvProfileTraceBuf.
+// aType = ESqlSrvProfilerNonSqlTrace       - non-SQL trace
+// aType = ESqlSrvProfilerMiddleLineSqlTrace - not last line of an SQL trace
+// aType = ESqlSrvProfilerLastLineSqlTrace  - last line of an SQL trace
+static void SqlSrvProfilePrintf(TSqlSrvProfilerTraceType aType)
+    {
+    SqlSrvProfileTimePrintf();
+    TheSqlSrvProfileTraceBuf8.Copy(TheSqlSrvProfileTraceBuf);
+    if(TheSqlSrvProfilerTraceToFile)
+        {
+        if(aType == 0 || aType == 2)
+            {
+            TheSqlSrvProfileTraceBuf8.Append(_L8("\r\n"));
+            }
+        (void)TheTheSqlSrvTraceFile.Write(TheSqlSrvProfileTraceBuf8);
+        }
+    else
+        {
+        TheSqlSrvProfileTraceBuf8.Append(_L8("\n"));
+        RDebug::RawPrint(TheSqlSrvProfileTraceBuf8);
+        }
+    }
+
+//Called at the beginning of CSqlSrvSession::ServiceL().
+void SqlIpcStart(TUint& aIpcCounter, TUint32& aStartTicks, TUint aDbHandle)
+    {
+    if(TheSqlSrvProfilerTraceEnabled)
+        {
+        if(TheSqlSrvProfilerTraceLevel == 0)
+            {
+            return;
+            }
+        if(KSqlSrvProfilerDbName().Length() > 0 && (aDbHandle == 0 || TheSqlSrvProfilerHandle != aDbHandle))
+            {
+            return;
+            }
+        ++aIpcCounter;
+        TheSqlSrvProfilerFileRead1 = TheSqlSrvProfilerFileRead;
+        TheSqlSrvProfilerFileWrite1 = TheSqlSrvProfilerFileWrite;
+        TheSqlSrvProfilerFileSync1 = TheSqlSrvProfilerFileSync;
+        TheSqlSrvProfilerFileSetSize1 = TheSqlSrvProfilerFileSetSize;
+        aStartTicks = User::FastCounter();
+        }
+    }
+
+//Called at the end of CSqlSrvSession::ServiceL().
+void SqlIpcEnd(TUint aIpcCounter, TUint32 aStartTicks, TSqlSrvFunction aFuncCode, 
+               TUint aDbHandle, TSqlSrvIpcTraceData aIpcTraceData[], TInt aRetCode)
+    {
+    if(TheSqlSrvProfilerTraceEnabled)
+        {
+        if(TheSqlSrvProfilerTraceLevel == 0)
+            {
+            return;
+            }
+        if(KSqlSrvProfilerDbName().Length() > 0 &&  (aDbHandle == 0 || TheSqlSrvProfilerHandle != aDbHandle))
+            {
+            return;
+            }
+        TUint32 endTicks = User::FastCounter();
+        TInt executionTime = SqlConvertTicks2Us(aStartTicks, endTicks);
+        TPtrC ipcCallName;
+        TInt ipcCallIdx = SqlIpcTraceIdxAndName(aFuncCode, ipcCallName); 
+        TInt64 timeFromStart = SqlTimeFromStartUs();
+        TInt64 ttlExecTime = 0;
+        TInt count = 0;
+        if(ipcCallIdx >= 0)
+            {
+            aIpcTraceData[ipcCallIdx].iExecutionTime += executionTime;
+            ttlExecTime = aIpcTraceData[ipcCallIdx].iExecutionTime;
+            count = ++aIpcTraceData[ipcCallIdx].iCount;
+            }
+        if(ipcCallIdx >= 0  || (ipcCallIdx == KErrNotFound && TheSqlSrvProfilerTraceLevel == 2))
+            {
+            TheSqlSrvProfileTraceBuf.Format(_L("%08X¬%012ld¬IPC¬%08u¬%20.20S¬%012ld¬%010d¬%08d¬%04d¬%04d¬%04d¬%04d¬rc=%d"),  
+                    aDbHandle, 
+                    timeFromStart,
+                    aIpcCounter,
+                    &ipcCallName, 
+                    ttlExecTime, 
+                    executionTime,
+                    count,
+                    TheSqlSrvProfilerFileRead - TheSqlSrvProfilerFileRead1,
+                    TheSqlSrvProfilerFileWrite - TheSqlSrvProfilerFileWrite1,
+                    TheSqlSrvProfilerFileSync - TheSqlSrvProfilerFileSync1,
+                    TheSqlSrvProfilerFileSetSize - TheSqlSrvProfilerFileSetSize1,
+                    aRetCode);
+            SqlSrvProfilePrintf(ESqlSrvProfilerNonSqlTrace);
+            }
+        }
+    }
+
+//Called at the end of CSqlSrvSession::ServiceError().
+void SqlIpcError(TUint aIpcCounter, TSqlSrvFunction aFuncCode, TUint aDbHandle, TInt aError)
+    {
+    if(TheSqlSrvProfilerTraceEnabled)
+        {
+        if(KSqlSrvProfilerDbName().Length() > 0 &&  (aDbHandle == 0 || TheSqlSrvProfilerHandle != aDbHandle))
+            {
+            return;
+            }
+        TPtrC ipcCallName;
+        (void)SqlIpcTraceIdxAndName(aFuncCode, ipcCallName); 
+        TInt64 timeFromStart = SqlTimeFromStartUs();
+        TheSqlSrvProfileTraceBuf.Format(_L("%08X¬%012ld¬ERR¬%08u¬%20.20S¬err=%d"), 
+                aDbHandle, 
+                timeFromStart,
+                aIpcCounter,
+                &ipcCallName,
+                aError);
+        SqlSrvProfilePrintf(ESqlSrvProfilerNonSqlTrace);
+        }
+    }
+
+//Prints the passed as a parameter 16-bit SQL statement.
+void SqlPrintSql16(TUint aDbHandle, const TDesC& aSql, TBool aPrepare)
+    {
+    if(!TheSqlSrvProfilerTraceEnabled || !TheSqlSrvProfilerSqlTraceEnabled)
+        {
+        return;
+        }
+    if(KSqlSrvProfilerDbName().Length() > 0 &&  (aDbHandle == 0 || TheSqlSrvProfilerHandle != aDbHandle))
+        {
+        return;
+        }
+    
+    aPrepare ? ++TheSqlSrvProfilerPreparedCnt16 : ++TheSqlSrvProfilerExecutedCnt16;
+    
+    TInt64 timeFromStart = SqlTimeFromStartUs();
+    TPtr line((TUint16*)TheSqlTraceBuf.Ptr(), 0, TheSqlTraceBuf.MaxLength());
+    TInt len = aSql.Length();
+    TInt pos = 0;
+    do
+        {
+        _LIT(KPrepare,  "Prepare16");
+        _LIT(KExec,     "Exec16");
+        _LIT(KEmptyStr,  "");
+        if(pos == 0)
+            {
+            line.Format(_L("%08X¬%012ld¬SQL¬%12.12S¬"), aDbHandle, timeFromStart, aPrepare ? &KPrepare : &KExec);
+            }
+        else
+            {
+            if(!TheSqlSrvProfilerTraceToFile)
+                {
+                line.Format(_L("%08X¬%012ld¬SQL¬%12.12S¬"), aDbHandle, timeFromStart, &KEmptyStr);
+                }
+            }
+        TInt l = Min(len, (line.MaxLength() - line.Length()));
+        TPtrC ptr(aSql.Ptr() + pos, l);
+        pos += l;
+        len -= l;
+        line.Append(ptr);
+        TheSqlSrvProfileTraceBuf.Format(_L("%S"), &line); 
+        SqlSrvProfilePrintf(len > 0 ? ESqlSrvProfilerMiddleLineSqlTrace : ESqlSrvProfilerLastLineSqlTrace);
+        line.Zero();
+        } while(len > 0);
+    }
+ 
+//Prints the passed as a parameter 8-bit SQL statement.
+void SqlPrintSql8(TUint aDbHandle, const TDesC8& aSql, TBool aPrepare)
+    {
+    if(!TheSqlSrvProfilerTraceEnabled || !TheSqlSrvProfilerSqlTraceEnabled)
+        {
+        return;
+        }
+    if(KSqlSrvProfilerDbName().Length() > 0 &&  (aDbHandle == 0 || TheSqlSrvProfilerHandle != aDbHandle))
+        {
+        return;
+        }
+    
+    aPrepare ? ++TheSqlSrvProfilerPreparedCnt8 : ++TheSqlSrvProfilerExecutedCnt8;
+    
+    TInt64 timeFromStart = SqlTimeFromStartUs();
+    TPtr line((TUint16*)TheSqlTraceBuf.Ptr(), 0, TheSqlTraceBuf.MaxLength());
+    TInt len = aSql.Length();
+    TInt pos = 0;
+    do
+        {
+        _LIT(KPrepare,   "Prepare8");
+        _LIT(KExec,      "Exec8");
+        _LIT(KEmptyStr,  "");
+        if(pos == 0)
+            {
+            line.Format(_L("%08X¬%012ld¬SQL¬%12.12S¬"), aDbHandle, timeFromStart, aPrepare ? &KPrepare : &KExec);
+            }
+        else
+            {
+            if(!TheSqlSrvProfilerTraceToFile)
+                {
+                line.Format(_L("%08X¬%012ld¬SQL¬%12.12S¬"), aDbHandle, timeFromStart, &KEmptyStr);
+                }
+            }
+        TInt l = Min(len, (line.MaxLength() - line.Length()));
+        TPtrC8 ptr(aSql.Ptr() + pos, l);
+        pos += l;
+        len -= l;
+        TPtr p2((TUint16*)line.Ptr() + line.Length(), 0, l);  
+        p2.Copy(ptr);
+        line.SetLength(line.Length() + p2.Length());
+        TheSqlSrvProfileTraceBuf.Format(_L("%S"), &line); 
+        SqlSrvProfilePrintf(len > 0 ? ESqlSrvProfilerMiddleLineSqlTrace : ESqlSrvProfilerLastLineSqlTrace);
+        line.Zero();
+        } while(len > 0);
+    }
+
+//Prints the name of the just created database.
+void SqlPrintDbCreate(TUint aDbHandle, const TDesC& aDbName)
+    {
+    if(TheSqlSrvProfilerTraceEnabled)
+        {
+        if(KSqlSrvProfilerDbName().Length() > 0 && aDbName.FindF(KSqlSrvProfilerDbName) >= 0)
+            {
+            TheSqlSrvProfilerHandle = aDbHandle;
+            }
+        if(KSqlSrvProfilerDbName().Length() > 0 &&  (aDbHandle == 0 || TheSqlSrvProfilerHandle != aDbHandle))
+            {
+            return;
+            }
+        TInt64 timeFromStart = SqlTimeFromStartUs();
+        TheSqlSrvProfileTraceBuf.Format(_L("%08X¬%012ld¬CRE¬%S"), 
+                aDbHandle, 
+                timeFromStart,
+                &aDbName);
+        SqlSrvProfilePrintf(ESqlSrvProfilerNonSqlTrace);
+        }
+    }
+
+//Prints the name of the just opened database.
+void SqlPrintDbOpen(TUint aDbHandle, const TDesC& aDbName)
+    {
+    if(TheSqlSrvProfilerTraceEnabled)
+        {
+        if(KSqlSrvProfilerDbName().Length() > 0 && aDbName.FindF(KSqlSrvProfilerDbName) >= 0)
+            {
+            TheSqlSrvProfilerHandle = aDbHandle;
+            }
+        if(KSqlSrvProfilerDbName().Length() > 0 &&  (aDbHandle == 0 || TheSqlSrvProfilerHandle != aDbHandle))
+            {
+            return;
+            }
+        TInt64 timeFromStart = SqlTimeFromStartUs();
+        TheSqlSrvProfileTraceBuf.Format(_L("%08X¬%012ld¬OPN¬%S"), 
+                aDbHandle, 
+                timeFromStart,
+                &aDbName);
+        SqlSrvProfilePrintf(ESqlSrvProfilerNonSqlTrace);
+        }
+    }
+
+//Prints the handle of the just closed database.
+void SqlPrintDbClose(TUint aDbHandle)
+    {
+    if(TheSqlSrvProfilerTraceEnabled)
+        {
+        if(KSqlSrvProfilerDbName().Length() > 0 &&  (aDbHandle == 0 || TheSqlSrvProfilerHandle != aDbHandle))
+            {
+            return;
+            }
+        TInt64 timeFromStart = SqlTimeFromStartUs();
+        TheSqlSrvProfileTraceBuf.Format(_L("%08X¬%012ld¬CSE"),  
+                aDbHandle, 
+                timeFromStart);
+        SqlSrvProfilePrintf(ESqlSrvProfilerNonSqlTrace);
+        if(aDbHandle == TheSqlSrvProfilerHandle)
+            {
+            TheSqlSrvProfilerHandle = 0;
+            }
+        }
+    }
+
+//Prints a trace when the SQL server starts
+void SqlPrintServerStart()
+    {
+    TInt64 timeFromStart = SqlTimeFromStartUs();
+    if(TheSqlSrvProfilerTraceToFile)
+        {
+        TInt err = TheSqlSrvTraceFs.Connect();
+        if(err == KErrNone)
+            {
+            TInt fileNum = 0;
+            err = KErrGeneral;
+            while(++fileNum < 1000 && err != KErrNone)
+                {
+                TBuf<80> ftrname;
+                ftrname.Copy(KSqlSrvTraceFileName);
+                ftrname.AppendNum(fileNum);
+                ftrname.Append(_L(".txt"));
+                err = TheTheSqlSrvTraceFile.Create(TheSqlSrvTraceFs, ftrname, EFileRead | EFileWrite);
+                if(err == KErrNone)
+                    {
+                    break;
+                    }
+                }
+            }
+        if(err != KErrNone)
+            {
+            TheSqlSrvTraceFs.Close();
+            TheSqlSrvProfilerTraceToFile = EFalse;
+            RDebug::Print(_L("SQL trace file creation failed with err=%d"), err);
+            }
+        }
+    TheSqlSrvProfileTraceBuf.Format(_L("%08X¬%012ld¬SRV¬START"), 0, timeFromStart); 
+    SqlSrvProfilePrintf(ESqlSrvProfilerNonSqlTrace);
+    }
+
+//Prints a trace when the SQL server stops
+void SqlPrintServerStop()
+    {
+    TInt64 timeFromStart = SqlTimeFromStartUs();
+    TheSqlSrvProfileTraceBuf.Format(_L("%08X¬%012ld¬SRV¬STOP"), 0, timeFromStart); 
+    SqlSrvProfilePrintf(ESqlSrvProfilerNonSqlTrace);
+    if(TheSqlSrvProfilerTraceToFile)
+        {
+        TheTheSqlSrvTraceFile.Close();
+        TheSqlSrvTraceFs.Close();
+        }
+    }
+
+#else //_SQLPROFILER
+
+void TSqlSrvResourceProfiler::StartL(const RMessage2&)
+	{
+	__SQLLEAVE(KErrNotSupported);
+	}
+	
+void TSqlSrvResourceProfiler::StopL(const RMessage2&)
+	{
+	__SQLLEAVE(KErrNotSupported);
+	}
+	
+void TSqlSrvResourceProfiler::ResetL(const RMessage2&)
+	{
+	__SQLLEAVE(KErrNotSupported);
+	}
+	
+void TSqlSrvResourceProfiler::QueryL(const RMessage2&)
+	{
+	__SQLLEAVE(KErrNotSupported);
+	}
+	
+#endif//_SQLPROFILER