persistentstorage/sql/SRC/Server/SqlSrvStatement.h
changeset 0 08ec8eefde2f
child 13 211563e4b919
child 17 55f2396f6d25
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 __SQLSRVSTATEMENT_H__
       
    17 #define __SQLSRVSTATEMENT_H__
       
    18 
       
    19 #include <e32base.h>
       
    20 #include <s32mem.h>					//TBufBuf
       
    21 #include "SqlUtil.h"				//Sql2OsErrCode()
       
    22 #include "SqlBufFlat.h"				//RSqlBufFlat
       
    23 #include "SqlSrvStatementUtil.h"	//Global SQL statement related functions
       
    24 
       
    25 //Forward declarations
       
    26 struct sqlite3;
       
    27 struct sqlite3_stmt;
       
    28 class RWriteStream;
       
    29 class CSqlSrvStatement;
       
    30 
       
    31 /////////////////////////////////////////////////////////////////////////////////////////////////////////
       
    32 //////////////////////                HSqlSrvStmtParamBuf              //////////////////////////////////
       
    33 /////////////////////////////////////////////////////////////////////////////////////////////////////////
       
    34 
       
    35 /**
       
    36 Buffer for storing binary/text parameter values (an input from client side write stream objects or bound text/binary parameters).
       
    37 Every CSqlSrvStatement object maintains a collection of HSqlSrvStmtParamBuf objects.
       
    38 
       
    39 Please, note that:
       
    40 
       
    41  - The life-time of the HSqlSrvStmtParamBuf objects is controlled by a set of flags:
       
    42 	 = iStatementFinalized - False by default, set to true if the bound statement has been finalized.
       
    43 	                         When DoRelease() is called, the method checks this poreperty and if the statement has been finalized,
       
    44 	                         then obviously no more parameter binding operations can be performed and it is safe to destroy the 
       
    45 	                         current HSqlSrvStmtParamBuf object. Otherwise the HSqlSrvStmtParamBuf object won't be destroyed, 
       
    46 	                         it will be marked as "dead" - see the "iAlive" property;
       
    47 	 = iAlive			   - True by default, set to false by the DoRelease() call, if the object cannot be destroyed because 
       
    48 	 					     the bound statement is not finalized yet;
       
    49 	 = iBufType		       - EBufIpcStream if the current HSqlSrvStmtParamBuf object is an IPC stream buffer, EBufSimpleBind 
       
    50 	 						 if the  object holds a parameter value, that has been bound not using an IPC stream. This property 
       
    51 	 						 is checked when the bound statement gets finalized - inside the NotifyStatementFinalized() function. 
       
    52 	 						 If the current object is not an IPC stream buffer, then it is safe to destroy the object because
       
    53 	 						 the bound statement is finalized;
       
    54    
       
    55    All these checks allow keeping the buffer object alive when it is needed and code like the code bellow should work without problems:
       
    56 @code
       
    57 	RSqlStatement stmt;			//Prepare a statement with a binary/text parameter
       
    58 	....
       
    59 	RSqlParamWriteStream strm;
       
    60 	strm.BindBinary(stmt,...);	//Use a stream object to bind the parameter value
       
    61 	strm.WriteL(...);
       
    62 	strm.CommitL();				//The stream commit call will bind the streamed parameter value to the statement
       
    63 	strm.Close();				//The stream close operation should not destroy the HSqlSrvStmtParamBuf object, because the parameter
       
    64 								//value is kept in the buffer, and when that value was bound to the statement, the
       
    65 								//SQLITE_STATIC constant was used, which means - SQLite won't make a copy of the parameter value,
       
    66 								//SQLite will keep a pointer to the parameter value and use it for the Exec() operation.
       
    67 	stmt.Exec();				//At this point the SQLite library should be able to get the parameter data and use it.
       
    68 @endcode
       
    69 
       
    70  - Another reason for keeping the HSqlSrvStmtParamBuf object alive during the life-time of the CSqlSrvStatement object is that
       
    71    the RSqlStatement::Reset() call should not destroy the buffer. The client should be able to resuse
       
    72    the buffered parameter data for the next RSqlStatement::Exec() call. For example:
       
    73 @code
       
    74 	RSqlStatement stmt;			//Prepare a statement with two  binary parameters
       
    75 	....
       
    76 	RSqlParamWriteStream strm1, strm2;
       
    77 	
       
    78 	strm1.BindBinary(stmt,...);	//Use a stream object to bind the 1st parameter value
       
    79 	strm1.WriteL(...);
       
    80 	strm1.CommitL();			
       
    81 	strm1.Close();				
       
    82 	
       
    83 	strm2.BindBinary(stmt,...);	//Use a stream object to bind the 2nd parameter value
       
    84 	strm2.WriteL(...);
       
    85 	strm2.CommitL();			
       
    86 	strm2.Close();				
       
    87 	
       
    88 	stmt.Exec();				//Do the operation using the bound parameter values
       
    89 	stmt.Reset();				//This call should not destroy the HSqlSrvStmtParamBuf objects that keep the parameter values
       
    90 
       
    91 	strm2.BindBinary(stmt,...);	//Use a stream object to bind the 2nd parameter value
       
    92 	strm2.WriteL(...);
       
    93 	strm2.CommitL();			
       
    94 	strm2.Close();				
       
    95 
       
    96 	stmt.Exec();				//Do the operation using the bound parameter values. 
       
    97 								//The operation should be able to use the old 1st parameter value without any problems,
       
    98 								//and also the new 2nd parameter value.
       
    99 @endcode
       
   100 								
       
   101  - The HSqlSrvStmtParamBuf object can be synch-ed just once. The reason for that is to prevent the double commit-s, 
       
   102    that will occur as a result of MStreamBuf::Close() calls on the client side, where the Close() method will try to sync the buffer.
       
   103    The single sync will prevent the SQL server from crashing, if the order of the RSqlStatement::Close() and
       
   104    RSqlParamWriteStream::Close() calls is reversed, e.g.:
       
   105 @code
       
   106 	RSqlStatement stmt;		
       
   107 	....
       
   108 	RSqlParamWriteStream strm;
       
   109 	strm.BindBinary(stmt,...);
       
   110 	strm.WriteL(...);
       
   111 	strm.CommitL();		
       
   112 	stmt.Exec();
       
   113 	stmt.Close();
       
   114 	strm.Close();		
       
   115 @endcode
       
   116    
       
   117  - For BC reasons, even though the HSqlSrvStmtParamBuf object can be synch-ed just once (the operation is controlled by the iSynchDone
       
   118    flag), the client side still will be able to update the buffer content, because the related HIpcStream stream object keeps a copy
       
   119    of the buffer's base address. Since the parameter is bound using the SQLITE_STATIC constant (SQLite won't make a copy of the 
       
   120    parameter value), at the moment of the Exec() call, SQLite will use the give pointer to the parameter value and will pick up
       
   121    the updated buffer even without a commit call;
       
   122  								
       
   123 @endcode
       
   124  
       
   125  - The iSynchDone flag controls the number of buffer commit operations. It is false by default, 
       
   126    set to true by the DoSynchL() call. The HSqlSrvStmtParamBuf object can be synch-ed just once, because DoSynchL() 
       
   127    calls sqlite3_bind_text/binary() and the expectation is that the whole buffer with the parameter data is ready for binding;
       
   128    If the buffer is not commited by calling DoSynchL(), the buffer still will be commited by the DoSynchL() call performed from
       
   129    MStreamBuf::Close(). But in a case of a sync failure, no error will be reported to the client side;
       
   130  
       
   131 @see HIpcStream 
       
   132 @see CSqlSrvStatement
       
   133  
       
   134 @internalComponent
       
   135 */
       
   136 NONSHARABLE_CLASS(HSqlSrvStmtParamBuf) : public TBufBuf
       
   137 	{
       
   138 public:
       
   139 	enum TDataType {EBinary, EText16};
       
   140 	enum TBufType {EBufSimpleBind, EBufIpcStream};
       
   141 	
       
   142 	static inline HSqlSrvStmtParamBuf* NewL(CSqlSrvStatement& aStatement, TInt aParamIndex, HSqlSrvStmtParamBuf::TDataType aDataType, 
       
   143 										    HSqlSrvStmtParamBuf::TBufType aBufType);
       
   144 	inline void Reset(HSqlSrvStmtParamBuf::TDataType aDataType, HSqlSrvStmtParamBuf::TBufType aBufType);
       
   145 	
       
   146 	inline const TPtrC8 SetDataL(const TDesC8& aData);
       
   147 	inline const TPtrC8 Data() const;
       
   148 	inline HSqlSrvStmtParamBuf::TDataType DataType() const;
       
   149 	
       
   150 	void NotifyStatementFinalized();
       
   151 	inline TInt ParamIndex() const;
       
   152 	
       
   153 private:
       
   154 	inline HSqlSrvStmtParamBuf(CSqlSrvStatement& aStatement, TInt aParamIndex, HSqlSrvStmtParamBuf::TDataType aDataType, 
       
   155 							   HSqlSrvStmtParamBuf::TBufType aBufType);
       
   156 	virtual ~HSqlSrvStmtParamBuf();
       
   157 	inline void ConstructL();
       
   158 	virtual void DoSynchL();
       
   159 	virtual void DoRelease();
       
   160 	
       
   161 private:
       
   162 	enum {EExpandSize = 512};
       
   163 	
       
   164 	CSqlSrvStatement&	iStatement;			//The bound CSqlSrvStatement object
       
   165 	CBufFlat* 			iBuf;				//Parameter buffer - not owned by HSqlSrvStmtParamBuf
       
   166 	TInt 				iParamIndex;		//The parameter index
       
   167 	TBool				iStatementFinalized;//True if the bound statement object has been finalized
       
   168 	TBool				iAlive;				//True if DoRelease() has not been called yet
       
   169 	HSqlSrvStmtParamBuf::TDataType iDataType;//The parameter type
       
   170 	HSqlSrvStmtParamBuf::TBufType iBufType;	//IPC stream buf or a simple "bind param" buf
       
   171 	TBool				iSynchDone;			//True if the buffer data has been bound to the statement
       
   172 	};
       
   173 
       
   174 /////////////////////////////////////////////////////////////////////////////////////////////////////////
       
   175 //////////////////                CSqlSrvStatement                	   //////////////////////////////////
       
   176 /////////////////////////////////////////////////////////////////////////////////////////////////////////
       
   177 
       
   178 /**
       
   179 SQL statement handle.
       
   180 
       
   181 CSqlSrvStatement is a server side class which processes the client side requests for:
       
   182  - preparing 16-bit and 8-bit SQL statements;
       
   183  - executing prepared SQL statement;
       
   184  - retrieving parameter names and column names;
       
   185  - binding SQL parameters;
       
   186  - retrieving column values;
       
   187  - reseting the prepared SQL statement;
       
   188  - moving the cursor to the next record;
       
   189 
       
   190 @see CSqlSrvStatement::NewLC()
       
   191 @see CSqlSrvStatement::NewLC()
       
   192 @see CSqlSrvStatement::BindL()
       
   193 @see CSqlSrvStatement::Next()
       
   194 @see CSqlSrvStatement::Reset()
       
   195 @see CSqlSrvStatement::Exec()
       
   196 @see CSqlSrvStatement::ColumnNamesL()
       
   197 @see CSqlSrvStatement::ParamNamesL()
       
   198 @see CSqlSrvStatement::ColumnValuesL()
       
   199 @see CSqlSrvStatement::ColumnSource()
       
   200 
       
   201 @see HSqlSrvStmtParamBuf
       
   202 
       
   203 @internalComponent
       
   204 */
       
   205 NONSHARABLE_CLASS(CSqlSrvStatement) : public CBase
       
   206 	{
       
   207 public:
       
   208 	static CSqlSrvStatement* NewLC(sqlite3* aDbHandle, const TDesC16& aSqlStmt, TInt& aColumnCount, TInt& aParamCount);
       
   209 	static CSqlSrvStatement* NewLC(sqlite3* aDbHandle, const TDesC8& aSqlStmt, TInt& aColumnCount, TInt& aParamCount);
       
   210 	virtual ~CSqlSrvStatement();
       
   211 
       
   212 	void BindL(const RSqlBufFlat& aParamBuf);	
       
   213 	inline TInt Next();
       
   214 	inline TInt Reset();
       
   215 	inline TInt Exec();
       
   216 	
       
   217 	inline const RSqlBufFlat& BufFlatL(TSqlBufFlatType aWhat) const;
       
   218 	const RSqlBufFlat& ColumnNamesL();
       
   219 	const RSqlBufFlat& ParamNamesL();
       
   220 	const RSqlBufFlat& ColumnValuesL();
       
   221 	TInt ColumnSource(TInt aColumnIndex, TPtrC8& aColumnSource) const;
       
   222 	
       
   223 	TInt ColumnInt(TInt aColIdx) const;
       
   224 	TInt64 ColumnInt64(TInt aColIdx) const;
       
   225 	TReal ColumnReal(TInt aColIdx) const;
       
   226 	TPtrC ColumnText(TInt aColIdx) const;
       
   227 	TPtrC8 ColumnBinary(TInt aColIdx) const;
       
   228 	
       
   229 	HBufC* GetDeclColumnTypesL();
       
   230 	
       
   231 	HSqlSrvStmtParamBuf* GetParamBufL(TInt aParamIndex, HSqlSrvStmtParamBuf::TDataType aDataType, HSqlSrvStmtParamBuf::TBufType aBufType);
       
   232 	void BindParamBufL(TInt aParamIndex);
       
   233 		
       
   234 private:
       
   235 	inline CSqlSrvStatement();
       
   236 	inline void ConstructL(sqlite3* aDbHandle, const TDesC16& aSqlStmt);
       
   237 	inline void ConstructL(sqlite3* aDbHandle, const TDesC8& aSqlStmt);
       
   238 	void DoCommonConstructL();
       
   239 	void DestroyParamBufArray();
       
   240 	void ExtendParamBufArrayL(TInt aParamIndex);
       
   241 	TPtrC8 CopyAndStoreParamL(TInt aParamIndex, HSqlSrvStmtParamBuf::TDataType aDataType, const TDesC8& aParamValue);
       
   242 
       
   243 private:
       
   244 	sqlite3_stmt*		iStmtHandle;		//SQL statement handle
       
   245 	TInt 				iColumnCount;		
       
   246 	TInt 				iParamCount;		
       
   247 	TSqlBufFlatType		iBufFlatType;		//What is in iFlatBuf data member
       
   248 	RSqlBufFlat  		iBufFlat;			//Flat buffer used for: column names, parameter names, column values
       
   249 	RArray<HSqlSrvStmtParamBuf*> iParamBufArray;//An array with pointers to HSqlSrvStmtParamBuf buffers for the text/binary parameters
       
   250 
       
   251 	};
       
   252 
       
   253 #include "SqlSrvStatement.inl"
       
   254 
       
   255 #endif//__SQLSRVSTATEMENT_H__