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