# HG changeset patch # User Dremov Kirill (Nokia-D-MSW/Tampere) # Date 1271256392 -10800 # Node ID 211563e4b919e4faf38920d9e71ac9a3d7649408 # Parent 31a8f755b7fe21dc9c3bc9b0330b49e0ced70bc5 Revision: 201015 Kit: 201015 diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/GROUP/BLD.INF --- a/persistentstorage/sql/GROUP/BLD.INF Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/GROUP/BLD.INF Wed Apr 14 17:46:32 2010 +0300 @@ -63,6 +63,7 @@ t_sqloom3.mmp t_sqloom4.mmp t_sqloom5.mmp +t_sqloom6.mmp t_sqlpanic.mmp t_sqllang.mmp t_sqlmulti.mmp diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/GROUP/SqlDb.mmp --- a/persistentstorage/sql/GROUP/SqlDb.mmp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/GROUP/SqlDb.mmp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2005-2010 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" @@ -31,6 +31,9 @@ UID 0x1000008d 0x10281E18 +//CodeWarrior compilation options - disable the "illegal pragma" warning +OPTION CW -w noillpragmas + OS_LAYER_SYSTEMINCLUDE_SYMBIAN USERINCLUDE ../INC USERINCLUDE ../SRC/Client diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/GROUP/SqlSrv.mmp --- a/persistentstorage/sql/GROUP/SqlSrv.mmp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/GROUP/SqlSrv.mmp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2005-2010 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" @@ -45,6 +45,9 @@ SMPSAFE +//CodeWarrior compilation options - disable the "illegal pragma" warning +OPTION CW -w noillpragmas + OS_LAYER_SYSTEMINCLUDE_SYMBIAN OS_LAYER_ESTLIB_SYSTEMINCLUDE USERINCLUDE ../INC diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/GROUP/sqltests.bat --- a/persistentstorage/sql/GROUP/sqltests.bat Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/GROUP/sqltests.bat Wed Apr 14 17:46:32 2010 +0300 @@ -25,6 +25,7 @@ T_SQLOOM3.EXE T_SQLOOM4.EXE T_SQLOOM5.EXE +T_SQLOOM6.EXE T_SQLMULTI.EXE T_SQLCOLLATE.EXE T_SQLTRANS.EXE diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/GROUP/sqltests.iby --- a/persistentstorage/sql/GROUP/sqltests.iby Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/GROUP/sqltests.iby Wed Apr 14 17:46:32 2010 +0300 @@ -69,6 +69,7 @@ file=ABI_DIR\BUILD_DIR\T_SQLOOM3.EXE \TEST\T_SQLOOM3.EXE file=ABI_DIR\BUILD_DIR\T_SQLOOM4.EXE \TEST\T_SQLOOM4.EXE file=ABI_DIR\BUILD_DIR\T_SQLOOM5.EXE \TEST\T_SQLOOM5.EXE +file=ABI_DIR\BUILD_DIR\T_SQLOOM6.EXE \TEST\T_SQLOOM6.EXE file=ABI_DIR\BUILD_DIR\T_SQLMULTI.EXE \TEST\T_SQLMULTI.EXE file=ABI_DIR\BUILD_DIR\T_SQLCOLLATE.EXE \TEST\T_SQLCOLLATE.EXE file=ABI_DIR\BUILD_DIR\T_SQLTRANS.EXE \TEST\T_SQLTRANS.EXE diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/GROUP/t_sqloom6.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/sql/GROUP/t_sqloom6.mmp Wed Apr 14 17:46:32 2010 +0300 @@ -0,0 +1,47 @@ +// Copyright (c) 2010 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: +// + +TARGET t_sqloom6.exe +TARGETTYPE EXE +CAPABILITY None + +EPOCSTACKSIZE 0x10000 + +USERINCLUDE . +USERINCLUDE ../INC +OS_LAYER_SYSTEMINCLUDE_SYMBIAN +OS_LAYER_ESTLIB_SYSTEMINCLUDE +USERINCLUDE ../OsLayer +#ifdef SYMBIAN_USE_SQLITE_VERSION_3_6_4 +USERINCLUDE ../SQLite364 +#else +USERINCLUDE ../SQLite +#endif + +SOURCEPATH ../TEST +SOURCE t_sqloom6.cpp + +LIBRARY euser.lib +LIBRARY efsrv.lib +LIBRARY sqldb.lib +LIBRARY bafl.lib +LIBRARY estor.lib +LIBRARY estlib.lib +LIBRARY hal.lib +STATICLIBRARY sqlite.lib + +VENDORID 0x70000001 + +SMPSAFE diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Client/SqlDbSession.cpp --- a/persistentstorage/sql/SRC/Client/SqlDbSession.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Client/SqlDbSession.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2005-2010 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" @@ -196,16 +196,14 @@ TPtr8 bufPtr = buf->Des(); RDesWriteStream out(bufPtr); TRAPD(err, SerializeToStreamL(out)); - if(err == KErrNone) - { - TUint32 arg0 = (TUint32)bufPtr.Length() | (aReadOnly ? 0x80000000 : 0); - TIpcArgs ipcArgs(arg0, &bufPtr); - err = aDbFile.TransferToServer(ipcArgs, 2, 3); - if(err == KErrNone) - { - err = iDbSession.SendReceive(ESqlSrvDbAttachFromHandle, ipcArgs); - } - } + __SQLASSERT(err == KErrNone, ESqlPanicInternalError);//"Write to descriptor" streaming operatons can't fail + TUint32 arg0 = (TUint32)bufPtr.Length() | (aReadOnly ? 0x80000000 : 0); + TIpcArgs ipcArgs(arg0, &bufPtr); + err = aDbFile.TransferToServer(ipcArgs, 2, 3); + if(err == KErrNone) + { + err = iDbSession.SendReceive(ESqlSrvDbAttachFromHandle, ipcArgs); + } delete buf; return err; } diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Client/SqlResourceProfiler.cpp --- a/persistentstorage/sql/SRC/Client/SqlResourceProfiler.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Client/SqlResourceProfiler.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2008-2010 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" @@ -18,6 +18,8 @@ #include "SqlDatabaseImpl.h" +#pragma BullseyeCoverage off + /** Initializes TSqlResourceProfiler data members with their default values. @@ -154,3 +156,5 @@ } #endif//_SQLPROFILER + +#pragma BullseyeCoverage on diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Client/SqlResourceTest.cpp --- a/persistentstorage/sql/SRC/Client/SqlResourceTest.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Client/SqlResourceTest.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2006-2010 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" @@ -23,6 +23,8 @@ //////////////////////// TSqlResourceTestData ///////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma BullseyeCoverage off + #ifdef _DEBUG /** @@ -274,3 +276,5 @@ } #endif//_DEBUG + +#pragma BullseyeCoverage on diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Client/SqlStatementImpl.cpp --- a/persistentstorage/sql/SRC/Client/SqlStatementImpl.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Client/SqlStatementImpl.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2005-2010 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" @@ -9,6 +9,7 @@ // Nokia Corporation - initial contribution. // // Contributors: +// NTT DOCOMO, INC - Fix for Bug 1915 "SQL server panics when using long column type strings" // // Description: // @@ -18,8 +19,6 @@ //Constants -_LIT(KSemiColon,";"); - _LIT(KTextKWD, "TEXT"); _LIT(KCharKWD, "CHAR"); _LIT(KClobKWD, "CLOB"); @@ -449,42 +448,50 @@ TInt CSqlStatementImpl::DeclaredColumnType(TInt aColumnIndex, TSqlColumnType& aColumnType) { __SQLASSERT_ALWAYS((TUint)aColumnIndex < (TUint)iColumnCnt, ESqlPanicBadColumnIndex); - if(iDeclaredColumnTypes.Count() == 0 && iColumnCnt > 0) //initialise iDeclaredColumnTypes array if necessary + if(iDeclaredColumnTypes.Count() == 0) //initialise iDeclaredColumnTypes array if necessary { - TInt err = iDeclaredColumnTypes.Reserve(iColumnCnt);//We know what the array size should be - iColumnCnt + RSqlBufFlat declaredColumnTypeBuf; + TInt err = declaredColumnTypeBuf.SetCount(iColumnCnt); if(err != KErrNone) { + declaredColumnTypeBuf.Close(); return err; } - HBufC* colTypeNamesBuf = NULL;//Buffer for declared column type names, delimited by ';'. - TRAP(err, colTypeNamesBuf = GetDeclColumnTypesL()); + + //Resize buffer to minimise the chance that two IPC calls are required to get all the column type name data. + //Allocates enough space to contain the header cells (already created by calling SetCount()) and a data buffer + //which assumes an average column type name length of 20 characters plus 8-byte alignment padding + const TInt KBufSizePerColumn = 48; + TInt newSize = declaredColumnTypeBuf.Size() + iColumnCnt*KBufSizePerColumn; + + err = declaredColumnTypeBuf.ReAlloc(newSize); if(err != KErrNone) { - __SQLASSERT(!colTypeNamesBuf, ESqlPanicInternalError); - iDeclaredColumnTypes.Reset(); + declaredColumnTypeBuf.Close(); return err; } - //Iterate over the column type names and map each column type name to one of the TSqlColumnType enum item values. - //No error can occur from here till the end of the function code. - __SQLASSERT(colTypeNamesBuf != NULL, ESqlPanicInternalError); - TPtrC colTypeNames(*colTypeNamesBuf); - TInt colIdx = 0; - while(colTypeNames.Length() > 0) + + err = iSqlStmtSession.GetDeclColumnTypes(declaredColumnTypeBuf); + if(err != KErrNone) + { + declaredColumnTypeBuf.Close(); + return err; + } + + err = iDeclaredColumnTypes.Reserve(iColumnCnt);//We know what the array size should be - iColumnCnt + if(err != KErrNone) { - TInt pos = colTypeNames.Find(KSemiColon); - if(pos < 0) - { - break; - } - TPtrC colTypeName(colTypeNames.Ptr(), pos); - if(pos == colTypeNames.Length() - 1) - { - colTypeNames.Set(NULL, 0); - } - else - { - colTypeNames.Set(colTypeNames.Ptr() + pos + 1, colTypeNames.Length() - (pos + 1)); - } + declaredColumnTypeBuf.Close(); + return err; + } + + //Iterate over the column type names buffer and map each column type name to one of the TSqlColumnType enum item values. + TSqlBufRIterator declColumnTypeBufIt; + declColumnTypeBufIt.Set(declaredColumnTypeBuf); + TInt colIdx = 0; + while(declColumnTypeBufIt.Next()) + { + TPtrC colTypeName(declColumnTypeBufIt.Text()); TSqlColumnType colType = ESqlInt; if(colTypeName.FindF(KCharKWD) >= 0 || colTypeName.FindF(KTextKWD) >= 0 || colTypeName.FindF(KClobKWD) >= 0) { @@ -501,10 +508,10 @@ err = iDeclaredColumnTypes.Append(colType); __SQLASSERT(err == KErrNone, ESqlPanicInternalError);//memory for the array elements has been reserved already ++colIdx; - }//end of - while(colTypeNames.Length() > 0) + } //end of - while(declColumnTypeBufIt.Next()) __SQLASSERT(colIdx == iColumnCnt, ESqlPanicInternalError); - delete colTypeNamesBuf; - }//end of - if(iDeclaredColumnTypes.Count() == 0 && iColumnCnt > 0) + declaredColumnTypeBuf.Close(); + } //end of - if(iDeclaredColumnTypes.Count() == 0 && iColumnCnt > 0) aColumnType = iDeclaredColumnTypes[aColumnIndex]; return KErrNone; } @@ -863,15 +870,3 @@ return KErrNone; } - -/** -Returns a buffer containing a ";" separated list with declared types of statement's columns. -The caller is responsible for deleting the result buffer. - -@return HBufC buffer - column types list. -*/ -HBufC* CSqlStatementImpl::GetDeclColumnTypesL() - { - return iSqlStmtSession.GetDeclColumnTypesL(iColumnCnt); - } - diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Client/SqlStatementImpl.h --- a/persistentstorage/sql/SRC/Client/SqlStatementImpl.h Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Client/SqlStatementImpl.h Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2005-2010 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" @@ -9,6 +9,7 @@ // Nokia Corporation - initial contribution. // // Contributors: +// NTT DOCOMO, INC - Fix for Bug 1915 "SQL server panics when using long column type strings" // // Description: // @@ -141,8 +142,6 @@ inline MStreamBuf* ColumnSourceL(TInt aColumnIndex); inline MStreamBuf* ParamSinkL(TSqlSrvFunction aFunction, TInt aParamIndex); - HBufC* GetDeclColumnTypesL(); - private: inline CSqlStatementImpl(); template TInt Construct(CSqlDatabaseImpl& aDatabase, const DES& aSqlStmt); diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Client/SqlStatementImpl.inl --- a/persistentstorage/sql/SRC/Client/SqlStatementImpl.inl Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Client/SqlStatementImpl.inl Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2006-2010 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" @@ -134,6 +134,8 @@ ESqlDbError or other system-wide error codes; KErrNone Operation has completed successfully. +@panic SqlDb 7 In _DEBUG mode, invalid column count. + @see CSqlStatementImpl::New() */ template TInt CSqlStatementImpl::Construct(CSqlDatabaseImpl& aDatabase, const DES& aSqlStmt) @@ -143,15 +145,13 @@ { return err; } - if(iColumnCnt >= 0) - { - err = iColumnValueBuf.SetCount(iColumnCnt); - if(err != KErrNone) - { - return err; - } - iColumnValBufIt.Set(iColumnValueBuf); - } + __SQLASSERT(iColumnCnt >= 0, ESqlPanicInternalError); + err = iColumnValueBuf.SetCount(iColumnCnt); + if(err != KErrNone) + { + return err; + } + iColumnValBufIt.Set(iColumnValueBuf); if(iParamCnt > 0) { err = iParamValueBuf.SetCount(iParamCnt); diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Client/SqlStmtSession.cpp --- a/persistentstorage/sql/SRC/Client/SqlStmtSession.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Client/SqlStmtSession.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2005-2010 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" @@ -9,6 +9,7 @@ // Nokia Corporation - initial contribution. // // Contributors: +// NTT DOCOMO, INC - Fix for Bug 1915 "SQL server panics when using long column type strings" // // Description: // @@ -131,25 +132,20 @@ } /** -Sends a command to the server for retrieving a string with ";" separated declared types of columns -The caller is responsible for deleting the result buffer. - -@param aColumnCount The number of the columns which the statement has. -@return A pointer to a heap based HBufC object, containing the column names, separated with ";". +Sends a command to the server for retrieving the declared types of columns Usage of the IPC call arguments: -Arg 0: [out] Input buffer max length -Arg 1: [in/out] Data buffer, will be filled with the declared types of columns, separated with ";" -*/ -HBufC* RSqlStatementSession::GetDeclColumnTypesL(TInt aColumnCount) +Arg 0: [out] buffer length in bytes +Arg 1: [in/out] buffer +*/ +TInt RSqlStatementSession::GetDeclColumnTypes(RSqlBufFlat& aDeclColumnTypeBuf) { - //The longest DBMS data type, represented as text, is "LONG VARBINARY" - 14 characters. - //So we can safely assume that 20 characters buffer space per DBMS column type is enough. - const TInt KLongestDbmsTypeLength = 20; - HBufC* colTypeBuf = HBufC::NewLC(aColumnCount * KLongestDbmsTypeLength); - TPtr ptr = colTypeBuf->Des(); - TInt err = DbSession().SendReceive(::MakeMsgCode(ESqlSrvStmtDeclColumnTypes, ESqlSrvStatementHandle, iHandle), TIpcArgs(ptr.MaxLength(), &ptr)); - __SQLLEAVE_IF_ERROR(err); - CleanupStack::Pop(colTypeBuf); - return colTypeBuf; + aDeclColumnTypeBuf.Reset(); + TPtr8& ptr = aDeclColumnTypeBuf.BufPtr(); + TInt err = DbSession().SendReceive(::MakeMsgCode(ESqlSrvStmtDeclColumnTypes, ESqlSrvStatementHandle, iHandle), TIpcArgs(ptr.MaxLength(), &ptr)); + if(err > KSqlClientBufOverflowCode) + { + err = Retry(aDeclColumnTypeBuf, err - KSqlClientBufOverflowCode, ESqlDeclColumnTypesBuf); + } + return err; } diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Client/SqlStmtSession.h --- a/persistentstorage/sql/SRC/Client/SqlStmtSession.h Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Client/SqlStmtSession.h Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2005-2010 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" @@ -9,6 +9,7 @@ // Nokia Corporation - initial contribution. // // Contributors: +// NTT DOCOMO, INC - Fix for Bug 1915 "SQL server panics when using long column type strings" // // Description: // @@ -97,8 +98,8 @@ inline MStreamBuf* ColumnSourceL(TInt aColumnIndex); inline MStreamBuf* ParamSinkL(TSqlSrvFunction aFunction, TInt aParamIndex); - HBufC* GetDeclColumnTypesL(TInt aColumnCount); - + TInt GetDeclColumnTypes(RSqlBufFlat& aDeclColumnTypeBuf); + private: TInt DoBindNext(TSqlSrvFunction aFunction, TIpcArgs& aIpcArgs, RSqlBufFlat& aColumnBuf); TInt Retry(RSqlBufFlat& aBufFlat, TInt aSize, TSqlBufFlatType aWhat); diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Common/SqlUtil.h --- a/persistentstorage/sql/SRC/Common/SqlUtil.h Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Common/SqlUtil.h Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2005-2010 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" @@ -9,6 +9,7 @@ // Nokia Corporation - initial contribution. // // Contributors: +// NTT DOCOMO, INC - Fix for Bug 1915 "SQL server panics when using long column type strings" // // Description: // @@ -65,7 +66,8 @@ { ESqlColumnNamesBuf, ESqlParamNamesBuf, - ESqlColumnValuesBuf + ESqlColumnValuesBuf, + ESqlDeclColumnTypesBuf }; /** diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Server/SqlSrvDatabase.cpp --- a/persistentstorage/sql/SRC/Server/SqlSrvDatabase.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Server/SqlSrvDatabase.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -925,10 +925,7 @@ { TAttachCleanup* cleanup = reinterpret_cast (aCleanup); __SQLASSERT(cleanup != NULL, ESqlPanicBadArgument); - if(cleanup) - { - (void)cleanup->iSelf.FinalizeAttachedDb(cleanup->iDbName); - } + (void)cleanup->iSelf.FinalizeAttachedDb(cleanup->iDbName); } /** @@ -1410,10 +1407,7 @@ { CSqlSrvDatabase* self = reinterpret_cast (aCleanup); __SQLASSERT(self != NULL, ESqlPanicBadArgument); - if(self) - { - self->ReleaseCompactEntry(KMainDb16); - } + self->ReleaseCompactEntry(KMainDb16); } /** diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Server/SqlSrvDbSysSettings.cpp --- a/persistentstorage/sql/SRC/Server/SqlSrvDbSysSettings.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Server/SqlSrvDbSysSettings.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2006-2010 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" @@ -337,6 +337,7 @@ stored table version or config file version is invalid or the stored compaction mode is invalid. KErrOverflow, aCollationDllName is not large enough to store the name of the collation dll that is stored in the settings table. + KErrNoMemory, an out of memory condition has occurred. Note that the function may also leave with other system-wide error codes or SQL errors of ESqlDbError type @panic SqlDb 2 In _DEBUG mode if iDbHandle is NULL (uninitialized TSqlDbSysSettings object). @@ -356,7 +357,8 @@ //Move to the first record TInt err = ::StmtNext(stmtHandle); __SQLLEAVE_IF_ERROR(err); - //Check that it is a valid row + //Check that it is a valid row. The error is checked on the previous line. + //The "if" bellow will check whether there is a valid record or not. if(err != KSqlAtRow) { __SQLLEAVE(KErrGeneral); @@ -378,21 +380,22 @@ __SQLLEAVE(KErrGeneral); } - //The "CollationDllName" column exists and its value can be read + //The "CollationDllName" column exists and its value can be read. + //The column type might be different than SQLITE_TEXT - malformed database. + if(sqlite3_column_type(stmtHandle, KCollationDllNameColIdx) != SQLITE_TEXT) + { + __SQLLEAVE(KErrGeneral); + } const void* ptr = sqlite3_column_text16(stmtHandle, KCollationDllNameColIdx); - if(ptr) - { - TPtrC16 src(reinterpret_cast (ptr)); - if(src.Length() > aCollationDllName.MaxLength()) - { - __SQLLEAVE(KErrOverflow); - } - aCollationDllName.Copy(src); - } - else - { - __SQLLEAVE(KErrGeneral); - } + //Null column value - this might be an indication of an "out of memory" problem, if the column text + //is in UTF8 format. (sqlite3_column_text16() may allocate memory for UTF8->UTF16 conversion) + __SQLLEAVE_IF_NULL(ptr); + TPtrC16 src(reinterpret_cast (ptr)); + if(src.Length() > aCollationDllName.MaxLength()) + { + __SQLLEAVE(KErrOverflow); + } + aCollationDllName.Copy(src); } if(aSettingsVersion > ESqlSystemVersion3) { @@ -853,8 +856,16 @@ { __SQLASSERT(aStmtHandle != NULL, ESqlPanicBadArgument); aObjType = sqlite3_column_int(aStmtHandle, KObjTypeColIdx); + //The "ObjectName" column type might be different than SQLITE_TEXT - malformed database. + if(sqlite3_column_type(aStmtHandle, KObjNameColIdx) != SQLITE_TEXT) + { + __SQLLEAVE(KErrGeneral); + } + const void* text = sqlite3_column_text16(aStmtHandle, KObjNameColIdx); + //Null column value - this might be an indication of an "out of memory" problem, if the column text + //is in UTF8 format. (sqlite3_column_text16() may allocate memory for UTF8->UTF16 conversion) + __SQLLEAVE_IF_NULL(text); TInt len = (TUint)sqlite3_column_bytes16(aStmtHandle, KObjNameColIdx) / sizeof(TUint16); - const void* text = sqlite3_column_text16(aStmtHandle, KObjNameColIdx); aObjName.Set(reinterpret_cast (text), len); aPolicyType = sqlite3_column_int(aStmtHandle, KObjPolicyTypeColIdx); len = sqlite3_column_bytes(aStmtHandle, KObjPolicyDataColIdx); diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Server/SqlSrvFileData.cpp --- a/persistentstorage/sql/SRC/Server/SqlSrvFileData.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Server/SqlSrvFileData.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -192,7 +192,11 @@ @panic SqlDb 4 In _DEBUG mode. Invalid aFileNameArgNum value. @panic SqlDb 7 In _DEBUG mode. Invalid TSqlSrvFileData object. Not initialized system drive and path. */ -void TSqlSrvFileData::SetL(const RMessage2& aMessage, TInt aFileNameLen, TInt aFileNameArgNum, const TDesC8* aConfigStr) +void TSqlSrvFileData::SetL(const RMessage2& aMessage, TInt aFileNameLen, TInt aFileNameArgNum, +#ifdef SQLSRV_STARTUP_TEST + const TDesC& aDbFileName, +#endif + const TDesC8* aConfigStr) { __SQLASSERT((TUint)aFileNameArgNum < KMaxMessageArguments, ESqlPanicBadArgument); __SQLASSERT(iSysDrivePrivatePath.DriveAndPath().Length() > 0, ESqlPanicInternalError); @@ -202,9 +206,11 @@ __SQLLEAVE(KErrBadName); } #ifdef SQLSRV_STARTUP_TEST - aMessage.Int0();//prevents compiler warning - aFileNameArgNum = aFileNameArgNum;//prevents compiler warning - iFileName.Copy(*(const TDesC*)aConfigStr); + //To prevent compiler warning + aMessage.Int0(); + aFileNameArgNum = aFileNameArgNum; + // + iFileName.Copy(aDbFileName); #else aMessage.ReadL(aFileNameArgNum, iFileName); #endif @@ -223,9 +229,7 @@ ::CreatePrivateDataPathL(iFs, iDrive); } iReadOnly = ::IsReadOnlyFileL(iFs, FileName()); -#ifndef SQLSRV_STARTUP_TEST ::ExtractConfigParamsL(aConfigStr, iConfigParams, iConfig); -#endif } /** diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Server/SqlSrvFileData.h --- a/persistentstorage/sql/SRC/Server/SqlSrvFileData.h Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Server/SqlSrvFileData.h Wed Apr 14 17:46:32 2010 +0300 @@ -72,7 +72,11 @@ public: inline void InitL(RFs& aFs, const TDriveName& aSysDriveName, const TDesC& aServerPrivatePath, const TDesC& aConfigFileName, const CDbConfigFiles* aDbConfigFiles); - void SetL(const RMessage2& aMessage, TInt aFileNameLen, TInt aFileNameArgNum, const TDesC8* aConfigStr = NULL); + void SetL(const RMessage2& aMessage, TInt aFileNameLen, TInt aFileNameArgNum, +#ifdef SQLSRV_STARTUP_TEST + const TDesC& aDbFileName, +#endif + const TDesC8* aConfigStr = NULL); void SetFromHandleL(const RMessage2& aMessage, const TDesC& aDbFileName, TBool aCreated, TBool aReadOnly, const TDesC8* aConfigStr = NULL); inline RFs& Fs() const; diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Server/SqlSrvMain.cpp --- a/persistentstorage/sql/SRC/Server/SqlSrvMain.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Server/SqlSrvMain.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -299,10 +299,7 @@ //the SQL server startup code. StartL(KSqlSrvName); #endif -#ifdef _SQLPROFILER - TheSqlSrvStartTime.UniversalTime(); SQLPROFILER_SERVER_START(); -#endif //Configure the SQLite library __SQLLEAVE_IF_ERROR(sqlite3_config(SQLITE_CONFIG_LOOKASIDE, KSqliteLookAsideCellSize, KSqliteLookAsideCellCount)); //Open SQLITE library - this must be the first call after StartL() (os_symbian.cpp, "TheAllocator" initialization rellated). diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Server/SqlSrvResourceProfiler.cpp --- a/persistentstorage/sql/SRC/Server/SqlSrvResourceProfiler.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Server/SqlSrvResourceProfiler.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2008-2010 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" @@ -60,12 +60,6 @@ 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 @@ -80,11 +74,6 @@ 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; @@ -627,15 +616,25 @@ return us; } -//Calculates the time since the SQL server boot in microseconds. +//Calculates the time since the first time this function has been called. static TInt64 SqlTimeFromStartUs() { + struct TStartTime + { + inline TStartTime() + { + iTime.UniversalTime(); + } + TTime iTime; + }; + static TStartTime startTime; TTime time; time.UniversalTime(); - TTimeIntervalMicroSeconds us = time.MicroSecondsFrom(TheSqlSrvStartTime); - if(us.Int64() < 0) + TTimeIntervalMicroSeconds us = time.MicroSecondsFrom(startTime.iTime); + const TInt64 KMaxDiff = 999999999999LL;//999999999999 is the max number that can be printed out using %12ld format spec + if(us.Int64() < 0 || us.Int64() >= KMaxDiff) { - TheSqlSrvStartTime = time; + startTime.iTime = time; us = 0; } return us.Int64(); @@ -643,7 +642,7 @@ //Tracing data buffer -const TInt KSqlSrvProfilePrnBufSize = 230; +const TInt KSqlSrvProfilePrnBufSize = 300; static TBuf TheSqlSrvProfileTraceBuf; static TBuf8 TheSqlSrvProfileTraceBuf8; @@ -663,7 +662,7 @@ 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"), + TheSqlSrvProfileTraceBuf8.Format(_L8("% 8X¬%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); @@ -716,6 +715,7 @@ { if(TheSqlSrvProfilerTraceEnabled) { + TheSqlSrvProfilerFileRead = TheSqlSrvProfilerFileWrite = TheSqlSrvProfilerFileSync = TheSqlSrvProfilerFileSetSize = 0; if(TheSqlSrvProfilerTraceLevel == 0) { return; @@ -725,10 +725,6 @@ return; } ++aIpcCounter; - TheSqlSrvProfilerFileRead1 = TheSqlSrvProfilerFileRead; - TheSqlSrvProfilerFileWrite1 = TheSqlSrvProfilerFileWrite; - TheSqlSrvProfilerFileSync1 = TheSqlSrvProfilerFileSync; - TheSqlSrvProfilerFileSetSize1 = TheSqlSrvProfilerFileSetSize; aStartTicks = User::FastCounter(); } } @@ -762,7 +758,7 @@ } 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"), + TheSqlSrvProfileTraceBuf.Format(_L("% 8X¬%012ld¬IPC¬%08u¬%20.20S¬%012ld¬%010d¬%08d¬%04d¬%04d¬%04d¬%04d¬rc=%d"), aDbHandle, timeFromStart, aIpcCounter, @@ -770,10 +766,10 @@ ttlExecTime, executionTime, count, - TheSqlSrvProfilerFileRead - TheSqlSrvProfilerFileRead1, - TheSqlSrvProfilerFileWrite - TheSqlSrvProfilerFileWrite1, - TheSqlSrvProfilerFileSync - TheSqlSrvProfilerFileSync1, - TheSqlSrvProfilerFileSetSize - TheSqlSrvProfilerFileSetSize1, + TheSqlSrvProfilerFileRead, + TheSqlSrvProfilerFileWrite, + TheSqlSrvProfilerFileSync, + TheSqlSrvProfilerFileSetSize, aRetCode); SqlSrvProfilePrintf(ESqlSrvProfilerNonSqlTrace); } @@ -792,7 +788,7 @@ TPtrC ipcCallName; (void)SqlIpcTraceIdxAndName(aFuncCode, ipcCallName); TInt64 timeFromStart = SqlTimeFromStartUs(); - TheSqlSrvProfileTraceBuf.Format(_L("%08X¬%012ld¬ERR¬%08u¬%20.20S¬err=%d"), + TheSqlSrvProfileTraceBuf.Format(_L("% 8X¬%012ld¬ERR¬%08u¬%20.20S¬err=%d"), aDbHandle, timeFromStart, aIpcCounter, @@ -827,13 +823,13 @@ _LIT(KEmptyStr, ""); if(pos == 0) { - line.Format(_L("%08X¬%012ld¬SQL¬%12.12S¬"), aDbHandle, timeFromStart, aPrepare ? &KPrepare : &KExec); + line.Format(_L("% 8X¬%012ld¬SQL¬%12.12S¬"), aDbHandle, timeFromStart, aPrepare ? &KPrepare : &KExec); } else { if(!TheSqlSrvProfilerTraceToFile) { - line.Format(_L("%08X¬%012ld¬SQL¬%12.12S¬"), aDbHandle, timeFromStart, &KEmptyStr); + line.Format(_L("% 8X¬%012ld¬SQL¬%12.12S¬"), aDbHandle, timeFromStart, &KEmptyStr); } } TInt l = Min(len, (line.MaxLength() - line.Length())); @@ -872,13 +868,13 @@ _LIT(KEmptyStr, ""); if(pos == 0) { - line.Format(_L("%08X¬%012ld¬SQL¬%12.12S¬"), aDbHandle, timeFromStart, aPrepare ? &KPrepare : &KExec); + line.Format(_L("% 8X¬%012ld¬SQL¬%12.12S¬"), aDbHandle, timeFromStart, aPrepare ? &KPrepare : &KExec); } else { if(!TheSqlSrvProfilerTraceToFile) { - line.Format(_L("%08X¬%012ld¬SQL¬%12.12S¬"), aDbHandle, timeFromStart, &KEmptyStr); + line.Format(_L("% 8X¬%012ld¬SQL¬%12.12S¬"), aDbHandle, timeFromStart, &KEmptyStr); } } TInt l = Min(len, (line.MaxLength() - line.Length())); @@ -908,7 +904,7 @@ return; } TInt64 timeFromStart = SqlTimeFromStartUs(); - TheSqlSrvProfileTraceBuf.Format(_L("%08X¬%012ld¬CRE¬%S"), + TheSqlSrvProfileTraceBuf.Format(_L("% 08X¬%012ld¬CRE¬%S"), aDbHandle, timeFromStart, &aDbName); @@ -930,7 +926,7 @@ return; } TInt64 timeFromStart = SqlTimeFromStartUs(); - TheSqlSrvProfileTraceBuf.Format(_L("%08X¬%012ld¬OPN¬%S"), + TheSqlSrvProfileTraceBuf.Format(_L("% 8X¬%012ld¬OPN¬%S"), aDbHandle, timeFromStart, &aDbName); @@ -948,7 +944,7 @@ return; } TInt64 timeFromStart = SqlTimeFromStartUs(); - TheSqlSrvProfileTraceBuf.Format(_L("%08X¬%012ld¬CSE"), + TheSqlSrvProfileTraceBuf.Format(_L("% 8X¬%012ld¬CSE"), aDbHandle, timeFromStart); SqlSrvProfilePrintf(ESqlSrvProfilerNonSqlTrace); @@ -990,7 +986,7 @@ RDebug::Print(_L("SQL trace file creation failed with err=%d"), err); } } - TheSqlSrvProfileTraceBuf.Format(_L("%08X¬%012ld¬SRV¬START"), 0, timeFromStart); + TheSqlSrvProfileTraceBuf.Format(_L("% 8X¬%012ld¬SRV¬START"), 0, timeFromStart); SqlSrvProfilePrintf(ESqlSrvProfilerNonSqlTrace); } @@ -998,7 +994,7 @@ void SqlPrintServerStop() { TInt64 timeFromStart = SqlTimeFromStartUs(); - TheSqlSrvProfileTraceBuf.Format(_L("%08X¬%012ld¬SRV¬STOP"), 0, timeFromStart); + TheSqlSrvProfileTraceBuf.Format(_L("% 8X¬%012ld¬SRV¬STOP"), 0, timeFromStart); SqlSrvProfilePrintf(ESqlSrvProfilerNonSqlTrace); if(TheSqlSrvProfilerTraceToFile) { diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Server/SqlSrvResourceProfiler.h --- a/persistentstorage/sql/SRC/Server/SqlSrvResourceProfiler.h Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Server/SqlSrvResourceProfiler.h Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2008-2010 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" @@ -64,10 +64,6 @@ ////////////////////////// IPC & SQL tracing related ///////////////////////////////// -//Every time, when the SQL server starts, the time is stored in TheSqlSrvStartTime variable. -//It is used later to calculate and trace the time offset of particular trace. -extern TTime TheSqlSrvStartTime; - //Level 1 IPC calls count. IPC calls types included: // ESqlSrvDbExec8, ESqlSrvDbExec16, ESqlSrvDbScalarFullSelect16, ESqlSrvStmtExec, // ESqlSrvStmtAsyncExec, ESqlSrvStmtBindExec, ESqlSrvStmtAsyncBindExec, ESqlSrvStmtNext, diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Server/SqlSrvSession.cpp --- a/persistentstorage/sql/SRC/Server/SqlSrvSession.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Server/SqlSrvSession.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -9,6 +9,7 @@ // Nokia Corporation - initial contribution. // // Contributors: +// NTT DOCOMO, INC - Fix for Bug 1915 "SQL server panics when using long column type strings" // // Description: // @@ -27,6 +28,8 @@ /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma BullseyeCoverage off + #ifdef _DEBUG const TInt KDelayedDbHeapFailureMask = 0x1000; @@ -80,9 +83,16 @@ //Executes the heap simulation failure. inline void CSqlSrvSession::DbSetAllocFail(TInt aHeapFailureMode, TInt aFailedAllocNumber) { - User::__DbgSetAllocFail(RHeap::EUser, - static_cast (aHeapFailureMode & (KDelayedDbHeapFailureMask - 1)), - aFailedAllocNumber); + TInt mode = aHeapFailureMode & (KDelayedDbHeapFailureMask - 1); + if(mode >= RAllocator::EBurstRandom && mode <= RAllocator::EBurstFailNext) + { + const TUint KBurst = 50; + User::__DbgSetBurstAllocFail(RHeap::EUser, static_cast (mode), aFailedAllocNumber, KBurst); + } + else + { + User::__DbgSetAllocFail(RHeap::EUser, static_cast (mode), aFailedAllocNumber); + } } //Executes the delayed heap simulation failure, if the connection is in test mode @@ -90,9 +100,16 @@ { if(iDbResourceTestMode & KDelayedDbHeapFailureMask) { - User::__DbgSetAllocFail(RHeap::EUser, - static_cast (iDbResourceTestMode & (KDelayedDbHeapFailureMask - 1)), - iFailedAllocNumber); + TInt mode = iDbResourceTestMode & (KDelayedDbHeapFailureMask - 1); + if(mode >= RAllocator::EBurstRandom && mode <= RAllocator::EBurstFailNext) + { + const TUint KBurst = 50; + User::__DbgSetBurstAllocFail(RHeap::EUser, static_cast (mode), iFailedAllocNumber, KBurst); + } + else + { + User::__DbgSetAllocFail(RHeap::EUser, static_cast (mode), iFailedAllocNumber); + } } } @@ -125,6 +142,8 @@ #endif//_DEBUG +#pragma BullseyeCoverage on + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -399,7 +418,7 @@ StmtColumnValueL(aMessage, handle); break; case ESqlSrvStmtDeclColumnTypes: - StmtDeclColumnTypesL(aMessage, handle); + retCode = StmtDeclColumnTypesL(aMessage, handle); break; ////////////////////// stream operations ////////////////////////////////// case ESqlSrvStreamRead: @@ -460,6 +479,8 @@ //////////////////////////// Profiler operations /////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma BullseyeCoverage off + /** Retrieves the counter values for the specified profiling counter. @@ -496,6 +517,8 @@ } } +#pragma BullseyeCoverage on + /////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////// Database operations /////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1063,6 +1086,7 @@ Arg 3: [in] database file handle @panic SqlDb 2 Client panic. iDatabase is NULL (the database object is not created yet). +@panic SqlDb 4 Client panic. Invalid IPC data, an indication of a problme in client side sql library. */ void CSqlSrvSession::DbAttachFromHandleL(const RMessage2& aMessage) { @@ -1070,10 +1094,7 @@ //Read-only flag, buffer length, buffer allocation TBool readOnly = (aMessage.Int0() & 0x80000000) != 0; const TInt KBufLen = aMessage.Int0() & 0x7FFFFFFF; - if(KBufLen <= 0) - { - __SQLLEAVE(KErrArgument); - } + __SQLPANIC_CLIENT(KBufLen > 0, aMessage, ESqlPanicBadArgument); HBufC8* buf = HBufC8::NewLC(KBufLen); TPtr8 bufPtr = buf->Des(); aMessage.ReadL(1, bufPtr); @@ -1486,22 +1507,26 @@ } /** +Processes the request for retrieving the statement declared column type names. + +If the client side buffer size is not big enough, the function returns the size + KSqlClientBufOverflowCode. +In this case the client must increase the buffer and try again to get the buffer only + Usage of the IPC call arguments: Arg 0: [in] input buffer max length in 16-bit characters -Arg 1: [in/out] buffer +Arg 1: [out] ipc buffer, declared column type names */ -void CSqlSrvSession::StmtDeclColumnTypesL(const RMessage2& aMessage, TInt aStmtHandle) - { +TInt CSqlSrvSession::StmtDeclColumnTypesL(const RMessage2& aMessage, TInt aStmtHandle) + { CSqlSrvStatement& stmt = ::SqlSessObjFind(iStatements, aStmtHandle, aMessage); - HBufC* colTypesBuf = stmt.GetDeclColumnTypesL(); - CleanupStack::PushL(colTypesBuf); - if(colTypesBuf->Des().Length() > aMessage.Int0()) + const RSqlBufFlat& declColumnTypesBuf = stmt.GetDeclColumnTypesL(); + TInt size = declColumnTypesBuf.Size(); + if(size <= aMessage.Int0()) { - __SQLLEAVE(KErrOverflow); + aMessage.WriteL(1, declColumnTypesBuf.BufDes()); + return 0; } - aMessage.WriteL(1, colTypesBuf->Des()); - SQLPROFILER_REPORT_IPC(ESqlIpcWrite, (colTypesBuf->Des().Length() * sizeof(TText))); - CleanupStack::PopAndDestroy(colTypesBuf); + return size + KSqlClientBufOverflowCode; } @@ -1555,8 +1580,8 @@ The string will be zero terminated after the "read" operation. Returns TDes8 reference pointing to the zero-terminated string. -@leave KErrBadDescriptor The transferred data length is bigger than the aByteLen value - +@panic SqlDb 3 Client panic. The string length is not equal to aByteLen. If happens then it is an indication of a + problem inside client side sql library. @panic SqlDb 4 Client panic. Negative aByteLen value. */ TDes8& CSqlSrvSession::ReadString8ZL(const RMessage2& aMessage, TInt aArgNum, TInt aByteLen) @@ -1565,10 +1590,7 @@ TDes8& buf = Server().GetBuf8L(aByteLen + 1); aMessage.ReadL(aArgNum, buf); SQLPROFILER_REPORT_IPC(ESqlIpcRead, aByteLen); - if(buf.Length() > aByteLen) - { - __SQLLEAVE(KErrBadDescriptor); - } + __SQLPANIC_CLIENT(buf.Length() == aByteLen, aMessage, ESqlPanicBadHandle); buf.Append(TChar(0)); return buf; } @@ -1578,8 +1600,8 @@ The string will be zero terminated after the "read" operation. Returns TDes16 reference pointing to the zero-terminated string. -@leave KErrBadDescriptor The transferred data length is bigger than the aCharLen value - +@panic SqlDb 3 Client panic. The string length is not equal to aCharLen. If happens then it is an indication of a + problem inside client side sql library. @panic SqlDb 4 Client panic. Negative aCharLen value. */ TDes16& CSqlSrvSession::ReadString16ZL(const RMessage2& aMessage, TInt aArgNum, TInt aCharLen) @@ -1588,10 +1610,7 @@ TDes16& buf = Server().GetBuf16L(aCharLen + 1); aMessage.ReadL(aArgNum, buf); SQLPROFILER_REPORT_IPC(ESqlIpcRead, (aCharLen * sizeof(TText))); - if(buf.Length() > aCharLen) - { - __SQLLEAVE(KErrBadDescriptor); - } + __SQLPANIC_CLIENT(buf.Length() == aCharLen, aMessage, ESqlPanicBadHandle); buf.Append(TChar(0)); return buf; } @@ -1600,8 +1619,8 @@ Reads a 16-bit string with "aCharLen" character length, which is in "aArgNum" argument of aMessage. Returns TDes16 reference pointing to the string. -@leave KErrBadDescriptor The transferred data length is bigger than the aCharLen value - +@panic SqlDb 3 Client panic. The string length is not equal to aCharLen. If happens then it is an indication of a + problem inside client side sql library. @panic SqlDb 4 Client panic. Negative aCharLen value. */ TDes16& CSqlSrvSession::ReadString16L(const RMessage2& aMessage, TInt aArgNum, TInt aCharLen) @@ -1610,10 +1629,7 @@ TDes16& buf = Server().GetBuf16L(aCharLen); aMessage.ReadL(aArgNum, buf); SQLPROFILER_REPORT_IPC(ESqlIpcRead, (aCharLen * sizeof(TText))); - if(buf.Length() > aCharLen) - { - __SQLLEAVE(KErrBadDescriptor); - } + __SQLPANIC_CLIENT(buf.Length() == aCharLen, aMessage, ESqlPanicBadHandle); return buf; } @@ -1726,7 +1742,7 @@ TPtrC8 val; if(aColType == ESqlText) { - TPtrC textVal = aStmt.ColumnText(0); + TPtrC textVal = aStmt.ColumnTextL(0); val.Set(reinterpret_cast (textVal.Ptr()), textVal.Length() * sizeof(TUint16)); } else diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Server/SqlSrvSession.h --- a/persistentstorage/sql/SRC/Server/SqlSrvSession.h Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Server/SqlSrvSession.h Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2005-2010 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" @@ -9,6 +9,7 @@ // Nokia Corporation - initial contribution. // // Contributors: +// NTT DOCOMO, INC - Fix for Bug 1915 "SQL server panics when using long column type strings" // // Description: // @@ -107,7 +108,7 @@ void StmtGetBufFlatL(const RMessage2& aMessage, TInt aStmtHandle); void StmtColumnValueL(const RMessage2& aMessage, TInt aStmtHandle); void DoStmtBindL(const RMessage2& aMessage, CSqlSrvStatement& aStmt); - void StmtDeclColumnTypesL(const RMessage2& aMessage, TInt aStmtHandle); + TInt StmtDeclColumnTypesL(const RMessage2& aMessage, TInt aStmtHandle); //Helper methods TInt NewOutputStreamL(const RMessage2& aMessage, MStreamBuf* aStreamBuf); TDes8& ReadString8ZL(const RMessage2& aMessage, TInt aArgNum, TInt aByteLen); diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Server/SqlSrvStatement.cpp --- a/persistentstorage/sql/SRC/Server/SqlSrvStatement.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Server/SqlSrvStatement.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -9,6 +9,7 @@ // Nokia Corporation - initial contribution. // // Contributors: +// NTT DOCOMO, INC - Fix for Bug 1915 "SQL server panics when using long column type strings" // // Description: // @@ -382,13 +383,22 @@ case SQLITE_TEXT: { TInt charLength = (TUint)sqlite3_column_bytes16(iStmtHandle, colIdx) / sizeof(TUint16); + //"charLength == 0" - this might be an indication of an "out of memory" problem, if the column text is in UTF8 format. + //(sqlite3_column_bytes16() may allocate memory for UTF8->UTF16 conversion) + if(charLength == 0 && sqlite3_errcode(sqlite3_db_handle(iStmtHandle)) == SQLITE_NOMEM) + { + __SQLLEAVE(KErrNoMemory); + } if(charLength >= KSqlMaxDesLen) { it.SetAsNotPresent(ESqlText, charLength); } else - { - __SQLLEAVE_IF_ERROR(it.SetText(TPtrC16(reinterpret_cast (sqlite3_column_text16(iStmtHandle, colIdx)), charLength))); + {//sqlite3_column_bytes16() already allocated the needed memory if a UTF8->UTF16 conversion + //had to be performed. The sqlite3_column_text16() on the next line is guaranteed to succeed. + const TUint16* text = reinterpret_cast (sqlite3_column_text16(iStmtHandle, colIdx)); + __SQLASSERT(text != NULL, ESqlPanicInternalError); + __SQLLEAVE_IF_ERROR(it.SetText(TPtrC16(text, charLength))); } } break; @@ -434,8 +444,11 @@ __SQLASSERT(iStmtHandle != NULL, ESqlPanicInvalidObj); TInt colType = sqlite3_column_type(iStmtHandle, aColumnIndex); if(colType == SQLITE_TEXT) - { + {//Since the first called function after the Next() operation is always CSqlSrvStatement::ColumnValuesL(), then + //sqlite3_column_bytes16() (called from ColumnValuesL()) already allocated the needed memory if a UTF8->UTF16 + //conversion had to be performed. The sqlite3_column_text16() on the next line is guaranteed to succeed. const void* text = sqlite3_column_text16(iStmtHandle, aColumnIndex); + __SQLASSERT(text != NULL, ESqlPanicInternalError); TInt length = sqlite3_column_bytes16(iStmtHandle, aColumnIndex); aColumnSource.Set(reinterpret_cast (text), length); } @@ -645,10 +658,12 @@ @see RSqlStatement +@leave KErrNoMemory, an out of memory condition has occurred. + @panic SqlDb 2 In _DEBUG mode. Invalid (not created) CSqlSrvStatement object. @panic SqlDb 4 In _DEBUG mode. Invalid aColIdx value. */ -TPtrC CSqlSrvStatement::ColumnText(TInt aColIdx) const +TPtrC CSqlSrvStatement::ColumnTextL(TInt aColIdx) const { __SQLASSERT(iStmtHandle != NULL, ESqlPanicInvalidObj); __SQLASSERT((TUint)aColIdx < iColumnCount, ESqlPanicBadArgument); @@ -657,7 +672,17 @@ if(colType == SQLITE_TEXT) { TInt charLength = (TUint)sqlite3_column_bytes16(iStmtHandle, aColIdx) / sizeof(TUint16); - res.Set(reinterpret_cast (sqlite3_column_text16(iStmtHandle, aColIdx)), charLength); + //"charLength == 0" - this might be an indication of an "out of memory" problem, if the column text is in UTF8 format. + //(sqlite3_column_bytes16() may allocate memory for UTF8->UTF16 conversion) + if(charLength == 0 && sqlite3_errcode(sqlite3_db_handle(iStmtHandle)) == SQLITE_NOMEM) + { + __SQLLEAVE(KErrNoMemory); + } + //sqlite3_column_bytes16() already allocated the needed memory if a UTF8->UTF16 conversion + //had to be performed. The sqlite3_column_text16() on the next line is guaranteed to succeed. + const TUint16* text = reinterpret_cast (sqlite3_column_text16(iStmtHandle, aColIdx)); + __SQLASSERT(text != NULL, ESqlPanicInternalError); + res.Set(text, charLength); } return res; } @@ -688,30 +713,47 @@ } /** -This function is used by the DBMS emulation library only. -The function retrieves the declared column types from the SQLITE library, compiles them in a single string -and then returns the string to the caller. +Retrieves the declared column types using the SQLITE library storing in a +flat buffer and returns a reference to the buffer. + +@return A const reference to a flat buffer containing the declared column type names. -@return A pointer to a heap allocated HBufC object with the delcared column types. The caller is responsible - for the HBufC object destruction. +@leave KErrNoMemory, an out of memory condition has occurred; + +@panic SqlDb 2 In _DEBUG mode. Invalid (not created) CSqlSrvStatement object. */ -HBufC* CSqlSrvStatement::GetDeclColumnTypesL() +const RSqlBufFlat& CSqlSrvStatement::GetDeclColumnTypesL() { - HBufC* buf = HBufC::NewL(iColumnCount * 20);//20 as length is enough for a single column type text - TPtr ptr = buf->Des(); - for(TInt i=0;i (-1); + __SQLLEAVE_IF_ERROR(iBufFlat.SetCount(iColumnCount)); + TSqlBufWIterator it; + it.Set(iBufFlat); + TInt colIdx = -1; + while(it.Next()) { - const TUint16* declTypeTxt = reinterpret_cast (sqlite3_column_decltype16(iStmtHandle, i)); - if(declTypeTxt) - { - TPtrC type(declTypeTxt, User::StringLength(declTypeTxt)); - ptr.Append(type); - } - ptr.Append(TChar(';')); + ++colIdx;//the first SQLITE column index is 0 + const TUint16* declTypeTxt = reinterpret_cast (sqlite3_column_decltype16(iStmtHandle, colIdx)); + TPtrC ptr(KNullDesC); + if(declTypeTxt) + { + ptr.Set(declTypeTxt, User::StringLength(declTypeTxt)); + } + else + { + //If sqlite3_column_decltype16() returns NULL but sqlite3_column_decltype() doesn't, then it is an "out of memory" condition + if(sqlite3_column_decltype(iStmtHandle, colIdx)) + { + __SQLLEAVE(KErrNoMemory); + } + } + __SQLLEAVE_IF_ERROR(it.SetText(ptr)); } - return buf; + iBufFlatType = ESqlDeclColumnTypesBuf; + return iBufFlat; } + /** Creates a new HSqlSrvStmtParamBuf object for the parameter with index "aParamIndex" or reuses the existing one. diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/SRC/Server/SqlSrvStatement.h --- a/persistentstorage/sql/SRC/Server/SqlSrvStatement.h Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/SRC/Server/SqlSrvStatement.h Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2005-2010 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" @@ -9,6 +9,7 @@ // Nokia Corporation - initial contribution. // // Contributors: +// NTT DOCOMO, INC - Fix for Bug 1915 "SQL server panics when using long column type strings" // // Description: // @@ -223,10 +224,10 @@ TInt ColumnInt(TInt aColIdx) const; TInt64 ColumnInt64(TInt aColIdx) const; TReal ColumnReal(TInt aColIdx) const; - TPtrC ColumnText(TInt aColIdx) const; + TPtrC ColumnTextL(TInt aColIdx) const; TPtrC8 ColumnBinary(TInt aColIdx) const; - HBufC* GetDeclColumnTypesL(); + const RSqlBufFlat& GetDeclColumnTypesL(); HSqlSrvStmtParamBuf* GetParamBufL(TInt aParamIndex, HSqlSrvStmtParamBuf::TDataType aDataType, HSqlSrvStmtParamBuf::TBufType aBufType); void BindParamBufL(TInt aParamIndex); diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/TEST/t_sqlapi.cpp --- a/persistentstorage/sql/TEST/t_sqlapi.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/TEST/t_sqlapi.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -1355,6 +1355,115 @@ } /** +@SYMTestCaseID PDS-SQL-CT-4191 +@SYMTestCaseDesc The test creates a test database and inserts one record using a stream. + MStreamBuf::SeekL() is used to modify the parameter data at specific positions. + Then the test executes a SELECT statement to read the just written record. + MStreamBuf::SeekL() is used to read the column content at specific positions + (the same positions used during the record write operation). The read byte values must + match the written byte values. +@SYMTestPriority High +@SYMTestActions RSqlColumnReadStream::ColumnBinary() and RSqlParamWriteStream::BindBinary() - MStreamBuf::SeekL() test. +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF145125 +*/ +void StreamSeekTestL() + { + RSqlDatabase db; + CleanupClosePushL(db); + TInt rc = db.Create(KTestDbName1); + TEST2(rc, KErrNone); + rc = db.Exec(_L("CREATE TABLE A(Fld1 INTEGER, Fld2 BLOB)")); + TEST(rc >= 0); + //Write a record to the database using a stream. MStreamBuf::SeekL() is used to modify the content at a specific position. + RSqlStatement stmt; + CleanupClosePushL(stmt); + rc = stmt.Prepare(db, _L("INSERT INTO A(Fld1, Fld2) VALUES(1, ?)")); + TEST2(rc, KErrNone); + + RSqlParamWriteStream strm1; + CleanupClosePushL(strm1); + rc = strm1.BindBinary(stmt, 0); + TEST2(rc, KErrNone); + + for(TInt i=0;i<256;++i) + { + strm1 << (TUint8)i; + } + + const TInt KStreamOffset = 10; + const TUint8 KByte = 'z'; + _LIT8(KData, "QWERTYUIOPASDFG"); + + MStreamBuf* strm1buf = strm1.Sink(); + TEST(strm1buf != NULL); + + strm1buf->SeekL(MStreamBuf::EWrite, EStreamBeginning, 0); + strm1buf->WriteL(&KByte, 1); + + strm1buf->SeekL(MStreamBuf::EWrite, EStreamMark, KStreamOffset); + strm1buf->WriteL(&KByte, 1); + + strm1buf->SeekL(MStreamBuf::EWrite, EStreamEnd, 0); + strm1buf->WriteL(KData().Ptr(), KData().Length()); + + strm1buf->SeekL(MStreamBuf::EWrite, EStreamEnd, -4 * KStreamOffset); + strm1buf->WriteL(&KByte, 1); + + strm1.CommitL(); + CleanupStack::PopAndDestroy(&strm1); + + rc = stmt.Exec(); + TEST2(rc, 1); + CleanupStack::PopAndDestroy(&stmt); + + //Read the record using a stream. MStreamBuf::SeekL() is used to read the content at a specific position. + CleanupClosePushL(stmt); + rc = stmt.Prepare(db, _L("SELECT Fld2 FROM A WHERE Fld1 = 1")); + TEST2(rc, KErrNone); + rc = stmt.Next(); + TEST2(rc, KSqlAtRow); + + RSqlColumnReadStream strm2; + CleanupClosePushL(strm2); + rc = strm2.ColumnBinary(stmt, 0); + TEST2(rc, KErrNone); + + TUint8 byte = 0; + MStreamBuf* strm2buf = strm2.Source(); + TEST(strm1buf != NULL); + + strm2buf->SeekL(MStreamBuf::ERead, EStreamBeginning, 0); + rc = strm2buf->ReadL(&byte, 1); + TEST2(rc, 1); + TEST2(byte, KByte); + + strm2buf->SeekL(MStreamBuf::ERead, EStreamMark, KStreamOffset); + rc = strm2buf->ReadL(&byte, 1); + TEST2(rc, 1); + TEST2(byte, KByte); + + strm2buf->SeekL(MStreamBuf::ERead, EStreamEnd, -KData().Length()); + TUint8 buf[20]; + rc = strm2buf->ReadL(buf, KData().Length()); + TEST2(rc, KData().Length()); + TPtrC8 bufptr(buf, rc); + TEST(bufptr == KData); + + strm2buf->SeekL(MStreamBuf::ERead, EStreamEnd, -4 * KStreamOffset); + rc = strm2buf->ReadL(&byte, 1); + TEST2(rc, 1); + TEST2(byte, KByte); + + CleanupStack::PopAndDestroy(&strm2); + CleanupStack::PopAndDestroy(&stmt); + + CleanupStack::PopAndDestroy(&db); + rc = RSqlDatabase::Delete(KTestDbName1); + TEST2(rc, KErrNone); + } + +/** @SYMTestCaseID PDS-SQL-CT-4174 @SYMTestCaseDesc Test for DEF144937: SQL, SQL server, the code coverage can be improved in some areas. @SYMTestPriority High @@ -2239,7 +2348,7 @@ void DoTestsL() { - TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1601 Create/Open/Close database tests ")); + TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1601 Create/Open/Close database tests ")); OpenCloseDatabaseTest(); TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1602 SetIsolationLevel() database tests ")); @@ -2283,6 +2392,9 @@ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1622 RSqlParamWriteStream test. Long binary parameter ")); BinaryParameterStreamTest(); + TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-CT-4191 MStreamBuf::SeekL() test")); + StreamSeekTestL(); + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1634 RSqlStatement test. Nameless parameter ")); NamelessParameterTest(); diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/TEST/t_sqlattach.cpp --- a/persistentstorage/sql/TEST/t_sqlattach.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/TEST/t_sqlattach.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2006-2010 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" @@ -290,6 +290,12 @@ err = TheDb.Detach(dbName3); TEST2(err, KSqlErrGeneral); + //Attach a non-existing database + _LIT(KAttachDbFile5, "c:\\test\\zxcvbnm987654321.db"); + _LIT(KAttachDb5, "zxcvbnm987654321"); + err = TheDb.Attach(KAttachDbFile5, KAttachDb5); + TEST2(err, KErrNotFound); + TheDb.Close(); } diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/TEST/t_sqlcompact3.cpp --- a/persistentstorage/sql/TEST/t_sqlcompact3.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/TEST/t_sqlcompact3.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -121,7 +121,7 @@ void CompactConfigTest1L() { //Create a test database with "manual" compaction mode - _LIT8(KConfigStr1, "encoding=utf8;compaction=manual"); + _LIT8(KConfigStr1, "encoding=utf-8;compaction=manual"); TInt err = TheDb.Create(KTestDbName1, &KConfigStr1); TEST2(err, KErrNone); //Check the vacuum mode. The SQLite vacuum mode should be "incremental" @@ -166,7 +166,7 @@ void CompactConfigTest2L() { //Create a test database with "auto" compaction mode - _LIT8(KConfigStr1, "encoding=utf8;compaction=auto"); + _LIT8(KConfigStr1, "encoding=utf-8;compaction=auto"); TInt err = TheDb.Create(KTestDbName1, &KConfigStr1); TEST2(err, KErrNone); //Check the vacuum mode. The SQLite vacuum mode should be "auto" @@ -177,7 +177,7 @@ //Create a test database with "synchronous" compaction mode err = RSqlDatabase::Delete(KTestDbName1); TEST2(err, KErrNone); - _LIT8(KConfigStr3, "encoding=utf8;compaction=synchronous"); + _LIT8(KConfigStr3, "encoding=utf-8;compaction=synchronous"); err = TheDb.Create(KTestDbName1, &KConfigStr3); TEST2(err, KErrNone); //Check the vacuum mode. The SQLite vacuum mode should be "auto" @@ -221,7 +221,7 @@ void CompactConfigTest3L() { //Create a test database with "background" compaction mode - _LIT8(KConfigStr1, "encoding=utf8;compaction=background"); + _LIT8(KConfigStr1, "encoding=utf-8;compaction=background"); TInt err = TheDb.Create(KTestDbName1, &KConfigStr1); TEST2(err, KErrNone); //Check the vacuum mode. The SQLite vacuum mode should be "incremental" @@ -278,7 +278,7 @@ err = RSqlDatabase::Delete(KTestDbName1); TEST2(err, KErrNone); //Create a test database with invalid configuration string - _LIT8(KConfigStr1, "encoding=utf8;compaction=backgrund"); + _LIT8(KConfigStr1, "encoding=utf-8;compaction=backgrund"); err = TheDb.Create(KTestDbName1, &KConfigStr1); TEST2(err, KErrNone); //Check the vacuum mode. The SQLite vacuum mode should be KSqlDefaultVacuum @@ -324,7 +324,7 @@ void CompactConfigTest5L() { //Create a private test database with "auto" compaction mode - _LIT8(KConfigStr1, "encoding=utf8;compaction=auto"); + _LIT8(KConfigStr1, "encoding=utf-8;compaction=auto"); TInt err = TheDb.Create(KTestPrivDbName, &KConfigStr1); TEST2(err, KErrNone); //Check the vacuum mode. The SQLite vacuum mode should be "auto" @@ -456,7 +456,7 @@ { //Create a secure test database with "auto" compaction mode. RSqlSecurityPolicy securityPolicy = CreateTestSecurityPolicy(); - _LIT8(KConfigStr1, "encoding=utf8;compaction=auto"); + _LIT8(KConfigStr1, "encoding=utf-8;compaction=auto"); TInt err = TheDb.Create(KTestSecureDbName, securityPolicy, &KConfigStr1); TEST2(err, KErrNone); securityPolicy.Close(); @@ -521,7 +521,7 @@ void CompactConfigTest7L() { //Create a test database with "auto" compaction mode. - _LIT8(KConfigStr1, "encoding=utf8;compaction = auto"); + _LIT8(KConfigStr1, "encoding=utf-8;compaction = auto"); TInt err = TheDb.Create(KTestDbName1, &KConfigStr1); TEST2(err, KErrNone); //Check the vacuum mode. The SQLite vacuum mode should be "auto" @@ -539,7 +539,7 @@ compact = scalarQuery2.SelectIntL(_L("PRAGMA auto_vacuum")); TEST2(compact, KAutoVacuum); //Open a third connection to the same database - "background" compaction mode config string - _LIT8(KConfigStr2, " encoding = utf8 ; ; ; compaction = background "); + _LIT8(KConfigStr2, " encoding = utf-8 ; ; ; compaction = background "); RSqlDatabase db3; err = db3.Open(KTestDbName1, &KConfigStr2); TEST2(err, KErrNone); @@ -577,7 +577,7 @@ compact = scalarQuery2.SelectIntL(_L("PRAGMA auto_vacuum")); TEST2(compact, KIncrementalVacuum); //Open a third connection to the same database - "auto" compaction mode config string - _LIT8(KConfigStr4, " encoding = utf16 ; compaction = auto ; ; ; "); + _LIT8(KConfigStr4, " encoding = utf-16 ; compaction = auto ; ; ; "); err = db3.Open(KTestDbName1, &KConfigStr4); TEST2(err, KErrNone); //Check the vacuum mode. The SQLite vacuum mode should be "incremental" diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/TEST/t_sqlcompact4.cpp --- a/persistentstorage/sql/TEST/t_sqlcompact4.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/TEST/t_sqlcompact4.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2008-2010 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" @@ -433,13 +433,17 @@ //Nonexisting attached database err = DoManualCompaction((TCompactionType)i, RSqlDatabase::EMaxCompaction, _L("aaa")); TEST2(err, KSqlErrGeneral); - //Very long name of a nonexisting attached database - TBuf fname; - fname.SetLength(fname.MaxLength()); - fname.Fill(0xDD); - err = DoManualCompaction((TCompactionType)i, RSqlDatabase::EMaxCompaction, fname); - TEST2(err, KErrBadName); - // + //Very long name of a nonexisting attached database + TBuf fname; + fname.SetLength(fname.MaxLength()); + fname.Fill(0xDD); + err = DoManualCompaction((TCompactionType)i, RSqlDatabase::EMaxCompaction, fname); + TEST2(err, KErrBadName); + //Invalid attached database name + fname.Copy(_L("c:\\|aaa|.db")); + err = DoManualCompaction((TCompactionType)i, RSqlDatabase::EMaxCompaction, fname); + TEST2(err, KSqlErrGeneral); + // TheDb.Close(); (void)RSqlDatabase::Delete(TheTestDbName); } diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/TEST/t_sqlconfig.cpp --- a/persistentstorage/sql/TEST/t_sqlconfig.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/TEST/t_sqlconfig.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2007-2010 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" @@ -430,8 +430,8 @@ (void)RSqlDatabase::Delete(KTestDbName2); (void)RSqlDatabase::Delete(KTestDbName); //Create 2 databases with different configuration parameters - _LIT8(KCfgStr2_1, "cache_size = 50; page_size = 512; encoding = UTF-16"); - _LIT8(KCfgStr2_2, "cache_size = 80; page_size = 4096; encoding = UTF-8"); + _LIT8(KCfgStr2_1, "cache_size = 50; page_size = 512; encoding = \"UTF-16\""); + _LIT8(KCfgStr2_2, "cache_size = 80; page_size = 4096; encoding = \"UTF-8\""); err = TheDb.Create(KTestDbName, &KCfgStr2_1); TEST2(err, KErrNone); err = TheDb2.Create(KTestDbName2, &KCfgStr2_2); diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/TEST/t_sqldefect.cpp --- a/persistentstorage/sql/TEST/t_sqldefect.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/TEST/t_sqldefect.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -9,6 +9,7 @@ // Nokia Corporation - initial contribution. // // Contributors: +// NTT DOCOMO, INC - Fix for Bug 1915 "SQL server panics when using long column type strings" // // Description: // @@ -1632,6 +1633,50 @@ TheDb.Close(); } +/** +Test defect where calling RSQLStatement::DeclaredColumnType() on a table which contains long (> 20 characters) column type +names results in a USER 11 panic. +This test should pass because these are valid SQL column types +*/ +void LongColumnTypeTest() + { + (void)RSqlDatabase::Delete(KTestDatabase3); + TInt err = TheDb.Create(KTestDatabase3); + TEST2(err, KErrNone); + + _LIT8(KCreateStmt, "CREATE TABLE t(a CHARACTER VARYING(100000), b NCHAR VARYING(100000), c NATIONAL CHARACTER(100000), d NATIONAL CHARACTER VARYING(100000))"); + err = TheDb.Exec(KCreateStmt); + TEST(err >= 0); + + //Select all columns (SELECT *) + _LIT(KSelectStmt, "SELECT * FROM t"); + RSqlStatement stmt; + err = stmt.Prepare(TheDb, KSelectStmt); + TEST2(err, KErrNone); + + TSqlColumnType colType; + err = stmt.DeclaredColumnType(0, colType); + TEST2(err,KErrNone); + TEST2(colType, ESqlText); + + err = stmt.DeclaredColumnType(1, colType); + TEST2(err,KErrNone); + TEST2(colType, ESqlText); + + err = stmt.DeclaredColumnType(2, colType); + TEST2(err,KErrNone); + TEST2(colType, ESqlText); + + err = stmt.DeclaredColumnType(3, colType); + TEST2(err,KErrNone); + TEST2(colType, ESqlText); + + stmt.Close(); + + TheDb.Close(); + (void)RSqlDatabase::Delete(KTestDatabase3); + } + void DoTestsL() { TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1763 \"SQL against a detached db\" test ")); @@ -1642,7 +1687,7 @@ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4035 Attempt to attach a file which name cannot be parsed")); AttachBadDbFileNameTest(); - + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4036 Attempt to attach a secure database. The client cannot pass the security checks")); AttachSecureDbTest(); @@ -1717,6 +1762,10 @@ TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-CT-4166 DEF144027: SQL Open returns error if the reported and actual file size are different")); DEF144027(); + + TheTest.Next(_L("RSQLStatement::DeclaredColumnType() causes USER 11 panic when table contains long column type strings")); + LongColumnTypeTest(); + } TInt E32Main() diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/TEST/t_sqlfserr.cpp --- a/persistentstorage/sql/TEST/t_sqlfserr.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/TEST/t_sqlfserr.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -284,6 +284,35 @@ TEST2(err, KErrNone); } +//Creates public shared, private secure and public secure databases. +void DoCreateTestDatabases(const TPtrC aDbName[], TInt aCount) + { + TEST(aCount > 0); + for(TInt i=0;i= 0); + err = TheDb.Exec(_L("INSERT INTO A(Id,Name) VALUES(1,'Name')")); + TEST2(err, 1); + TheDb.Close(); + } + } + /** @SYMTestCaseID SYSLIB-SQL-UT-3421 @SYMTestCaseDesc Test for DEF103859 "SQLITE panic, _DEBUG mode, persistent file I/O error simulation". @@ -300,30 +329,11 @@ { TPtrC dbName[] = {KTestDbName(), KPrivateTestDbName(), KSecureTestDbName()}; const TInt KDbNameCnt = sizeof(dbName) / sizeof(dbName[0]); + DoCreateTestDatabases(dbName, KDbNameCnt); for(TInt k=0;k= 0); - err = TheDb.Exec(_L("INSERT INTO A(Id,Name) VALUES(1,'Name')")); - TEST2(err, 1); - TheDb.Close(); - - err = KErrNotFound; + TInt err = KErrNotFound; for(TInt cnt=1;err=KErrDied;--fsError) + { + err = TheDb.Open(KTestDbName); + TEST2(err, KErrNone); + (void)TheFs.SetErrorCondition(fsError, cnt); + err = TheDb.Attach(dbName[k], _L("DB2")); + (void)TheFs.SetErrorCondition(KErrNone); + (void)TheDb.Detach(_L("DB2")); + TheDb.Close();//close the database to recover from the last error + } + } + TEST2(err, KErrNone); + err = RSqlDatabase::Delete(dbName[k]); + TEST2(err, KErrNone); + TheTest.Printf(_L("\r\n")); + } + } + +/** +@SYMTestCaseID PDS-SQL-UT-4190 +@SYMTestCaseDesc Test for DEF145125 "SQL, low code coverage". + The tests attempts to delete a database in a file I/O error simulation loop. +@SYMTestPriority High +@SYMTestActions Test for DEF145125 - "SQL, low code coverage". +@SYMTestExpectedResults The test must not fail +@SYMDEF DEF145125 +*/ +void DeleteDatabaseTest() + { + TPtrC dbName[] = {KTestDbName(), KPrivateTestDbName(), KSecureTestDbName()}; + const TInt KDbNameCnt = sizeof(dbName) / sizeof(dbName[0]); + DoCreateTestDatabases(dbName, KDbNameCnt); + for(TInt k=0;k?"); TInt err = aStmt.Prepare(aDb, KSqlString); User::LeaveIfError(err); } @@ -53,14 +53,14 @@ //"RSqlStatement::PrepareL()" OOM test (8-bit SELECT SQL statement) void PrepareStmt8_2L(RSqlDatabase& aDb, RSqlStatement& aStmt) { - _LIT8(KSqlString, "SELECT * FROM BBB"); + _LIT8(KSqlString, "SELECT * FROM BBB WHERE Fld1=? AND Fld4<>?"); aStmt.PrepareL(aDb, KSqlString); } //"RSqlStatement::Prepare()" OOM test (8-bit SELECT SQL statement), syntax error void PrepareBadStmt8L(RSqlDatabase& aDb, RSqlStatement& aStmt) { - _LIT8(KSqlString, "SELECT123 * FROM BBB"); + _LIT8(KSqlString, "SELECT123 * FROM BBB WHERE Fld1=? AND Fld4<>?"); TInt err = aStmt.Prepare(aDb, KSqlString); User::LeaveIfError(err); } @@ -68,16 +68,18 @@ //"RSqlStatement::Prepare()" OOM test (8-bit SELECT SQL statement, move next) void PrepareMoveStmt8L(RSqlDatabase& aDb, RSqlStatement& aStmt) { - _LIT8(KSqlString, "SELECT * FROM BBB"); + _LIT8(KSqlString, "SELECT * FROM BBB WHERE Fld1=? AND Fld4<>?"); TInt err = aStmt.Prepare(aDb, KSqlString); - if(err == KErrNone) - { - err = aStmt.Next(); - if(err == KSqlAtRow) - { - err = KErrNone; - } - } + User::LeaveIfError(err); + err = aStmt.BindInt(0, 1); + User::LeaveIfError(err); + err = aStmt.BindText(1, _L("data244weewfn43wr83224iu23ewkjfbrektug4i433b3k45b")); + User::LeaveIfError(err); + err = aStmt.Next(); + if(err == KSqlAtRow) + { + err = KErrNone; + } User::LeaveIfError(err); } @@ -261,7 +263,7 @@ err = KErrNoMemory; const TInt KMaxAllocation = TheOomTestType[i] == EServerSideTest ? KStmtOomTestAllocLimitServer : KStmtOomTestAllocLimitClient; TInt allocationNo = 0; - TInt failingAllocationNo = 0; + TInt failingAllocationNo = 0;//the real exit point of the OOM test. allocationNo is set KMaxAllocation times. while(allocationNo < KMaxAllocation) { MarkHandles(); @@ -726,7 +728,7 @@ err = KErrNoMemory; const TInt KMaxAllocation = TheOomTestType[i] == EServerSideTest ? KStmtOomTestAllocLimitServer : KStmtOomTestAllocLimitClient; TInt allocationNo = 0; - TInt failingAllocationNo = 0; + TInt failingAllocationNo = 0;//the real exit point of the OOM test. allocationNo is set KMaxAllocation times. while(allocationNo < KMaxAllocation) { MarkHandles(); @@ -961,7 +963,7 @@ err = KErrNoMemory; const TInt KMaxAllocation = TheOomTestType[i] == EServerSideTest ? KBlobOomTestAllocLimitServer : KBlobOomTestAllocLimitClient; TInt allocationNo = 0; - TInt failingAllocationNo = 0; + TInt failingAllocationNo = 0;//the real exit point of the OOM test. allocationNo is set KMaxAllocation times. while(allocationNo < KMaxAllocation) { MarkHandles(); @@ -1151,7 +1153,7 @@ err = KErrNoMemory; const TInt KMaxAllocation = TheOomTestType[i] == EServerSideTest ? KStmtOomTestAllocLimitServer : KStmtOomTestAllocLimitClient; TInt allocationNo = 0; - TInt failingAllocationNo = 0; + TInt failingAllocationNo = 0;//the real exit point of the OOM test. allocationNo is set KMaxAllocation times. while(allocationNo < KMaxAllocation) { MarkHandles(); diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/TEST/t_sqloom3.cpp --- a/persistentstorage/sql/TEST/t_sqloom3.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/TEST/t_sqloom3.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2005-2010 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" @@ -57,7 +57,7 @@ (void)RSqlDatabase::Delete(aDbFileName); } TInt err = KErrNone; - TInt failingAllocationNo = 0; + TInt failingAllocationNo = 0;//the real exit point of the OOM test. allocationNo is set maxAllocationNo times. TInt allocationNo = 0; TInt maxAllocationNo = TheOomTestType[i] == EServerSideTest ? KDoCreateDatabaseOomTestAllocLimitServer : KDoCreateDatabaseOomTestAllocLimitClient; while(allocationNo < maxAllocationNo) diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/TEST/t_sqloom5.cpp --- a/persistentstorage/sql/TEST/t_sqloom5.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/TEST/t_sqloom5.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -32,6 +32,8 @@ _LIT(KDbFile3, "c:[10281E17]t_sqloom5_2.db"); _LIT(KDbFile4, "c:[10281E17]t_sqloom5_3.db"); +_LIT8(KConfig, "encoding=UTF-8"); + extern CSqlServer* TheServer; static TInt TheProcessHandleCount = 0; @@ -42,6 +44,12 @@ static const TInt KBurstRate = 20; #endif +enum TSqlDbEncoding + { + ESqlDbUtf16, + ESqlDbUtf8 + }; + /////////////////////////////////////////////////////////////////////////////////////// void DestroyTestEnv() @@ -148,15 +156,7 @@ return server; } -/** -@SYMTestCaseID PDS-SQL-UT-4167 -@SYMTestCaseDesc CSqlSrvDatabase::CreateL() OOM test. -@SYMTestPriority High -@SYMTestActions The test runs CSqlSrvDatabase::CreateL() in an OOM loop. -@SYMTestExpectedResults Test must not fail -@SYMDEF DEF144577 -*/ -void CreateDatabaseOomTest() +void CreateDatabaseOomTest(TSqlDbEncoding aEncoding) { (void)TheFs.Delete(KDbFile); TInt failingAllocationNo = 0; @@ -174,7 +174,7 @@ TSqlSrvFileData& fdata = TheServer->FileData(); RMessage2 msg; - TRAP(err, fdata.SetL(msg, KDbFile().Length(), 0, (const TDesC8*)&KDbFile)); + TRAP(err, fdata.SetL(msg, KDbFile().Length(), 0, KDbFile, aEncoding == ESqlDbUtf8 ? &KConfig : NULL)); if(err == KErrNone) { CSqlSrvDatabase* db = NULL; @@ -192,13 +192,33 @@ } /** -@SYMTestCaseID PDS-SQL-UT-4168 -@SYMTestCaseDesc CSqlSrvDatabase::OpenL() OOM test - non-secure database. +@SYMTestCaseID PDS-SQL-UT-4167 +@SYMTestCaseDesc CSqlSrvDatabase::CreateL() OOM test. @SYMTestPriority High -@SYMTestActions The test runs CSqlSrvDatabase::OpenL() in an OOM loop. +@SYMTestActions The test runs CSqlSrvDatabase::CreateL() in an OOM loop. + UTF16 encoded database is used. @SYMTestExpectedResults Test must not fail @SYMDEF DEF144577 */ +void Utf16CreateDatabaseOomTest() + { + CreateDatabaseOomTest(ESqlDbUtf16); + } + +/** +@SYMTestCaseID PDS-SQL-UT-4182 +@SYMTestCaseDesc CSqlSrvDatabase::CreateL() OOM test. +@SYMTestPriority High +@SYMTestActions The test runs CSqlSrvDatabase::CreateL() in an OOM loop. + UTF8 encoded database is used. +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF145047 +*/ +void Utf8CreateDatabaseOomTest() + { + CreateDatabaseOomTest(ESqlDbUtf8); + } + void OpenDatabaseOomTest() { //The database is created by the previous test: CreateDatabaseOomTest(). @@ -218,7 +238,7 @@ TSqlSrvFileData& fdata = TheServer->FileData(); RMessage2 msg; - TRAP(err, fdata.SetL(msg, KDbFile().Length(), 0, (const TDesC8*)&KDbFile)); + TRAP(err, fdata.SetL(msg, KDbFile().Length(), 0, KDbFile)); if(err == KErrNone) { CSqlSrvDatabase* db = NULL; @@ -237,14 +257,34 @@ } /** -@SYMTestCaseID PDS-SQL-UT-4169 -@SYMTestCaseDesc CSqlSrvDatabase::CreateSecureL() OOM test. +@SYMTestCaseID PDS-SQL-UT-4168 +@SYMTestCaseDesc CSqlSrvDatabase::OpenL() OOM test - non-secure database. @SYMTestPriority High -@SYMTestActions The test runs CSqlSrvDatabase::CreateSecureL() in an OOM loop. +@SYMTestActions The test runs CSqlSrvDatabase::OpenL() in an OOM loop. + UTF16 encoded database is used. @SYMTestExpectedResults Test must not fail @SYMDEF DEF144577 */ -void CreateSecureDatabaseOomTest() +void Utf16OpenDatabaseOomTest() + { + OpenDatabaseOomTest(); + } + +/** +@SYMTestCaseID PDS-SQL-UT-4183 +@SYMTestCaseDesc CSqlSrvDatabase::OpenL() OOM test - non-secure database. +@SYMTestPriority High +@SYMTestActions The test runs CSqlSrvDatabase::OpenL() in an OOM loop. + UTF8 encoded database is used. +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF145047 +*/ +void Utf8OpenDatabaseOomTest() + { + OpenDatabaseOomTest(); + } + +void CreateSecureDatabaseOomTest(TSqlDbEncoding aEncoding) { (void)TheFs.Delete(KDbFile2); TInt failingAllocationNo = 0; @@ -262,7 +302,7 @@ TSqlSrvFileData& fdata = TheServer->FileData(); RMessage2 msg; - TRAP(err, fdata.SetL(msg, KDbFile2().Length(), 0, (const TDesC8*)&KDbFile2)); + TRAP(err, fdata.SetL(msg, KDbFile2().Length(), 0, KDbFile2, aEncoding == ESqlDbUtf8 ? &KConfig : NULL)); if(err == KErrNone) { TSecurityPolicy defaultPolicy(TSecurityPolicy::EAlwaysPass); @@ -286,13 +326,33 @@ } /** -@SYMTestCaseID PDS-SQL-UT-4170 -@SYMTestCaseDesc CSqlSrvDatabase::OpenL() OOM test - secure database. +@SYMTestCaseID PDS-SQL-UT-4169 +@SYMTestCaseDesc CSqlSrvDatabase::CreateSecureL() OOM test. @SYMTestPriority High -@SYMTestActions The test runs CSqlSrvDatabase::OpenL() in an OOM loop. +@SYMTestActions The test runs CSqlSrvDatabase::CreateSecureL() in an OOM loop. + UTF16 encoded database is used. @SYMTestExpectedResults Test must not fail @SYMDEF DEF144577 */ +void Utf16CreateSecureDatabaseOomTest() + { + CreateSecureDatabaseOomTest(ESqlDbUtf16); + } + +/** +@SYMTestCaseID PDS-SQL-UT-4184 +@SYMTestCaseDesc CSqlSrvDatabase::CreateSecureL() OOM test. +@SYMTestPriority High +@SYMTestActions The test runs CSqlSrvDatabase::CreateSecureL() in an OOM loop. + UTF8 encoded database is used. +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF145047 +*/ +void Utf8CreateSecureDatabaseOomTest() + { + CreateSecureDatabaseOomTest(ESqlDbUtf8); + } + void OpenSecureDatabaseOomTest() { //The database is created by the previous test: CreateSecureDatabaseOomTest(). @@ -312,7 +372,7 @@ TSqlSrvFileData& fdata = TheServer->FileData(); RMessage2 msg; - TRAP(err, fdata.SetL(msg, KDbFile2().Length(), 0, (const TDesC8*)&KDbFile2)); + TRAP(err, fdata.SetL(msg, KDbFile2().Length(), 0, KDbFile2)); if(err == KErrNone) { CSqlSrvDatabase* db = NULL; @@ -330,6 +390,34 @@ TheTest.Printf(_L("\r\n===CSqlSrvDatabase::OpenL() [secure db] OOM test succeeded at heap failure rate of %d ===\r\n"), failingAllocationNo); } +/** +@SYMTestCaseID PDS-SQL-UT-4170 +@SYMTestCaseDesc CSqlSrvDatabase::OpenL() OOM test - secure database. +@SYMTestPriority High +@SYMTestActions The test runs CSqlSrvDatabase::OpenL() in an OOM loop. + UTF16 encoded database is used. +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF144577, PDEF44845 +*/ +void Utf16OpenSecureDatabaseOomTest() + { + OpenSecureDatabaseOomTest(); + } + +/** +@SYMTestCaseID PDS-SQL-UT-4185 +@SYMTestCaseDesc CSqlSrvDatabase::OpenL() OOM test - secure database. +@SYMTestPriority High +@SYMTestActions The test runs CSqlSrvDatabase::OpenL() in an OOM loop. + UTF8 encoded database is used. +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF145047 +*/ +void Utf8OpenSecureDatabaseOomTest() + { + OpenSecureDatabaseOomTest(); + } + ///////////////////////////////////////////////////////////// const TInt KDbConnCount = 7; @@ -356,7 +444,7 @@ //N is the number of the database to be opened, between 1 and KDbConnCount. #define TEST_OPEN_DB(N, dbFile) \ __ASSERT_DEBUG(N > 0 && N <= KDbConnCount, User::Invariant()); \ - TRAP(err, fdata.SetL(msg, dbFile.Length(), 0, (const TDesC8*)&dbFile)); \ + TRAP(err, fdata.SetL(msg, dbFile.Length(), 0, dbFile)); \ if(err != KErrNone) \ { \ goto Cleanup; \ @@ -375,7 +463,7 @@ #define TEST_ATTACH_DB(N, dbFile, M) \ __ASSERT_DEBUG(N > 0 && N <= KDbConnCount, User::Invariant()); \ __ASSERT_DEBUG(M > 0 && M <= KDbAttachedCount, User::Invariant()); \ - TRAP(err, fdata.SetL(msg, dbFile.Length(), 0, (const TDesC8*)&dbFile)); \ + TRAP(err, fdata.SetL(msg, dbFile.Length(), 0, dbFile)); \ if(err != KErrNone) \ { \ goto Cleanup; \ @@ -404,7 +492,7 @@ ///////////////////////////////////////////////////////////// -void CreateSecureTestDb(const TDesC& aDbFile) +void CreateSecureTestDb(const TDesC& aDbFile, TSqlDbEncoding aEncoding) { (void)TheFs.Delete(aDbFile); @@ -415,7 +503,7 @@ TSqlSrvFileData& fdata = TheServer->FileData(); RMessage2 msg; - TRAP(err, fdata.SetL(msg, aDbFile.Length(), 0, (const TDesC8*)&aDbFile)); + TRAP(err, fdata.SetL(msg, aDbFile.Length(), 0, aDbFile, aEncoding == ESqlDbUtf8 ? &KConfig : NULL)); CSqlSrvDatabase* db = NULL; TRAP(err, db = CSqlSrvDatabase::CreateSecureL(fdata, policy)); @@ -423,18 +511,7 @@ TEST2(err, KErrNone); } -/** -@SYMTestCaseID PDS-SQL-UT-4171 -@SYMTestCaseDesc CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::AttachDbL() OOM test. -@SYMTestPriority High -@SYMTestActions The test runs CSqlSrvDatabase::OpenL() and CSqlSrvDatabase::AttachDbL() in an OOM test. - The test is a complex one - 7 (KDbConnCount constant) databases opened - (secure and non-secure), 10 (KDbAttachedCount constant) databases - attached (secure and non-secure). -@SYMTestExpectedResults Test must not fail -@SYMDEF DEF144577, DEF144603 -*/ -void OpenAttachDatabaseOomTest() +void OpenAttachDatabaseOomTest(TSqlDbEncoding aEncoding) { //Part of the databases are created by the previous tests. @@ -445,8 +522,8 @@ TRAPD(err, TheServer = CreateSqlServerL()); TEST2(err, KErrNone); - CreateSecureTestDb(KDbFile3); - CreateSecureTestDb(KDbFile4); + CreateSecureTestDb(KDbFile3, aEncoding); + CreateSecureTestDb(KDbFile4, aEncoding); //The following 2 declarations are used by the macros in the OOM loop RMessage2 msg; @@ -511,24 +588,47 @@ } /** -@SYMTestCaseID PDS-SQL-UT-4172 +@SYMTestCaseID PDS-SQL-UT-4171 @SYMTestCaseDesc CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::AttachDbL() OOM test. @SYMTestPriority High @SYMTestActions The test runs CSqlSrvDatabase::OpenL() and CSqlSrvDatabase::AttachDbL() in an OOM test. - Two secure databases are created and then, in an OOM loop, the test executes this sequence of - commands: open first database, attach the second database, detach the attached database, - close the first database. + The test is a complex one - 7 (KDbConnCount constant) databases opened + (secure and non-secure), 10 (KDbAttachedCount constant) databases + attached (secure and non-secure). + UTF16 encoded database is used. @SYMTestExpectedResults Test must not fail -@SYMDEF DEF144577, PDEF44845 +@SYMDEF DEF144577, DEF144603 */ -void OpenAttachDatabaseOomTest2() +void Utf16OpenAttachDatabaseOomTest() + { + OpenAttachDatabaseOomTest(ESqlDbUtf16); + } + +/** +@SYMTestCaseID PDS-SQL-UT-4186 +@SYMTestCaseDesc CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::AttachDbL() OOM test. +@SYMTestPriority High +@SYMTestActions The test runs CSqlSrvDatabase::OpenL() and CSqlSrvDatabase::AttachDbL() in an OOM test. + The test is a complex one - 7 (KDbConnCount constant) databases opened + (secure and non-secure), 10 (KDbAttachedCount constant) databases + attached (secure and non-secure). + UTF8 encoded database is used. +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF???? +*/ +void Utf8OpenAttachDatabaseOomTest() + { + OpenAttachDatabaseOomTest(ESqlDbUtf8); + } + +void OpenAttachDatabaseOomTest2(TSqlDbEncoding aEncoding) { TheServer = NULL; TRAPD(err, TheServer = CreateSqlServerL()); TEST2(err, KErrNone); - CreateSecureTestDb(KDbFile3); - CreateSecureTestDb(KDbFile4); + CreateSecureTestDb(KDbFile3, aEncoding); + CreateSecureTestDb(KDbFile4, aEncoding); TInt failingAllocationNo = 0; TheTest.Printf(_L("Iteration:\r\n")); @@ -542,14 +642,14 @@ TheTest.Printf(_L(" %d"), ++failingAllocationNo); OomPreStep(failingAllocationNo); - TRAP(err, fdata.SetL(msg, KDbFile3().Length(), 0, (const TDesC8*)&KDbFile3)); + TRAP(err, fdata.SetL(msg, KDbFile3().Length(), 0, KDbFile3)); if(err == KErrNone) { CSqlSrvDatabase* db = NULL; TRAP(err, db = CSqlSrvDatabase::OpenL(fdata)); if(err == KErrNone) { - TRAP(err, fdata.SetL(msg, KDbFile4().Length(), 0, (const TDesC8*)&KDbFile4)); + TRAP(err, fdata.SetL(msg, KDbFile4().Length(), 0, KDbFile4)); if(err == KErrNone) { TRAP(err, db->AttachDbL(fdata, _L("db2"))); @@ -575,25 +675,47 @@ } /** -@SYMTestCaseID PDS-SQL-UT-4173 -@SYMTestCaseDesc CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::CreateSecureL() OOM test. +@SYMTestCaseID PDS-SQL-UT-4172 +@SYMTestCaseDesc CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::AttachDbL() OOM test. @SYMTestPriority High -@SYMTestActions The test runs CSqlSrvDatabase::OpenL() and CSqlSrvDatabase::CreateSecureL() in an OOM test. - The test creates a secure database then executes CSqlSrvDatabase::OpenL() in an OOM loop. - After that the database is deleted and the test executes CSqlSrvDatabase::CreateSecureL() in an OOM loop. - The purpose of the test is to check that the CSqlSrver maps are properly updated when - the database is closed. +@SYMTestActions The test runs CSqlSrvDatabase::OpenL() and CSqlSrvDatabase::AttachDbL() in an OOM test. + Two secure databases are created and then, in an OOM loop, the test executes this sequence of + commands: open first database, attach the second database, detach the attached database, + close the first database. + UTF16 encoded database is used. @SYMTestExpectedResults Test must not fail @SYMDEF DEF144577, PDEF44845 */ -void OpenCreateDatabaseOomTest() +void Utf16OpenAttachDatabaseOomTest2() + { + OpenAttachDatabaseOomTest2(ESqlDbUtf16); + } + +/** +@SYMTestCaseID PDS-SQL-UT-4187 +@SYMTestCaseDesc CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::AttachDbL() OOM test. +@SYMTestPriority High +@SYMTestActions The test runs CSqlSrvDatabase::OpenL() and CSqlSrvDatabase::AttachDbL() in an OOM test. + Two secure databases are created and then, in an OOM loop, the test executes this sequence of + commands: open first database, attach the second database, detach the attached database, + close the first database. + UTF8 encoded database is used. +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF145047 +*/ +void Utf8OpenAttachDatabaseOomTest2() + { + OpenAttachDatabaseOomTest2(ESqlDbUtf8); + } + +void OpenCreateDatabaseOomTest(TSqlDbEncoding aEncoding) { TheServer = NULL; TRAPD(err, TheServer = CreateSqlServerL()); TEST2(err, KErrNone); (void)TheFs.Delete(KDbFile2); - CreateSecureTestDb(KDbFile2); + CreateSecureTestDb(KDbFile2, aEncoding); TheTest.Printf(_L("Iteration:\r\n")); @@ -607,7 +729,7 @@ RMessage2 msg; TSqlSrvFileData& fdata = TheServer->FileData(); - TRAP(err, fdata.SetL(msg, KDbFile2().Length(), 0, (const TDesC8*)&KDbFile2)); + TRAP(err, fdata.SetL(msg, KDbFile2().Length(), 0, KDbFile2)); if(err == KErrNone) { CSqlSrvDatabase* db = NULL; @@ -635,7 +757,7 @@ OomPreStep(failingAllocationNo2); RMessage2 msg; TSqlSrvFileData& fdata = TheServer->FileData(); - TRAP(err, fdata.SetL(msg, KDbFile2().Length(), 0, (const TDesC8*)&KDbFile2)); + TRAP(err, fdata.SetL(msg, KDbFile2().Length(), 0, KDbFile2, aEncoding == ESqlDbUtf8 ? &KConfig : NULL)); if(err == KErrNone) { TSecurityPolicy defaultPolicy(TSecurityPolicy::EAlwaysPass); @@ -668,6 +790,42 @@ failingAllocationNo + failingAllocationNo2); } +/** +@SYMTestCaseID PDS-SQL-UT-4173 +@SYMTestCaseDesc CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::CreateSecureL() OOM test. +@SYMTestPriority High +@SYMTestActions The test runs CSqlSrvDatabase::OpenL() and CSqlSrvDatabase::CreateSecureL() in an OOM test. + The test creates a secure database then executes CSqlSrvDatabase::OpenL() in an OOM loop. + After that the database is deleted and the test executes CSqlSrvDatabase::CreateSecureL() in an OOM loop. + The purpose of the test is to check that the CSqlSrver maps are properly updated when + the database is closed. + UTF16 encoded database is used. +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF144577, PDEF44845 +*/ +void Utf16OpenCreateDatabaseOomTest() + { + OpenCreateDatabaseOomTest(ESqlDbUtf16); + } + +/** +@SYMTestCaseID PDS-SQL-UT-4188 +@SYMTestCaseDesc CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::CreateSecureL() OOM test. +@SYMTestPriority High +@SYMTestActions The test runs CSqlSrvDatabase::OpenL() and CSqlSrvDatabase::CreateSecureL() in an OOM test. + The test creates a secure database then executes CSqlSrvDatabase::OpenL() in an OOM loop. + After that the database is deleted and the test executes CSqlSrvDatabase::CreateSecureL() in an OOM loop. + The purpose of the test is to check that the CSqlSrver maps are properly updated when + the database is closed. + UTF8 encoded database is used. +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF145047 +*/ +void Utf8OpenCreateDatabaseOomTest() + { + OpenCreateDatabaseOomTest(ESqlDbUtf8); + } + void DoTests() { #ifndef _DEBUG @@ -678,26 +836,47 @@ CActiveScheduler::Install(scheduler); TheTest.Start(_L(" @SYMTestCaseID:PDS-SQL-UT-4167 CSqlSrvDatabase::CreateL() OOM unit test")); - CreateDatabaseOomTest(); + Utf16CreateDatabaseOomTest(); TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4168 CSqlSrvDatabase::OpenL() OOM unit test - non-secure database")); - OpenDatabaseOomTest(); + Utf16OpenDatabaseOomTest(); TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4169 CSqlSrvDatabase::CreateSecureL() OOM unit test")); - CreateSecureDatabaseOomTest(); + Utf16CreateSecureDatabaseOomTest(); TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4170 CSqlSrvDatabase::OpenL() OOM unit test - secure database")); - OpenSecureDatabaseOomTest(); + Utf16OpenSecureDatabaseOomTest(); TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4171 CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::AttachDbL() OOM unit test")); - OpenAttachDatabaseOomTest(); + Utf16OpenAttachDatabaseOomTest(); TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4172 CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::AttachDbL() OOM unit test - 2")); - OpenAttachDatabaseOomTest2(); + Utf16OpenAttachDatabaseOomTest2(); TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4173 CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::CreateL() OOM unit test")); - OpenCreateDatabaseOomTest(); + Utf16OpenCreateDatabaseOomTest(); + + TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4182 CSqlSrvDatabase::CreateL() OOM unit test, UTF8 database")); + Utf8CreateDatabaseOomTest(); + + TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4183 CSqlSrvDatabase::OpenL() OOM unit test - non-secure UTF8 database")); + Utf8OpenDatabaseOomTest(); + + TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4184 CSqlSrvDatabase::CreateSecureL() OOM unit test, UTF8 database")); + Utf8CreateSecureDatabaseOomTest(); + TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4185 CSqlSrvDatabase::OpenL() OOM unit test - secure UTF8 database")); + Utf8OpenSecureDatabaseOomTest(); + + TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4186 CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::AttachDbL() OOM unit test, UTF8 database")); + Utf8OpenAttachDatabaseOomTest(); + + TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4187 CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::AttachDbL() OOM unit test 2, UTF8 database")); + Utf8OpenAttachDatabaseOomTest2(); + + TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4188 CSqlSrvDatabase::OpenL() & CSqlSrvDatabase::CreateL() OOM unit test, UTF8 database")); + Utf8OpenCreateDatabaseOomTest(); + delete scheduler; #endif //_DEBUG } diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/TEST/t_sqloom6.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/sql/TEST/t_sqloom6.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -0,0 +1,733 @@ +// Copyright (c) 2010 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 +#include +#include +#include +#include +#include +#include "SqlResourceTester.h" //TSqlResourceTester +#include "sqlite3.h" +#include "SqliteSymbian.h" + +//In order to be able to compile the test, the following variables are defined (used inside the OS porting layer, +//when _SQLPROFILER macro is defined) +#ifdef _SQLPROFILER +TInt TheSqlSrvProfilerFileRead = 0; +TInt TheSqlSrvProfilerFileWrite = 0; +TInt TheSqlSrvProfilerFileSync = 0; +TInt TheSqlSrvProfilerFileSetSize = 0; +#endif + +/////////////////////////////////////////////////////////////////////////////////////// + +RTest TheTest(_L("t_sqloom6 test")); + +_LIT(KTestDir, "c:\\test\\"); +_LIT(KDbFile, "c:\\test\\t_sqloom6.db"); + +static RSqlDatabase TheDb; +static RSqlStatement TheStmt; + +static TInt TheProcessHandleCount = 0; +static TInt TheThreadHandleCount = 0; +static TInt TheAllocatedCellsCount = 0; + +/////////////////////////////////////////////////////////////////////////////////////// + +void DestroyTestEnv() + { + TheStmt.Close(); + TheDb.Close(); + (void)RSqlDatabase::Delete(KDbFile); + sqlite3SymbianLibFinalize(); + CloseSTDLIB(); + } + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +//Test macros and functions +void Check(TInt aValue, TInt aLine) + { + if(!aValue) + { + DestroyTestEnv(); + RDebug::Print(_L("*** Expresssion evaluated to false\r\n")); + TheTest(EFalse, aLine); + } + } +void Check(TInt aValue, TInt aExpected, TInt aLine) + { + if(aValue != aExpected) + { + DestroyTestEnv(); + RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue); + TheTest(EFalse, aLine); + } + } +#define TEST(arg) ::Check((arg), __LINE__) +#define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static void MarkHandles() + { + RThread().HandleCount(TheProcessHandleCount, TheThreadHandleCount); + } + +static void MarkAllocatedCells() + { + TheAllocatedCellsCount = User::CountAllocCells(); + } + +static void CheckAllocatedCells() + { + TInt allocatedCellsCount = User::CountAllocCells(); + TEST2(allocatedCellsCount, TheAllocatedCellsCount); + } + +static void CheckHandles() + { + TInt endProcessHandleCount; + TInt endThreadHandleCount; + + RThread().HandleCount(endProcessHandleCount, endThreadHandleCount); + + TEST2(TheProcessHandleCount, endProcessHandleCount); + TEST2(TheThreadHandleCount, endThreadHandleCount); + } + +static void OomPreStep(TInt aFailingAllocationNo) + { + MarkHandles(); + MarkAllocatedCells(); + __UHEAP_MARK; + TSqlResourceTester::Mark(); + TSqlResourceTester::SetHeapFailure(RHeap::EBurstFailNext, aFailingAllocationNo); + } + +static void OomPostStep() + { + __UHEAP_RESET; + TSqlResourceTester::SetHeapFailure(RHeap::ENone, 0); + TSqlResourceTester::Check(); + CheckAllocatedCells(); + CheckHandles(); + } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void CreateTestEnv() + { + RFs fs; + TInt err = fs.Connect(); + TEST2(err, KErrNone); + + err = fs.MkDir(KTestDir); + TEST(err == KErrNone || err == KErrAlreadyExists); + + err = fs.CreatePrivatePath(EDriveC); + TEST(err == KErrNone || err == KErrAlreadyExists); + + fs.Close(); + + sqlite3SymbianLibInit(); + } + +//Creates a UTF8 encoded database with: +// - One table with three colums: A(ColumnName1234567890, Col2, Col3); +// - One record in the table with values: ('A1234567890', 'A12345', ''); +void CreateTestDb(const TDesC& aDbName) + { + TBuf8<100> dbName8; + dbName8.Copy(aDbName); + sqlite3* db = 0; + int rc = sqlite3_open((const char*)dbName8.PtrZ(), &db); + TEST2(rc, SQLITE_OK); + rc = sqlite3_exec(db, "CREATE TABLE A(ColumnName1234567890 TEXT, Col2 LONG TEXT, Col3 SMALL TEXT)", 0, 0, 0); + TEST2(rc, SQLITE_OK); + rc = sqlite3_exec(db, "INSERT INTO A VALUES('A1234567890', 'A12345', '')", 0, 0, 0); + TEST2(rc, SQLITE_OK); + sqlite3_close(db); + } + +/** +@SYMTestCaseID PDS-SQL-CT-4176 +@SYMTestCaseDesc RSqlStatement::ColumnName() OOM test. +@SYMTestPriority High +@SYMTestActions The test runs RSqlStatement::ColumnName() in an OOM simulation loop. + The difference betwee this test case and the similar test case in t_sqloom2 is that here: + - burst OOM simulation is used; + - UTF8 encoded database is used; + - only SQL server side OOM simulation is performed; + The purpose of the test is to verify that the ColumnName() call behaves correctly + when the related sqlite3_column_name16() call performed by the SQL server fails + with "no memory". +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF145033 +*/ +void ColumnNameOomTest() + { + //This is not really a full OOM test, because the SQL server counts only the number of active statement and + //stream objects, the allocated memory cells are not counted. + //The reason that the allocated memory cells are not counted, and in case of an OOM failure - checked, is + //because the SQL server can make some per-connection memory allocations (cache pages, etc.) + //and they will not be deallocated when the statement object is closed. + //But the result of the RSqlStatement::ColumnName() operation is checked. If there is a failed memory + //allocation on the server side, the returned column name can be NULL and that will be tested. + + (void)RSqlDatabase::Delete(KDbFile); + + TheTest.Printf(_L("Iteration:\r\n")); + + CreateTestDb(KDbFile);//Creates UTF8 encoded database with one table with one record. + + TInt err = TheDb.Open(KDbFile); + TEST2(err, KErrNone); + + TInt failingAllocationNo = 0; + err = KErrNoMemory; + while(err == KErrNoMemory) + { + TheTest.Printf(_L(" %d"), ++failingAllocationNo); + OomPreStep(failingAllocationNo); + + err = TheStmt.Prepare(TheDb, _L("SELECT * FROM A")); + if(err != KErrNone) + { + goto LabelOomPostStep; + } + + TPtrC name; + err = TheStmt.ColumnName(0, name); + if(err != KErrNone) + { + goto LabelStmtClose; + } + TEST(name == _L("ColumnName1234567890")); + + err = TheStmt.ColumnName(1, name); + if(err != KErrNone) + { + goto LabelStmtClose; + } + TEST(name == _L("Col2")); + + err = TheStmt.ColumnName(2, name); + if(err != KErrNone) + { + goto LabelStmtClose; + } + TEST(name == _L("Col3")); + +LabelStmtClose: + TheStmt.Close(); + +LabelOomPostStep: + OomPostStep(); + } + + TheDb.Close(); + (void)RSqlDatabase::Delete(KDbFile); + + TEST2(err, KErrNone); + TheTest.Printf(_L("\r\n===RSqlStatement::ColumnName() OOM test succeeded at heap failure rate of %d ===\r\n"), failingAllocationNo); + } + +/** +@SYMTestCaseID PDS-SQL-CT-4177 +@SYMTestCaseDesc RSqlStatement::ParameterName() OOM test. +@SYMTestPriority High +@SYMTestActions The test runs RSqlStatement::ParameterName() in an OOM simulation loop. + The difference betwee this test case and the similar test case in t_sqloom2 is that here: + - burst OOM simulation is used; + - UTF8 encoded database is used; + - only SQL server side OOM simulation is performed; + The purpose of the test is to verify that the ParameterName() call behaves correctly + if the related sqlite3_bind_parameter_name() call performed by the SQL server fails + with "no memory". +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF145033 +*/ +void ParameterNameOomTest() + { + //This is not really a full OOM test, because the SQL server counts only the number of active statement and + //stream objects, the allocated memory cells are not counted. + //The reason that the allocated memory cells are not counted, and in case of an OOM failure - checked, is + //because the SQL server can make some per-connection memory allocations (cache pages, etc.) + //and they will not be deallocated when the statement object is closed. + //But the result of the RSqlStatement::ParameterName() operation is checked. If there is a failed memory + //allocation on the server side, the returned column name can be NULL and that will be tested. + + (void)RSqlDatabase::Delete(KDbFile); + + TheTest.Printf(_L("Iteration:\r\n")); + + CreateTestDb(KDbFile);//Creates UTF8 encoded database with one table with one record. + + TInt err = TheDb.Open(KDbFile); + TEST2(err, KErrNone); + + TInt failingAllocationNo = 0; + err = KErrNoMemory; + while(err == KErrNoMemory) + { + TheTest.Printf(_L(" %d"), ++failingAllocationNo); + OomPreStep(failingAllocationNo); + + err = TheStmt.Prepare(TheDb, _L("SELECT * FROM A WHERE Col2 != :Prm1234567890 AND Col3 != :Prm2 AND ColumnName1234567890 != ?")); + if(err != KErrNone) + { + goto LabelOomPostStep; + } + + TPtrC name; + err = TheStmt.ParameterName(0, name); + if(err != KErrNone) + { + goto LabelStmtClose; + } + TEST(name == _L(":Prm1234567890")); + + err = TheStmt.ParameterName(1, name); + if(err != KErrNone) + { + goto LabelStmtClose; + } + TEST(name == _L(":Prm2")); + + err = TheStmt.ParameterName(2, name); + if(err != KErrNone) + { + goto LabelStmtClose; + } + TEST(name == _L("?2")); + +LabelStmtClose: + TheStmt.Close(); + +LabelOomPostStep: + OomPostStep(); + } + + TheDb.Close(); + (void)RSqlDatabase::Delete(KDbFile); + + TEST2(err, KErrNone); + TheTest.Printf(_L("\r\n===RSqlStatement::ColumnName() OOM test succeeded at heap failure rate of %d ===\r\n"), failingAllocationNo); + } + +/** +@SYMTestCaseID PDS-SQL-CT-4178 +@SYMTestCaseDesc RSqlStatement::ColumnText() OOM test. +@SYMTestPriority High +@SYMTestActions The test runs RSqlStatement::ColumnText() in an OOM simulation loop. + The difference betwee this test case and the similar test case in t_sqloom2 is that here: + - burst OOM simulation is used; + - UTF8 encoded database is used; + - only SQL server side OOM simulation is performed; + The purpose of the test is to verify that the ColumnText() call behaves correctly + when the related sqlite3_column_text16() call performed by the SQL server fails + with "no memory" (or the sqlite3_column_bytes16() call). +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF145033 +*/ +void ColumnTextOomTest() + { + //This is not really a full OOM test, because the SQL server counts only the number of active statement and + //stream objects, the allocated memory cells are not counted. + //The reason that the allocated memory cells are not counted, and in case of an OOM failure - checked, is + //because the SQL server can make some per-connection memory allocations (cache pages, etc.) + //and they will not be deallocated when the statement object is closed. + //But the result of the RSqlStatement::ColumnText() operation is checked. If there is a failed memory + //allocation on the server side, the returned column name can be NULL and that will be tested. + + (void)RSqlDatabase::Delete(KDbFile); + + TheTest.Printf(_L("Iteration:\r\n")); + + CreateTestDb(KDbFile);//Creates UTF8 encoded database with one table with one record. + + TInt err = TheDb.Open(KDbFile); + TEST2(err, KErrNone); + + TInt failingAllocationNo = 0; + err = KErrNoMemory; + while(err == KErrNoMemory) + { + TheTest.Printf(_L(" %d"), ++failingAllocationNo); + OomPreStep(failingAllocationNo); + + err = TheStmt.Prepare(TheDb, _L("SELECT * FROM A")); + if(err != KErrNone) + { + goto LabelOomPostStep; + } + err = TheStmt.Next(); + if(err != KSqlAtRow) + { + goto LabelStmtClose; + } + + TPtrC data; + err = TheStmt.ColumnText(0, data); + if(err != KErrNone) + { + goto LabelStmtClose; + } + TEST(data == _L("A1234567890")); + + err = TheStmt.ColumnText(1, data); + if(err != KErrNone) + { + goto LabelStmtClose; + } + TEST(data == _L("A12345")); + + err = TheStmt.ColumnText(2, data); + if(err != KErrNone) + { + goto LabelStmtClose; + } + TEST(data == _L("")); + +LabelStmtClose: + TheStmt.Close(); + +LabelOomPostStep: + OomPostStep(); + } + + TheDb.Close(); + (void)RSqlDatabase::Delete(KDbFile); + + TEST2(err, KErrNone); + TheTest.Printf(_L("\r\n===RSqlStatement::ColumnText() OOM test succeeded at heap failure rate of %d ===\r\n"), failingAllocationNo); + } + +/** +@SYMTestCaseID PDS-SQL-CT-4179 +@SYMTestCaseDesc RSqlColumnReadStream OOM test. +@SYMTestPriority High +@SYMTestActions The test runs RSqlColumnReadStream in an OOM simulation loop. + The difference betwee this test case and the similar test case in t_sqloom2 is that here: + - burst OOM simulation is used; + - UTF8 encoded database is used; + - only SQL server side OOM simulation is performed; + The purpose of the test is to verify that the RSqlColumnReadStream APIs behave correctly + when the related sqlite3_column_text16() call performed by the SQL server fails + with "no memory" (or the sqlite3_column_bytes16() call). +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF145033 +*/ +void TextColumnReadStreamOomTest() + { + //This is not really a full OOM test, because the SQL server counts only the number of active statement and + //stream objects, the allocated memory cells are not counted. + //The reason that the allocated memory cells are not counted, and in case of an OOM failure - checked, is + //because the SQL server can make some per-connection memory allocations (cache pages, etc.) + //and they will not be deallocated when the statement object is closed. + //But the result of the RSqlColumnReadStream::ReadL() operation is checked. If there is a failed memory + //allocation on the server side, the returned column name can be NULL and that will be tested. + + (void)RSqlDatabase::Delete(KDbFile); + + TheTest.Printf(_L("Iteration:\r\n")); + + CreateTestDb(KDbFile);//Creates UTF8 encoded database with one table with one record. + + TInt err = TheDb.Open(KDbFile); + TEST2(err, KErrNone); + + TInt failingAllocationNo = 0; + err = KErrNoMemory; + while(err == KErrNoMemory) + { + TheTest.Printf(_L(" %d"), ++failingAllocationNo); + OomPreStep(failingAllocationNo); + + err = TheStmt.Prepare(TheDb, _L("SELECT * FROM A")); + if(err != KErrNone) + { + goto LabelOomPostStep; + } + err = TheStmt.Next(); + if(err != KSqlAtRow) + { + goto LabelCloseStmt; + } + + RSqlColumnReadStream strm; + err = strm.ColumnText(TheStmt, 0); + if(err != KErrNone) + { + goto LabelCloseStmt; + } + TBuf<50> data; + TRAP(err, strm.ReadL(data, 11)); + strm.Close(); + if(err != KErrNone) + { + goto LabelCloseStmt; + } + TEST(data == _L("A1234567890")); + + err = strm.ColumnText(TheStmt, 1); + if(err != KErrNone) + { + goto LabelCloseStmt; + } + TRAP(err, strm.ReadL(data, 6)); + strm.Close(); + if(err != KErrNone) + { + goto LabelCloseStmt; + } + TEST(data == _L("A12345")); + + err = strm.ColumnText(TheStmt, 2); + if(err != KErrNone) + { + goto LabelCloseStmt; + } + TInt len = -1; + TRAP(err, len = strm.Source()->SizeL());//The column value is with 0 length + strm.Close(); + if(err != KErrNone) + { + goto LabelCloseStmt; + } + TEST2(len, 0); + +LabelCloseStmt: + TheStmt.Close(); + +LabelOomPostStep: + OomPostStep(); + } + + TheDb.Close(); + (void)RSqlDatabase::Delete(KDbFile); + + TEST2(err, KErrNone); + TheTest.Printf(_L("\r\n===RSqlColumnReadStream OOM test succeeded at heap failure rate of %d ===\r\n"), failingAllocationNo); + } + +/** +@SYMTestCaseID PDS-SQL-CT-4180 +@SYMTestCaseDesc TSqlScalarFullSelectQuery::SelectTextL() OOM test. +@SYMTestPriority High +@SYMTestActions The test runs TSqlScalarFullSelectQuery::SelectTextL() in an OOM simulation loop. + The difference betwee this test case and the similar test case in t_sqloom2 is that here: + - burst OOM simulation is used; + - UTF8 encoded database is used; + - only SQL server side OOM simulation is performed; + The purpose of the test is to verify that the SelectTextL() call behaves correctly + when the related sqlite3_column_text16() call performed by the SQL server fails + with "no memory" (or the sqlite3_column_bytes16() call). +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF145033 +*/ +void ScalarColumnTextOomTest() + { + //This is not really a full OOM test, because the SQL server counts only the number of active statement and + //stream objects, the allocated memory cells are not counted. + //The reason that the allocated memory cells are not counted, and in case of an OOM failure - checked, is + //because the SQL server can make some per-connection memory allocations (cache pages, etc.) + //and they will not be deallocated when the statement object is closed. + //But the result of the TSqlScalarFullSelectQuery::SelectTextL() operation is checked. If there is a failed memory + //allocation on the server side, the returned column name can be NULL and that will be tested. + + (void)RSqlDatabase::Delete(KDbFile); + + TheTest.Printf(_L("Iteration:\r\n")); + + CreateTestDb(KDbFile);//Creates UTF8 encoded database with one table with one record. + + TInt err = TheDb.Open(KDbFile); + TEST2(err, KErrNone); + + TInt failingAllocationNo = 0; + err = KErrNoMemory; + while(err == KErrNoMemory) + { + TheTest.Printf(_L(" %d"), ++failingAllocationNo); + OomPreStep(failingAllocationNo); + + TSqlScalarFullSelectQuery query(TheDb); + TBuf<50> data; + TRAP(err, query.SelectTextL(_L("SELECT ColumnName1234567890 FROM A"), data)); + if(err != KErrNone) + { + goto LabelOomPostStep; + } + TEST(data == _L("A1234567890")); + + TRAP(err, query.SelectTextL(_L("SELECT Col2 FROM A"), data)); + if(err != KErrNone) + { + goto LabelOomPostStep; + } + TEST(data == _L("A12345")); + + TRAP(err, query.SelectTextL(_L("SELECT Col3 FROM A"), data)); + if(err != KErrNone) + { + goto LabelOomPostStep; + } + TEST(data == _L("")); + +LabelOomPostStep: + OomPostStep(); + } + + TheDb.Close(); + (void)RSqlDatabase::Delete(KDbFile); + + TEST2(err, KErrNone); + TheTest.Printf(_L("\r\n===TSqlScalarFullSelectQuery::SelectTextL() OOM test succeeded at heap failure rate of %d ===\r\n"), failingAllocationNo); + } + +/** +@SYMTestCaseID PDS-SQL-CT-4181 +@SYMTestCaseDesc RSqlStatement::DeclaredColumnType() OOM test. +@SYMTestPriority High +@SYMTestActions The test runs RSqlStatement::DeclaredColumnType() in an OOM simulation loop. + The difference betwee this test case and the similar test case in t_sqloom2 is that here: + - burst OOM simulation is used; + - UTF8 encoded database is used; + - only SQL server side OOM simulation is performed; + The purpose of the test is to verify that the DeclaredColumnType() call behaves correctly + when the related sqlite3_column_name16() call performed by the SQL server fails + with "no memory". +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF145033 +*/ +void DeclaredColumnTypeOomTest() + { + //This is not really a full OOM test, because the SQL server counts only the number of active statement and + //stream objects, the allocated memory cells are not counted. + //The reason that the allocated memory cells are not counted, and in case of an OOM failure - checked, is + //because the SQL server can make some per-connection memory allocations (cache pages, etc.) + //and they will not be deallocated when the statement object is closed. + //But the result of the RSqlStatement::DeclaredColumnType() operation is checked. If there is a failed memory + //allocation on the server side, the returned column name can be NULL and that will be tested. + + (void)RSqlDatabase::Delete(KDbFile); + + TheTest.Printf(_L("Iteration:\r\n")); + + CreateTestDb(KDbFile);//Creates UTF8 encoded database with one table with one record. + + TInt err = TheDb.Open(KDbFile); + TEST2(err, KErrNone); + + TInt failingAllocationNo = 0; + err = KErrNoMemory; + while(err == KErrNoMemory) + { + TheTest.Printf(_L(" %d"), ++failingAllocationNo); + OomPreStep(failingAllocationNo); + + err = TheStmt.Prepare(TheDb, _L("SELECT * FROM A")); + if(err != KErrNone) + { + goto LabelOomPostStep; + } + + TSqlColumnType colType = ESqlNull; + err = TheStmt.DeclaredColumnType(0, colType); + if(err != KErrNone) + { + goto LabelStmtClose; + } + TEST2(colType, ESqlText); + + colType = ESqlNull; + err = TheStmt.DeclaredColumnType(1, colType); + if(err != KErrNone) + { + goto LabelStmtClose; + } + TEST2(colType, ESqlText); + + colType = ESqlNull; + err = TheStmt.DeclaredColumnType(2, colType); + if(err != KErrNone) + { + goto LabelStmtClose; + } + TEST2(colType, ESqlText); + +LabelStmtClose: + TheStmt.Close(); + +LabelOomPostStep: + OomPostStep(); + } + + TheDb.Close(); + (void)RSqlDatabase::Delete(KDbFile); + + TEST2(err, KErrNone); + TheTest.Printf(_L("\r\n===RSqlStatement::DeclaredColumnType() OOM test succeeded at heap failure rate of %d ===\r\n"), failingAllocationNo); + } + +void DoTests() + { + TheTest.Start(_L(" @SYMTestCaseID:PDS-SQL-CT-4176 RSqlStatement::ColumnName() OOM test")); + ColumnNameOomTest(); + + TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-CT-4177 RSqlStatement::ParameterName() OOM test")); + ParameterNameOomTest(); + + TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-CT-4178 RSqlStatement::ColumnText() OOM test")); + ColumnTextOomTest(); + + TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-CT-4179 RSqlColumnReadStream OOM test")); + TextColumnReadStreamOomTest(); + + TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-CT-4180 TSqlScalarFullSelectQuery::SelectTextL() OOM test")); + ScalarColumnTextOomTest(); + + TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-CT-4181 RSqlStatement::DeclaredColumnType() OOM test")); + DeclaredColumnTypeOomTest(); + } + +TInt E32Main() + { + TheTest.Title(); + + CTrapCleanup* tc = CTrapCleanup::New(); + TheTest(tc != NULL); + + __UHEAP_MARK; + + CreateTestEnv(); + DoTests(); + DestroyTestEnv(); + + __UHEAP_MARKEND; + + TheTest.End(); + TheTest.Close(); + + delete tc; + + User::Heap().Check(); + return KErrNone; + } diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/TEST/t_sqlprivcage.cpp --- a/persistentstorage/sql/TEST/t_sqlprivcage.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/TEST/t_sqlprivcage.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2006-2010 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" @@ -242,6 +242,9 @@ //Very long private database name err = db.Create(_L("c:\\private\\21212124\\hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh.db")); TEST2(err, KErrBadName); + //Private database name without drive letter + err = db.Create(_L("\\private\\21212124\\dbname_no_drive_letter.db")); + TEST2(err, KErrBadName); //Zero length private database name err = db.Create(_L("")); TEST2(err, KErrBadName); @@ -302,10 +305,14 @@ TEST2(err, 1); db2.Close(); - //Open database 1, attach database 2 + //Open database 1 RSqlDatabase db; err = db.Open(KTestDb1); TEST2(err, KErrNone); + //An attempt to attach a database with zero length name + err = db.Attach(_L(""), _L("Db2")); + TEST2(err, KErrBadName); + //Attach database 2 err = db.Attach(KTestDb2, _L("Db2")); TEST2(err, KErrNone); @@ -349,6 +356,32 @@ stmt.Close(); db.Close(); + //Open database 1, attach read-only database 2 + err = db.Open(KTestDb1); + TEST2(err, KErrNone); + //Make database 2 read-only. + err = TheFs.SetAtt(KTestDb2, KEntryAttReadOnly, 0); + TEST2(err, KErrNone); + //Attach database 2 + err = db.Attach(KTestDb2, _L("Db2")); + TEST2(err, KErrNone); + // + err = db.Exec(_L("INSERT INTO Db2.A(ID, T) VALUES(3, 'AAA')")); + TPtrC errmsg = db.LastErrorMessage(); + TheTest.Printf(_L(" === Read-only private attached database. Msg=%S, err=%d\r\n"), &errmsg, err); + TEST(err != KErrNone); + TSqlScalarFullSelectQuery q(db); + TBuf<20> text2; + TRAP(err, q.SelectTextL(_L("SELECT T FROM Db2.A WHERE ID=2"), text2)); + TEST2(err, KErrNone); + TEST(text2 == _L("AAA")); + // + err = db.Detach(_L("Db2")); + TEST2(err, KErrNone); + err = TheFs.SetAtt(KTestDb2, 0, KEntryAttReadOnly); + TEST2(err, KErrNone); + db.Close(); + err = RSqlDatabase::Delete(KTestDb2); TEST2(err, KErrNone); err = RSqlDatabase::Delete(KTestDb1); diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sql/TEST/t_sqlstartup.cpp --- a/persistentstorage/sql/TEST/t_sqlstartup.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sql/TEST/t_sqlstartup.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -306,6 +306,17 @@ name2[1] = TChar(0xFC00); rc = UTF16ToUTF8(name2, bufout); TEST(!rc); +#ifndef _DEBUG + //Test where the input buffer is too big + TBuf bufin; + bufin.SetLength(bufin.MaxLength()); + rc = UTF16ToUTF8(bufin, bufout); + TEST(!rc); + //Test where the output buffer max length is less than KMaxFileName + TBuf8 bufout2; + rc = UTF16ToUTF8(name2, bufout2); + TEST(!rc); +#endif ///////// UTF16ToUTF8Z() /////////////////////// _LIT8(KStr8Z, "abcd\x0"); rc = UTF16ToUTF8Z(KStr16, bufout); diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sqlite3api/OsLayer/test_fileutil.cpp --- a/persistentstorage/sqlite3api/OsLayer/test_fileutil.cpp Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sqlite3api/OsLayer/test_fileutil.cpp Wed Apr 14 17:46:32 2010 +0300 @@ -334,11 +334,31 @@ extern "C" void PrintS(const char* aTxt) { - TBuf<128> buf; - buf.Copy(TPtrC8((const TUint8*)aTxt)); - - RProcess process; - TProcessId processId = process.Id(); - - RDebug::Print(_L("%S. Process Id=%ld.\n"), &buf, processId.Id()); + if(!aTxt) + { + return; + } + TPtrC8 msg((const TUint8*)aTxt); + TInt msglen = msg.Length(); + TInt pos = 0; + const TInt KMaxLineLength = 220; + TBuf line; + do + { + if(pos == 0) + { + RProcess process; + TProcessId processId = process.Id(); + line.Format(_L("Process Id=%ld: "), processId.Id()); + } + TInt len = Min(msglen, (line.MaxLength() - line.Length())); + TPtrC8 ptr(msg.Ptr() + pos, len); + pos += len; + msglen -= len; + TPtr p2((TUint16*)line.Ptr() + line.Length(), 0, len); + p2.Copy(ptr); + line.SetLength(line.Length() + p2.Length()); + RDebug::Print(_L("%S\n"), &line); + line.Zero(); + } while(msglen > 0); } diff -r 31a8f755b7fe -r 211563e4b919 persistentstorage/sqlite3api/TEST/SRC/tclsqlite.c --- a/persistentstorage/sqlite3api/TEST/SRC/tclsqlite.c Thu Apr 01 00:19:42 2010 +0300 +++ b/persistentstorage/sqlite3api/TEST/SRC/tclsqlite.c Wed Apr 14 17:46:32 2010 +0300 @@ -2665,7 +2665,7 @@ #endif PrintS("###TclSqlite3: Tests begin"); if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){ - char errMsg[300]; + char errMsg[1024]; const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); if( zInfo==0 ) zInfo = interp->result;