persistentstorage/sql/SRC/Common/SqlUtil.cpp
changeset 0 08ec8eefde2f
child 12 6b6fd149daa2
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <e32svr.h>
       
    17 #include <sqldb.h>		//ESqlAtRow, ESqlAtEnd, ESqlErrGeneral
       
    18 #include "SqlUtil.h"
       
    19 #include "SqlPanic.h"	//SqlPanic(), TSqlPanic
       
    20 #include "sqlite3.h"	//SQLITE_OK, SQLITE_ROW, SQLITE_DONE
       
    21 #include "UTraceSql.h"
       
    22 
       
    23 /**
       
    24 SQL panic category.
       
    25 
       
    26 @internalComponent
       
    27 */
       
    28 _LIT(KPanicCategory,"SqlDb");
       
    29 
       
    30 /**
       
    31 Panics the caller with aPanicCode panic code.
       
    32 The call will terminate the thread where it is called from.
       
    33 
       
    34 @param aPanicCode Panic code.
       
    35 
       
    36 @internalComponent
       
    37 */
       
    38 void SqlPanic(TSqlPanic aPanicCode)
       
    39 	{
       
    40 	User::Panic(KPanicCategory, aPanicCode);
       
    41 	}
       
    42 	
       
    43 /**
       
    44 Panics the client with aPanicCode panic code.
       
    45 This function is used by the SQL server to panic the caller (the client).
       
    46 
       
    47 @param aMessage Client's message
       
    48 @param aPanicCode Panic code.
       
    49 
       
    50 @leave KSqlLeavePanic
       
    51 
       
    52 @return KErrNone
       
    53 
       
    54 @internalComponent
       
    55 */
       
    56 TInt SqlPanicClientL(const RMessage2& aMessage, TSqlPanic aPanicCode)
       
    57 	{
       
    58 	aMessage.Panic(KPanicCategory, aPanicCode);
       
    59 	__SQLLEAVE(KSqlLeavePanic);
       
    60 	return KErrNone;
       
    61 	}
       
    62 	
       
    63 /**
       
    64 Processes SQL database error code and OS error code and returns unified error code.
       
    65 If aSqlError == SQLITE_ROW then the function returns KSqlAtRow.
       
    66 If aSqlError == SQLITE_DONE then the function returns KSqlAtEnd.
       
    67 If aSqlError == SQLITE_NOMEM then the function returns KErrNoMemory.
       
    68 If aOsError != KErrNone then the function returns aOsError.
       
    69 Otherwise the function converts aSqlError to one of error codes in [KSqlErrGeneral..KSqlErrStmtExpired] range.
       
    70 
       
    71 @param aSqlError SQL database error code.
       
    72 @param aOsError OS error code.
       
    73 
       
    74 @return Database specific error code.
       
    75 
       
    76 @panic SqlDb 4 in debug mode - if aSqlError < 0
       
    77 @panic SqlDb 4 in debug mode - if aOsError > 0
       
    78 
       
    79 @internalComponent
       
    80 */
       
    81 TInt Sql2OsErrCode(TInt aSqlError, TInt aOsError)
       
    82 	{
       
    83 	__SQLASSERT(aSqlError >= SQLITE_OK && aOsError <= KErrNone, ESqlPanicBadArgument);
       
    84 	TInt err = KErrNone;
       
    85 	if(aOsError == KErrDiskFull)
       
    86 		{//Whatever is the aSqlError value, even SQLITE_OK, never ignore KErrDiskFull errors
       
    87 		 //(For example: ROLLBACK statement execution, when the disk is full).
       
    88 		err = aOsError;
       
    89 		}
       
    90 	else if(aSqlError == SQLITE_ROW)
       
    91 		{
       
    92 		err = KSqlAtRow;
       
    93 		}
       
    94 	else if(aSqlError == SQLITE_DONE)
       
    95 		{
       
    96 		err = KSqlAtEnd;
       
    97 		}
       
    98 	else if(aSqlError == SQLITE_NOMEM)
       
    99 		{
       
   100 		err = KErrNoMemory;
       
   101 		}
       
   102 	else if(aSqlError == SQLITE_AUTH)
       
   103 		{
       
   104 		err = KErrPermissionDenied;
       
   105 		}
       
   106 	else if(aSqlError == SQLITE_NOTADB)
       
   107 		{
       
   108 		err = KSqlErrNotDb;	
       
   109 		}
       
   110 	else if(aSqlError > SQLITE_OK)
       
   111 		{
       
   112 		err = aOsError != KErrNone ? aOsError : KSqlErrGeneral - aSqlError + 1;
       
   113 		}
       
   114 	return err;
       
   115 	}
       
   116 
       
   117 ////////////////////////////////////////////////////////////////////////////////////////////////////////
       
   118 ////////////////////////////////   class Util   ////////////////////////////////////////////////////////
       
   119 ////////////////////////////////////////////////////////////////////////////////////////////////////////
       
   120 #if defined _LOGGING || defined SYMBIAN_TRACE_SQL_ERR
       
   121 
       
   122 /**
       
   123 This function is used to log the message "msg" containing the "err" error code.
       
   124 The message "msg" should contain the format specifier %d.
       
   125 
       
   126 The function is used when _LOGGING or SYMBIAN_TRACE_SQL_ERR is defined.
       
   127 
       
   128 @param aMsg Error message
       
   129 @param aErr Error code
       
   130 
       
   131 @internalComponent
       
   132 */	
       
   133 void Util::ErrorPrint(const TDesC& aMsg, TInt aErr)
       
   134 	{
       
   135 	SYMBIAN_TRACE_SQL_ERR_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EError), aMsg, aErr));
       
   136 	RDebug::Print(aMsg, aErr);
       
   137 	}
       
   138 
       
   139 /**
       
   140 This macro should be used to log the message "msg" containing the "str" string.
       
   141 The message "msg" should contain the format specifier %S.
       
   142 
       
   143 The function is used when _LOGGING or SYMBIAN_TRACE_SQL_ERR is defined.
       
   144 
       
   145 @param aMsg Error message
       
   146 @param aErr Error code
       
   147 
       
   148 @internalComponent
       
   149 */	
       
   150 void Util::ErrorPrint(const TDesC& aMsg, const TDesC& aStr)
       
   151 	{
       
   152 	SYMBIAN_TRACE_SQL_ERR_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EError), aMsg, &aStr));
       
   153 	RDebug::Print(aMsg, &aStr);
       
   154 	}
       
   155 
       
   156 #endif  //_LOGGING || SYMBIAN_TRACE_SQL_ERR
       
   157 
       
   158 #if defined _ASSERTIONS
       
   159 
       
   160 /**
       
   161 The function prints out a "SQL panic" message to the console and panics the thread where it is called from.
       
   162 It gives a useful information about the found error together with the source file name and line number where
       
   163 it occurred.
       
   164 
       
   165 The function is used when _ASSERTIONS is defined.
       
   166 
       
   167 @param aFile Source file name
       
   168 @param aLine Source line number
       
   169 @param aPanicCode Panic code
       
   170 
       
   171 @return KErrNone
       
   172 
       
   173 @internalComponent
       
   174 */	
       
   175 TInt Util::Assert(const TText* aFile, TInt aLine, TInt aPanicCode)
       
   176 	{
       
   177 	TBuf<16> tbuf;
       
   178 	Util::GetTimeStr(tbuf);
       
   179 	TBuf<80> buf;
       
   180 	_LIT(KFormat,"**%S* SQL panic %d, at %S(%d)");
       
   181 	TPtrC fname(Filename(aFile));
       
   182 	SYMBIAN_TRACE_SQL_ERR_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EError), KSqlPanic, aPanicCode, &fname, aLine));
       
   183 	buf.Format(KFormat, &tbuf, aPanicCode, &fname, aLine);
       
   184 	RDebug::Print(buf);
       
   185 	::SqlPanic(static_cast <TSqlPanic> (aPanicCode));
       
   186 	return KErrNone;
       
   187 	}
       
   188 
       
   189 #else //_ASSERTIONS
       
   190 
       
   191 /**
       
   192 The function panics the thread where it is called from.
       
   193 
       
   194 The function is used when _ASSERTIONS is not defined.
       
   195 
       
   196 @param Not used
       
   197 @param Not used
       
   198 @param aPanicCode Panic code
       
   199 
       
   200 @return KErrNone
       
   201 
       
   202 @internalComponent
       
   203 */	
       
   204 TInt Util::Assert(const TText*, TInt, TInt aPanicCode)
       
   205 	{
       
   206 	::SqlPanic(static_cast <TSqlPanic> (aPanicCode));
       
   207 	return KErrNone;
       
   208 	}
       
   209 	
       
   210 #endif //_ASSERTIONS
       
   211 
       
   212 #if defined _NOTIFY || defined SYMBIAN_TRACE_SQL_ERR
       
   213 	
       
   214 /**
       
   215 The function prints out a "SQL leave" message to the console and leaves with aError error code.
       
   216 It gives a usefull information about the found error together with the source file name and line number where
       
   217 it occured.
       
   218 
       
   219 The function is used when _NOTIFY is defined.
       
   220 
       
   221 @param aFile Source file name
       
   222 @param aLine Source line number
       
   223 @param aError Error code
       
   224 
       
   225 @internalComponent
       
   226 */	
       
   227 void Util::Leave(const TText* aFile, TInt aLine, TInt aError)
       
   228 	{
       
   229 	SYMBIAN_TRACE_SQL_ERR_ONLY(TPtrC filename(Filename(aFile)));
       
   230 	SYMBIAN_TRACE_SQL_ERR_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EError), KSqlLeave, aError, &filename, aLine));	
       
   231 
       
   232 #ifdef _NOTIFY
       
   233 	TBuf<16> tbuf;
       
   234 	Util::GetTimeStr(tbuf);
       
   235 	TPtrC f(Filename(aFile));
       
   236 	TBuf<80> buf;
       
   237 	_LIT(KFormat,"**%S* SQL leave, error=%d at %S(%d)\r\n");
       
   238 	buf.Format(KFormat, &tbuf, aError, &f, aLine);
       
   239 	RDebug::Print(buf);
       
   240 #endif //_NOTIFY
       
   241 	User::Leave(aError);
       
   242 	}
       
   243 	
       
   244 /**
       
   245 The function prints out a "SQL leave" message to the console and leaves with aError error code, if it is 
       
   246 negative.
       
   247 It gives a usefull information about the found error together with the source file name and line number where
       
   248 it occured.
       
   249 
       
   250 The function is used when _NOTIFY is defined.
       
   251 
       
   252 @param aFile Source file name
       
   253 @param aLine Source line number
       
   254 @param aError Error code
       
   255 
       
   256 @internalComponent
       
   257 */	
       
   258 TInt Util::LeaveIfError(const TText* aFile, TInt aLine, TInt aError)
       
   259 	{
       
   260 	if(aError<0)
       
   261 		Util::Leave(aFile,aLine,aError);
       
   262 	return aError;
       
   263 	}
       
   264 
       
   265 /**
       
   266 The function prints out a "SQL leave" message to the console and leaves with KErrNoMemory if 
       
   267 aPtr parameter is NULL.
       
   268 
       
   269 The function is used when _NOTIFY is defined.
       
   270 
       
   271 @param aFile Source file name
       
   272 @param aLine Source line number
       
   273 @param aPtr The pointer to be tested against NULL value.
       
   274 
       
   275 @internalComponent
       
   276 */	
       
   277 void* Util::LeaveIfNull(const TText* aFile, TInt aLine, void* aPtr)
       
   278 	{
       
   279 	if(!aPtr)
       
   280 		{
       
   281 		Util::Leave(aFile, aLine, KErrNoMemory);
       
   282 		}
       
   283 	return aPtr;
       
   284 	}
       
   285 
       
   286 /**
       
   287 The function is used by the SQL server.
       
   288 It prints out a "SQL panic" message to the console and panic the client.
       
   289 It gives a usefull information about the found error together with the source file name and line number where
       
   290 it occured.
       
   291 
       
   292 The function is used when _NOTIFY is defined.
       
   293 
       
   294 @param aFile Source file name
       
   295 @param aLine Source line number
       
   296 @param aMessage The client message, which processing caused the panic.
       
   297 @param aPanicCode Error code
       
   298 
       
   299 @leave KSqlLeavePanic
       
   300 
       
   301 @return KErrNone;
       
   302 
       
   303 @internalComponent
       
   304 */	
       
   305 TInt Util::PanicClientL(const TText* aFile, TInt aLine, const RMessage2& aMessage, TInt aPanicCode)
       
   306 	{
       
   307 	SYMBIAN_TRACE_SQL_ERR_ONLY(TPtrC filename(Filename(aFile)));
       
   308 	SYMBIAN_TRACE_SQL_ERR_ONLY(UTF::Printf(UTF::TTraceContext(UTF::EError), KSqlPanicClient, aPanicCode, &filename, aLine));	
       
   309 	
       
   310 #ifdef _NOTIFY
       
   311 	TBuf<16> tbuf;
       
   312 	Util::GetTimeStr(tbuf);
       
   313 	TPtrC fname(Filename(aFile));
       
   314 	TBuf<80> buf;
       
   315 	_LIT(KFormat,"**%S* SQL panic=%d at %S(%d)\r\n");
       
   316 	buf.Format(KFormat, &tbuf, aPanicCode, &fname, aLine);
       
   317 	RDebug::Print(buf);
       
   318 #endif
       
   319 	return ::SqlPanicClientL(aMessage, static_cast <TSqlPanic> (aPanicCode));
       
   320 	}
       
   321 
       
   322 #endif//defined _NOTIFY || SYMBIAN_TRACE_SQL_ERR
       
   323 
       
   324 #if defined _ASSERTIONS || defined _NOTIFY ||defined SYMBIAN_TRACE_SQL_ERR
       
   325 
       
   326 /**
       
   327 Formats the current time into aWhere descriptor.
       
   328 
       
   329 @param aWhere Output parameter. The current time will be formatted there. The buffer length should be at least 16 characters.
       
   330 
       
   331 The function is used when _ASSERT or _NOTIFY or SYMBIAN_TRACE_SQL_ERR is defined.
       
   332 
       
   333 @internalComponent
       
   334 */
       
   335 void Util::GetTimeStr(TDes& aWhere)
       
   336 	{
       
   337 	TTime time;
       
   338 	time.HomeTime();
       
   339 	TDateTime dt = time.DateTime();
       
   340 	aWhere.Format(_L("%02d:%02d:%02d.%06d"), dt.Hour(), dt.Minute(), dt.Second(), dt.MicroSecond());
       
   341 	};
       
   342 	
       
   343 /**
       
   344 The function creates and returns TPtrC object which points to aFile parameter.
       
   345 
       
   346 @param aFile File name
       
   347 @return TPtrC object pointing to aFile parameter.
       
   348 
       
   349 The function is used when _ASSERT or _NOTIFY or SYMBIAN_TRACE_SQL_ERR is defined.
       
   350 
       
   351 @internalComponent
       
   352 */	
       
   353 TPtrC Util::Filename(const TText* aFile)
       
   354 	{
       
   355 	TPtrC p(aFile);
       
   356 	TInt ix = p.LocateReverse('\\');
       
   357 	if(ix<0)
       
   358 		ix=p.LocateReverse('/');
       
   359 	if(ix>=0)
       
   360 		p.Set(p.Mid(1+ix));
       
   361 	return p;
       
   362 	}
       
   363 
       
   364 #endif//defined _ASSERTIONS || defined _NOTIFY || SYMBIAN_TRACE_SQL_ERR