diff -r 000000000000 -r 08ec8eefde2f persistentstorage/sql/SRC/Client/SqlStmtSession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/sql/SRC/Client/SqlStmtSession.cpp Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,155 @@ +// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include "SqlStmtSession.h" //RSqlStatementSession + +/** +Sends a request to the server to close the statement handle. +Closes the session object. +*/ +void RSqlStatementSession::Close() + { + if(iDbSession && iHandle > 0) + { + (void)iDbSession->SendReceive(::MakeMsgCode(ESqlSrvStmtClose, ESqlSrvStatementHandle, iHandle)); + } + iDbSession = NULL; + iHandle = -1; + } + +/** +Binds the statement parameters and sends a request to the SQL server to move to the next record which satisfies the +condition of the prepared SQL statement. +If there is a valid next record, the method transfers the column values from the server. + +@param aParamBuf It references RSqlBufFlat object where the parameter values are stored. +@param aColumnBuf It references RSqlBufFlat object where the column values will be stored. + +@return KSqlAtRow, the record data is ready for processing by the caller; + KSqlAtEnd, there is no more record data; + KSqlErrBusy, the database file is locked; + KErrNoMemory, an out of memory condition has occurred - the statement + will be reset; + KSqlErrGeneral, a run-time error has occured - this function must not + be called again; + KSqlErrMisuse, this function has been called after a previous call + returned KSqlAtEnd or KSqlErrGeneral. + KSqlErrStmtExpired, the SQL statement has expired (if new functions or + collating sequences have been registered or if an + authorizer function has been added or changed); +*/ +TInt RSqlStatementSession::BindNext(const RSqlBufFlat& aParamBuf, RSqlBufFlat& aColumnBuf) + { + TPtrC8 prmData(aParamBuf.BufDes()); + TIpcArgs ipcArgs; + ipcArgs.Set(0, prmData.Length()); + ipcArgs.Set(1, &prmData); + return DoBindNext(ESqlSrvStmtBindNext, ipcArgs, aColumnBuf); + } + +/** +Implements RSqlStatementSession::Next() and RSqlStatementSession::BindNext(). +Sends a "Next" command to the server combined with optional "Bind" command. +In a single IPC call the statement parameters will be bound and the current row columns - returned. +If the client side flat buffer is not big enough, a second IPC call will be made after reallocating the buffer. + +Usage of the IPC call arguments: +Arg 0: [out] parameter buffer length in bytes +Arg 1: [out] parameter buffer +Arg 2: [out] column buffer length in bytes +Arg 3: [in/out] column buffer + +@see RSqlStatementSession::Next() +@see RSqlStatementSession::BindNext() +*/ +TInt RSqlStatementSession::DoBindNext(TSqlSrvFunction aFunction, TIpcArgs& aIpcArgs, RSqlBufFlat& aColumnBuf) + { + aColumnBuf.Reset(); + aIpcArgs.Set(2, aColumnBuf.MaxSize()); + aIpcArgs.Set(3, &aColumnBuf.BufPtr()); + TInt err = DbSession().SendReceive(::MakeMsgCode(aFunction, ESqlSrvStatementHandle, iHandle), aIpcArgs); + if(err > KSqlClientBufOverflowCode) + { + err = Retry(aColumnBuf, err - KSqlClientBufOverflowCode, ESqlColumnValuesBuf); + if(err == KErrNone) + { + err = KSqlAtRow; + } + } + return err; + } + +/** +Sends a command to the server for retrieving parameter names or column names. + +Usage of the IPC call arguments: +Arg 0: [out] buffer length in bytes +Arg 1: [in/out] buffer +*/ +TInt RSqlStatementSession::GetNames(TSqlSrvFunction aFunction, RSqlBufFlat& aNameBuf) + { + aNameBuf.Reset(); + TPtr8& ptr = aNameBuf.BufPtr(); + TInt err = DbSession().SendReceive(::MakeMsgCode(aFunction, ESqlSrvStatementHandle, iHandle), TIpcArgs(ptr.MaxLength(), &ptr)); + if(err > KSqlClientBufOverflowCode) + { + err = Retry(aNameBuf, err - KSqlClientBufOverflowCode, aFunction == ESqlSrvStmtColumnNames ? ESqlColumnNamesBuf : ESqlParamNamesBuf); + } + return err; + } + +/** +Sends a command to the server for retrieving specified data (aWhat parameter). + +Usage of the IPC call arguments: +Arg 0: [out] The type of the data to be retrieved +Arg 1: [in/out] Data buffer +*/ +TInt RSqlStatementSession::Retry(RSqlBufFlat& aBufFlat, TInt aSize, TSqlBufFlatType aWhat) + { + aBufFlat.Reset(); + TInt err = aBufFlat.ReAlloc(aSize); + if(err == KErrNone) + { + TPtr8& ptr = aBufFlat.BufPtr(); + err = DbSession().SendReceive(::MakeMsgCode(ESqlSrvStmtBufFlat, ESqlSrvStatementHandle, iHandle), TIpcArgs(aWhat, &ptr)); + } + return err; + } + +/** +Sends a command to the server for retrieving a string with ";" separated declared types of columns +The caller is responsible for deleting the result buffer. + +@param aColumnCount The number of the columns which the statement has. +@return A pointer to a heap based HBufC object, containing the column names, separated with ";". + +Usage of the IPC call arguments: +Arg 0: [out] Input buffer max length +Arg 1: [in/out] Data buffer, will be filled with the declared types of columns, separated with ";" +*/ +HBufC* RSqlStatementSession::GetDeclColumnTypesL(TInt aColumnCount) + { + //The longest DBMS data type, represented as text, is "LONG VARBINARY" - 14 characters. + //So we can safely assume that 20 characters buffer space per DBMS column type is enough. + const TInt KLongestDbmsTypeLength = 20; + HBufC* colTypeBuf = HBufC::NewLC(aColumnCount * KLongestDbmsTypeLength); + TPtr ptr = colTypeBuf->Des(); + TInt err = DbSession().SendReceive(::MakeMsgCode(ESqlSrvStmtDeclColumnTypes, ESqlSrvStatementHandle, iHandle), TIpcArgs(ptr.MaxLength(), &ptr)); + __SQLLEAVE_IF_ERROR(err); + CleanupStack::Pop(colTypeBuf); + return colTypeBuf; + }