1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/dbms/pcdbms/usql/UQ_LIT.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,285 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// SQL Literal value and node classes
1.18 +//
1.19 +//
1.20 +
1.21 +#include "UQ_STD.H"
1.22 +
1.23 +// internalising literal strings, overload selectors
1.24 +
1.25 +inline HBufC8* Alloc8L(const TDesC8& aDes)
1.26 + {return aDes.AllocL();}
1.27 +inline HBufC8* Alloc8L(const TDesC16& aDes)
1.28 + {HBufC8* cell=HBufC8::NewL(aDes.Length());cell->Des().Copy(aDes);return cell;}
1.29 +inline HBufC16* Alloc16L(const TDesC16& aDes)
1.30 + {return aDes.AllocL();}
1.31 +inline HBufC16* Alloc16L(const TDesC8& aDes)
1.32 + {HBufC16* cell=HBufC16::NewL(aDes.Length());cell->Des().Copy(aDes);return cell;}
1.33 +
1.34 +template <class B,class T>
1.35 +inline B* DoInternString(B* aBuf,T*)
1.36 + {
1.37 + const T* base=aBuf->Ptr();
1.38 + const T* from=base;
1.39 + const T* end=base+aBuf->Length();
1.40 + for (;;)
1.41 + {
1.42 + if (from==end)
1.43 + return aBuf;
1.44 + if (*from++=='\'')
1.45 + break;
1.46 + }
1.47 + T* to=(T*)from;
1.48 + ++from;
1.49 + while (from<end)
1.50 + {
1.51 + T c=*from++;
1.52 + if (c=='\'')
1.53 + ++from;
1.54 + *to++=c;
1.55 + }
1.56 + aBuf->Des().SetLength(to-base);
1.57 + return aBuf;
1.58 + }
1.59 +
1.60 +template <class B>
1.61 +inline B* InternString(B* aBuf)
1.62 + {return DoInternString(aBuf,PtrType(*aBuf));}
1.63 +
1.64 +// Class RSqlLiteral
1.65 +
1.66 +void RSqlLiteral::Close()
1.67 +//
1.68 +// Free any allocated cell
1.69 +//
1.70 + {
1.71 + if(iBuffer)
1.72 + delete iBuffer;
1.73 + if (IsAlloc())
1.74 + User::Free(iVal.iAlloc);
1.75 +
1.76 + }
1.77 +
1.78 +void RSqlLiteral::ToInt32L()
1.79 +//
1.80 +// Convert a numeric type to Int32
1.81 +//
1.82 + {
1.83 + ToInt64L();
1.84 + const TInt64& v=iVal.iInt64;
1.85 + TInt32 l = I64LOW(v);
1.86 + TInt32 h = I64HIGH(v);
1.87 + if (h==(l>>31)) // domain check, in signed 32-bit range
1.88 + {
1.89 + iVal.iInt32=l;
1.90 + iType=EInt32;
1.91 + }
1.92 + else
1.93 + __LEAVE(KErrOverflow); // cannot convert
1.94 + }
1.95 +
1.96 +void RSqlLiteral::ToUint32L()
1.97 +//
1.98 +// Convert a numeric type to Uint32
1.99 +//
1.100 + {
1.101 + ToInt64L();
1.102 + const TInt64& v=iVal.iInt64;
1.103 + if (I64HIGH(v)==0) // domain check, in unsigned 32-bit range
1.104 + {
1.105 + iVal.iUint32 = I64LOW(v);
1.106 + iType=EUint32;
1.107 + }
1.108 + else
1.109 + __LEAVE(KErrOverflow); // cannot convert
1.110 + }
1.111 +
1.112 +void RSqlLiteral::ToInt64L()
1.113 +//
1.114 +// Convert a numeric type to int64
1.115 +//
1.116 + {
1.117 + __ASSERT(IsBasic()); // only apply conversions once
1.118 + TType t=iType;
1.119 + if (t==EReal64)
1.120 + {
1.121 + iVal.iInt64() = static_cast<TInt64>(Real64());
1.122 + iType=EInt64;
1.123 + }
1.124 + else if (t!=EInt64)
1.125 + __LEAVE(KErrGeneral);
1.126 + }
1.127 +
1.128 +void RSqlLiteral::ToReal64L()
1.129 +//
1.130 +// Convert a numeric type to real64
1.131 +//
1.132 + {
1.133 + __ASSERT(IsBasic()); // only apply conversions once
1.134 + TType t=iType;
1.135 + if (t==EInt64)
1.136 + {
1.137 + iVal.iReal64=I64REAL(Int64());
1.138 + iType=EReal64;
1.139 + }
1.140 + else if (t!=EReal64)
1.141 + __LEAVE(KErrGeneral);
1.142 + }
1.143 +
1.144 +void RSqlLiteral::ToReal32L()
1.145 +//
1.146 +// Convert a numeric type to real32
1.147 +//
1.148 + {
1.149 + ToReal64L();
1.150 + __LEAVE_IF_ERROR(TRealX(iVal.iReal64).GetTReal(iVal.iReal32));
1.151 + iType=EReal32;
1.152 + }
1.153 +
1.154 +void RSqlLiteral::ToTimeL()
1.155 +//
1.156 +// Ensure we are a time
1.157 +//
1.158 + {
1.159 + __ASSERT(IsBasic()); // only apply conversions once
1.160 + if (iType!=ETime)
1.161 + __LEAVE(KErrGeneral); // type mismatch
1.162 + }
1.163 +
1.164 +void RSqlLiteral::ToText8L()
1.165 +//
1.166 +// Convert a ptr to a text8
1.167 +//
1.168 + {
1.169 + __ASSERT(IsBasic()); // only apply conversions once
1.170 + if (iType==EPtr)
1.171 + {
1.172 + iVal.iAlloc=InternString(Alloc8L(DesC()));
1.173 + iType=EBuf8;
1.174 + }
1.175 + else
1.176 + __LEAVE(KErrGeneral); // type mismatch
1.177 + }
1.178 +
1.179 +void RSqlLiteral::ToText16L()
1.180 +//
1.181 +// Convert a ptr to a text8
1.182 +//
1.183 + {
1.184 + __ASSERT(IsBasic()); // only apply conversions once
1.185 + if (iType==EPtr)
1.186 + {
1.187 + iVal.iAlloc=InternString(Alloc16L(DesC()));
1.188 + iType=EBuf16;
1.189 + }
1.190 + else
1.191 + __LEAVE(KErrGeneral); // type mismatch
1.192 + }
1.193 +
1.194 +void RSqlLiteral::ToBlobL()
1.195 +//
1.196 +// Convert a hex encoded ptr to a blob
1.197 +//
1.198 + {
1.199 + __ASSERT(IsBasic()); // only apply conversions once
1.200 + if (iType==EBlob)
1.201 + {
1.202 + RBuf8 blobBuf;
1.203 + HBufC* buf = Alloc16L(DesC());
1.204 + CleanupStack::PushL(buf);
1.205 + HexDecodeL(*buf, blobBuf);
1.206 + CleanupStack::PopAndDestroy(buf);
1.207 + iVal.iAlloc=Alloc8L(blobBuf);
1.208 + blobBuf.Close();
1.209 + iType=EBlob;
1.210 + }
1.211 + else
1.212 + __LEAVE(KErrGeneral); // type mismatch
1.213 + }
1.214 +
1.215 +
1.216 +
1.217 +// class CSqlLiteralNode
1.218 +
1.219 +CSqlLiteralNode::CSqlLiteralNode(TType aType,const TDesC& aColumn,const RSqlLiteral& aLiteral)
1.220 + :CSqlBoundNode(aType,aColumn),iLiteral(aLiteral)
1.221 + {}
1.222 +
1.223 +CSqlLiteralNode::~CSqlLiteralNode()
1.224 + {
1.225 + iLiteral.Close();
1.226 + }
1.227 +
1.228 +void CSqlLiteralNode::BindL(const RDbTableRow& aSource)
1.229 + {
1.230 + CSqlBoundNode::BindL(aSource);
1.231 + switch (ColType())
1.232 + {
1.233 + default: // type not allowed in evaluation expressions
1.234 + __LEAVE(KErrGeneral);
1.235 + break;
1.236 + case EDbColBit:
1.237 + case EDbColInt8:
1.238 + case EDbColUint8:
1.239 + case EDbColInt16:
1.240 + case EDbColUint16:
1.241 + case EDbColInt32:
1.242 + case EDbColUint32:
1.243 + case EDbColInt64:
1.244 + iLiteral.ToInt64L();
1.245 + break;
1.246 + case EDbColReal32:
1.247 + case EDbColReal64:
1.248 + iLiteral.ToReal64L();
1.249 + break;
1.250 + case EDbColDateTime:
1.251 + iLiteral.ToTimeL();
1.252 + break;
1.253 + case EDbColText8:
1.254 + case EDbColLongText8:
1.255 + iLiteral.ToText8L();
1.256 + break;
1.257 + case EDbColText16:
1.258 + case EDbColLongText16:
1.259 + iLiteral.ToText16L();
1.260 + break;
1.261 + case EDbColBinary:
1.262 + case EDbColLongBinary:
1.263 + iLiteral.ToBlobL();
1.264 + break;
1.265 + }
1.266 + }
1.267 +// copy text to buffer for LIKE Escape support
1.268 +TInt RSqlLiteral::CopyText()
1.269 + {
1.270 + if (iType==EPtr)
1.271 + {
1.272 + TInt length = iVal.iPtr.iEnd - iVal.iPtr.iPtr;
1.273 + if(iBuffer)
1.274 + delete iBuffer;
1.275 + if((iBuffer=HBufC::New(length+1)) == NULL)
1.276 + {
1.277 + return KErrNoMemory;
1.278 + }
1.279 + iBuffer->Des().Copy(iVal.iPtr.iPtr,length);
1.280 + iVal.iPtr.iPtr= &iBuffer->Des()[0];
1.281 + iBuffer->Des().Append(iVal.iPtr.iEnd,1);
1.282 + iVal.iPtr.iEnd=&iBuffer->Des()[length];
1.283 + }
1.284 + else
1.285 + return KErrGeneral; // type mismatch
1.286 + return KErrNone;
1.287 + }
1.288 +