persistentstorage/sql/SRC/Client/SqlStatementImpl.cpp
branchRCL_3
changeset 11 211563e4b919
parent 8 fa9941cf3867
child 23 26645d81f48d
equal deleted inserted replaced
10:31a8f755b7fe 11:211563e4b919
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     7 //
     8 // Initial Contributors:
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
     9 // Nokia Corporation - initial contribution.
    10 //
    10 //
    11 // Contributors:
    11 // Contributors:
       
    12 // NTT DOCOMO, INC - Fix for Bug 1915 "SQL server panics when using long column type strings"
    12 //
    13 //
    13 // Description:
    14 // Description:
    14 //
    15 //
    15 
    16 
    16 #include "SqlStatementImpl.h" 	//CSqlStatementImpl
    17 #include "SqlStatementImpl.h" 	//CSqlStatementImpl
    17 #include "SqlDatabaseImpl.h"	//CSqlDatabaseImpl::Session()
    18 #include "SqlDatabaseImpl.h"	//CSqlDatabaseImpl::Session()
    18 
    19 
    19 //Constants
    20 //Constants
    20 
       
    21 _LIT(KSemiColon,";");
       
    22 
    21 
    23 _LIT(KTextKWD, 	"TEXT");
    22 _LIT(KTextKWD, 	"TEXT");
    24 _LIT(KCharKWD, 	"CHAR");
    23 _LIT(KCharKWD, 	"CHAR");
    25 _LIT(KClobKWD, 	"CLOB");
    24 _LIT(KClobKWD, 	"CLOB");
    26 
    25 
   447 @see RSqlStatement::DeclaredColumnType().
   446 @see RSqlStatement::DeclaredColumnType().
   448 */
   447 */
   449 TInt CSqlStatementImpl::DeclaredColumnType(TInt aColumnIndex, TSqlColumnType& aColumnType)
   448 TInt CSqlStatementImpl::DeclaredColumnType(TInt aColumnIndex, TSqlColumnType& aColumnType)
   450 	{
   449 	{
   451 	__SQLASSERT_ALWAYS((TUint)aColumnIndex < (TUint)iColumnCnt, ESqlPanicBadColumnIndex);
   450 	__SQLASSERT_ALWAYS((TUint)aColumnIndex < (TUint)iColumnCnt, ESqlPanicBadColumnIndex);
   452 	if(iDeclaredColumnTypes.Count() == 0 && iColumnCnt > 0) //initialise iDeclaredColumnTypes array if necessary
   451 	if(iDeclaredColumnTypes.Count() == 0) //initialise iDeclaredColumnTypes array if necessary
   453 		{
   452 		{
   454 		TInt err = iDeclaredColumnTypes.Reserve(iColumnCnt);//We know what the array size should be - iColumnCnt
   453 		RSqlBufFlat declaredColumnTypeBuf;
       
   454 		TInt err = declaredColumnTypeBuf.SetCount(iColumnCnt);
   455 		if(err != KErrNone)
   455 		if(err != KErrNone)
   456 			{
   456 			{
       
   457 			declaredColumnTypeBuf.Close();
   457 			return err;
   458 			return err;
   458 			}
   459 			}
   459 		HBufC* colTypeNamesBuf = NULL;//Buffer for declared column type names, delimited by ';'.
   460 		
   460 		TRAP(err, colTypeNamesBuf = GetDeclColumnTypesL());
   461 		//Resize buffer to minimise the chance that two IPC calls are required to get all the column type name data.
       
   462 		//Allocates enough space to contain the header cells (already created by calling SetCount()) and a data buffer
       
   463 		//which assumes an average column type name length of 20 characters plus 8-byte alignment padding
       
   464 		const TInt KBufSizePerColumn = 48;
       
   465 		TInt newSize = declaredColumnTypeBuf.Size() + iColumnCnt*KBufSizePerColumn;
       
   466 
       
   467 		err = declaredColumnTypeBuf.ReAlloc(newSize);
   461 		if(err != KErrNone)
   468 		if(err != KErrNone)
   462 			{
   469 			{
   463 			__SQLASSERT(!colTypeNamesBuf, ESqlPanicInternalError);
   470 			declaredColumnTypeBuf.Close();
   464 			iDeclaredColumnTypes.Reset();
       
   465 			return err;	
   471 			return err;	
   466 			}
   472 			}
   467 		//Iterate over the column type names and map each column type name to one of the TSqlColumnType enum item values.
   473 		
   468 		//No error can occur from here till the end of the function code.
   474 		err = iSqlStmtSession.GetDeclColumnTypes(declaredColumnTypeBuf);
   469 		__SQLASSERT(colTypeNamesBuf != NULL, ESqlPanicInternalError);
   475 		if(err != KErrNone)
   470 		TPtrC colTypeNames(*colTypeNamesBuf);
   476 			{
       
   477 			declaredColumnTypeBuf.Close();
       
   478 			return err;	
       
   479 			}
       
   480 
       
   481 		err = iDeclaredColumnTypes.Reserve(iColumnCnt);//We know what the array size should be - iColumnCnt
       
   482 		if(err != KErrNone)
       
   483 			{
       
   484 			declaredColumnTypeBuf.Close();
       
   485 			return err;
       
   486 			}	
       
   487 
       
   488 		//Iterate over the column type names buffer and map each column type name to one of the TSqlColumnType enum item values.
       
   489 		TSqlBufRIterator declColumnTypeBufIt;
       
   490 		declColumnTypeBufIt.Set(declaredColumnTypeBuf);
   471 		TInt colIdx = 0;
   491 		TInt colIdx = 0;
   472 		while(colTypeNames.Length() > 0)
   492 		while(declColumnTypeBufIt.Next())
   473 			{
   493 			{
   474 			TInt pos = colTypeNames.Find(KSemiColon);
   494 			TPtrC colTypeName(declColumnTypeBufIt.Text());
   475 			if(pos < 0)
       
   476 				{
       
   477 				break;
       
   478 				}
       
   479 			TPtrC colTypeName(colTypeNames.Ptr(), pos);
       
   480 			if(pos == colTypeNames.Length() - 1)
       
   481 				{
       
   482 				colTypeNames.Set(NULL, 0);	
       
   483 				}
       
   484 			else
       
   485 				{
       
   486 				colTypeNames.Set(colTypeNames.Ptr() + pos + 1, colTypeNames.Length() - (pos + 1));
       
   487 				}
       
   488 			TSqlColumnType colType = ESqlInt;
   495 			TSqlColumnType colType = ESqlInt;
   489 			if(colTypeName.FindF(KCharKWD) >= 0 || colTypeName.FindF(KTextKWD) >= 0 || colTypeName.FindF(KClobKWD) >= 0)
   496 			if(colTypeName.FindF(KCharKWD) >= 0 || colTypeName.FindF(KTextKWD) >= 0 || colTypeName.FindF(KClobKWD) >= 0)
   490 				{
   497 				{
   491 				colType = ESqlText;
   498 				colType = ESqlText;
   492 				}
   499 				}
   499 				colType = ESqlReal;
   506 				colType = ESqlReal;
   500 				}
   507 				}
   501 			err = iDeclaredColumnTypes.Append(colType);
   508 			err = iDeclaredColumnTypes.Append(colType);
   502 			__SQLASSERT(err == KErrNone, ESqlPanicInternalError);//memory for the array elements has been reserved already
   509 			__SQLASSERT(err == KErrNone, ESqlPanicInternalError);//memory for the array elements has been reserved already
   503 			++colIdx;
   510 			++colIdx;
   504 			}//end of - while(colTypeNames.Length() > 0)
   511 			} //end of - while(declColumnTypeBufIt.Next())
   505 		__SQLASSERT(colIdx == iColumnCnt, ESqlPanicInternalError);
   512 		__SQLASSERT(colIdx == iColumnCnt, ESqlPanicInternalError);
   506 		delete colTypeNamesBuf;
   513 		declaredColumnTypeBuf.Close();
   507 		}//end of - if(iDeclaredColumnTypes.Count() == 0 && iColumnCnt > 0)
   514 		} //end of - if(iDeclaredColumnTypes.Count() == 0 && iColumnCnt > 0)
   508 	aColumnType = iDeclaredColumnTypes[aColumnIndex];
   515 	aColumnType = iDeclaredColumnTypes[aColumnIndex];
   509 	return KErrNone;
   516 	return KErrNone;
   510 	}
   517 	}
   511 	
   518 	
   512 /**
   519 /**
   861 			}
   868 			}
   862 		}
   869 		}
   863 	return KErrNone;
   870 	return KErrNone;
   864 	}
   871 	}
   865 
   872 
   866 
       
   867 /**
       
   868 Returns a buffer containing a ";" separated list with declared types of statement's columns.
       
   869 The caller is responsible for deleting the result buffer.
       
   870 
       
   871 @return HBufC buffer - column types list.
       
   872 */
       
   873 HBufC* CSqlStatementImpl::GetDeclColumnTypesL()
       
   874 	{
       
   875 	return iSqlStmtSession.GetDeclColumnTypesL(iColumnCnt);
       
   876 	}
       
   877