【c操作mysql】极简封装,两行代码插入任何表单
/*************************************************************************
> File Name: mysqlTest.c
> Author:Gin.TaMa
> Mail:1137554811@qq.com
> Created Time: 2019年03月23日 星期六 09时51分25秒
************************************************************************/
#include<iostream>
#include<string>
#include<string.h>
#include<sstream>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<mysql/mysql.h>
using namespace std;
#define Fn_apply(type,fn,...){\
int tmp[] = {0};type *stopper_for_apply = (type*)tmp;\
type* list_for_apply[] = {__VA_ARGS__,stopper_for_apply};\
for(int i = 0;list_for_apply[i] != stopper_for_apply;i ++){\
fn(list_for_apply[i]);}\
}
#define Free_all(...) Fn_apply(void,free,__VA_ARGS__);
typedef struct mysqlCLR{
char * server;
char * user;
char * passwd;
char * db;
unsigned int port;
MYSQL*mysql;
}mysqlClr;
void freeMysqlClr(mysqlClr*clr){
Free_all(clr->server,clr->user,clr->passwd,clr->db);
mysql_close(clr->mysql);
}
int connectDatabase(mysqlClr* clr){
clr->mysql = mysql_init(NULL);
if(mysql_real_connect(clr->mysql,clr->server,clr->user,clr->passwd,clr->db,0,NULL,0)){
return 1;
}else{
perror("wrong connect");
return 0;
}
}
#define coutFn(string){sin <<"'" << string << "',";}
#define getInsertSQL(s,tables,...){\
ostringstream sin;\
sin << "insert into "<<tables<<" ("<<#__VA_ARGS__<<") values (";\
Fn_apply(char,coutFn,__VA_ARGS__);\
s = sin.str();s[s.length() - 1] = ')';}
// 插入算是封装完了
#define inserDataNew(clr,...){\
string query;\
getInsertSQL(query,__VA_ARGS__);\
if(mysql_query(clr.mysql,query.c_str())){\
cout << "query failde " << query << endl;}\
}
// fetchAll 封装完毕
int fetchAll(mysqlClr*clr,string tables,void(*dofetch)(MYSQL_ROW,void*),void* arg){
MYSQL* tmp = clr -> mysql;
string a = "select * from "+tables;
if(mysql_query(tmp,a.c_str())){
printf("wrong\n");
return 0;
}
MYSQL_RES *res; //行的一个查询结果集
res = mysql_store_result(tmp);
int i = 0;
MYSQL_ROW column; //数据行的列
while(column = mysql_fetch_row(res)){
dofetch(column,arg);
i ++;
}
return i;
}
/
// 使用
// 某个表单
typedef struct types{
char* tid;
char* tname;
}types;
// 回调函数用来填充数据的
void getTypes(MYSQL_ROW c,void* arg_){
vector<types*>* arg = (vector<types*>*)arg_;
types* tmp = new types();
tmp->tid = strdup(c[0]);
tmp->tname = strdup(c[1]);
arg -> push_back(tmp);
}
int main(){
// 初始化
mysqlClr clr;
asprintf(&clr.server,"localhost");
asprintf(&clr.user,"root");
asprintf(&clr.passwd,"536842");
asprintf(&clr.db,"piHealth");
clr.port = 3306;
if(!connectDatabase(&clr)){
return -1;
}
vector<types*> t;
// 插入
char tid[] = "1";
char tname[] = "aa";
// 这个是可变参的。
inserDataNew(clr,/*表名*/,tid,tname);
// 取数据
fetchAll(&clr,"types",getTypes,(void*)&t);
for(auto item:t){
printf("%s:%s\n",item->tid,item->tname);
}
freeMysqlClr(&clr);
return 0;
}
这个就是使用变参宏实现的一个封装,
比如对于这个样的表单
+-----+-------+
| tid | tname |
+-----+-------+
我要插入一个条记录只用写两行代码
char tid[] = "1";char tname[] = "aa";
inserDataNew(clr,/*表名*/,tid,tname);
而且是具有扩展性。
对于这个表,只要这么写就OK了
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| nid | int(11) | NO | PRI | NULL | auto_increment |
| ntime | datetime(5) | YES | | NULL | |
| nip | varchar(20) | NO | | NULL | |
| ntypes | int(5) | NO | | NULL | |
| ndetails | varchar(255) | NO | | NULL | |
+----------+--------------+------+-----+---------+----------------+
char nid[] = "123";
char ntime[] = "qqq";
char nip[] = "123456";
char ntypes[] = "12345";
char ndetails[] = "yes";
inserDataNew(clr,"notes_events",nid,ntime,nip,ntypes,ndetails);
使用还是蛮简单的啦。