diff -r 000000000000 -r e686773b3f54 phonebookengines/contactsmodel/cntplsql/src/cntsqlprovider.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines/contactsmodel/cntplsql/src/cntsqlprovider.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,771 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +/** + @file + @internalComponent + @released +*/ + +#include +#include +#include "cntsqlprovider.h" + +/** +Constant descriptor representing 'update' sql key word. Used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KSqlUpdate, "UPDATE"); + + +/** +Constant descriptor representing 'delete' sql key word. Used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KSqlDelete, "DELETE"); + + +/** +Constant descriptor representing 'insert' sql key word. Used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KSqlInsert, "INSERT"); + + +/** +Constant descriptor representing 'select' sql key word. Used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KSqlSelect, "SELECT"); + + +/** +Constant descriptor used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KSqlWhere, "WHERE"); + + +/** +Constant descriptor used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KSqlSet, "SET"); + + +/** +Constant descriptor used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KSqlInto, "INTO"); + + +/** +Constant descriptor used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KSqlValues, "VALUES"); + + +/** +Constant descriptor used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KSqlFrom, "FROM"); + + +/** +Constant descriptor used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KSpace, " "); + + +/** +Constant descriptor used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KEqual, " = "); + + +/** +Constant descriptor used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KSemicolon, ";"); + + +/** +Constant descriptor used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KComma, ","); + + +/** +Constant descriptor used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KOpenBracket, "("); + + +/** +Constant descriptor used to build sql statements. + +@internalComponent +@released +*/ +_LIT(KCloseBracket, ")"); + +/** +TStatement type constructor, + +@param aSqlStatement Specifies the sql statement type: select, insert, delete, update. +@param aTableName Table against which sql statement will be built + +*/ +TCntSqlStatementType::TCntSqlStatementType(TCntSqlStatement aSqlStatement, const TDesC& aTableName) + : + iSqlStatement(aSqlStatement), + iTableName(aTableName) + { + } + +/** +TSqlStatement setter. Set the TSqlStatement held by this class, + +@param aSqlStatement Specifies the sql statement type: select, insert, delete, update. + +*/ +void TCntSqlStatementType::SetSqlStatement(TCntSqlStatement aSqlStatement) + { + iSqlStatement = aSqlStatement; + } + +/** +TSqlStatement getter. Returns the sql statement type held by this class, + +@return TSqlStatement type held by this class + +*/ +TCntSqlStatement TCntSqlStatementType::SqlStatement() const + { + return iSqlStatement; + } + +/** +Table name getter. Returns the table's name held by this class, + +@return TDesC containing the table's name held by this class + +*/ +const TDesC& TCntSqlStatementType::TableName() const + { + return iTableName; + } + +/** +Factory method used to construct and retrieve CCntSqlStatement based objects. +CCntSqlStatement objects are used to build and provide sql strings (sql statements) to be +used in RSqlStatement. + +@param aStatementType TStatementType containing thwe sql statement type requested and the + table name against which sql query will be run. + +@return Pointer to concrete CCntSqlStatement implementation used to retrieve sql strings. + +*/ +CCntSqlStatement* TSqlProvider::GetSqlStatementL(TCntSqlStatementType aStatementType) + { + CCntSqlStatement* cntSqlStatement = NULL; + + switch(aStatementType.SqlStatement()) + { + case EInsert: + cntSqlStatement = CCntSqlInsert::NewL( aStatementType.TableName() ); + break; + case EUpdate: + cntSqlStatement = CCntSqlUpdate::NewL( aStatementType.TableName() ); + break; + case EDelete: + cntSqlStatement = CCntSqlDelete::NewL( aStatementType.TableName() ); + break; + case ESelect: + cntSqlStatement = CCntSqlSelect::NewL( aStatementType.TableName() ); + } + + return(cntSqlStatement); + } + +/** +SQL parameter setter. Set value for a specified sql parameter, + +@param aParam SQL parameter name +@param aValue SQL parameter value. + +@leave KErrNoMemory, an out of memory occured + +@panic USER 0 panic; in debug mode if number of specified parameters is not equal with + number of parameter values + +*/ +void CCntSqlStatement::SetParamL(const TDesC& aParam, const TDesC& aValue) + { + ASSERT( iParams->Count() == iValues->Count() ); // in debug mode check + // if number of provided params is equal + // with number of provided values + + ASSERT( iProcessed == EFalse ); // in debug mode check if the statement wasn't processed yet + + iParams->AppendL(aParam); + iValues->AppendL(aValue); + } + +/** +Utility method used to retrieve the position of a given parameter. +The array of parameters is searched sequentially because we have to provide +the index of the parameter as it was inserted (so binary search is not usefull here) +Limit the usage of this method since it can be time consuming. + +@param aParam parameter name for which index has to be retrieved +@return index of the parameter if this is found in the parameter array (eg. previous set) + or KErrNotFound if the parameter was not found +*/ +TInt CCntSqlStatement::ParameterIndex(const TDesC& aParam) const + { + ASSERT( iParams->Count() == iValues->Count() ); // in debug mode check + // if number of provided params is equal + // with number of provided values + for(TInt i = 0; i < iParams->Count(); ++i) + { + if(aParam.Compare((*iParams)[i]) == 0) + { + return i; + } + } + + return KErrNotFound; + } + +/** +SQL condition setter, Set condition for a sql statement (to be used in where clause) + +@param aCondition condition value. + +@leave KErrNoMemory, an out of memory occured + +*/ +void CCntSqlStatement::SetConditionL(const TDesC& aCondition) + { + ClearCondition(); + + iCondition = aCondition.AllocL(); + iProcessed = EFalse; + delete iSqlString; + iSqlString = NULL; + } + +/** +Clearing SQL condition from a sql statement +*/ +void CCntSqlStatement::ClearCondition() + { + if(iCondition) + { + delete iCondition; + iCondition = NULL; + iProcessed = EFalse; + delete iSqlString; + iSqlString = NULL; + } + } + + +/** +Remove all sql parameters prviously set and their values. Also reset previously set +sql condition. + +*/ +void CCntSqlStatement::Reset() + { + if(iCondition) + { + delete iCondition; + iCondition = NULL; + } + + delete iSqlString; + iSqlString = NULL; + + iParams->Reset(); + iValues->Reset(); + iProcessed = EFalse; + } + +/** +Second phase constructor for CCntSqlStatement based classes + +@param aTableName table name against which sql statement will be run + +@leave KErrNoMemory, an out of memory occured + +*/ +void CCntSqlStatement::ConstructL(const TDesC& aTableName) + { + const TInt KGranularity = 5; + + iTableName = aTableName.AllocL(); + iParams = new (ELeave) CDesCArrayFlat(KGranularity); + iValues = new (ELeave) CDesCArrayFlat(KGranularity); + + // Lazy initialisation for iSqlString; iSqlString is initialised in SqlStringL() method. + // This is done because in SqlStringL() method we know what size buffer must have + + iProcessed = EFalse; + } + +/** +CCntSqlStatement destructor. + +*/ +CCntSqlStatement::~CCntSqlStatement() + { + delete iTableName; + delete iCondition; + delete iSqlString; + + if (iParams) + { + iParams->Reset(); + delete iParams; + } + + if (iValues) + { + iValues->Reset(); + delete iValues; + } + } + +/** +Creates a concrete CCntSqlUpdate object (used to retrieve sql update statements) + +@param aTableName table name against which update statement will be run + +@return concrete CCntSqlUpdate object + +@leave KErrNoMemory, an out of memory occured + +*/ +CCntSqlUpdate* CCntSqlUpdate::NewL(const TDesC& aTableName) + { + CCntSqlUpdate* self = new (ELeave) CCntSqlUpdate(); + CleanupStack::PushL(self ); + self->ConstructL(aTableName); + CleanupStack::Pop(self); + return self; + } + +/** +Return a string representing an update sql statement + +@leave KErrArgument if the no parameter was provided +*/ +TDesC& CCntSqlUpdate::SqlStringL() + { + if(iProcessed) + { + return *iSqlString; + } + + ASSERT( iParams->Count() == iValues->Count() ); // in debug mode check + // if number of provided params is equal + // with number of provided values + + if(iParams->Count() == 0) + { + User::Leave( KErrArgument ); + } + + // First calculate the buffer size + TInt bufferSize = 0; + bufferSize = KSqlUpdate().Size() + + iTableName->Size() + + KSpace().Size() + + KSqlSet().Size() + + KSpace().Size(); + + for(TInt loop = 0; loop < iParams->Count(); ++loop) + { + bufferSize += (*iParams)[loop].Size() + + KEqual().Size() + + (*iValues)[loop].Size(); + if(loop < iParams->Count() -1) + { + bufferSize += KComma().Size(); + } + } + if(iCondition) + { + bufferSize += KSpace().Size() + + KSqlWhere().Size() + + KSpace().Size() + iCondition->Size(); + } + bufferSize += KSemicolon().Size(); + + // Allocate buffer + iSqlString = HBufC::NewL( bufferSize ); + + TPtr dataPtr = iSqlString->Des(); + + dataPtr.Append(KSqlUpdate); + dataPtr.Append(KSpace); + dataPtr.Append(*iTableName); + dataPtr.Append(KSpace); + dataPtr.Append(KSqlSet); + dataPtr.Append(KSpace); + + for(TInt loop = 0; loop < iParams->Count(); ++loop) + { + dataPtr.Append((*iParams)[loop]); + dataPtr.Append(KEqual); + dataPtr.Append((*iValues)[loop]); + if(loop < iParams->Count() -1) + { + dataPtr.Append(KComma); + } + } + + if(iCondition) + { + dataPtr.Append(KSpace); + dataPtr.Append(KSqlWhere); + dataPtr.Append(KSpace); + dataPtr.Append(*iCondition); + } + dataPtr.Append(KSemicolon); + + iProcessed = ETrue; + return *iSqlString; + } + +/** +Creates a concrete CCntSqlDelete object (used to retrieve sql delete statements) + +@param aTableName table name against which delete statement will be run + +@return concrete CCntSqlDelete object + +@leave KErrNoMemory, an out of memory occured + +*/ +CCntSqlDelete* CCntSqlDelete::NewL(const TDesC& aTableName) + { + CCntSqlDelete* self = new (ELeave) CCntSqlDelete(); + CleanupStack::PushL(self); + self->ConstructL(aTableName); + CleanupStack::Pop(self); + return self; + } + +/** +Return a string representing a delete sql statement + +@leave KErrArgument if condition is not set +*/ +TDesC& CCntSqlDelete::SqlStringL() + { + if(iProcessed) + { + return *iSqlString; + } + + if(!iCondition) + { + User::Leave(KErrArgument); + } + + // First calculate the buffer size + TInt bufferSize = 0; + bufferSize = KSqlDelete().Size() + + KSpace().Size() + + KSqlFrom().Size() + + KSpace().Size() + + iTableName->Size() + + KSpace().Size() + + KSqlWhere().Size() + + KSpace().Size() + + iCondition->Size() + + KSemicolon().Size(); + + // Allocate buffer + iSqlString = HBufC::NewL( bufferSize ); + + TPtr dataPtr = iSqlString->Des(); + + dataPtr.Append(KSqlDelete); + dataPtr.Append(KSpace); + dataPtr.Append(KSqlFrom); + dataPtr.Append(KSpace); + dataPtr.Append(*iTableName); + + dataPtr.Append(KSpace); + dataPtr.Append(KSqlWhere); + dataPtr.Append(KSpace); + dataPtr.Append(*iCondition); + dataPtr.Append(KSemicolon); + + iProcessed = ETrue; + return *iSqlString; + } + +/** +Creates a concrete CCntSqlInsert object (used to retrieve sql insert statements) + +@param aTableName table name against which insert statement will be run + +@return concrete CCntSqlInsert object + +@leave KErrNoMemory, an out of memory occured + +*/ +CCntSqlInsert* CCntSqlInsert::NewL(const TDesC& aTableName) + { + CCntSqlInsert* self = new (ELeave) CCntSqlInsert(); + CleanupStack::PushL(self); + self->ConstructL(aTableName); + CleanupStack::Pop(self); + return self; + } + +/** +Return a string representing an insert sql statement + +@leave KErrArgument if the no parameter was provided +*/ +TDesC& CCntSqlInsert::SqlStringL() + { + if(iProcessed) + { + return *iSqlString; + } + + ASSERT( iParams->Count() == iValues->Count() ); // in debug mode check + // if number of provided params is equal + // with number of provided values + + if(iParams->Count() == 0) + { + User::Leave( KErrArgument ); + } + + // First calculate the buffer size + TInt bufferSize = 0; + bufferSize = KSqlInsert().Size() + + KSpace().Size() + + KSqlInto().Size() + + KSpace().Size() + + iTableName->Size() + + KSpace().Size() + + KOpenBracket().Size(); + for(TInt loop = 0; loop < iParams->Count(); ++loop) + { + bufferSize += (*iParams)[loop].Size() + (*iValues)[loop].Size(); + if(loop < iParams->Count() - 1) + { + bufferSize += KComma().Size() + KComma().Size(); + } + } + bufferSize += KCloseBracket().Size() + + KSpace().Size() + + KSqlValues().Size() + + KSpace().Size() + + KCloseBracket().Size() + + KSemicolon().Size(); + + // Allocate buffer + iSqlString = HBufC::NewL( bufferSize ); + + TPtr dataPtr = iSqlString->Des(); + + dataPtr.Append(KSqlInsert); + dataPtr.Append(KSpace); + dataPtr.Append(KSqlInto); + dataPtr.Append(KSpace); + dataPtr.Append(*iTableName); + dataPtr.Append(KSpace); + + dataPtr.Append(KOpenBracket); + for(TInt loop = 0; loop < iParams->Count(); ++loop) + { + dataPtr.Append((*iParams)[loop]); + if(loop < iParams->Count() - 1) + { + dataPtr.Append(KComma); + } + } + + dataPtr.Append(KCloseBracket); + + dataPtr.Append(KSpace); + dataPtr.Append(KSqlValues); + dataPtr.Append(KSpace); + + dataPtr.Append(KOpenBracket); + for(TInt loop = 0; loop < iValues->Count(); ++loop) + { + dataPtr.Append((*iValues)[loop]); + if(loop < iValues->Count() - 1) + { + dataPtr.Append(KComma); + } + } + + dataPtr.Append(KCloseBracket); + dataPtr.Append(KSemicolon); + + iProcessed = ETrue; + + return *iSqlString; + } + +/** +Creates a concrete CCntSqlSelect object (used to retrieve sql select statements) + +@param aTableName table name against which select statement will be run + +@return concrete CCntSqlSelect object + +@leave KErrNoMemory, an out of memory occured + +*/ +CCntSqlSelect* CCntSqlSelect::NewL(const TDesC& aTableName) + { + CCntSqlSelect* self = new (ELeave) CCntSqlSelect(); + CleanupStack::PushL(self); + self->ConstructL(aTableName); + CleanupStack::Pop(self); + return self; + } + +/** +Return a string representing a select sql statement +When constructing simple select statement (against one single table) table name +has to be provided. +For making joint selects a list of tables will be provided: table1, table2 as +table name. + +@leave KErrArgument if there is no argument provided +*/ +TDesC& CCntSqlSelect::SqlStringL() + { + if(iProcessed) + { + return *iSqlString; + } + + if(iParams->Count() == 0) + { + User::Leave(KErrArgument); + } + + // First calculate the buffer size + TInt bufferSize = 0; + bufferSize = KSqlSelect().Size() + + KSpace().Size(); + for(TInt loop = 0; loop < iParams->Count(); ++loop) + { + bufferSize += (*iParams)[loop].Size(); + if(loop < iParams->Count() - 1) + { + bufferSize += KComma().Size(); + } + } + bufferSize += KSpace().Size() + + KSqlFrom().Size() + + KSpace().Size() + + iTableName->Size(); + if(iCondition) + { + bufferSize += KSpace().Size() + + KSqlWhere().Size() + + KSpace().Size() + + iCondition->Size(); + } + bufferSize += KSemicolon().Size(); + + // Allocate buffer + iSqlString = HBufC::NewL( bufferSize ); + TPtr dataPtr = iSqlString->Des(); + + dataPtr.Append(KSqlSelect); + dataPtr.Append(KSpace); + + for(TInt loop = 0; loop < iParams->Count(); ++loop) + { + dataPtr.Append((*iParams)[loop]); + if(loop < iParams->Count() - 1) + { + dataPtr.Append(KComma); + } + } + + dataPtr.Append(KSpace); + + dataPtr.Append(KSqlFrom); + dataPtr.Append(KSpace); + dataPtr.Append(*iTableName); + + if(iCondition) + { + dataPtr.Append(KSpace); + dataPtr.Append(KSqlWhere); + dataPtr.Append(KSpace); + dataPtr.Append(*iCondition); + } + dataPtr.Append(KSemicolon); + + iProcessed = ETrue; + + return *iSqlString; + }