persistentstorage/sql/SRC/Client/SqlStatementImpl.h
changeset 0 08ec8eefde2f
child 11 211563e4b919
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2005-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 //
       
    15 
       
    16 #ifndef __SQLSTATEMENTIMPL_H__
       
    17 #define __SQLSTATEMENTIMPL_H__
       
    18 
       
    19 #include "SqlBufIterator.h"	//TSqlBufFlat, TSqlBufRIterator, TSqlBufWIterator
       
    20 #include "SqlDatabaseImpl.h"//CSqlDatabaseImpl
       
    21 #include "SqlStmtSession.h"	//RSqlStatementSession
       
    22 
       
    23 //Forward declarations
       
    24 class MStreamBuf;
       
    25 class CSqlStatementImpl;
       
    26 
       
    27 #ifdef _DEBUG
       
    28 #define LONGCOL_INVARIANT()	Invariant()
       
    29 #else
       
    30 #define LONGCOL_INVARIANT()
       
    31 #endif
       
    32 
       
    33 /**
       
    34 RSqlLongColumnColl class represents a collection of long text/binary column values.
       
    35 Once a column value is added to the collection, it is guaranteed that the memory address of the 
       
    36 column value will never change.
       
    37 The class was designed to solve one specific problem - to exclude the possibility that SQL clients
       
    38 may get a dangling pointer to a block of memory which already has been deleted.
       
    39 Without RSqlLongColumnColl class, it may happen for example, when client prepares a SELECT sql
       
    40 statement, where the record consists of two long binary/text column values.
       
    41 The client calls RSqlStatement::Next() to move to a record. Since the column values are long, they will
       
    42 not be transferred on the client side by the Next() call, so the client side row buffer (CSqlStatementImpl::iColumnValueBuf)
       
    43 will mark them as "not present". 
       
    44 Then the client calls RSqlStatement::ColumnBinary(0, TPtrC8&) to get a pointer to the first column value.
       
    45 The row buffer is reallocated, and the column value is retrieved from the server and copied into the buffer, the client's pointer
       
    46 is set to point to the place in the row buffer, where the column value is.
       
    47 While keeping the pointer to the first column value, the client calls again RSqlStatement::ColumnBinary(1, TPtrC8&) to retrieve
       
    48 the second column value. In which case, the row buffer may get reallocated again, so the first pointer will point to a 
       
    49 block of memory, which has been deleted.
       
    50 With the implementation and use of RSqlLongColumnColl class, the long column values will be kept in a different place,
       
    51 RSqlLongColumnColl's collection, where it is guaranteed that the memory address of the column value is constant.
       
    52 
       
    53 @internalComponent
       
    54 */
       
    55 NONSHARABLE_CLASS(RSqlLongColumnColl)
       
    56 	{
       
    57 public:	
       
    58 	struct TColumnReader
       
    59 		{
       
    60 		virtual TInt Read(TInt aColumnIndex, TDes8& aBuf) = 0;
       
    61 		};
       
    62 		
       
    63 public:	
       
    64 	inline RSqlLongColumnColl();
       
    65 	inline void Close();
       
    66 	inline void Reset();
       
    67 	TInt Append(TColumnReader& aReader, TInt aColumnIndex, TInt aColumnSize);
       
    68 	inline TPtrC Text(TInt aColumnIndex) const;
       
    69 	inline TPtrC8 Binary(TInt aColumnIndex) const;
       
    70 	inline TBool IsPresent(TInt aColumnIndex) const;
       
    71 
       
    72 private:
       
    73 	inline TInt FindValue(TInt aColumnIndex) const;
       
    74 #ifdef _DEBUG
       
    75 	void Invariant() const;	
       
    76 #endif
       
    77 	
       
    78 private:
       
    79 	struct TData
       
    80 		{
       
    81 		static TBool Compare(const TInt* aIndex, const TData& aData);
       
    82 		inline TData(TInt aIndex, HBufC8* aData);
       
    83 		TInt	iIndex;
       
    84 		HBufC8*	iData;
       
    85 		};
       
    86 	enum {KLongColumnCollGranularity = 8};
       
    87 	RArray<TData>	iValues;
       
    88 	
       
    89 	};
       
    90 
       
    91 template <class DES> TInt SqlCreateStatement(CSqlStatementImpl*& aImpl, CSqlDatabaseImpl& aDatabase, const DES& aSqlStmt);
       
    92 
       
    93 /**
       
    94 CSqlStatementImpl implements RSqlStatement functionality.
       
    95 CSqlStatementImpl can prepare and execute parametrized SQL statements and SQL statements without parameters.
       
    96 CSqlStatementImpl cannot prepare and execute SQL strings containing more than one SQL statement.
       
    97 @internalComponent
       
    98 */
       
    99 NONSHARABLE_CLASS(CSqlStatementImpl) : public CBase
       
   100 	{
       
   101 	template <class DES> friend TInt SqlCreateStatement(CSqlStatementImpl*& aImpl, CSqlDatabaseImpl& aDatabase, const DES& aSqlStmt);
       
   102 	
       
   103 public:
       
   104 	static inline TInt New(CSqlStatementImpl*& aImpl, CSqlDatabaseImpl& aDatabase, const TDesC16& aSqlStmt);
       
   105 	static inline TInt New(CSqlStatementImpl*& aImpl, CSqlDatabaseImpl& aDatabase, const TDesC8& aSqlStmt);
       
   106 	virtual ~CSqlStatementImpl();
       
   107 	
       
   108 	inline TBool AtRow() const;
       
   109 	
       
   110 	TInt Reset();
       
   111 	TInt Exec();
       
   112 	void Exec(TRequestStatus& aStatus);
       
   113 	TInt Next();
       
   114 	
       
   115 	TInt BindNull(TInt aParamIndex);
       
   116 	TInt BindInt(TInt aParamIndex, TInt aParamValue);
       
   117 	TInt BindInt64(TInt aParamIndex, TInt64 aParamValue);
       
   118 	TInt BindReal(TInt aParamIndex, TReal aParamValue);
       
   119 	TInt BindText(TInt aParamIndex, const TDesC& aParamText);
       
   120 	TInt BindBinary(TInt aParamIndex, const TDesC8& aParamData);
       
   121 	TInt BindZeroBlob(TInt aParamIndex, TInt aBlobSize);
       
   122 
       
   123 	inline TInt ColumnCount() const;
       
   124 	TSqlColumnType ColumnType(TInt aColumnIndex);
       
   125 	TInt DeclaredColumnType(TInt aColumnIndex, TSqlColumnType& aColumnType);
       
   126 	TInt ColumnSize(TInt aColumnIndex);
       
   127 	TInt ColumnInt(TInt aColumnIndex);
       
   128 	TInt64 ColumnInt64(TInt aColumnIndex);
       
   129 	TReal ColumnReal(TInt aColumnIndex);
       
   130 	TInt ColumnText(TInt aColumnIndex, TPtrC& aPtr);
       
   131 	TInt ColumnText(TInt aColumnIndex, TDes& aDest);
       
   132 	TInt ColumnBinary(TInt aColumnIndex, TPtrC8& aPtr);
       
   133 	TInt ColumnBinary(TInt aColumnIndex, TDes8& aDest);
       
   134 
       
   135 	TInt ColumnName(TInt aColumnIndex, TPtrC& aNameDest);
       
   136 	TInt ParameterName(TInt aParamIndex, TPtrC& aNameDest);
       
   137 
       
   138 	inline TInt ParamIndex(const TDesC& aParamName);
       
   139 	inline TInt ColumnIndex(const TDesC& aColumnName);
       
   140 		
       
   141 	inline MStreamBuf* ColumnSourceL(TInt aColumnIndex);
       
   142 	inline MStreamBuf* ParamSinkL(TSqlSrvFunction aFunction, TInt aParamIndex);
       
   143 
       
   144 	HBufC* GetDeclColumnTypesL();
       
   145 
       
   146 private:
       
   147 	inline CSqlStatementImpl();
       
   148 	template <class DES> TInt Construct(CSqlDatabaseImpl& aDatabase, const DES& aSqlStmt);
       
   149 	TInt Name2Index(const TDesC& aName, RSqlBufFlat& aNameBufFlat, TInt aCount, TSqlSrvFunction aFunction, TBool& aPresent);
       
   150 	TInt Index2Name(TInt aIndex, RSqlBufFlat& aNameBufFlat, TInt aCount, TSqlSrvFunction aFunction, TBool& aPresent, TPtrC& aColName);
       
   151 	TInt CheckNameBufPresent(TBool& aPresent, RSqlBufFlat& aNameBufFlat, TInt aCount, TSqlSrvFunction aFunction);
       
   152 	
       
   153 private:
       
   154 	RSqlStatementSession	iSqlStmtSession;
       
   155 	TBool					iBound;
       
   156 	enum TState				{EUnknown, EAtRow};
       
   157 	TState					iState;
       
   158 	
       
   159 	TInt 					iColumnCnt;
       
   160 	TBool					iColumnNameBufPresent;
       
   161 	RSqlBufFlat				iColumnNameBuf;
       
   162 	RSqlBufFlat				iColumnValueBuf;
       
   163 	TSqlBufRIterator		iColumnValBufIt;
       
   164 	
       
   165 	TInt 					iParamCnt;
       
   166 	TBool					iParamNameBufPresent;
       
   167 	RSqlBufFlat				iParamNameBuf;
       
   168 	RSqlBufFlat				iParamValueBuf;
       
   169 	TSqlBufWIterator		iParamValBufIt;
       
   170 	
       
   171 	RSqlLongColumnColl		iLongColumnColl;
       
   172 	
       
   173 	RArray<TSqlColumnType>	iDeclaredColumnTypes;	//Array of declared column types for current statement.
       
   174 	};
       
   175 
       
   176 #include "SqlStatementImpl.inl"
       
   177 
       
   178 #endif //__SQLSTATEMENTIMPL_H__