--- /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