summaryrefslogtreecommitdiff
path: root/innobase/odbc/odbc0odbc.c
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/odbc/odbc0odbc.c')
-rw-r--r--innobase/odbc/odbc0odbc.c714
1 files changed, 0 insertions, 714 deletions
diff --git a/innobase/odbc/odbc0odbc.c b/innobase/odbc/odbc0odbc.c
deleted file mode 100644
index 0deb17c6714..00000000000
--- a/innobase/odbc/odbc0odbc.c
+++ /dev/null
@@ -1,714 +0,0 @@
-/******************************************************
-Innobase ODBC client library
-
-(c) 1998 Innobase Oy
-
-Created 2/22/1998 Heikki Tuuri
-*******************************************************/
-
-#include "odbc0odbc.h"
-
-#include "mem0mem.h"
-#include "com0com.h"
-#include "usr0sess.h"
-
-#define ODBC_STAT_INITIAL 1
-#define ODBC_STAT_PREPARED 2
-#define ODBC_STAT_EXECUTED 3
-
-
-typedef struct odbc_conn_struct odbc_conn_t;
-typedef struct odbc_env_struct odbc_env_t;
-
-/* ODBC parameter description struct */
-
-typedef struct odbc_param_struct odbc_param_t;
-struct odbc_param_struct{
- ulint data_type; /* SQL_CHAR, ... */
- ibool is_input; /* TRUE if an input parameter of a stored
- procedure, FALSE if an output parameter */
- byte* buf; /* buffer where the value is stored before
- SQLExecute, or where it comes after SQLExecute
- in the case of an output parameter */
- lint* data_len; /* pointer to where the data len or the value
- SQL_NULL_DATA is stored */
- ulint buf_len; /* buffer size */
-};
-
-/* ODBC statement data structure */
-
-typedef struct odbc_stat_struct odbc_stat_t;
-struct odbc_stat_struct{
- ulint state; /* ODBC_STAT_INITIAL,
- ODBC_STAT_PREPARED,
- ODBC_STAT_EXECUTED */
- ulint id; /* statement id */
- ulint n_params; /* number of parameters */
- odbc_param_t* params; /* pointer to an array describing
- the parameters, if any */
- ulint n_params_bound; /* number of parameters that have
- been bound: the statement cannot be
- executed before n_params_bound
- == n_params */
- byte* error_msg; /* possible error message, or NULL;
- allocated separately from dynamic
- memory */
- ulint error_msg_len; /* error mesage length if it is
- non-NULL */
- odbc_conn_t* conn; /* connection */
- UT_LIST_NODE_T(odbc_stat_t)
- stat_list; /* list of the statements of the
- connection */
-};
-
-/* ODBC connection data structure */
-
-struct odbc_conn_struct{
- ibool connected; /* TRUE if connected */
- char* server_name; /* server name where connected
- (= server address) */
- ulint server_name_len;/* length of the server name */
- com_endpoint_t* com_endpoint; /* connection endpoint for this client
- connection */
- dulint out_msg_count; /* count of outgoing messages */
- byte* out_datagram_buf;/* buffer for outgoing datagrams to
- the server */
- byte* in_datagram_buf;/* buffer for incoming datagrams from
- the server */
- byte* addr_buf; /* buffer for the address from which
- an incoming datagram came; in practice,
- this will be the server address */
- dulint sess_id; /* user session id, once the
- connection to the server is
- established */
- odbc_env_t* env; /* environment */
- UT_LIST_BASE_NODE_T(odbc_stat_t)
- stat_list; /* list of the statements of the
- connection */
- UT_LIST_NODE_T(odbc_conn_t)
- conn_list; /* list of the connections of the
- environment */
-};
-
-/* ODBC environment data structure */
-
-struct odbc_env_struct{
- UT_LIST_BASE_NODE_T(odbc_conn_t) conn_list;
- /* list of the connections of the
- environment */
-};
-
-/**************************************************************************
-Gets the nth parameter description struct for a statement. */
-UNIV_INLINE
-odbc_param_t*
-stat_get_nth_param(
-/*===============*/
- /* out: nth parameter */
- odbc_stat_t* stat, /* in: pointer to statement handle */
- ulint i) /* in: parameter index */
-{
- ut_ad(stat->n_params > i);
-
- return(stat->params + i);
-}
-
-/**************************************************************************
-Allocates an SQL environment. */
-
-RETCODE
-SQLAllocEnv(
-/*========*/
- /* out: SQL_SUCCESS */
- HENV* phenv) /* out: pointer to an environment handle */
-{
- odbc_env_t* env;
-
- if (!sync_initialized) {
- sync_init();
- mem_init(2000000);
- }
-
- env = mem_alloc(sizeof(odbc_env_t));
-
- UT_LIST_INIT(env->conn_list);
-
- *phenv = env;
-
- return(SQL_SUCCESS);
-}
-
-/**************************************************************************
-Allocates an SQL connection. */
-
-RETCODE
-SQLAllocConnect(
-/*============*/
- /* out: SQL_SUCCESS */
- HENV henv, /* in: pointer to an environment handle */
- HDBC* phdbc) /* out: pointer to a connection handle */
-{
- odbc_conn_t* conn;
- odbc_env_t* env;
-
- ut_a(henv);
-
- env = henv;
- conn = mem_alloc(sizeof(odbc_conn_t));
-
- conn->connected = FALSE;
- conn->env = env;
-
- UT_LIST_INIT(conn->stat_list);
-
- UT_LIST_ADD_LAST(conn_list, env->conn_list, conn);
-
- *phdbc = conn;
-
- return(SQL_SUCCESS);
-}
-
-/**************************************************************************
-Allocates an SQL statement. */
-
-RETCODE
-SQLAllocStmt(
-/*=========*/
- HDBC hdbc, /* in: SQL connection */
- HSTMT* phstmt) /* out: pointer to a statement handle */
-{
- odbc_conn_t* conn;
- odbc_stat_t* stat;
-
- ut_a(hdbc);
-
- conn = hdbc;
-
- stat = mem_alloc(sizeof(odbc_stat_t));
-
- stat->state = ODBC_STAT_INITIAL;
- stat->error_msg = NULL;
- stat->conn = conn;
-
- UT_LIST_ADD_LAST(stat_list, conn->stat_list, stat);
-
- *phstmt = stat;
-
- return(SQL_SUCCESS);
-}
-
-/**************************************************************************
-Sends the message in datagram_buf to the server. */
-static
-void
-odbc_send_cli_msg(
-/*==============*/
- odbc_conn_t* conn, /* in: connection, does not have to be
- connected yet */
- ulint len) /* in: message length (excluding the standard
- header of size SESS_CLI_MSG_DATA) */
-{
- ulint ret;
- ulint fold;
- byte* msg;
-
- ut_a(len + SESS_CLI_MSG_DATA <= ODBC_DATAGRAM_SIZE);
-
- msg = conn->out_datagram_buf;
-
- mach_write_to_8(msg + SESS_CLI_MSG_NO, conn->out_msg_count);
-
- UT_DULINT_INC(conn->out_msg_count);
-
- fold = ut_fold_binary(msg + 4, len + SESS_CLI_MSG_DATA - 4);
-
- ut_ad(SESS_CLI_MSG_CHECKSUM == 0);
-
- mach_write_to_4(msg + SESS_CLI_MSG_CHECKSUM, fold);
-
- ret = com_sendto(conn->com_endpoint, msg, SESS_CLI_MSG_DATA + len,
- conn->server_name, conn->server_name_len);
- ut_a(ret == 0);
-}
-
-/**************************************************************************
-Receives a message in datagram_buf from the server. */
-static
-void
-odbc_recv_srv_msg(
-/*==============*/
- odbc_conn_t* conn, /* in: connection, does not have to be
- connected yet */
- ulint* len) /* out: received message length (excluding the
- standard header of size SESS_SRV_MSG_DATA) */
-{
- ulint total_len;
- ulint addr_len;
- ulint ret;
-
- ret = com_recvfrom(conn->com_endpoint, conn->in_datagram_buf,
- ODBC_DATAGRAM_SIZE, &total_len, (char*)conn->addr_buf,
- ODBC_ADDRESS_SIZE, &addr_len);
- ut_a(ret == 0);
- ut_a(total_len >= SESS_SRV_MSG_DATA);
-
- *len = total_len - SESS_SRV_MSG_DATA;
-}
-
-/**************************************************************************
-Connects to a database server process (establishes a connection and a
-session). */
-
-RETCODE
-SQLConnect(
-/*=======*/
- /* out: SQL_SUCCESS */
- HDBC hdbc, /* in: SQL connection handle */
- UCHAR* szDSN, /* in: data source name (server name) */
- SWORD cbDSN, /* in: data source name length */
- UCHAR* szUID, /* in: user name */
- SWORD cbUID, /* in: user name length */
- UCHAR* szAuthStr, /* in: password */
- SWORD cbAuthStr) /* in: password length */
-{
- com_endpoint_t* ep;
- odbc_conn_t* conn;
- ulint err;
- ulint size;
- byte* msg;
- ulint len;
- UCHAR catenated_name[100];
-
- ut_a(hdbc && szDSN);
-
- UT_NOT_USED(szUID);
- UT_NOT_USED(cbUID);
- UT_NOT_USED(szAuthStr);
- UT_NOT_USED(cbAuthStr);
-
- conn = hdbc;
-
- ut_a(!conn->connected);
-
- conn->server_name = mem_alloc(cbDSN);
- ut_memcpy(conn->server_name, szDSN, cbDSN);
-
- conn->server_name_len = cbDSN;
-
- ep = com_endpoint_create(COM_SHM);
-
- ut_a(ep);
-
- conn->com_endpoint = ep;
-
- conn->out_msg_count = ut_dulint_zero;
-
- size = ODBC_DATAGRAM_SIZE;
-
- err = com_endpoint_set_option(ep, COM_OPT_MAX_DGRAM_SIZE,
- (byte*)&size, 4);
- ut_a(err == 0);
-
- /* Make the data source name catenated to user name as the
- address of the communications endpoint */
-
- ut_a((ulint)cbDSN + (ulint)cbUID < 100);
-
- ut_memcpy(catenated_name, szDSN, (ulint)cbDSN);
- ut_memcpy(catenated_name + (ulint)cbDSN, szUID, (ulint)cbUID);
-
- err = com_bind(ep, (char*)catenated_name, (ulint)cbDSN
- + (ulint)cbUID);
- ut_a(err == 0);
-
- conn->in_datagram_buf = mem_alloc(ODBC_DATAGRAM_SIZE);
-
- msg = mem_alloc(ODBC_DATAGRAM_SIZE);
-
- conn->out_datagram_buf = msg;
- conn->addr_buf = mem_alloc(ODBC_ADDRESS_SIZE);
-
- /* Set the session id to dulint 0 as we are not yet connected */
-
- sess_cli_msg_set_sess(msg, ut_dulint_zero);
- sess_cli_msg_set_type(msg, SESS_CLI_CONNECT);
-
- /*------------------------------------------*/
-
- odbc_send_cli_msg(conn, 0);
-
- odbc_recv_srv_msg(conn, &len);
-
- /*------------------------------------------*/
-
- ut_a(len == 0);
- ut_a(sess_srv_msg_get_type(conn->in_datagram_buf)
- == SESS_SRV_ACCEPT_CONNECT);
-
- conn->sess_id = mach_read_from_8(conn->in_datagram_buf
- + SESS_SRV_MSG_SESS_ID);
-
- /* Write the session id to out_datagram_buf: it will not be rewritten
- until the connection is closed, as the session id will stay the same */
-
- sess_cli_msg_set_sess(msg, conn->sess_id);
-
- /* We currently only send single part messages: the following will
- stay 0 during the connection */
-
- mach_write_to_4(msg + SESS_CLI_MSG_CONTINUE, 0);
- mach_write_to_4(msg + SESS_CLI_MSG_CONT_SIZE, 0);
-
- conn->connected = TRUE;
-
- return(SQL_SUCCESS);
-}
-
-/**************************************************************************
-Stores an error message to a statement handle, so that it can be later
-queried with SQLError. */
-static
-void
-odbc_stat_store_error_msg(
-/*======================*/
- odbc_stat_t* stat, /* in: statement handle */
- byte* msg, /* in: error message sent by the server */
- ulint len) /* in: length of msg */
-{
- if (stat->error_msg) {
- mem_free(stat->error_msg);
- }
-
- stat->error_msg_len = len;
-
- len += SESS_SRV_MSG_DATA;
-
- stat->error_msg = mem_alloc(len);
- ut_memcpy(stat->error_msg, msg, len);
-}
-
-/**************************************************************************
-Queries an error message. */
-
-RETCODE
-SQLError(
-/*=====*/
- /* out: SQL_SUCCESS or SQL_NO_DATA_FOUND */
- HENV henv, /* in: SQL_NULL_HENV */
- HDBC hdbc, /* in: SQL_NULL_HDBC */
- HSTMT hstmt, /* in: statement handle */
- UCHAR* szSqlState, /* in/out: SQLSTATE as a null-terminated string,
- (currently, always == "S1000") */
- SDWORD* pfNativeError, /* out: native error code */
- UCHAR* szErrorMsg, /* in/out: buffer for an error message as a
- null-terminated string */
- SWORD cbErrorMsgMax, /* in: buffer size for szErrorMsg */
- SWORD* pcbErrorMsg) /* out: error message length */
-{
- odbc_stat_t* stat;
- ulint len;
-
- ut_a(henv == SQL_NULL_HENV);
- ut_a(hdbc == SQL_NULL_HDBC);
- ut_a(hstmt);
- ut_a(cbErrorMsgMax > 1);
-
- stat = hstmt;
-
- if (stat->error_msg == NULL) {
-
- return(SQL_NO_DATA_FOUND);
- }
-
- *pfNativeError = 0;
- ut_memcpy(szSqlState, (char *) "S1000", 6);
-
- len = (ulint)cbErrorMsgMax - 1;
-
- if (stat->error_msg_len < len) {
- len = stat->error_msg_len;
- }
-
- ut_memcpy(szErrorMsg, stat->error_msg + SESS_SRV_MSG_DATA, len);
-
- *(szErrorMsg + len) = '\0';
-
- *pcbErrorMsg = (SWORD)len;
-
- if (stat->error_msg) {
- mem_free(stat->error_msg);
- stat->error_msg = NULL;
- }
-
- return(SQL_SUCCESS);
-}
-
-/**************************************************************************
-Makes the server to parse and optimize an SQL string. */
-
-RETCODE
-SQLPrepare(
-/*=======*/
- /* out: SQL_SUCCESS or SQL_ERROR */
- HSTMT hstmt, /* in: statement handle */
- UCHAR* szSqlStr, /* in: SQL string */
- SDWORD cbSqlStr) /* in: SQL string length */
-{
- odbc_stat_t* stat;
- odbc_conn_t* conn;
- odbc_param_t* param;
- ulint len;
- byte* msg;
- ulint i;
-
- stat = hstmt;
- conn = stat->conn;
-
- if (stat->error_msg) {
- mem_free(stat->error_msg);
- stat->error_msg = NULL;
- }
-
- ut_memcpy(conn->out_datagram_buf + SESS_CLI_MSG_DATA, szSqlStr,
- 1 + (ulint)cbSqlStr);
-
- sess_cli_msg_set_type(conn->out_datagram_buf, SESS_CLI_PREPARE);
-
- /* The client message will be decoded in sess_receive_prepare */
-
- /*------------------------------------------*/
-
- odbc_send_cli_msg(conn, 1 + (ulint)cbSqlStr);
-
- odbc_recv_srv_msg(conn, &len);
-
- /*------------------------------------------*/
-
- /* The server message was coded in sess_receive_prepare */
-
- ut_a(len >= 8);
-
- msg = conn->in_datagram_buf;
-
- if (sess_srv_msg_get_type(msg) != SESS_SRV_SUCCESS) {
-
- ut_a(sess_srv_msg_get_type(msg) == SESS_SRV_ERROR);
-
- odbc_stat_store_error_msg(stat, msg, len);
-
- return(SQL_ERROR);
- }
-
- stat->id = mach_read_from_4(msg + SESS_SRV_MSG_DATA);
-
- stat->n_params = mach_read_from_4(msg + SESS_SRV_MSG_DATA + 4);
-
- stat->n_params_bound = 0;
-
- ut_a(len == 8 + stat->n_params);
-
- if (stat->n_params > 0) {
-
- stat->params = mem_alloc(stat->n_params
- * sizeof(odbc_param_t));
- for (i = 0; i < stat->n_params; i++) {
- param = stat_get_nth_param(stat, i);
-
- param->is_input = mach_read_from_1(
- msg + SESS_SRV_MSG_DATA + 8 + i);
- /* Set buf to NULL so that we know when the parameter
- has been bound */
-
- param->buf = NULL;
- }
- }
-
- stat->state = ODBC_STAT_PREPARED;
-
- return(SQL_SUCCESS);
-}
-
-/**************************************************************************
-Binds a parameter in a prepared statement. */
-
-RETCODE
-SQLBindParameter(
-/*=============*/
- /* out: SQL_SUCCESS */
- HSTMT hstmt, /* in: statement handle */
- UWORD ipar, /* in: parameter index, starting from 1 */
- SWORD fParamType, /* in: SQL_PARAM_INPUT or SQL_PARAM_OUTPUT */
- SWORD fCType, /* in: SQL_C_CHAR, ... */
- SWORD fSqlType, /* in: SQL_CHAR, ... */
- UDWORD cbColDef, /* in: precision: ignored */
- SWORD ibScale, /* in: scale: ignored */
- PTR rgbValue, /* in: pointer to a buffer for the data */
- SDWORD cbValueMax, /* in: buffer size */
- SDWORD* pcbValue) /* in: pointer to a buffer for the data
- length or SQL_NULL_DATA */
-{
- odbc_stat_t* stat;
- odbc_param_t* param;
-
- stat = hstmt;
-
- ut_a(stat->state != ODBC_STAT_INITIAL);
- ut_a(rgbValue);
- ut_a(ipar <= stat->n_params);
- ut_a(ipar > 0);
- ut_a(cbValueMax >= 0);
- ut_a(pcbValue);
-
- UT_NOT_USED(ibScale);
- UT_NOT_USED(fCType);
- UT_NOT_USED(cbColDef);
-
- if (stat->error_msg) {
- mem_free(stat->error_msg);
- stat->error_msg = NULL;
- }
-
- param = stat_get_nth_param(stat, ipar - 1);
-
- if (param->buf == NULL) {
- stat->n_params_bound++;
- }
-
- param->data_type = fSqlType;
-
- ut_a((fParamType != SQL_PARAM_INPUT) || param->is_input);
- ut_a((fParamType == SQL_PARAM_INPUT) || !param->is_input);
-
- param->buf = rgbValue;
- param->buf_len = cbValueMax;
- param->data_len = pcbValue;
-
- return(SQL_SUCCESS);
-}
-
-/**************************************************************************
-Executes a prepared statement where all parameters have been bound. */
-
-RETCODE
-SQLExecute(
-/*=======*/
- /* out: SQL_SUCCESS or SQL_ERROR */
- HSTMT hstmt) /* in: statement handle */
-{
- odbc_stat_t* stat;
- odbc_conn_t* conn;
- odbc_param_t* param;
- lint len;
- ulint msg_len;
- byte* msg;
- byte* ptr;
- lint int_val;
- ulint i;
-
- stat = hstmt;
-
- ut_a(stat->state != ODBC_STAT_INITIAL);
- ut_a(stat->n_params == stat->n_params_bound);
-
- if (stat->error_msg) {
- mem_free(stat->error_msg);
- stat->error_msg = NULL;
- }
-
- conn = stat->conn;
- msg = conn->out_datagram_buf;
-
- sess_cli_msg_set_type(msg, SESS_CLI_EXECUTE);
-
- ptr = msg + SESS_CLI_MSG_DATA;
-
- mach_write_to_4(ptr, stat->id);
-
- ptr += 4;
-
- for (i = 0; i < stat->n_params; i++) {
-
- param = stat_get_nth_param(stat, i);
-
- if (param->is_input) {
- /* Copy its length and data to the message buffer */
-
- len = *(param->data_len);
-
- mach_write_to_4(ptr, (ulint)len);
-
- ptr += 4;
-
- if (len != SQL_NULL_DATA) {
- if (param->data_type == SQL_INTEGER) {
- ut_ad(len == 4);
- int_val = *((lint*)(param->buf));
-
- mach_write_to_4(ptr, (ulint)int_val);
- } else {
- ut_memcpy(ptr, param->buf, len);
- }
-
- ptr += len;
- }
- }
- }
-
- /* The client message will be decoded in sess_receive_command */
-
- /*------------------------------------------*/
-
- odbc_send_cli_msg(conn, ptr - (msg + SESS_CLI_MSG_DATA));
-
- odbc_recv_srv_msg(conn, &msg_len);
-
- /*------------------------------------------*/
-
- /* The server message was coded in sess_command_completed_message */
-
- msg = conn->in_datagram_buf;
-
- if (sess_srv_msg_get_type(msg) != SESS_SRV_SUCCESS) {
-
- ut_a(sess_srv_msg_get_type(msg) == SESS_SRV_ERROR);
-
- odbc_stat_store_error_msg(stat, msg, msg_len);
-
- return(SQL_ERROR);
- }
-
- ptr = msg + SESS_SRV_MSG_DATA;
-
- for (i = 0; i < stat->n_params; i++) {
-
- param = stat_get_nth_param(stat, i);
-
- if (!param->is_input) {
- /* Copy its length and data from the message buffer */
-
- len = (lint)mach_read_from_4(ptr);
-
- ptr += 4;
-
- *(param->data_len) = len;
-
- if (len != SQL_NULL_DATA) {
- if (param->data_type == SQL_INTEGER) {
- ut_ad(len == 4);
-
- int_val = (lint)mach_read_from_4(ptr);
-
- *((lint*)(param->buf)) = int_val;
- } else {
- ut_memcpy(param->buf, ptr, (ulint)len);
- }
-
- ptr += len;
- }
- }
- }
-
- ut_ad(msg + SESS_SRV_MSG_DATA + msg_len == ptr);
-
- return(SQL_SUCCESS);
-}