// CCommand.h: interface for the CConnection class.
//
//////////////////////////////////////////////////////////////////////
#pragma once
class CServerConnection;
namespace scdriver
{
// forward declaration
class CConnection;
class CRecordset;
///
/// Supported parameter directions. For input output parameter, use: DBPARAMETER_IN|DBPARAMETER_OUT.
///
enum DBPARAMETER_DIRECTION
{
DBPARAMETER_IN = 1,
DBPARAMETER_OUT = 2
};
///
/// Execute prepared SQL/DQL statements, stored procedures with or without parameters
///
class __declspec( dllexport ) CCommand
{
public:
CCommand();
virtual ~CCommand();
/**************************************
*
* function: g e t _ c a l l _ s i z e
*
**************************************
*
* Functional description
*
* return the size of the class
**************************************/
static int get_class_size();
///
/// Prepare parametrized SQL/DQL statements
///
/// Valid connection instance. The connection to server or embedded DB must be already established
/// SQL or DQL statement. For example: "select * from where id = @myid" is prepared SQL with a single input parameter "myid"
/// If method fails, the node_exception exception, containing the error message, will be thrown
void PrepareText(CConnection *conn, const char *cmd);
///
/// Prepare to execute stored procedure
///
/// Valid connection instance. The connection to server or embedded DB must be already established
/// Stored procedure's name
/// If method fails, the node_exception exception, containing the error message, will be thrown
void PrepareProcedure(CConnection *conn, const char *proc);
///
/// Declare input or input/output parameter
///
/// Name of the parameter.
/// Define if parameter is input or input/output. Only output parameter should use overloaded AddParameter function without specifying the value.
/// Data type of the parameter. If parameter does not matching column, it will be converted.
/// Pointer to parameter's value.
/// Default - 0. For fixed length data types and strings, the parameter is ignored. The size is required for BLOB data type.
/// If method fails, the node_exception exception, containing the error message, will be thrown
void AddParameter(const char *name, const DBPARAMETER_DIRECTION direction, const DATA_TYPE type, void *data, const int size = 0 /* set size for DB_BLOB type parameter */);
///
/// Declare output parameter
///
/// Name of the parameter.
/// Define parameter direction as DBPARAMETER_OUT.
/// Data type of the parameter.
/// If method fails, the node_exception exception, containing the error message, will be thrown
void AddParameter(const char *name, const DBPARAMETER_DIRECTION direction, const DATA_TYPE type);
///
/// Read output parameter's value
///
/// Name of output the parameter.
/// Data type of the parameter.
/// Pointer to the buffer to receive the patameter's value.
/// Size in bytes of the buffer.
/// If the value of the parameter's has been sucesfully read - returns true, if buffer size is not enough or parameter name does not exists - false.
bool GetParameter(const char *name, DATA_TYPE *type, void *data, const int size);
///
/// Execute command
///
/// If method fails, the node_exception exception, containing the error message, will be thrown
void Execute();
///
/// Execute SQL,DQL or stored procedure command and initialize recordset class to handle query's output
///
/// Pointer to the CRecorset class instance
/// On success recordset will read output rows, otherwise, empty recordset is returned. If error occurs, the node_exception exception, containing the error message, will be thrown.
void Open(CRecordset *rec);
/**************************************
*
* function: P r e p a r e T e x t
*
**************************************
*
* Functional description
*
* prepare parametrized SQL/DQL:
* select * from where id = ?myid
* for UDI
**************************************/
void PrepareText(CServerConnection *conn, const char *cmd);
/**************************************
*
* function: P r e p a r e P r o c e d u r e
*
**************************************
*
* Functional description
*
* set procedure name for UDI
**************************************/
void PrepareProcedure(CServerConnection *conn, const char *proc);
private:
/**************************************
*
* function: S e n d P a r a m e t e r s
*
**************************************
*
* Functional description
*
* group all parameters to a single batch (8kb),
* if parameters are top long, split to chunk them
* and send to the server
**************************************/
void SendParameters(void *param);
/**************************************
*
* function: r e a d _ p a r a m s
*
**************************************
*
* Functional description
*
* read output parameters if declared
**************************************/
static void __stdcall read_params(CConnection *conn, void *command);
private:
CConnection *m_conn;
CServerConnection *m_server_conn;
char *m_stmt;
byte m_storage[PAGE_SIZE];
char m_output_params[PAGE_SIZE];
int m_noutput_params;
int m_text;
int m_isend; // number of packages of parameters already sent
};
}