diff -r 000000000000 -r 08ec8eefde2f persistentstorage/dbms/pcdbms/usql/UQ_LIT.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/dbms/pcdbms/usql/UQ_LIT.CPP Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,285 @@ +// Copyright (c) 1998-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: +// SQL Literal value and node classes +// +// + +#include "UQ_STD.H" + +// internalising literal strings, overload selectors + +inline HBufC8* Alloc8L(const TDesC8& aDes) + {return aDes.AllocL();} +inline HBufC8* Alloc8L(const TDesC16& aDes) + {HBufC8* cell=HBufC8::NewL(aDes.Length());cell->Des().Copy(aDes);return cell;} +inline HBufC16* Alloc16L(const TDesC16& aDes) + {return aDes.AllocL();} +inline HBufC16* Alloc16L(const TDesC8& aDes) + {HBufC16* cell=HBufC16::NewL(aDes.Length());cell->Des().Copy(aDes);return cell;} + +template +inline B* DoInternString(B* aBuf,T*) + { + const T* base=aBuf->Ptr(); + const T* from=base; + const T* end=base+aBuf->Length(); + for (;;) + { + if (from==end) + return aBuf; + if (*from++=='\'') + break; + } + T* to=(T*)from; + ++from; + while (fromDes().SetLength(to-base); + return aBuf; + } + +template +inline B* InternString(B* aBuf) + {return DoInternString(aBuf,PtrType(*aBuf));} + +// Class RSqlLiteral + +void RSqlLiteral::Close() +// +// Free any allocated cell +// + { + if(iBuffer) + delete iBuffer; + if (IsAlloc()) + User::Free(iVal.iAlloc); + + } + +void RSqlLiteral::ToInt32L() +// +// Convert a numeric type to Int32 +// + { + ToInt64L(); + const TInt64& v=iVal.iInt64; + TInt32 l = I64LOW(v); + TInt32 h = I64HIGH(v); + if (h==(l>>31)) // domain check, in signed 32-bit range + { + iVal.iInt32=l; + iType=EInt32; + } + else + __LEAVE(KErrOverflow); // cannot convert + } + +void RSqlLiteral::ToUint32L() +// +// Convert a numeric type to Uint32 +// + { + ToInt64L(); + const TInt64& v=iVal.iInt64; + if (I64HIGH(v)==0) // domain check, in unsigned 32-bit range + { + iVal.iUint32 = I64LOW(v); + iType=EUint32; + } + else + __LEAVE(KErrOverflow); // cannot convert + } + +void RSqlLiteral::ToInt64L() +// +// Convert a numeric type to int64 +// + { + __ASSERT(IsBasic()); // only apply conversions once + TType t=iType; + if (t==EReal64) + { + iVal.iInt64() = static_cast(Real64()); + iType=EInt64; + } + else if (t!=EInt64) + __LEAVE(KErrGeneral); + } + +void RSqlLiteral::ToReal64L() +// +// Convert a numeric type to real64 +// + { + __ASSERT(IsBasic()); // only apply conversions once + TType t=iType; + if (t==EInt64) + { + iVal.iReal64=I64REAL(Int64()); + iType=EReal64; + } + else if (t!=EReal64) + __LEAVE(KErrGeneral); + } + +void RSqlLiteral::ToReal32L() +// +// Convert a numeric type to real32 +// + { + ToReal64L(); + __LEAVE_IF_ERROR(TRealX(iVal.iReal64).GetTReal(iVal.iReal32)); + iType=EReal32; + } + +void RSqlLiteral::ToTimeL() +// +// Ensure we are a time +// + { + __ASSERT(IsBasic()); // only apply conversions once + if (iType!=ETime) + __LEAVE(KErrGeneral); // type mismatch + } + +void RSqlLiteral::ToText8L() +// +// Convert a ptr to a text8 +// + { + __ASSERT(IsBasic()); // only apply conversions once + if (iType==EPtr) + { + iVal.iAlloc=InternString(Alloc8L(DesC())); + iType=EBuf8; + } + else + __LEAVE(KErrGeneral); // type mismatch + } + +void RSqlLiteral::ToText16L() +// +// Convert a ptr to a text8 +// + { + __ASSERT(IsBasic()); // only apply conversions once + if (iType==EPtr) + { + iVal.iAlloc=InternString(Alloc16L(DesC())); + iType=EBuf16; + } + else + __LEAVE(KErrGeneral); // type mismatch + } + +void RSqlLiteral::ToBlobL() +// +// Convert a hex encoded ptr to a blob +// + { + __ASSERT(IsBasic()); // only apply conversions once + if (iType==EBlob) + { + RBuf8 blobBuf; + HBufC* buf = Alloc16L(DesC()); + CleanupStack::PushL(buf); + HexDecodeL(*buf, blobBuf); + CleanupStack::PopAndDestroy(buf); + iVal.iAlloc=Alloc8L(blobBuf); + blobBuf.Close(); + iType=EBlob; + } + else + __LEAVE(KErrGeneral); // type mismatch + } + + + +// class CSqlLiteralNode + +CSqlLiteralNode::CSqlLiteralNode(TType aType,const TDesC& aColumn,const RSqlLiteral& aLiteral) + :CSqlBoundNode(aType,aColumn),iLiteral(aLiteral) + {} + +CSqlLiteralNode::~CSqlLiteralNode() + { + iLiteral.Close(); + } + +void CSqlLiteralNode::BindL(const RDbTableRow& aSource) + { + CSqlBoundNode::BindL(aSource); + switch (ColType()) + { + default: // type not allowed in evaluation expressions + __LEAVE(KErrGeneral); + break; + case EDbColBit: + case EDbColInt8: + case EDbColUint8: + case EDbColInt16: + case EDbColUint16: + case EDbColInt32: + case EDbColUint32: + case EDbColInt64: + iLiteral.ToInt64L(); + break; + case EDbColReal32: + case EDbColReal64: + iLiteral.ToReal64L(); + break; + case EDbColDateTime: + iLiteral.ToTimeL(); + break; + case EDbColText8: + case EDbColLongText8: + iLiteral.ToText8L(); + break; + case EDbColText16: + case EDbColLongText16: + iLiteral.ToText16L(); + break; + case EDbColBinary: + case EDbColLongBinary: + iLiteral.ToBlobL(); + break; + } + } +// copy text to buffer for LIKE Escape support +TInt RSqlLiteral::CopyText() + { + if (iType==EPtr) + { + TInt length = iVal.iPtr.iEnd - iVal.iPtr.iPtr; + if(iBuffer) + delete iBuffer; + if((iBuffer=HBufC::New(length+1)) == NULL) + { + return KErrNoMemory; + } + iBuffer->Des().Copy(iVal.iPtr.iPtr,length); + iVal.iPtr.iPtr= &iBuffer->Des()[0]; + iBuffer->Des().Append(iVal.iPtr.iEnd,1); + iVal.iPtr.iEnd=&iBuffer->Des()[length]; + } + else + return KErrGeneral; // type mismatch + return KErrNone; + } +