os/persistentdata/persistentstorage/dbms/pcdbms/usql/UQ_LIT.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // SQL Literal value and node classes
    15 // 
    16 //
    17 
    18 #include "UQ_STD.H"
    19 
    20 // internalising literal strings, overload selectors
    21 
    22 inline HBufC8* Alloc8L(const TDesC8& aDes)
    23 	{return aDes.AllocL();}
    24 inline HBufC8* Alloc8L(const TDesC16& aDes)
    25 	{HBufC8* cell=HBufC8::NewL(aDes.Length());cell->Des().Copy(aDes);return cell;}
    26 inline HBufC16* Alloc16L(const TDesC16& aDes)
    27 	{return aDes.AllocL();}
    28 inline HBufC16* Alloc16L(const TDesC8& aDes)
    29 	{HBufC16* cell=HBufC16::NewL(aDes.Length());cell->Des().Copy(aDes);return cell;}
    30 
    31 template <class B,class T>
    32 inline B* DoInternString(B* aBuf,T*)
    33 	{
    34 	const T* base=aBuf->Ptr();
    35 	const T* from=base;
    36 	const T* end=base+aBuf->Length();
    37 	for (;;)
    38 		{
    39 		if (from==end)
    40 			return aBuf;
    41 		if (*from++=='\'')
    42 			break;
    43 		}
    44 	T* to=(T*)from;
    45 	++from;
    46 	while (from<end)
    47 		{
    48 		T c=*from++;
    49 		if (c=='\'')
    50 			++from;
    51 		*to++=c;
    52 		}
    53 	aBuf->Des().SetLength(to-base);
    54 	return aBuf;
    55 	}
    56 
    57 template <class B>
    58 inline B* InternString(B* aBuf)
    59 	{return DoInternString(aBuf,PtrType(*aBuf));}
    60 
    61 // Class RSqlLiteral
    62 
    63 void RSqlLiteral::Close()
    64 //
    65 // Free any allocated cell
    66 //
    67 	{
    68 	if(iBuffer)
    69 		delete iBuffer;
    70 	if (IsAlloc())
    71 		User::Free(iVal.iAlloc);
    72 		
    73 	}
    74 
    75 void RSqlLiteral::ToInt32L()
    76 //
    77 // Convert a numeric type to Int32
    78 //
    79 	{
    80 	ToInt64L();
    81 	const TInt64& v=iVal.iInt64;
    82 	TInt32 l = I64LOW(v);
    83 	TInt32 h = I64HIGH(v);
    84 	if (h==(l>>31))	// domain check, in signed 32-bit range
    85 		{
    86 		iVal.iInt32=l;
    87 		iType=EInt32;
    88 		}
    89 	else
    90 		__LEAVE(KErrOverflow);	// cannot convert
    91 	}
    92 
    93 void RSqlLiteral::ToUint32L()
    94 //
    95 // Convert a numeric type to Uint32
    96 //
    97 	{
    98 	ToInt64L();
    99 	const TInt64& v=iVal.iInt64;
   100 	if (I64HIGH(v)==0)		// domain check, in unsigned 32-bit range
   101 		{
   102 		iVal.iUint32 = I64LOW(v);
   103 		iType=EUint32;
   104 		}
   105 	else
   106 		__LEAVE(KErrOverflow);	// cannot convert
   107 	}
   108 
   109 void RSqlLiteral::ToInt64L()
   110 //
   111 // Convert a numeric type to int64
   112 //
   113 	{
   114 	__ASSERT(IsBasic());	// only apply conversions once
   115 	TType t=iType;
   116 	if (t==EReal64)
   117 		{
   118 		iVal.iInt64() = static_cast<TInt64>(Real64());
   119 		iType=EInt64;
   120 		}
   121 	else if (t!=EInt64)
   122 		__LEAVE(KErrGeneral);
   123 	}
   124 
   125 void RSqlLiteral::ToReal64L()
   126 //
   127 // Convert a numeric type to real64
   128 //
   129 	{
   130 	__ASSERT(IsBasic());	// only apply conversions once
   131 	TType t=iType;
   132 	if (t==EInt64)
   133 		{
   134 		iVal.iReal64=I64REAL(Int64());
   135 		iType=EReal64;
   136 		}
   137 	else if (t!=EReal64)
   138 		__LEAVE(KErrGeneral);
   139 	}
   140 
   141 void RSqlLiteral::ToReal32L()
   142 //
   143 // Convert a numeric type to real32
   144 //
   145 	{
   146 	ToReal64L();
   147 	__LEAVE_IF_ERROR(TRealX(iVal.iReal64).GetTReal(iVal.iReal32));
   148 	iType=EReal32;
   149 	}
   150 
   151 void RSqlLiteral::ToTimeL()
   152 //
   153 // Ensure we are a time
   154 //
   155 	{
   156 	__ASSERT(IsBasic());	// only apply conversions once
   157 	if (iType!=ETime)
   158 		__LEAVE(KErrGeneral);	// type mismatch
   159 	}
   160 
   161 void RSqlLiteral::ToText8L()
   162 //
   163 // Convert a ptr to a text8
   164 //
   165 	{
   166 	__ASSERT(IsBasic());	// only apply conversions once
   167 	if (iType==EPtr)
   168 		{
   169 		iVal.iAlloc=InternString(Alloc8L(DesC()));
   170 		iType=EBuf8;
   171 		}
   172 	else
   173 		__LEAVE(KErrGeneral);	// type mismatch
   174 	}
   175 
   176 void RSqlLiteral::ToText16L()
   177 //
   178 // Convert a ptr to a text8
   179 //
   180 	{
   181 	__ASSERT(IsBasic());	// only apply conversions once
   182 	if (iType==EPtr)
   183 		{
   184 		iVal.iAlloc=InternString(Alloc16L(DesC()));
   185 		iType=EBuf16;
   186 		}
   187 	else
   188 		__LEAVE(KErrGeneral);	// type mismatch
   189 	}
   190 
   191 void RSqlLiteral::ToBlobL()
   192 //
   193 // Convert a hex encoded ptr to a blob
   194 //
   195 	{
   196 	__ASSERT(IsBasic());	// only apply conversions once
   197 	if (iType==EBlob)
   198 		{
   199 		RBuf8 blobBuf;
   200 		HBufC* buf = Alloc16L(DesC());
   201 		CleanupStack::PushL(buf);
   202 		HexDecodeL(*buf, blobBuf);
   203 		CleanupStack::PopAndDestroy(buf);
   204 		iVal.iAlloc=Alloc8L(blobBuf);
   205 		blobBuf.Close();
   206 		iType=EBlob;
   207 		}
   208 	else
   209 		__LEAVE(KErrGeneral);	// type mismatch
   210 	}
   211 
   212 
   213 
   214 // class CSqlLiteralNode
   215 
   216 CSqlLiteralNode::CSqlLiteralNode(TType aType,const TDesC& aColumn,const RSqlLiteral& aLiteral)
   217 	:CSqlBoundNode(aType,aColumn),iLiteral(aLiteral)
   218 	{}
   219 
   220 CSqlLiteralNode::~CSqlLiteralNode()
   221 	{
   222 	iLiteral.Close();
   223 	}
   224 
   225 void CSqlLiteralNode::BindL(const RDbTableRow& aSource)
   226 	{
   227 	CSqlBoundNode::BindL(aSource);
   228 	switch (ColType())
   229 		{
   230 	default:	// type not allowed in evaluation expressions
   231 		__LEAVE(KErrGeneral);
   232 		break;
   233 	case EDbColBit:
   234 	case EDbColInt8:
   235 	case EDbColUint8:
   236 	case EDbColInt16:
   237 	case EDbColUint16:
   238 	case EDbColInt32:
   239 	case EDbColUint32:
   240 	case EDbColInt64:
   241 		iLiteral.ToInt64L();
   242 		break;
   243 	case EDbColReal32:
   244 	case EDbColReal64:
   245 		iLiteral.ToReal64L();
   246 		break;
   247 	case EDbColDateTime:
   248 		iLiteral.ToTimeL();
   249 		break;
   250 	case EDbColText8:
   251 	case EDbColLongText8:
   252 		iLiteral.ToText8L();
   253 		break;
   254 	case EDbColText16:
   255 	case EDbColLongText16:
   256 		iLiteral.ToText16L();
   257 		break;
   258 	case EDbColBinary:
   259 	case EDbColLongBinary:
   260 		iLiteral.ToBlobL();
   261 		break;
   262 		}
   263 	}
   264 // copy text to buffer for LIKE Escape support
   265 TInt RSqlLiteral::CopyText()
   266 	{
   267 	if (iType==EPtr)
   268 		{
   269 		TInt length = iVal.iPtr.iEnd - iVal.iPtr.iPtr;
   270 		if(iBuffer)
   271 			delete iBuffer;
   272 		if((iBuffer=HBufC::New(length+1)) == NULL)
   273 	        	{
   274 			return KErrNoMemory;
   275 			}
   276 		iBuffer->Des().Copy(iVal.iPtr.iPtr,length);
   277 		iVal.iPtr.iPtr= &iBuffer->Des()[0];
   278 		iBuffer->Des().Append(iVal.iPtr.iEnd,1);
   279 		iVal.iPtr.iEnd=&iBuffer->Des()[length]; 
   280 		}
   281 	else
   282 		return KErrGeneral;	// type mismatch
   283 	return KErrNone;
   284 	}
   285