persistentstorage/dbms/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 
       
    76 void RSqlLiteral::ToInt32L()
       
    77 //
       
    78 // Convert a numeric type to Int32
       
    79 //
       
    80 	{
       
    81 	ToInt64L();
       
    82 	const TInt64& v=iVal.iInt64;
       
    83 	TInt32 l = I64LOW(v);
       
    84 	TInt32 h = I64HIGH(v);
       
    85 	if (h==(l>>31))	// domain check, in signed 32-bit range
       
    86 		{
       
    87 		iVal.iInt32=l;
       
    88 		iType=EInt32;
       
    89 		}
       
    90 	else
       
    91 		__LEAVE(KErrOverflow);	// cannot convert
       
    92 	}
       
    93 
       
    94 void RSqlLiteral::ToUint32L()
       
    95 //
       
    96 // Convert a numeric type to Uint32
       
    97 //
       
    98 	{
       
    99 	ToInt64L();
       
   100 	const TInt64& v=iVal.iInt64;
       
   101 	if (I64HIGH(v)==0)		// domain check, in unsigned 32-bit range
       
   102 		{
       
   103 		iVal.iUint32 = I64LOW(v);
       
   104 		iType=EUint32;
       
   105 		}
       
   106 	else
       
   107 		__LEAVE(KErrOverflow);	// cannot convert
       
   108 	}
       
   109 
       
   110 void RSqlLiteral::ToInt64L()
       
   111 //
       
   112 // Convert a numeric type to int64
       
   113 //
       
   114 	{
       
   115 	__ASSERT(IsBasic());	// only apply conversions once
       
   116 	TType t=iType;
       
   117 	if (t==EReal64)
       
   118 		{
       
   119 		iVal.iInt64() = static_cast<TInt64>(Real64());
       
   120 		iType=EInt64;
       
   121 		}
       
   122 	else if (t!=EInt64)
       
   123 		__LEAVE(KErrGeneral);
       
   124 	}
       
   125 
       
   126 void RSqlLiteral::ToReal64L()
       
   127 //
       
   128 // Convert a numeric type to real64
       
   129 //
       
   130 	{
       
   131 	__ASSERT(IsBasic());	// only apply conversions once
       
   132 	TType t=iType;
       
   133 	if (t==EInt64)
       
   134 		{
       
   135 		iVal.iReal64=I64REAL(Int64());
       
   136 		iType=EReal64;
       
   137 		}
       
   138 	else if (t!=EReal64)
       
   139 		__LEAVE(KErrGeneral);
       
   140 	}
       
   141 
       
   142 void RSqlLiteral::ToReal32L()
       
   143 //
       
   144 // Convert a numeric type to real32
       
   145 //
       
   146 	{
       
   147 	ToReal64L();
       
   148 	__LEAVE_IF_ERROR(TRealX(iVal.iReal64).GetTReal(iVal.iReal32));
       
   149 	iType=EReal32;
       
   150 	}
       
   151 
       
   152 void RSqlLiteral::ToTimeL()
       
   153 //
       
   154 // Ensure we are a time
       
   155 //
       
   156 	{
       
   157 	__ASSERT(IsBasic());	// only apply conversions once
       
   158 	if (iType!=ETime)
       
   159 		__LEAVE(KErrGeneral);	// type mismatch
       
   160 	}
       
   161 
       
   162 void RSqlLiteral::ToText8L()
       
   163 //
       
   164 // Convert a ptr to a text8
       
   165 //
       
   166 	{
       
   167 	__ASSERT(IsBasic());	// only apply conversions once
       
   168 	if (iType==EPtr)
       
   169 		{
       
   170 		iVal.iAlloc=InternString(Alloc8L(DesC()));
       
   171 		iType=EBuf8;
       
   172 		}
       
   173 	else
       
   174 		__LEAVE(KErrGeneral);	// type mismatch
       
   175 	}
       
   176 
       
   177 void RSqlLiteral::ToText16L()
       
   178 //
       
   179 // Convert a ptr to a text8
       
   180 //
       
   181 	{
       
   182 	__ASSERT(IsBasic());	// only apply conversions once
       
   183 	if (iType==EPtr)
       
   184 		{
       
   185 		iVal.iAlloc=InternString(Alloc16L(DesC()));
       
   186 		iType=EBuf16;
       
   187 		}
       
   188 	else
       
   189 		__LEAVE(KErrGeneral);	// type mismatch
       
   190 	}
       
   191 
       
   192 
       
   193 
       
   194 // class CSqlLiteralNode
       
   195 
       
   196 CSqlLiteralNode::CSqlLiteralNode(TType aType,const TDesC& aColumn,const RSqlLiteral& aLiteral)
       
   197 	:CSqlBoundNode(aType,aColumn),iLiteral(aLiteral)
       
   198 	{}
       
   199 
       
   200 CSqlLiteralNode::~CSqlLiteralNode()
       
   201 	{
       
   202 	iLiteral.Close();
       
   203 	}
       
   204 
       
   205 void CSqlLiteralNode::BindL(const RDbTableRow& aSource)
       
   206 	{
       
   207 	CSqlBoundNode::BindL(aSource);
       
   208 	switch (ColType())
       
   209 		{
       
   210 	default:	// type not allowed in evaluation expressions
       
   211 		__LEAVE(KErrGeneral);
       
   212 		break;
       
   213 	case EDbColBit:
       
   214 	case EDbColInt8:
       
   215 	case EDbColUint8:
       
   216 	case EDbColInt16:
       
   217 	case EDbColUint16:
       
   218 	case EDbColInt32:
       
   219 	case EDbColUint32:
       
   220 	case EDbColInt64:
       
   221 		iLiteral.ToInt64L();
       
   222 		break;
       
   223 	case EDbColReal32:
       
   224 	case EDbColReal64:
       
   225 		iLiteral.ToReal64L();
       
   226 		break;
       
   227 	case EDbColDateTime:
       
   228 		iLiteral.ToTimeL();
       
   229 		break;
       
   230 	case EDbColText8:
       
   231 	case EDbColLongText8:
       
   232 		iLiteral.ToText8L();
       
   233 		break;
       
   234 	case EDbColText16:
       
   235 	case EDbColLongText16:
       
   236 		iLiteral.ToText16L();
       
   237 		break;
       
   238 		}
       
   239 	}
       
   240 // copy text to buffer for LIKE Escape support
       
   241 TInt RSqlLiteral::CopyText()
       
   242 	{
       
   243 	if (iType==EPtr)
       
   244 		{
       
   245 		TInt length = iVal.iPtr.iEnd - iVal.iPtr.iPtr;
       
   246 		if(iBuffer)
       
   247 			delete iBuffer;
       
   248 		if((iBuffer=HBufC::New(length+1)) == NULL)
       
   249 	        	{
       
   250 			return KErrNoMemory;
       
   251 			}
       
   252 		iBuffer->Des().Copy(iVal.iPtr.iPtr,length);
       
   253 		iVal.iPtr.iPtr= &iBuffer->Des()[0];
       
   254 		iBuffer->Des().Append(iVal.iPtr.iEnd,1);
       
   255 		iVal.iPtr.iEnd=&iBuffer->Des()[length]; 
       
   256 		}
       
   257 	else
       
   258 		return KErrGeneral;	// type mismatch
       
   259 	return KErrNone;
       
   260 	}
       
   261