persistentstorage/dbms/pcdbms/usql/UQ_LIT.CPP
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     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