信息来源: CU
郑重声明:本MCI程序已经过严格的,长时间的反复测试和使用!
可支持对char,varchar,varchar2,int,float等类型数据进行各种select,update,insert操作
欢迎C++高手,MySQL来指点
本接口程序用C++完成,尤其适合server端使用,可通行于Linux/Unix/Windows平台
包括:mci.hmci.cpp以及测试用例test.htest.cpp和一个makefile文件,可直接在RedHat上编译运行
本接口功能相信可满足大部分朋友的需要,你只需在你的程序里面包含这两个文件即可
(当然相应的makefile文件也需修改)
作者:欧昕中国-成都欢迎大家改进之,让其功能更加强大,我的联系QQ:30991118,欢迎骚扰...:)
[mci.h]:
[CODE]
#ifndef_MCI_H_
#define_MCI_H_
#include
#include
#include
#include
#include
#include
#include"/usr/local/mysql/include/mysql.h"
constunsignedintMAX_FIELD_LEN=1024*1;
classMCIException
{
public:
int ErrNo;
char ErrInfo[256];
MCIException(constchar*errinfo,interrno);
char*getErrInfo();
intgetErrNo(){returnErrNo;};
//自定义错误类型
//1不支持的字段类型
//2字段越界
//3字段不存在
//MySQL内部错误类型
//2002Can'tconnecttolocalMySQLserverthroughsocket
//2003Can'tconnecttoMySQLserver
//2013LostconnectiontoMySQLserverduringquery
//1045Accessdeniedforuser
};
classMCIDatabase
{
public:
charDBIP[20];//数据库IP地址
charUser[10]; //用户名
charPwd[10]; //密码
charDBName[20];//数据库名
MYSQL*mysql;
public:
MCIDatabase();
MYSQL*getMySQL(){returnmysql;};
voidsetLogin(constchar*dbip,constchar*usr,constchar*pwd,constchar*dbname);
intconnect();
voiddisConnect();
};
classMCIField
{
public:
friendclassMCIQuery;
MCIQuery*pParentQuery; //指向该Field所属于的Query
charFieldName[30]; //字段名称(目前支持30长度)
char StrBuf[255]; //用于保存转换为字符串后的值
unsignedchar* DataBuf; //预绑定缓冲区
enum_field_typesFieldType; //MySQL内部数据类型
unsignedint FieldLength; //数据长度
public:
MCIField();
~MCIField();
voidsetFieldName(constchar*s);
voidsetFieldType(enum_field_typesn);
voidsetFieldLength(unsignedintn);
char*getFieldName();
char*getStrBuf();
enum_field_typesgetFieldType();
unsignedintgetFieldLength();
MCIQuery*getParentQuery();
voidsetParentQuery(MCIQuery*pQry);
staticvoidtrimLeft(char*str);
staticvoidtrimRight(char*str);
staticchar*allTrim(char*str);
char*asString();
intasInteger();
floatasFloat();
charasChar(intpos=0);
};
classMCIQuery
{
public:
MCIDatabase*pDB;
MYSQL_RES*pRes;
intFieldNum;//字段个数
MYSQL_FIELD*pFields; //得到的字段信息
MCIField*pMCIFieldList;//在内部保存的所有字段信息
MYSQL_ROWRow;
intRowNum;
charSqlStr[1024*3];
int CurrRow;
/*
//检查超时用
int ThreadExist;
int ThreadMode;
pthread_tQryID;
intErrNo;
charErrInfo[256];
*/
public:
MCIQuery();
voidsetDB(MCIDatabase*dblink);
~MCIQuery();
voidsetSql(char*sqlstr);
voidopen();//执行select型SQL语句
intgetFieldsDef();//获得字段信息,并为字段分配取值的缓冲区
intgetRecordCount(); //返回查询到的符合条件的记录的条数
intnext(); //移动到下一个记录,同时获取字段值
MCIField*field(inti);//取相应字段值
MCIField*fieldByName(constchar*s);
intexec(); //执行insert,update型SQL语句,返回被此语句影响的记录条数
voidclose(); //关闭一个Query,为下次执行做准备
/*
//检查超时用
intrunSql();
staticvoid*QryThread(void*arg);
*/
};
#endif
[mci.cpp]:
#include"mci.h"
MCIException::MCIException(constchar*errinfo,interrno)
{
memset(ErrInfo,0,sizeof(ErrInfo));
strncpy(ErrInfo,errinfo,sizeof(ErrInfo)-1);
ErrNo=errno;
}
char*MCIException::getErrInfo()
{
returnErrInfo;
}
MCIDatabase::MCIDatabase()
{
memset(DBName,0,sizeof(DBName));
memset(User,0,sizeof(User));
memset(Pwd,0,sizeof(Pwd));
mysql=NULL;
}
//设置登陆信息
voidMCIDatabase::setLogin(constchar*dbip,constchar*usr,constchar*pwd,constchar*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);
}
//连接到数据库
intMCIDatabase::connect()
{
mysql=NULL;
mysql=mysql_init(NULL);
if(mysql==NULL)
{
charerrinfo[256];
memset(errinfo,0,sizeof(errinfo));
sprintf(errinfo,"%s\n",mysql_error(mysql));
interrno=mysql_errno(mysql);
throwMCIException(errinfo,errno);
return0;
}
unsignedinttimeout=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)
{
charerrinfo[256];
memset(errinfo,0,sizeof(errinfo));
sprintf(errinfo,"%s\n",mysql_error(mysql));
interrno=mysql_errno(mysql);
throwMCIException(errinfo,errno);
return0;
}
return1;
}
//关闭连接
voidMCIDatabase::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()
{
returnpParentQuery;
}
voidMCIField::setParentQuery(MCIQuery*pQry)
{
pParentQuery=pQry;
}
char*MCIField::getFieldName()
{
returnFieldName;
}
char*MCIField::getStrBuf()
{
returnStrBuf;
}
enum_field_typesMCIField::getFieldType()
{
returnFieldType;
}
unsignedintMCIField::getFieldLength()
{
returnFieldLength;
}
voidMCIField::setFieldName(constchar*s)
{
memset(FieldName,0,sizeof(FieldName));
strncpy(FieldName,s,sizeof(FieldName)-1);
}
voidMCIField::setFieldType(enum_field_typesn)
{
FieldType=n;
}
voidMCIField::setFieldLength(unsignedintn)
{
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
voidMCIQuery::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语句
voidMCIQuery::setSql(char*sqlstr)
{
memset(SqlStr,0,sizeof(SqlStr));
strcpy(SqlStr,sqlstr);
}
intMCIQuery::getRecordCount()
{
returnRowNum;
}
//获得字段信息,并为字段分配取值的缓冲区
intMCIQuery::getFieldsDef()
{
pRes=mysql_store_result(pDB->getMySQL());//获取结果集
pFields=mysql_fetch_fields(pRes); //获取MySQL字段信息
FieldNum=mysql_num_fields(pRes); //字段个数
if(FieldNum>0)
{
pMCIFieldList=newMCIField[FieldNum];//建立自己的字段信息
MCIField*pCurrField=NULL;
for(inti=0;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]'sLength:[%d]MoreThan1024\n",pCurrField->FieldName,pCurrField->FieldLength);fflush(stdout);
pCurrField->setFieldLength(MAX_FIELD_LEN);
}
//建立供输出数据的缓冲区
switch(pCurrField->getFieldType())
{
caseFIELD_TYPE_SET:
throwMCIException("NotSupportedDataType:[FIELD_TYPE_SET]",1);
break;
caseFIELD_TYPE_ENUM:
throwMCIException("NotSupportedDataType:[FIELD_TYPE_ENUM]",1);
break;
caseFIELD_TYPE_NULL:
throwMCIException("NotSupportedDataType:[FIELD_TYPE_NULL]",1);
break;
default:
pCurrField->DataBuf=newunsignedchar[pCurrField->getFieldLength()+1];
memset(pCurrField->DataBuf,0,sizeof(pCurrField->DataBuf));
}
}
return1;
}
return0;
}
//移动到下一个记录,同时获取字段值
intMCIQuery::next()
{
if(RowNum<=0)return0;
if(CurrRow>RowNum)return0;
//将当前行的各个列的值写入MCIField中
Row=mysql_fetch_row(pRes);
if(Row==NULL)return0;
for(inti=0;i{
if((Row==NULL)||(pMCIFieldList.DataBuf==NULL))continue;
memcpy(pMCIFieldList.DataBuf,Row,pMCIFieldList.getFieldLength());
}
CurrRow++;
return1;
}
MCIField*MCIQuery::field(inti)
{
if((i>=0)&&(ireturn&pMCIFieldList;
else
{
charerrinfo[256];
memset(errinfo,0,sizeof(errinfo));
sprintf(errinfo,"Field:[%d]OutOfBound",i);
interrno=2;
throwMCIException(errinfo,errno);
}
}
MCIField*MCIQuery::fieldByName(constchar*s)
{
for(inti=0;i{
if(strcmp(pMCIFieldList.getFieldName(),s)==0)
return&pMCIFieldList;
}
charerrinfo[256];
memset(errinfo,0,sizeof(errinfo));
sprintf(errinfo,"Field:[%s]NotFind",s);
interrno=3;
throwMCIException(errinfo,errno);
}
char*MCIField::allTrim(char*szString)
{
trimLeft(szString);
trimRight(szString);
returnszString;
}
voidMCIField::trimLeft(char*str)
{
intiStart=0;
intiLen,iCount;
iLen=strlen(str);
while((str[iStart]=='')||(str[iStart]=='\t'))iStart++;
for(iCount=iStart;iCount<=iLen;iCount++)
{
str[iCount-iStart]=str[iCount];
}
}
voidMCIField::trimRight(char*str)
{
intlen=strlen(str);
while(1)
{
if(len<=0)break;
if((str[len-1]=='')||(str[len-1]=='\t'))
{
str[len-1]=0;
len--;
}
else
break;
}
}
char*MCIField::asString()
{
staticcharnullstr[]="";
char*p=(char*)DataBuf;
if((p==NULL)||(strlen(p)==0))
{
returnnullstr;
}
else
returnallTrim(p);
}
intMCIField::asInteger()
{
return(atoi((char*)DataBuf));
}
floatMCIField::asFloat()
{
return(atof((char*)DataBuf));
}
charMCIField::asChar(intpos)
{
returnDataBuf[pos];
}
voidMCIQuery::close()
{
memset(SqlStr,0,sizeof(SqlStr));
if((RowNum>0)&&(pRes!=NULL))
{
mysql_free_result(pRes);
pRes=NULL;
}
if(FieldNum>0)
{
for(inti=0;i{
MCIField*pCurrField=&pMCIFieldList;
delete[]pCurrField->DataBuf;
pCurrField->DataBuf=NULL;
}
}
if(pMCIFieldList!=NULL)
{
delete[]pMCIFieldList;
pMCIFieldList=NULL;
}
if(pFields!=NULL)
{
//deletepFields;
pFields=NULL;
}
FieldNum=0;
RowNum=0;
CurrRow=0;
}
//执行需要返回结果集的SQL语句
voidMCIQuery::open()
{
if(pDB->getMySQL()==NULL)return;
/*
//fprintf(stdout,"mysql_ping\n");fflush(stdout);
if(mysql_ping(pDB->getMySQL())!=0)
{
//fprintf(stdout,"mysql_pingfailure\n");fflush(stdout);
intErrNo=mysql_errno(pDB->getMySQL());
charErrInfo[256];
memset(ErrInfo,0,sizeof(ErrInfo));
sprintf(ErrInfo,"%s\n",mysql_error(pDB->getMySQL()));
throwMCIException(ErrInfo,ErrNo);
}
*/
if(mysql_real_query(pDB->getMySQL(),SqlStr,strlen(SqlStr))!=0)
{
intErrNo=mysql_errno(pDB->getMySQL());
charErrInfo[256];
memset(ErrInfo,0,sizeof(ErrInfo));
sprintf(ErrInfo,"%s\n",mysql_error(pDB->getMySQL()));
throwMCIException(ErrInfo,ErrNo);
}
if(getFieldsDef()==1)
{
RowNum=mysql_num_rows(pRes);
CurrRow=0;
}
}
intMCIQuery::exec()
{
if(pDB->getMySQL()==NULL)return0;
/*
//fprintf(stdout,"mysql_ping\n");fflush(stdout);
if(mysql_ping(pDB->getMySQL())!=0)
{
//fprintf(stdout,"mysql_pingfailure\n");fflush(stdout);
intErrNo=mysql_errno(pDB->getMySQL());
charErrInfo[256];
memset(ErrInfo,0,sizeof(ErrInfo));
sprintf(ErrInfo,"%s\n",mysql_error(pDB->getMySQL()));
throwMCIException(ErrInfo,ErrNo);
}
*/
//fprintf(stdout,"mysql_real_query\n");fflush(stdout);
if(mysql_real_query(pDB->getMySQL(),SqlStr,strlen(SqlStr))!=0)
{
//fprintf(stdout,"mysql_real_queryfailure\n");fflush(stdout);
intErrNo=mysql_errno(pDB->getMySQL());
charErrInfo[256];
memset(ErrInfo,0,sizeof(ErrInfo));
sprintf(ErrInfo,"%s\n",mysql_error(pDB->getMySQL()));
throwMCIException(ErrInfo,ErrNo);
}
//fprintf(stdout,"mysql_real_querysuccess\n");fflush(stdout);
returnmysql_affected_rows(pDB->getMySQL());
}
[test.h]//呵呵,test.h其实什么东西都没有,只是一个架子
#ifndef_TEST_H_
#define_TEST_H_
#include"mci.h"
#endif
[test.cpp]
#include"test.h"
MCIDatabaseMCIDB;
intmain(intargc,char*argv[])
{
charSqlStr[256];
try
{
//连接数据库
MCIDB.disConnect();
MCIDB.setLogin("192.168.0.111","sa","abc","atcdb");
MCIDB.connect();
fprintf(stdout,"connectdbsuccess\n");fflush(stdout);
//创建一个Query
MCIQuery*q=newMCIQuery();
q->setDB(&MCIDB);
//执行select语句
memset(SqlStr,0,sizeof(SqlStr));
strcpy(SqlStr,"select*fromtable1");//假设有表table1
q->close();
q->setSql(SqlStr);
q->open();
while(q->next())
{
fprintf(stdout,"%s\n",q->fieldByName("field1")->asString());fflush(stdout);//假设该表有varchar2型字段field1
}
//执行update或insert语句
q->close();
sprintf(sql,"deletefromtable1");
q->setSql(sql);
q->exec();
q->close();
//释放内存
deleteq;
MCIDB.disConnect();
}
catch(MCIException&oe)
{
fprintf(stdout,"%s\n",oe.getErrInfo());
MCIDB.disConnect();
deleteq;
}
}
[/CODE]
[makefile]
CC =g++
CFLAGS =-Wall
SQLHOME =-L/usr/lib64-lmysqlclient
all:test
test:mci.otest.o
$(CC)-s-otest-m64*.o$(SQLHOME)
mci.o:mci.cppmci.h
$(CC)$(CFLAGS)-cmci.cpp
test.o:test.cpptest.h
$(CC)$(CFLAGS)-ctest.cpp
clean::
rm-f*.o