#include
typedef std::string string; struct mysql_parm{ string host; string user; string password; string database; string unixsock; }; class DBSTMT; class DBMysql; class DBSTMT{ DBSTMT(const DBSTMT&); DBSTMT& operator=(const DBSTMT&); MYSQL_STMT* stmt_; public: DBSTMT(pcsz_t query,DBMysql& mysql); void execute(){ if(mysql_stmt_execute(stmt_)) throw mysql_stmt_error(stmt_); } void execute(MYSQL_BIND* bind){ if(mysql_stmt_execute(stmt_)) throw mysql_stmt_error(stmt_); if(mysql_stmt_bind_result(stmt_,bind)){ throw mysql_stmt_error(stmt_); } if(mysql_stmt_store_result(stmt_)) throw mysql_stmt_error(stmt_); } //void execute(){ // if(mysql_stmt_execute(stmt_)) // throw mysql_stmt_error(stmt_); //} void bind(MYSQL_BIND* bind){ if(mysql_stmt_bind_param(stmt_,bind) ) throw mysql_stmt_error(stmt_); } int fetch(){ return mysql_stmt_fetch(stmt_)==0; } ~DBSTMT(){ if(stmt_){ mysql_stmt_close(stmt_); } } };
class DBMysql{ DBMysql(const DBMysql&); DBMysql&operator=(const DBMysql&); MYSQL * mysqlPtr_;
uint32_t errno_; protected: friend class DBSTMT; MYSQL_STMT* _createSTMT(){ MYSQL_STMT *ret=mysql_stmt_init(mysqlPtr_); if(ret) return ret; errno_=mysql_errno(mysqlPtr_); throw mysql_error(mysqlPtr_); } public: const char* strerr(){ return mysql_error(mysqlPtr_); } DBMysql():mysqlPtr_(NULL){ mysqlPtr_=mysql_init(NULL); if(NULL== mysqlPtr_) throw "Mysql :outof memory"; } void open(const mysql_parm& parm){ if(!mysql_real_connect(mysqlPtr_, parm.host.c_str(), parm.user.c_str(), parm.password.c_str(), parm.database.c_str(), 0, parm.unixsock.c_str(), 0 )) { errno_=mysql_errno(mysqlPtr_); throw(mysql_error(mysqlPtr_)); } }
void close(){ if(mysqlPtr_) { mysql_close(mysqlPtr_); mysqlPtr_=NULL; } }
};
DBSTMT::DBSTMT(pcsz_t query,DBMysql& mysql):stmt_(NULL){ stmt_=mysql._createSTMT(); if(!stmt_) throw mysql.strerr(); if( mysql_stmt_prepare(stmt_,query,strlen(query)) ) { //const char* err=
throw mysql_stmt_error(stmt_); }
}
#define DECL_BIND(h,n)\ class bind_##h:public h{\ typedef h parent;\ MYSQL_BIND _bind[n];\ my_bool _is_null[n];\ unsigned long _length[n];\ public:\ bind_##h(){\ int i=0;\ bzero(_bind,sizeof(_bind));
#define BIND_BIN(x,l)\ _bind[i].buffer_type= MYSQL_TYPE_STRING;\ _bind[i].buffer= (char *)&(parent::x);\ _bind[i].buffer_length= l;\ _bind[i].is_null= _is_null+i;\ _bind[i].length= _length+i;\ ++i;
#define BIND_INT(x)\ _bind[i].buffer_type= MYSQL_TYPE_LONG;\ _bind[i].buffer= (char *)&(parent::x);\ _bind[i].buffer_length= 0;\ _bind[i].is_null= _is_null+i;\ _bind[i].length= _length+i;\ ++i;
#define END_BIND(h) }\ operator MYSQL_BIND*(){\ return _bind;\ }\ };
使用方法;
例如想查询的内容具有以下结构 struct account{ char user[36]; byte password[16]; uint32_t status; uint32_t id; };
//声明查询bind 结构account,参数4个 DECL_BIND(account,4) BIND_BIN(user,32) BIND_BIN(password,16) BIND_INT(status) BIND_INT(id) END_BIND(account)
int main(){
try{ DBMysql mysql; mysql_parm parm; parm.host="localhost"; parm.user="root"; parm.password="test"; parm.unixsock="/var/lib/mysql/mysql.sock"; parm.database="testdb"; mysql.open(parm);//打开数据库 DBSTMT smt("select user,password,status,id from account",mysql); //生成一个查询语法 DBSTMT smt1("insert into account(user,password,status) value(?,?,?)",mysql); //另外一个 // bind_account acc;
smt.execute(acc);//执行查询,并bind返回结果到account结构 while(smt.fetch()){ printf("%s %d %d\n",acc.user,acc.status,acc.id); };
smt1.bind(acc);//bind查询参数 smt1.execute();//执行 }catch(const char* err){ printf("error:%s\n",err); }
}
|