- 主题:如何写一个函数能够序列化任意结构
注意这个函数没有指定任何特定结构,就是void *data,
全靠后边那个参数,typ,来认识这个data。
【 在 ylh0315 的大作中提到: 】
: 看看程序是怎样的:
: JSON_OBJECT stu_to_json(JSON_OBJECT json,void *data,T_PkgType * typ,const char *choose,char *colidx)
: {
: ...................
--
FROM 221.218.61.*
分析.h,.hpp来建立模板,理论上可以,实际上有点复杂。
我用了个相反的方法,写一个元文件,描述一个数据结构。然后用它生成一个结构和一个模板。这就是半自动的方法。
全自动的方法是,在数据库里读表结构,自动生成结构和模板。
【 在 RunningOn 的大作中提到: 】
: 如果说是通过程序来分析.h/.cpp文件来自动建立结构,那问题就简单一些了。
: python里有个pycparser工具,就能分析C的代码结构了。
: python还有个CppHeaderParser,听名字就知道是专门用来解析c++头文件的,解析的结果很
: ...................
--
FROM 221.218.61.*
是。
由struct生成模板比较困难,由表结构生成结构和模板比较容易。整个方案是在学习了JAVA的HIBNATE后设计的。
【 在 StephenLee 的大作中提到: 】
: 你这个只适合搞逆向的事情,比如你说的SRM系统。自动化生成你的模板,前提是数据库schema是定义好的。
: ORM一般是正向来干的,用户代码定义结构体,编译自动生成数据库访问相关代码,运行时自动建表
--
FROM 221.218.61.*
整个方案考虑了字节对齐。
每个数据库类型都有c类型对应,按照c类型的对齐规则。
这个设计允许结构套结构,但是不允许套结构指针。
【 在 DoorWay 的大作中提到: 】
: 明白了,除了根据表定义生成数据结构,带正反序列化到某种指定结构化的文档或数据格式,
: 你的另一个研究点在于从数据库里拖出一块内存,像解析流一样,或先分行,再把每行分成字段(根据每个成员变量的描述,即字节长度),这样一大块内存(查询结果)就变成了多个C的结构体。
: 只考虑字节长度是不够的,还要考虑对齐问题。这用C语言来做描述挺合适。我的应用数据库不是重点,没考虑这个。不过好奇,每种数据库查询结果,内存块里各行的各字段,对齐是一样的吗?应该也需要实战调试到稳定吧。
: ...................
--
修改:ylh1969 FROM 221.218.61.*
FROM 221.218.61.*
1000条记录用结构数组表示。
每条记录一个结构,一个数组一个结果集。
int loadfile(char *tablename,FILE *ifd,char *buf,int buflen,char dlmt)
{
char *p,tabn[512];
OAD oad;
int ret;
int n,num;
INT8 now;
T_SQL_Connect *SQL_Connect;
struct batch_data *bp;
char *recs=NULL;
int rec_siz;
ret=get_DB_connect(&SQL_Connect,0);
if(ret) return -1;
// ShowLog(5,"loadfile:entry dlmt=0X%02X",dlmt&255);
now=now_usec();
ret=DAU_init(&_DAU,SQL_Connect,tablename,0,0);//按照tablename表结构,生成模板和数据结构。
if(ret) {
ShowLog(1,"loadfile:DAU_init tabname=%s,ret=%d",tablename,ret);
return -1;
}
rec_siz=DAU_RecSize(&_DAU);//求出struct的尺寸。
。。。。。。。。。
for(rows=0;!ferror(ifd);) {
if(!recs) {
recs=malloc(BATCH_NUM*rec_siz);//分配数组,用完由thread释放
p=recs;
}
if(!fgets(buf,buflen,ifd)) break;
TRIM(buf);
if(!*buf) continue;
pkg_dispack(p,buf,_DAU.srm.tp,dlmt);//用buf的数据填充这个结构
p+=rec_siz;
if(BATCH_NUM == ++n) {
ret=put_to_thread(n,recs);//发射到线程池进行多线程批量插入。
recs=NULL;
n=0;
}
}
}
if(n) {
ret=put_to_thread(n,recs);
n=0;
} else if(recs) free(recs);
【 在 DoorWay 的大作中提到: 】
: 你这个handle是?base也是自己算的吗?
: 假设查询结果返回1000条记录,怎么遍历这1000条记录,这1000条记录在内存里表示,各个数据库都一样?
: 不考虑你的结构体,想明白数据库结果集的内存表示。
--
修改:ylh1969 FROM 221.218.61.*
FROM 221.218.61.*
【 在 DoorWay 的大作中提到: 】
: 你这个handle是?base也是自己算的吗?
: 假设查询结果返回1000条记录,怎么遍历这1000条记录,这1000条记录在内存里表示,各个数据库都一样?
: 不考虑你的结构体,想明白数据库结果集的内存表示。
base和offset的计算是系统的基本功能,一切在此基础之上。
--
FROM 221.218.61.*
【 在 DoorWay 的大作中提到: 】
: 换了一种数据库,你这也方案也得改改生成那部分代码,生成新表的“模板”,对吧?
目前支持ORACLE,DB2,MYSQL。
其他数据库需要重新写数据库接口部分。
hanle叫做DAU,Data Access Unit。其中分为2部分,一个是映象器,就是结构和模板,一个是访问器,包括数据库句柄,游标,绑定区。。。。。。
不同的数据库,访问器需要修改,外部使用的应用程序不需要修改。
--
FROM 221.218.61.*
【 在 Bernstein 的大作中提到: 】
: 那没必要弄成结构,这种处理也没什么意义,因为效率较低
:
必须弄成结构。不然,数据库的批量插入,M行N列,没办法弄通用的批量绑定。
--
FROM 221.218.61.*
【 在 RunningOn 的大作中提到: 】
: 原来标题里说的“结构”不是指 struct 或 class ...
:
是struct。
用数据库生成模板,依据模板生成一个与对应结构一样布局的内存区域。
然后可以直接使用,也可以把这两东西转换成C程序文件输出。
57楼和58楼就是用数据库生成的,include到应用程序里就可以用了。
缺点是,数据结构如果改变,就要重新生成。
--
修改:ylh1969 FROM 221.218.61.*
FROM 221.218.61.*
嗯。JAVA的与我的对应功能叫ORM.
【 在 StephenLee 的大作中提到: 】
: 抱歉我以为楼主的SRM是供应链系统呢,原来还有别的含义,我狭隘了
--
FROM 221.218.61.*