#ifndef __MYSQL_H
#define __MYSQL_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <mysql.h>
struct LOGINENV
{
char ip[32];
char user[32];
char pass[32];
char dbname[51];
int port;
};
struct CDA_DEF
{
int rc;
unsigned long rpc;
char message[2048];
};
class connection
{
public:
MYSQL *m_conn;
int m_state;
LOGINENV m_env;
int m_autocommitopt;
char m_dbtype[21];
connection();
~connection();
int connecttodb(char *connstr,char *charset,unsigned int autocommitopt=0);
void setdbopt(char *connstr);
int disconnect();
void character(char *charset);
int commit();
int rollback();
void err_report();
CDA_DEF m_cda;
};
#define MAXPARAMS 256
class sqlstatement
{
public:
int m_state;
MYSQL_STMT *m_handle;
MYSQL_BIND params_in[MAXPARAMS];
MYSQL_BIND params_out[MAXPARAMS];
connection *m_conn;
char m_sql[10240];
CDA_DEF m_cda;
int m_sqltype;
int m_autocommitopt;
sqlstatement();
sqlstatement(connection *conn);
void initial();
~sqlstatement();
int connect(connection *conn);
int disconnect();
int prepare(const char *fmt,...);
int bindin(unsigned int position,int *value);
int bindin(unsigned int position,long *value);
int bindin(unsigned int position,unsigned int *value);
int bindin(unsigned int position,unsigned long *value);
int bindin(unsigned int position,float *value);
int bindin(unsigned int position,double *value);
int bindin(unsigned int position,char *value,unsigned int len);
int bindout(unsigned int position,int *value);
int bindout(unsigned int position,long *value);
int bindout(unsigned int position,unsigned int *value);
int bindout(unsigned int position,unsigned long *value);
int bindout(unsigned int position,float *value);
int bindout(unsigned int position,double *value);
int bindout(unsigned int position,char *value,unsigned int len);
int execute();
int execute(const char *fmt,...);
int next();
void err_report();
};
#endif
#include "_mysql.h"
connection::connection()
{
m_conn = NULL;
m_state = 0;
memset(&m_env,0,sizeof(LOGINENV));
memset(&m_cda,0,sizeof(m_cda));
m_cda.rc=-1;
strncpy(m_cda.message,"database not open.",128);
memset(m_dbtype,0,sizeof(m_dbtype));
strcpy(m_dbtype,"mysql");
}
connection::~connection()
{
disconnect();
}
void connection::setdbopt(char *connstr)
{
memset(&m_env,0,sizeof(LOGINENV));
char *bpos,*epos;
bpos=epos=0;
bpos=connstr;
epos=strstr(bpos,",");
if (epos > 0)
{
strncpy(m_env.ip,bpos,epos-bpos);
}else return;
bpos=epos+1;
epos=0;
epos=strstr(bpos,",");
if (epos > 0)
{
strncpy(m_env.user,bpos,epos-bpos);
}else return;
bpos=epos+1;
epos=0;
epos=strstr(bpos,",");
if (epos > 0)
{
strncpy(m_env.pass,bpos,epos-bpos);
}else return;
bpos=epos+1;
epos=0;
epos=strstr(bpos,",");
if (epos > 0)
{
strncpy(m_env.dbname,bpos,epos-bpos);
}else return;
m_env.port=atoi(epos+1);
}
int connection::connecttodb(char *connstr,char *charset,unsigned int autocommitopt)
{
if (m_state == 1) return 0;
setdbopt(connstr);
memset(&m_cda,0,sizeof(m_cda));
if ( (m_conn = mysql_init(NULL)) == NULL )
{
m_cda.rc=-1; strncpy(m_cda.message,"initialize mysql failed.\n",128); return -1;
}
if ( mysql_real_connect(m_conn,m_env.ip,m_env.user,m_env.pass,m_env.dbname,m_env.port, NULL, 0 ) == NULL )
{
m_cda.rc=mysql_errno(m_conn); strncpy(m_cda.message,mysql_error(m_conn),2000); mysql_close(m_conn); m_conn=NULL; return -1;
}
m_autocommitopt=autocommitopt;
if ( mysql_autocommit(m_conn, m_autocommitopt ) != 0 )
{
m_cda.rc=mysql_errno(m_conn); strncpy(m_cda.message,mysql_error(m_conn),2000); mysql_close(m_conn); m_conn=NULL; return -1;
}
character(charset);
m_state = 1;
return 0;
}
void connection::character(char *charset)
{
mysql_set_character_set(m_conn,charset);
return;
}
int connection::disconnect()
{
memset(&m_cda,0,sizeof(m_cda));
if (m_state == 0)
{
m_cda.rc=-1; strncpy(m_cda.message,"database not open.",128); return -1;
}
rollback();
mysql_close(m_conn);
m_conn=NULL;
m_state = 0;
return 0;
}
int connection::rollback()
{
memset(&m_cda,0,sizeof(m_cda));
if (m_state == 0)
{
m_cda.rc=-1; strncpy(m_cda.message,"database not open.",128); return -1;
}
if ( mysql_rollback(m_conn ) != 0 )
{
m_cda.rc=mysql_errno(m_conn); strncpy(m_cda.message,mysql_error(m_conn),2000); mysql_close(m_conn); m_conn=NULL; return -1;
}
return 0;
}
int connection::commit()
{
memset(&m_cda,0,sizeof(m_cda));
if (m_state == 0)
{
m_cda.rc=-1; strncpy(m_cda.message,"database not open.",128); return -1;
}
if ( mysql_commit(m_conn ) != 0 )
{
m_cda.rc=mysql_errno(m_conn); strncpy(m_cda.message,mysql_error(m_conn),2000); mysql_close(m_conn); m_conn=NULL; return -1;
}
return 0;
}
void connection::err_report()
{
if (m_state == 0)
{
m_cda.rc=-1; strncpy(m_cda.message,"database not open.",128); return;
}
memset(&m_cda,0,sizeof(m_cda));
m_cda.rc=-1;
strncpy(m_cda.message,"call err_report failed.",128);
m_cda.rc=mysql_errno(m_conn);
strncpy(m_cda.message,mysql_error(m_conn),1024);
return;
}
sqlstatement::sqlstatement()
{
initial();
}
void sqlstatement::initial()
{
m_state=0;
m_handle=NULL;
memset(&m_cda,0,sizeof(m_cda));
memset(m_sql,0,sizeof(m_sql));
m_cda.rc=-1;
strncpy(m_cda.message,"sqlstatement not connect to connection.\n",128);
}
sqlstatement::sqlstatement(connection *conn)
{
initial();
connect(conn);
}
sqlstatement::~sqlstatement()
{
disconnect();
}
int sqlstatement::connect(connection *conn)
{
if ( m_state == 1 ) return 0;
memset(&m_cda,0,sizeof(m_cda));
m_conn=conn;
if (m_conn == 0)
{
m_cda.rc=-1; strncpy(m_cda.message,"database not open.\n",128); return -1;
}
if (m_conn->m_state == 0)
{
m_cda.rc=-1; strncpy(m_cda.message,"database not open.\n",128); return -1;
}
if ( (m_handle=mysql_stmt_init(m_conn->m_conn)) == NULL)
{
err_report(); return m_cda.rc;
}
m_state = 1;
m_autocommitopt=m_conn->m_autocommitopt;
return 0;
}
int sqlstatement::disconnect()
{
if (m_state == 0) return 0;
memset(&m_cda,0,sizeof(m_cda));
mysql_stmt_close(m_handle);
m_state=0;
m_handle=NULL;
memset(&m_cda,0,sizeof(m_cda));
memset(m_sql,0,sizeof(m_sql));
m_cda.rc=-1;
strncpy(m_cda.message,"cursor not open.",128);
return 0;
}
void sqlstatement::err_report()
{
if (m_state == 0)
{
m_cda.rc=-1; strncpy(m_cda.message,"cursor not open.\n",128); return;
}
memset(&m_conn->m_cda,0,sizeof(m_conn->m_cda));
m_cda.rc=-1;
strncpy(m_cda.message,"call err_report() failed.\n",128);
m_cda.rc=mysql_stmt_errno(m_handle);
snprintf(m_cda.message,2000,"%d,%s",m_cda.rc,mysql_stmt_error(m_handle));
m_conn->err_report();
return;
}
int sqlstatement::prepare(const char *fmt,...)
{
memset(&m_cda,0,sizeof(m_cda));
if (m_state == 0)
{
m_cda.rc=-1; strncpy(m_cda.message,"cursor not open.\n",128); return -1;
}
memset(m_sql,0,sizeof(m_sql));
va_list ap;
va_start(ap,fmt);
vsnprintf(m_sql,10000,fmt,ap);
va_end(ap);
int ilen=strlen(m_sql);
for (int ii=0;ii<ilen;ii++)
{
if ( (m_sql[ii]==':') && (isdigit(m_sql[ii+1])!=0) )
{
m_sql[ii]='?';
m_sql[ii+1]=' ';
if (isdigit(m_sql[ii+2])!=0) m_sql[ii+2]=' ';
if (isdigit(m_sql[ii+3])!=0) m_sql[ii+3]=' ';
}
}
if (mysql_stmt_prepare(m_handle,m_sql,strlen(m_sql)) != 0)
{
err_report(); return m_cda.rc;
}
m_sqltype=1;
char strtemp[16]; memset(strtemp,0,sizeof(strtemp)); strncpy(strtemp,m_sql,15);
if ( (strstr(strtemp,"select") > 0) || (strstr(strtemp,"Select") > 0) || (strstr(strtemp,"SELECT") > 0) ) m_sqltype=0;
memset(params_in,0,sizeof(params_in));
memset(params_out,0,sizeof(params_out));
return 0;
}
int sqlstatement::bindin(unsigned int position,int *value)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->param_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_in[position-1].buffer_type = MYSQL_TYPE_LONG;
params_in[position-1].buffer = value;
return 0;
}
int sqlstatement::bindin(unsigned int position,long *value)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->param_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_in[position-1].buffer_type = MYSQL_TYPE_LONGLONG;
params_in[position-1].buffer = value;
return 0;
}
int sqlstatement::bindin(unsigned int position,unsigned int *value)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->param_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_in[position-1].buffer_type = MYSQL_TYPE_LONG;
params_in[position-1].buffer = value;
return 0;
}
int sqlstatement::bindin(unsigned int position,unsigned long *value)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->param_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_in[position-1].buffer_type = MYSQL_TYPE_LONGLONG;
params_in[position-1].buffer = value;
return 0;
}
int sqlstatement::bindin(unsigned int position,char *value,unsigned int len)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->param_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_in[position-1].buffer_type = MYSQL_TYPE_VAR_STRING;
params_in[position-1].buffer = value;
params_in[position-1].buffer_length = len;
return 0;
}
int sqlstatement::bindin(unsigned int position,float *value)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->param_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_in[position-1].buffer_type = MYSQL_TYPE_FLOAT;
params_in[position-1].buffer = value;
return 0;
}
int sqlstatement::bindin(unsigned int position,double *value)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->param_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_in[position-1].buffer_type = MYSQL_TYPE_DOUBLE;
params_in[position-1].buffer = value;
return 0;
}
int sqlstatement::bindout(unsigned int position,int *value)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->field_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_out[position-1].buffer_type = MYSQL_TYPE_LONG;
params_out[position-1].buffer = value;
return 0;
}
int sqlstatement::bindout(unsigned int position,long *value)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->field_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_out[position-1].buffer_type = MYSQL_TYPE_LONGLONG;
params_out[position-1].buffer = value;
return 0;
}
int sqlstatement::bindout(unsigned int position,unsigned int *value)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->field_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_out[position-1].buffer_type = MYSQL_TYPE_LONG;
params_out[position-1].buffer = value;
return 0;
}
int sqlstatement::bindout(unsigned int position,unsigned long *value)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->field_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_out[position-1].buffer_type = MYSQL_TYPE_LONGLONG;
params_out[position-1].buffer = value;
return 0;
}
int sqlstatement::bindout(unsigned int position,char *value,unsigned int len)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->field_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_out[position-1].buffer_type = MYSQL_TYPE_VAR_STRING;
params_out[position-1].buffer = value;
params_out[position-1].buffer_length = len;
return 0;
}
int sqlstatement::bindout(unsigned int position,float *value)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->field_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_out[position-1].buffer_type = MYSQL_TYPE_FLOAT;
params_out[position-1].buffer = value;
return 0;
}
int sqlstatement::bindout(unsigned int position,double *value)
{
if ( (position<1) || (position>=MAXPARAMS) || (position>m_handle->field_count) )
{
m_cda.rc=-1; strncpy(m_cda.message,"array bound.",128);
}
params_out[position-1].buffer_type = MYSQL_TYPE_DOUBLE;
params_out[position-1].buffer = value;
return 0;
}
int sqlstatement::execute()
{
memset(&m_cda,0,sizeof(m_cda));
if (m_state == 0)
{
m_cda.rc=-1; strncpy(m_cda.message,"cursor not open.\n",128); return -1;
}
if ( (m_handle->param_count>0) && (m_handle->bind_param_done == 0))
{
if (mysql_stmt_bind_param(m_handle,params_in) != 0)
{
err_report(); return m_cda.rc;
}
}
if ( (m_handle->field_count>0) && (m_handle->bind_result_done == 0) )
{
if (mysql_stmt_bind_result(m_handle,params_out) != 0)
{
err_report(); return m_cda.rc;
}
}
if (mysql_stmt_execute(m_handle) != 0)
{
err_report(); return m_cda.rc;
}
if (m_sqltype == 1) m_cda.rpc=m_handle->affected_rows;
return 0;
}
int sqlstatement::execute(const char *fmt,...)
{
char strtmpsql[10240];
memset(strtmpsql,0,sizeof(strtmpsql));
va_list ap;
va_start(ap,fmt);
vsnprintf(strtmpsql,10000,fmt,ap);
va_end(ap);
if (prepare(strtmpsql) != 0) return m_cda.rc;
return execute();
}
int sqlstatement::next()
{
if (m_state == 0)
{
m_cda.rc=-1; strncpy(m_cda.message,"cursor not open.\n",128); return -1;
}
if (m_cda.rc != 0) return m_cda.rc;
if (m_sqltype != 0)
{
m_cda.rc=-1; strncpy(m_cda.message,"no recordset found.\n",128); return -1;
}
int ret=mysql_stmt_fetch(m_handle);
if (ret==0)
{
m_cda.rpc++; return 0;
}
if (ret==1)
{
err_report(); return m_cda.rc;
}
if (ret==MYSQL_NO_DATA) return MYSQL_NO_DATA;
if (ret==MYSQL_DATA_TRUNCATED)
{
m_cda.rpc++; return 0;
}
return 0;
}