哈,说对了。
还要回答大家一个问题,泛型编程效率高吗?是不是因为需要一些语句的组装和类型的判断就牺牲了一定的性能呢?下面举个例子,这是一个可以加载任何单表的程序,为了逻辑清晰,略去了错误处理:
int loadfile(T_SQL_Connect *SQL_Connect,char *tablename,FILE *ifd,
FILE *ofd,int Pflg,char *buf,int buflen,char dlmt)
{
char *p,tabn[512];
DAU _DAU;
int rows,ret;
int upd,loss;
int num;
INT64 now;
ret=DAU_init(&_DAU,SQL_Connect,tablename,0,0);//依据tablename,从数据库建立模板
upd=loss=0;
num=0;
now=now_usec();
for(rows=0;!ferror(ifd);rows++) {
fgets(buf,buflen,ifd);
if(feof(ifd)) break;
if(dlmt=='J') {//JSON格式
JSON_OBJECT json=json_tokener_parse(buf);
DAU_fromJSON(&_DAU,json); //泛型,JSON反序列化到DAU里边的struct。
json_object_put(json);
} else {//CSV格式
ret=DAU_pkg_dispack(&_DAU,buf,dlmt);//泛型,CSV反序列化到DAU里边的struct
}
*buf=0;
ret=DAU_insert(&_DAU,buf);//虽然在循环体里,但只有第一次会生成语句,打开游标,绑定变量。之后,只进行bind和exec,所以效率是非常高的。
。。。。。。。。。
}
【 在 z16166 的大作中提到: 】
: 现阶段反射的实现,处理meta信息,只能是要么用宏,要么用预处理了
: 用预处理的库也有现成的,比如开源的ODB,支持ORM
: ylh1969老哥说的是他在pure C时代的实现,他跟我们讨论C++的实现那是财务自由退休了放不下技术讨论着玩
: ...................
--
修改:ylh1969 FROM 221.221.52.*
FROM 221.221.52.*
89楼的那个回调函数,绑定变量操作,不过是一堆switch....case..
效率不会太低吧!
static int bind_proc(void *content) //bind处理
{
register struct bindnod *bp;
T_PkgType *tp;
char *p,*bindp;
int ret,n;
short nf;
bp=(struct bindnod *)content;
p=*bp->tail;
tp=bp->tp;
bindp=*(bp->rec)+tp->offset;//要绑定的位置
//bind NULL
nf=isnull(bindp,tp->type)?-1:0;
if(1&bp->flg) bp->flg=!(nf ^ bp->ind); //如果NULL状态有变化,清空免bind标志
bp->ind=nf;
ret=0;
if(!(1&bp->flg)) {
//ShowLog(5,"bind_proc sth=%d,%s:%d",*bp->sth,tp->name,bp->bindnum);
switch(tp->type) {
#ifdef SDBC_PTR_63+1
case CH_INT63+1:
#endif
case CH_LONG:
case CH_TINY:
case CH_SHORT:
case CH_INT:
ret=sqlo_bind_by_pos(*bp->sth, bp->bindnum, SQLOT_INT, bindp, tp->len, &bp->ind, 0);
bp->flg=1; //下次免bind
break;
case CH_FLOAT:
case CH_DOUBLE:
ret=sqlo_bind_by_pos(*bp->sth, bp->bindnum, SQLOT_FLT, bindp, tp->len, &bp->ind, 0);
bp->flg=1; //下次免bind
break;
case CH_BYTE:
ret=sqlo_bind_by_pos(*bp->sth, bp->bindnum, SQLOT_BIN, bindp, tp->len, &bp->ind, 0);
bp->flg=1; //下次免bind
break;
case CH_CHAR:
case CH_CNUM:
case CH_DATE:
ret=sqlo_bind_by_pos(*bp->sth, bp->bindnum, SQLOT_STR, bindp, tp->len, &bp->ind, 0);
bp->flg=1; //下次免bind
break;
default: //类型与ORACLE不符,需变换
bindp=p;
if(tp->bindtype & RETURNING) { //bind RETURNING
n=40;
*bindp=0;
p=bindp+n; //CH_JUL...CH_USEC,.....
bp->flg=2;
} else {
p+=get_one_str(p,*bp->rec,tp,0);
n=strlen(bindp)+1;
if(n<40) n=40;
bp->flg=0;
}
ret=0;
if(bindp != bp->last_bindp) {
ret=sqlo_bind_by_pos(*bp->sth, bp->bindnum, SQLOT_STR, bindp,n,&bp->ind, 0);
bp->last_bindp=bindp;
}
*(++p)=0;
break;
}
}
*bp->tail=p;
return 0;
}
【 在 ylh1969 的大作中提到: 】
: 再来看看DAU_insert是干啥的:
: 经过环境检查后,调用:
: int bind_ins(register DAU *DP,char *buf)
: ...................
--
修改:ylh1969 FROM 221.221.52.*
FROM 221.221.52.*