os/persistentdata/persistentstorage/sql/SRC/Client/SqlStmtSession.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sql/SRC/Client/SqlStmtSession.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,229 @@
     1.4 +// Copyright (c) 2005-2010 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 +// NTT DOCOMO, INC - Fix for Bug 1915 "SQL server panics when using long column type strings"
    1.16 +//
    1.17 +// Description:
    1.18 +//
    1.19 +
    1.20 +#include <s32mem.h>
    1.21 +#include "SqlStmtSession.h"		//RSqlStatementSession
    1.22 +#include "OstTraceDefinitions.h"
    1.23 +#ifdef OST_TRACE_COMPILER_IN_USE
    1.24 +#include "SqlStmtSessionTraces.h"
    1.25 +#endif
    1.26 +#include "SqlTraceDef.h"
    1.27 +
    1.28 +/**
    1.29 + Sends a request to the SQL server to prepare 16-bit aSqlStmt statement.
    1.30 + 
    1.31 + Usage of the IPC call arguments:
    1.32 + Arg 0: [in/out]        data buffer for the column and parameter count.
    1.33 + Arg 1: [out]       statement length in characters
    1.34 + Arg 2: [out]       16-bit statement
    1.35 + 
    1.36 + @param aDbSession A reference to RSqlDbSession instance.
    1.37 + @param aSqlStmt 16-bit SQL statement.
    1.38 + @param aColumnCount Output parameter. Statement column count.
    1.39 + @param aParamCount Output parameter. Statement parameter count.
    1.40 + 
    1.41 + @return KErrNoMemory, an out of memory condition has occured;
    1.42 + KErrArgument, bad argument, for example - the SQL string contains more than one SQL statements.
    1.43 + Note that the function may return some database specific errors categorised as 
    1.44 + ESqlDbError or other system-wide error codes;
    1.45 + KErrNone      The operation has completed successfully. 
    1.46 + 
    1.47 + @panic SqlDb 7 In _DEBUG mode if the statement handle is 0.
    1.48 +*/
    1.49 +TInt RSqlStatementSession::Prepare(RSqlDbSession& aDbSession, const TDesC& aSqlStmt, 
    1.50 +                                          TInt& aColumnCount, TInt& aParamCount)
    1.51 +    {
    1.52 +    iDbSession = &aDbSession;
    1.53 +    TSqlIpcData data;
    1.54 +    TPckg<TSqlIpcData> pckg(data);
    1.55 +    TUint stmtLen = aSqlStmt.Length();
    1.56 +    iHandle = iDbSession->SendReceive(ESqlSrvStmtPrepare16, TIpcArgs(&pckg, stmtLen, &aSqlStmt));
    1.57 +    __ASSERT_DEBUG(iHandle != 0, __SQLPANIC(ESqlPanicInternalError));   
    1.58 +    aColumnCount = static_cast <TInt> (data.iPrm1);
    1.59 +    aParamCount = static_cast <TInt> (data.iPrm2);
    1.60 +    SQL_TRACE_SESSION(OstTraceExt2(TRACE_INTERNALS, RSQLSTATEMENTSESSION_PREPARE16, "0x%X;RSqlStatementSession::Prepare-16;iHandle=%d", (TUint)this, iHandle));
    1.61 +    return iHandle > 0 ? KErrNone : iHandle;
    1.62 +    }
    1.63 +
    1.64 +/**
    1.65 +Sends a request to the SQL server to prepare 8-bit aSqlStmt statement.
    1.66 +
    1.67 +Usage of the IPC call arguments:
    1.68 +Arg 0: [in/out]     data buffer for the column and parameter count.
    1.69 +Arg 1: [out]        statement length in characters
    1.70 +Arg 2: [out]        8-bit statement
    1.71 +
    1.72 +@param aDbSession A reference to RSqlDbSession instance.
    1.73 +@param aSqlStmt 8-bit SQL statement.
    1.74 +@param aColumnCount Output parameter. Statement column count.
    1.75 +@param aParamCount Output parameter. Statement parameter count.
    1.76 +
    1.77 +@return KErrNoMemory, an out of memory condition has occured;
    1.78 +        KErrArgument, bad argument, for example - the SQL string contains more than one SQL statements.
    1.79 +                      Note that the function may return some database specific errors categorised as 
    1.80 +                      ESqlDbError or other system-wide error codes;
    1.81 +        KErrNone      The operation has completed successfully. 
    1.82 +
    1.83 +@panic SqlDb 7 In _DEBUG mode if the statement handle is 0.
    1.84 +*/
    1.85 +TInt RSqlStatementSession::Prepare(RSqlDbSession& aDbSession, const TDesC8& aSqlStmt, 
    1.86 +                                          TInt& aColumnCount, TInt& aParamCount)
    1.87 +    {
    1.88 +    iDbSession = &aDbSession;
    1.89 +    TSqlIpcData data;
    1.90 +    TPckg<TSqlIpcData> pckg(data);
    1.91 +    TUint stmtLen = aSqlStmt.Length();
    1.92 +    iHandle = iDbSession->SendReceive(ESqlSrvStmtPrepare8, TIpcArgs(&pckg, stmtLen, &aSqlStmt));
    1.93 +    __ASSERT_DEBUG(iHandle != 0, __SQLPANIC(ESqlPanicInternalError));
    1.94 +    aColumnCount = static_cast <TInt> (data.iPrm1);
    1.95 +    aParamCount = static_cast <TInt> (data.iPrm2);
    1.96 +    SQL_TRACE_SESSION(OstTraceExt2(TRACE_INTERNALS, RSQLSTATEMENTSESSION_PREPARE8, "0x%X;RSqlStatementSession::Prepare-8;iHandle=%d", (TUint)this, iHandle));
    1.97 +    return iHandle > 0 ? KErrNone : iHandle;
    1.98 +    }
    1.99 +
   1.100 +/**
   1.101 +Sends a request to the server to close the statement handle.
   1.102 +Closes the session object.
   1.103 +*/
   1.104 +void RSqlStatementSession::Close()
   1.105 +	{
   1.106 +	SQL_TRACE_SESSION(OstTraceExt2(TRACE_INTERNALS, RSQLSTATEMENTSESSION_CLOSE, "0x%X;RSqlStatementSession::Close;iHandle=%d", (TUint)this, iHandle));
   1.107 +	if(iDbSession && iHandle > 0)
   1.108 +		{
   1.109 +		(void)iDbSession->SendReceive(::MakeMsgCode(ESqlSrvStmtClose, ESqlSrvStatementHandle, iHandle));
   1.110 +		}
   1.111 +	iDbSession = NULL;
   1.112 +	iHandle = -1;
   1.113 +	}
   1.114 +
   1.115 +/**
   1.116 +Binds the statement parameters and sends a request to the SQL server to move to the next record which satisfies the 
   1.117 +condition of the prepared SQL statement.
   1.118 +If there is a valid next record, the method transfers the column values from the server.
   1.119 +
   1.120 +@param aParamBuf  It references RSqlBufFlat object where the parameter values are stored.
   1.121 +@param aColumnBuf It references RSqlBufFlat object where the column values will be stored.
   1.122 +
   1.123 +@return KSqlAtRow,      the record data is ready for processing by the caller;
   1.124 +        KSqlAtEnd,      there is no more record data;
   1.125 +        KSqlErrBusy,    the database file is locked;
   1.126 +        KErrNoMemory,   an out of memory condition has occurred - the statement
   1.127 +                        will be reset;
   1.128 +        KSqlErrGeneral, a run-time error has occured - this function must not
   1.129 +                        be called again;        
   1.130 +        KSqlErrMisuse,  this function has been called after a previous call
   1.131 +                        returned KSqlAtEnd or KSqlErrGeneral.
   1.132 +        KSqlErrStmtExpired, the SQL statement has expired (if new functions or
   1.133 +                            collating sequences have been registered or if an
   1.134 +                            authorizer function has been added or changed);
   1.135 +*/
   1.136 +TInt RSqlStatementSession::BindNext(const RSqlBufFlat& aParamBuf, RSqlBufFlat& aColumnBuf)
   1.137 +	{
   1.138 +	TPtrC8 prmData(aParamBuf.BufDes());
   1.139 +	TIpcArgs ipcArgs;
   1.140 +	ipcArgs.Set(0, prmData.Length());
   1.141 +	ipcArgs.Set(1, &prmData);
   1.142 +	return DoBindNext(ESqlSrvStmtBindNext, ipcArgs, aColumnBuf);
   1.143 +	}
   1.144 +
   1.145 +/**
   1.146 +Implements RSqlStatementSession::Next() and RSqlStatementSession::BindNext().
   1.147 +Sends a "Next" command to the server combined with optional "Bind" command.
   1.148 +In a single IPC call the statement parameters will be bound and the current row columns - returned.
   1.149 +If the client side flat buffer is not big enough, a second IPC call will be made after reallocating the buffer.
   1.150 +
   1.151 +Usage of the IPC call arguments:
   1.152 +Arg 0: [out]		parameter buffer length in bytes
   1.153 +Arg 1: [out]		parameter buffer
   1.154 +Arg 2: [out]		column buffer length in bytes
   1.155 +Arg 3: [in/out]		column buffer
   1.156 +
   1.157 +@see RSqlStatementSession::Next()
   1.158 +@see RSqlStatementSession::BindNext()
   1.159 +*/
   1.160 +TInt RSqlStatementSession::DoBindNext(TSqlSrvFunction aFunction, TIpcArgs& aIpcArgs, RSqlBufFlat& aColumnBuf)
   1.161 +	{
   1.162 +	aColumnBuf.Reset();
   1.163 +	aIpcArgs.Set(2, aColumnBuf.MaxSize());
   1.164 +	aIpcArgs.Set(3, &aColumnBuf.BufPtr());
   1.165 +	TInt err = DbSession().SendReceive(::MakeMsgCode(aFunction, ESqlSrvStatementHandle, iHandle), aIpcArgs);
   1.166 +	if(err > KSqlClientBufOverflowCode)
   1.167 +		{
   1.168 +		err = Retry(aColumnBuf, err - KSqlClientBufOverflowCode, ESqlColumnValuesBuf);
   1.169 +		if(err == KErrNone)
   1.170 +			{
   1.171 +			err = KSqlAtRow;	
   1.172 +			}
   1.173 +		}
   1.174 +	return err;
   1.175 +	}
   1.176 +
   1.177 +/**
   1.178 +Sends a command to the server for retrieving parameter names or column names.
   1.179 +
   1.180 +Usage of the IPC call arguments:
   1.181 +Arg 0: [out]		buffer length in bytes
   1.182 +Arg 1: [in/out]		buffer
   1.183 +*/	
   1.184 +TInt RSqlStatementSession::GetNames(TSqlSrvFunction aFunction, RSqlBufFlat& aNameBuf)
   1.185 +	{
   1.186 +	aNameBuf.Reset();
   1.187 +	TPtr8& ptr = aNameBuf.BufPtr();
   1.188 +	TInt err = DbSession().SendReceive(::MakeMsgCode(aFunction, ESqlSrvStatementHandle, iHandle), TIpcArgs(ptr.MaxLength(), &ptr));
   1.189 +	if(err > KSqlClientBufOverflowCode)
   1.190 +		{
   1.191 +		err = Retry(aNameBuf, err - KSqlClientBufOverflowCode, aFunction == ESqlSrvStmtColumnNames ? ESqlColumnNamesBuf : ESqlParamNamesBuf);
   1.192 +		}
   1.193 +	return err;
   1.194 +	}
   1.195 +
   1.196 +/**
   1.197 +Sends a command to the server for retrieving specified data (aWhat parameter).
   1.198 +
   1.199 +Usage of the IPC call arguments:
   1.200 +Arg 0: [out]		The type of the data to be retrieved
   1.201 +Arg 1: [in/out]		Data buffer
   1.202 +*/	
   1.203 +TInt RSqlStatementSession::Retry(RSqlBufFlat& aBufFlat, TInt aSize, TSqlBufFlatType aWhat)
   1.204 +	{
   1.205 +	aBufFlat.Reset();
   1.206 +	TInt err = aBufFlat.ReAlloc(aSize);
   1.207 +	if(err == KErrNone)
   1.208 +		{
   1.209 +		TPtr8& ptr = aBufFlat.BufPtr();
   1.210 +		err = DbSession().SendReceive(::MakeMsgCode(ESqlSrvStmtBufFlat, ESqlSrvStatementHandle, iHandle), TIpcArgs(aWhat, &ptr));
   1.211 +		}
   1.212 +	return err;	
   1.213 +	}
   1.214 +
   1.215 +/**
   1.216 +Sends a command to the server for retrieving the declared types of columns
   1.217 +
   1.218 +Usage of the IPC call arguments:
   1.219 +Arg 0: [out]		buffer length in bytes
   1.220 +Arg 1: [in/out]		buffer
   1.221 +*/	 
   1.222 +TInt RSqlStatementSession::GetDeclColumnTypes(RSqlBufFlat& aDeclColumnTypeBuf)
   1.223 +	{
   1.224 +	aDeclColumnTypeBuf.Reset();
   1.225 +	TPtr8& ptr = aDeclColumnTypeBuf.BufPtr();
   1.226 +	TInt err = DbSession().SendReceive(::MakeMsgCode(ESqlSrvStmtDeclColumnTypes, ESqlSrvStatementHandle, iHandle), TIpcArgs(ptr.MaxLength(), &ptr));	
   1.227 +	if(err > KSqlClientBufOverflowCode)
   1.228 +		{
   1.229 +		err = Retry(aDeclColumnTypeBuf, err - KSqlClientBufOverflowCode, ESqlDeclColumnTypesBuf);
   1.230 +		}
   1.231 +	return err;	
   1.232 +	}