sl@0: /* sl@0: * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * Implements a read-only interface for UPS Database. sl@0: * sl@0: */ sl@0: sl@0: sl@0: /** sl@0: @file sl@0: @internalTechnology sl@0: @released sl@0: */ sl@0: sl@0: #include "upsdbw.h" sl@0: #include "upscommon.h" sl@0: sl@0: using namespace UserPromptService; sl@0: sl@0: sl@0: // sl@0: //CDecisionView sl@0: // sl@0: sl@0: CDecisionView::CDecisionView():CActive(EPriorityStandard) sl@0: /** sl@0: Constructor for decision view object. sl@0: */ sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: sl@0: sl@0: CDecisionView::~CDecisionView() sl@0: /** sl@0: Destructor for the decision view object. sl@0: */ sl@0: { sl@0: iDbView.Close(); sl@0: delete iColSet; sl@0: Deque(); sl@0: } sl@0: sl@0: sl@0: EXPORT_C CDecisionView* CDecisionView::NewLC() sl@0: /** sl@0: Creates a decision view object. The function leaves, if creation of the view object fails. sl@0: sl@0: @return A pointer to the newly allocated view object, if creation is successful. sl@0: The pointer is also put onto the cleanup stack. sl@0: */ sl@0: { sl@0: CDecisionView* self = new(ELeave) CDecisionView(); sl@0: CleanupStack::PushL(self); sl@0: return self; sl@0: } sl@0: sl@0: sl@0: void CDecisionView::DoCancel() sl@0: //From CActive sl@0: { sl@0: iDbView.Cancel(); sl@0: if (iClientStatus) sl@0: { sl@0: User::RequestComplete(iClientStatus, KErrCancel); sl@0: } sl@0: } sl@0: sl@0: sl@0: TInt CDecisionView::RunError(TInt aError) sl@0: //From CActive sl@0: { sl@0: if (iClientStatus) sl@0: { sl@0: User::RequestComplete(iClientStatus, aError); sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: void CDecisionView::RunL() sl@0: //From CActive sl@0: { sl@0: TInt status = iStatus.Int(); sl@0: User::LeaveIfError(status); sl@0: sl@0: if(status > 0) sl@0: { sl@0: iDbView.Evaluate(iStatus); sl@0: SetActive(); sl@0: } sl@0: else sl@0: { sl@0: User::RequestComplete(iClientStatus,status); sl@0: } sl@0: } sl@0: sl@0: sl@0: EXPORT_C void CDecisionView::EvaluateView(TRequestStatus& aStatus) sl@0: /** sl@0: Performs all steps of the view evaluation, returning immediately and sl@0: signalling when all steps are complete. sl@0: sl@0: @param aStatus The request status used to contain completion information for the function. sl@0: On completion, the status value should be interpreted as follows: sl@0: 0, evaluation is complete.< 0, an error code. sl@0: */ sl@0: { sl@0: __ASSERT_ALWAYS(!IsActive(), User::Panic(KDecisionViewPanic,KErrInUse)); sl@0: sl@0: aStatus = KRequestPending; sl@0: iClientStatus = &aStatus; sl@0: sl@0: iDbView.Evaluate(iStatus); sl@0: sl@0: SetActive(); sl@0: sl@0: } sl@0: sl@0: sl@0: CDecisionRecord* CDecisionView::GenerateRecordL(RDbRowSet& aRowSet, CDbColSet* aColSet) sl@0: /** sl@0: Retrieves all decision record fileds from the given rowset and generates sl@0: a decision record from these information. sl@0: sl@0: @param aRowSet A database rowset object. sl@0: @param aColSet A database column set object. sl@0: sl@0: @return The newly,created decision record if it is successful; otherwise, leaves. sl@0: */ sl@0: { sl@0: TSecureId clientSid(aRowSet.ColUint32(aColSet->ColNo(KColClientSid))); //Client Secure Id sl@0: TSecureId serverId = TSecureId(aRowSet.ColUint32(aColSet->ColNo(KColServerSid))); //Service Secure Id sl@0: TUid evaluatorId = TUid::Uid(aRowSet.ColUint32(aColSet->ColNo(KColEvaluatorId))); //Evaluator Uid sl@0: TUid serviceId = TUid::Uid(aRowSet.ColUint32(aColSet->ColNo(KColServiceId))); //Service Uid sl@0: TPtrC8 fingerprint = aRowSet.ColDes8(aColSet->ColNo(KColFingerprint)); //Fingerprint sl@0: TPtrC8 clientEntity = aRowSet.ColDes8(aColSet->ColNo(KColClientEntity)); //Client Entity sl@0: TInt8 result = aRowSet.ColInt8(aColSet->ColNo(KColResult)); //Result sl@0: TUint16 ver = aRowSet.ColUint16(aColSet->ColNo(KColMajorPolicyVersion)); //Major Policy Version sl@0: TUint32 recordId = aRowSet.ColUint32(aColSet->ColNo(KColRecordId)); //Unique Record ID sl@0: TUint32 evaluatorInfo = aRowSet.ColUint32(aColSet->ColNo(KColEvaluatorInfo)); //EvaluatorInfo sl@0: sl@0: //a stream is used to read long columns sl@0: TDbColNo col = aColSet->ColNo(KColDescription); sl@0: TInt len = aRowSet.ColLength(col); sl@0: sl@0: RBuf description; sl@0: CleanupClosePushL(description); sl@0: description.CreateL(len); sl@0: sl@0: RDbColReadStream str; sl@0: str.OpenLC(aRowSet,col); sl@0: str.ReadL(description,len); sl@0: str.Close(); sl@0: CleanupStack::PopAndDestroy(&str); sl@0: sl@0: CDecisionRecord *retval = CDecisionRecord::NewL(clientSid,evaluatorId,serviceId,serverId,fingerprint, sl@0: clientEntity,description,result,ver,evaluatorInfo,recordId); sl@0: sl@0: CleanupStack::PopAndDestroy(&description); sl@0: return retval; sl@0: } sl@0: sl@0: sl@0: EXPORT_C CDecisionRecord* CDecisionView::NextDecisionL() sl@0: /** sl@0: Moves the cursor to the next row in the view object and returns the current decision row. sl@0: If there are no more rows, the cursor is positioned to the end of the view object. sl@0: sl@0: @return 0, If the cursor is positioned at the end of the view. Otherwise, current record. sl@0: */ sl@0: { sl@0: CDecisionRecord *record(0); sl@0: sl@0: if(iDbView.NextL()) sl@0: { sl@0: iDbView.GetL(); sl@0: record = GenerateRecordL(iDbView,iColSet); sl@0: } sl@0: else sl@0: { sl@0: iDbView.Close(); sl@0: } sl@0: sl@0: return record; sl@0: } sl@0: sl@0: sl@0: // sl@0: //CDecisionDb sl@0: // sl@0: sl@0: sl@0: CDecisionDb::CDecisionDb() sl@0: /** sl@0: Constructor for read-only decision database object sl@0: */ sl@0: { sl@0: sl@0: } sl@0: sl@0: sl@0: CDecisionDb::~CDecisionDb() sl@0: /** sl@0: Destructor for read-only decision database object sl@0: */ sl@0: { sl@0: sl@0: } sl@0: sl@0: const TDesC* CDecisionDb::GetComparisonOperator(const TUint32& aFlag) const sl@0: /** sl@0: Finds and returns the correspondent comparision operator string. sl@0: sl@0: @param aFlag sl@0: */ sl@0: { sl@0: UserPromptService::TComparisonOp op = static_cast(aFlag & 0xFFFF0000); sl@0: switch (op) sl@0: { sl@0: case UserPromptService::EEqual: sl@0: { sl@0: return &KSQLQueryEqual; sl@0: } sl@0: case UserPromptService::ENotEqual: sl@0: { sl@0: return &KSQLQueryNotEqual; sl@0: } sl@0: case UserPromptService::ELessThan: sl@0: { sl@0: return &KSQLQueryLessThan; sl@0: } sl@0: case UserPromptService::EGreaterThan: sl@0: { sl@0: return &KSQLQueryGreaterThan; sl@0: } sl@0: case UserPromptService::ELessThanOrEqual: sl@0: { sl@0: return &KSQLQueryLessThanOrEqual; sl@0: } sl@0: case UserPromptService::EGreaterThanOrEqual: sl@0: { sl@0: return &KSQLQueryGreaterThanOrEqual; sl@0: } sl@0: } sl@0: return &KSQLQueryEqual; sl@0: } sl@0: sl@0: sl@0: void CDecisionDb::CreateSqlStatementLC(CDecisionFilter& aFilter, RBuf& aSql) sl@0: /** sl@0: Creates an sql statement from a given filter. sl@0: sl@0: @param aFilter A filter object used to create the SQL statement. sl@0: @param aSql The newly created SQL statement. sl@0: */ sl@0: { sl@0: //Estimate the maximum required buffer (maxLen) to save the sql statement. sl@0: //KSQLQueryBase must be in the statement at least. sl@0: TInt maxLen = KBaseSQLLength; sl@0: sl@0: //Get the bits belonging to ID values (ClientSid,EvaluatorId,ServiceId,ServerSid) sl@0: TUint32 combinedFlags = (aFilter.iSetFlag[KPosClientSid] | aFilter.iSetFlag[KPosEvaluatorId] | sl@0: aFilter.iSetFlag[KPosServiceId] | aFilter.iSetFlag[KPosServerSid] | sl@0: aFilter.iSetFlag[KPosFingerprint] | aFilter.iSetFlag[KPosClientEntity]| sl@0: aFilter.iSetFlag[KPosMajorPolicyVersion] | aFilter.iSetFlag[KPosRecordId] | sl@0: aFilter.iSetFlag[KPosDescription] | aFilter.iSetFlag[KPosResult] | sl@0: aFilter.iSetFlag[KPosEvaluatorInfo]); sl@0: sl@0: TUint16 flag = combinedFlags & 0x000006CF; sl@0: //Count how many bits are set, and add KMaxIntCondition for each set bit sl@0: while(flag != 0) sl@0: { sl@0: flag &= (flag-1); sl@0: maxLen += KMaxIntCondition; sl@0: } sl@0: //Get the bits belonging to string values (Fingerprint and ClientEntity) sl@0: flag = combinedFlags & 0x00000130; sl@0: //Count how many bits are set, and add KMaxStringCondition length for each set bit sl@0: while(flag != 0) sl@0: { sl@0: flag &= (flag-1); sl@0: maxLen += KMaxStringCondition; sl@0: } sl@0: sl@0: //Allocate the estimated number of bytes for the sql statement sl@0: aSql.CreateL(maxLen); sl@0: aSql.CleanupClosePushL(); sl@0: //First copy the basic SQL statement sl@0: aSql.AppendFormat(KSQLQueryBase,&KDecisionTable); sl@0: sl@0: //If the filter is empty, there is no condition to add to the sql statement. sl@0: //So, simply return the base sql statement. In this case, all rows of sl@0: //the decision table are listed. sl@0: if(maxLen == KBaseSQLLength) sl@0: { sl@0: return; sl@0: } sl@0: sl@0: //Filter is not empty, add 'WHERE' key word into the statement sl@0: aSql.Append(KSQLQueryWhere); sl@0: sl@0: TBool multiple = EFalse; sl@0: //Append server SID if exists in the filter sl@0: AppendQueryInteger(aFilter.iServerSid.iId, aSql, multiple, aFilter.iSetFlag[KPosServerSid], KSetServerSid, KColServerSid); sl@0: //Append service UID if exists in the filter sl@0: AppendQueryInteger(aFilter.iServiceId.iUid, aSql, multiple, aFilter.iSetFlag[KPosServiceId], KSetServiceId, KColServiceId); sl@0: //Append client SID if exists in the filter sl@0: AppendQueryInteger(aFilter.iClientSid.iId, aSql, multiple, aFilter.iSetFlag[KPosClientSid], KSetClientSid, KColClientSid); sl@0: //Append evaluator UID if exists in the filter sl@0: AppendQueryInteger(aFilter.iEvaluatorId.iUid, aSql, multiple, aFilter.iSetFlag[KPosEvaluatorId], KSetEvaluatorId, KColEvaluatorId); sl@0: //Append major policy version if exists in the filter sl@0: AppendQueryInteger(aFilter.iMajorPolicyVersion, aSql, multiple, aFilter.iSetFlag[KPosMajorPolicyVersion], KSetMajorPolicyVersion, KColMajorPolicyVersion); sl@0: //Append record id if exists in the filter sl@0: AppendQueryInteger(aFilter.iRecordId, aSql, multiple, aFilter.iSetFlag[KPosRecordId], KSetRecordId, KColRecordId); sl@0: //Append result if exists in the filter sl@0: AppendQueryInteger(aFilter.iResult, aSql, multiple, aFilter.iSetFlag[KPosResult], KSetResult, KColResult); sl@0: //Append evaluator info if exists in the filter sl@0: AppendQueryInteger(aFilter.iEvaluatorInfo, aSql, multiple, aFilter.iSetFlag[KPosEvaluatorInfo], KSetEvaluatorInfo, KColEvaluatorInfo); sl@0: //Append description if exists in the filter sl@0: AppendQueryStringL(*aFilter.iDescription, aSql, multiple, aFilter.iSetFlag[KPosDescription], KSetDescription, KColDescription); sl@0: sl@0: //Append fingerprint if exists in the filter sl@0: //Convert 8-bit value to 16-bit sl@0: if(aFilter.iFingerprint) sl@0: { sl@0: HBufC* fp = HBufC::NewLC(aFilter.iFingerprint->Length()); sl@0: TPtr ptrFp(fp->Des()); sl@0: ptrFp.Copy(*aFilter.iFingerprint); sl@0: sl@0: AppendQueryStringL(*fp, aSql, multiple, aFilter.iSetFlag[KPosFingerprint], KSetFingerprint, KColFingerprint); sl@0: CleanupStack::PopAndDestroy(fp); sl@0: } sl@0: sl@0: //Append client entity if exists in the filter sl@0: //Convert 8-bit value to 16-bit sl@0: if(aFilter.iClientEntity) sl@0: { sl@0: HBufC* ce = HBufC::NewLC(aFilter.iClientEntity->Length()); sl@0: TPtr ptrCe(ce->Des()); sl@0: ptrCe.Copy(*aFilter.iClientEntity); sl@0: sl@0: AppendQueryStringL(*ce, aSql, multiple, aFilter.iSetFlag[KPosClientEntity], KSetClientEntity, KColClientEntity); sl@0: CleanupStack::PopAndDestroy(ce); sl@0: } sl@0: } sl@0: sl@0: sl@0: void CDecisionDb::AppendQueryInteger(const TUint32& aValue, TDes& aSql, TBool& aMultiple, const TUint32& aFlag, const TUint32& aSetCol, const TDesC& aColName) sl@0: /** sl@0: Appends an integer-based query key field to an SQL query string. sl@0: sl@0: @param aValue The integer value which will be added to the query. sl@0: @param aSql The SQL query string. sl@0: @param aMultiple EFalse, if there is only one query key in the query string. Otherwise, ETrue. sl@0: @param aFlag The flag value corresponding to the query key. sl@0: @param aSetCol A constant value indicating whether or not a specific column is set. sl@0: @param aColName The column name of the query key. sl@0: */ sl@0: { sl@0: if(aFlag & aSetCol) sl@0: { sl@0: if(aMultiple) sl@0: { sl@0: aSql.Append(KSQLQueryAnd); sl@0: } sl@0: else sl@0: { sl@0: aMultiple=ETrue; sl@0: } sl@0: sl@0: aSql.Append(aColName); sl@0: aSql.AppendFormat(KSQLQueryString,GetComparisonOperator(aFlag)); sl@0: aSql.AppendFormat(KSQLQueryConditionInt,aValue); sl@0: } sl@0: } sl@0: sl@0: sl@0: void CDecisionDb::AppendQueryStringL(const TDesC& aValue, TDes& aSql, TBool& aMultiple, const TUint32& aFlag, const TUint32& aSetCol, const TDesC& aColName) sl@0: /** sl@0: Appends an string query key to an SQL query string. sl@0: sl@0: @param aValue The string value which will be added to the query. sl@0: @param aSql The SQL query string. sl@0: @param aMultiple EFalse, if there is only one query key in the query string. Otherwise, ETrue. sl@0: @param aFlag The flag value corresponding to the query key. sl@0: @param aSetCol A constant value indicating whether or not a specific column is set. sl@0: @param aColName The column name of the query key. sl@0: */ sl@0: { sl@0: if(aFlag & aSetCol) sl@0: { sl@0: if(aMultiple) sl@0: { sl@0: aSql.Append(KSQLQueryAnd); sl@0: } sl@0: else sl@0: { sl@0: aMultiple=ETrue; sl@0: } sl@0: sl@0: aSql.Append(aColName); sl@0: sl@0: if(aValue.Length() != 0) sl@0: { sl@0: //Scan for single quote sl@0: RBuf dbValue; sl@0: DoubleSingleQuotesL(aValue, dbValue); sl@0: dbValue.CleanupClosePushL(); sl@0: sl@0: aSql.AppendFormat(KSQLQueryString,GetComparisonOperator(aFlag)); sl@0: aSql.AppendFormat(KSQLQueryConditionString,&dbValue); sl@0: sl@0: CleanupStack::PopAndDestroy(&dbValue); sl@0: } sl@0: else sl@0: { sl@0: aSql.Append(KSQLQueryNull); sl@0: } sl@0: } sl@0: } sl@0: sl@0: sl@0: void CDecisionDb::DoubleSingleQuotesL(const TDesC& aSource, RBuf& aDestination) sl@0: /** sl@0: Copies a source descriptor into a destination descriptor. If a single quote sl@0: character is found an extra single quote is copied to the destination. sl@0: Because, it is not possible to search for a string in SQL with single quote ('). sl@0: sl@0: @param aSource A source descriptor. sl@0: @param aDestination A destination descriptor. sl@0: */ sl@0: { sl@0: _LIT(KSingleQuote,"'"); sl@0: sl@0: aDestination.Close(); sl@0: sl@0: if(aSource.FindF(KSingleQuote) > KErrNotFound) sl@0: { sl@0: const TUint16 KSingleQuoteHex = 0x27; sl@0: TInt len = aSource.Length(); sl@0: sl@0: //Define a temporary buffer and set its maximum size to twice of the original (if it contained all quotes!) sl@0: RBuf temp; sl@0: temp.CreateL(len*2); sl@0: CleanupClosePushL(temp); sl@0: sl@0: const TUint16 *ptrSrc = aSource.Ptr(); sl@0: TUint16 *ptrDes = (TUint16 *)temp.Ptr(); sl@0: TInt srcIndex=0; sl@0: TInt desIndex=0; sl@0: sl@0: for(srcIndex=0; srcIndexiDbView.Prepare(iDatabase,TDbQuery(sqlStatement),TDbWindow::EUnlimited)); sl@0: sl@0: dbView->iColSet = dbView->iDbView.ColSetL(); sl@0: sl@0: CleanupStack::Pop(dbView); sl@0: CleanupStack::PopAndDestroy(&sqlStatement); //sqlStatement sl@0: sl@0: return dbView; sl@0: } sl@0: