郑重声明:本MCI程序已经过严格的,长时间的反复测试和使用!
可支持对char,varchar,varchar2,int,float等类型数据进行各种select,update,insert操作 欢迎C++高手,MySQL来指点
本接口程序用C++完成,尤其适合server端使用,可通行于Linux/Unix/Windows平台包括:mci.h mci.cpp 以及测试用例test.h test.cpp和一个makefile文件,可直接在RedHat上编译运行
本接口功能相信可满足大部分朋友的需要,你只需在你的程序里面包含这两个文件即可(当然相应的makefile文件也需修改)
作者:欧昕 中国-成都 欢迎大家改进之,让其功能更加强大,我的联系QQ:30991118,欢迎骚扰...:)
#ifndef _MCI_H_
#define _MCI_H_
#include
#include
#include
#include
#include
#include
#include "/usr/local/mysql/include/mysql.h"
const unsigned int MAX_FIELD_LEN = 1024*1;
class MCIException
{
public:
int ErrNo;
char ErrInfo[256];
MCIException(const char *errinfo,int errno);
char *getErrInfo();
int getErrNo(){return ErrNo;};
//自定义错误类型
//1 不支持的字段类型
//2 字段越界
//3 字段不存在
//MySQL内部错误类型
//2002 Can't connect to local MySQL server through socket
//2003 Can't connect to MySQL server
//2013 Lost connection to MySQL server during query
//1045 Access denied for user
};
class MCIDatabase
{
public:
char DBIP[20]; //数据库IP地址
char User[10]; //用户名
char Pwd[10]; //密码
char DBName[20]; //数据库名
MYSQL *mysql;
public:
MCIDatabase();
MYSQL* getMySQL(){return mysql;};
void setLogin(const char* dbip,const char* usr, const char* pwd, const char* dbname) ;
int connect();
void disConnect();
};
class MCIField
{
public:
friend class MCIQuery;
MCIQuery* pParentQuery; //指向该Field所属于的Query
char FieldName[30]; //字段名称(目前支持30长度)
char StrBuf[255]; //用于保存转换为字符串后的值
unsigned char* DataBuf; //预绑定缓冲区
enum_field_types FieldType; //MySQL内部数据类型
unsigned int FieldLength; //数据长度
public:
MCIField();
~MCIField();
void setFieldName(const char* s);
void setFieldType(enum_field_types n);
void setFieldLength(unsigned int n);
char* getFieldName();
char* getStrBuf();
enum_field_types getFieldType();
unsigned int getFieldLength();
MCIQuery* getParentQuery();
void setParentQuery(MCIQuery* pQry);
static void trimLeft(char* str);
static void trimRight(char* str);
static char* allTrim(char* str);
char* asString();
int asInteger();
float asFloat();
char asChar(int pos = 0);
};
class MCIQuery
{
public:
MCIDatabase* pDB;
MYSQL_RES* pRes;
int FieldNum; //字段个数
MYSQL_FIELD* pFields; //得到的字段信息
MCIField* pMCIFieldList; //在内部保存的所有字段信息
MYSQL_ROW Row;
int RowNum;
char SqlStr[1024*3];
int CurrRow;
/*
//检查超时用
int ThreadExist;
int ThreadMode;
pthread_t QryID;
int ErrNo;
char ErrInfo[256];
*/
public:
MCIQuery();
void setDB(MCIDatabase *dblink);
~MCIQuery();
void setSql(char* sqlstr);
void open(); //执行select型SQL语句
int getFieldsDef(); //获得字段信息,并为字段分配取值的缓冲区
int getRecordCount(); //返回查询到的符合条件的记录的条数
int next(); //移动到下一个记录,同时获取字段值
MCIField* field(int i); //取相应字段值
MCIField* fieldByName(const char* s);
int exec(); //执行insert,update型SQL语句,返回被此语句影响的记录条数
void close(); //关闭一个Query,为下次执行做准备
/*
//检查超时用
int runSql();
static void* QryThread(void* arg);
*/
};
#endif
[mci.cpp]:
#include "mci.h"
MCIException::MCIException(const char *errinfo,int errno)
{
memset(ErrInfo,0,sizeof(ErrInfo));
strncpy(ErrInfo,errinfo,sizeof(ErrInfo)-1);
ErrNo = errno;
}
char* MCIException::getErrInfo()
{
return ErrInfo;
}
MCIDatabase::MCIDatabase()
{
memset(DBName,0,sizeof(DBName));
memset(User,0,sizeof(User));
memset(Pwd,0,sizeof(Pwd));
mysql = NULL;
}
//设置登陆信息
void MCIDatabase::setLogin(const char* dbip,const char* usr, const char* pwd,const char* dbname)
{
memset(DBIP,0,sizeof(DBIP));
strcpy(DBIP,dbip);
memset(User,0,sizeof(User));
strcpy(User,usr);
memset(Pwd,0,sizeof(Pwd));
strcpy(Pwd,pwd);
memset(DBName,0,sizeof(DBName));
strcpy(DBName,dbname);
}
//连接到数据库
int MCIDatabase::connect()
{
mysql = NULL;
mysql = mysql_init(NULL);
if (mysql == NULL)
{
char errinfo[256];
memset(errinfo,0,sizeof(errinfo));
sprintf(errinfo, "%s\n",mysql_error(mysql));
int errno = mysql_errno(mysql);
throw MCIException(errinfo,errno);
return 0;
}
unsigned int timeout = 3;
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT,(char *) &timeout);//超时
//mysql_options(mysql, MYSQL_OPT_COMPRESS,NULL);//与服务器的通信采用压缩协议
//建立连接
//DBIP如果设为"localhost"或NULL,则表示使用socket连接本地主机
//DBIP如果设为字符串或IP数字形式的主机名,则表示使用TCP/IP连接本地主机
if(mysql_real_connect(mysql,DBIP,User,Pwd,DBName,0,NULL,CLIENT_INTERACTIVE) == NULL)
{
char errinfo[256];
memset(errinfo,0,sizeof(errinfo));
sprintf(errinfo, "%s\n",mysql_error(mysql));
int errno = mysql_errno(mysql);
throw MCIException(errinfo,errno);
return 0;
}
return 1;
}
//关闭连接
void MCIDatabase::disConnect()
{
if (mysql != NULL) mysql_close(mysql);
}
MCIField::MCIField()
{
pParentQuery = NULL;
memset(FieldName,0,sizeof(FieldName));
memset(StrBuf,0,sizeof(StrBuf));
DataBuf = NULL;
FieldType = FIELD_TYPE_STRING;
}
MCIField::~MCIField()
{
if (DataBuf != NULL)
{
delete[] DataBuf;
DataBuf = NULL;
}
}
MCIQuery* MCIField::getParentQuery()
{
return pParentQuery;
}
void MCIField::setParentQuery(MCIQuery* pQry)
{
pParentQuery = pQry;
}
char* MCIField::getFieldName()
{
return FieldName;
}
char* MCIField::getStrBuf()
{
return StrBuf;
}
enum_field_types MCIField::getFieldType()
{
return FieldType;
}
unsigned int MCIField::getFieldLength()
{
return FieldLength;
}
void MCIField::setFieldName(const char* s)
{
memset(FieldName,0,sizeof(FieldName));
strncpy(FieldName,s,sizeof(FieldName)-1);
}
void MCIField::setFieldType(enum_field_types n)
{
FieldType = n;
}
void MCIField::setFieldLength(unsigned int n)
{
FieldLength = n;
}
MCIQuery::MCIQuery()
{
pDB = NULL;
pRes = NULL;
FieldNum = 0;
pFields = NULL;
pMCIFieldList = NULL;
RowNum = 0;
memset(SqlStr,0,sizeof(SqlStr));
CurrRow = 0;
/*
//检查超时用
ThreadExist = 0;
ThreadMode = 0;
QryID = 0;
ErrNo = 0;
memset(ErrInfo,0,sizeof(ErrInfo));
*/
}
//确定Qry指向的DataBase
void MCIQuery::setDB(MCIDatabase *dblink)
{
pDB = dblink;
}
MCIQuery::~MCIQuery()
{
if(pRes != NULL)
{
mysql_free_result(pRes);
pRes = NULL;
}
if(pMCIFieldList != NULL)
{
delete[] pMCIFieldList;
pMCIFieldList = NULL;
}
pFields = NULL;
}
//设置SQL语句
void MCIQuery::setSql(char* sqlstr)
{
memset(SqlStr,0,sizeof(SqlStr));
strcpy(SqlStr,sqlstr);
}
int MCIQuery::getRecordCount()
{
return RowNum;
}
//获得字段信息,并为字段分配取值的缓冲区
int MCIQuery::getFieldsDef()
{
pRes = mysql_store_result(pDB->getMySQL()); //获取结果集
pFields = mysql_fetch_fields(pRes); //获取MySQL字段信息
FieldNum = mysql_num_fields(pRes); //字段个数
if (FieldNum > 0)
{
pMCIFieldList = new MCIField[FieldNum];//建立自己的字段信息
MCIField *pCurrField = NULL;
for(int i = 0; i < FieldNum; i ++)
{
pCurrField = &pMCIFieldList;
//设置此字段名称-类型-字段宽度
pCurrField->setParentQuery(this);
pCurrField->setFieldName(pFields.name);
pCurrField->setFieldType(pFields.type);
pCurrField->setFieldLength(pFields.length);
if (pCurrField->getFieldLength() > MAX_FIELD_LEN)
{
//fprintf(stdout,"field:[%s]'s Length:[%d] More Than 1024\n",pCurrField->FieldName,pCurrField->FieldLength);fflush(stdout);
pCurrField->setFieldLength(MAX_FIELD_LEN);
}
//建立供输出数据的缓冲区
switch (pCurrField->getFieldType())
{
case FIELD_TYPE_SET:
throw MCIException("Not Supported Data Type:[FIELD_TYPE_SET]",1);
break;
case FIELD_TYPE_ENUM:
throw MCIException("Not Supported Data Type:[FIELD_TYPE_ENUM]",1);
break;
case FIELD_TYPE_NULL:
throw MCIException("Not Supported Data Type:[FIELD_TYPE_NULL]",1);
break;
default:
pCurrField->DataBuf = new unsigned char[pCurrField->getFieldLength() + 1];
memset(pCurrField->DataBuf,0,sizeof(pCurrField->DataBuf));
}
}
return 1;
}
return 0;
}
//移动到下一个记录,同时获取字段值
int MCIQuery::next()
{
if (RowNum <= 0) return 0;
if (CurrRow > RowNum) return 0;
//将当前行的各个列的值写入MCIField中
Row = mysql_fetch_row(pRes);
if (Row == NULL) return 0;
for(int i = 0; i < FieldNum; i ++)
{
if( (Row == NULL) || (pMCIFieldList.DataBuf == NULL) ) continue;
memcpy(pMCIFieldList.DataBuf,Row,pMCIFieldList.getFieldLength());
}
CurrRow++;
return 1;
}
MCIField* MCIQuery::field(int i)
{
if ( (i>=0) && (i
|
|
|