免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: BetonArmEE
打印 上一主题 下一主题

[C] [开源]C结构体工具DirectStruct,更新至v1.3.0 [复制链接]

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
41 [报告]
发表于 2014-10-13 13:59 |只看该作者
本帖最后由 yulihua49 于 2014-10-13 14:00 编辑
BetonArmEE 发表于 2014-10-13 13:50
回复 38# yulihua49

见4楼:
http://bbs.chinaunix.net/thread-4156642-1-1.html
你这个帖子我有点晕,不知回到哪了。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
42 [报告]
发表于 2014-10-13 14:05 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
43 [报告]
发表于 2014-10-13 14:06 |只看该作者
本帖最后由 yulihua49 于 2014-10-13 14:16 编辑
BetonArmEE 发表于 2014-10-13 13:46
回复 37# yulihua49
DBVLLIST_userinfo是自动生成的宏。

    泛化函数在运行处理时会否性能损失?泛化函数是否会不够灵活,比如在复杂SQL的表达上?
    我的DirectStruct在解决以上第一点时因为是直接生成特化代码,运行的也是特化代码,所以直接、简单、高效。在解决第二点时,推荐应用弃用SQLACTION功能,直接用ESQL来实现表达复杂SQL,但其中的很多冗余代码(如字段名列表)都还是可以直接调用自动生成的代码片段来避免繁琐的手工编码。

处理好了,性能损失可以忽略不计。
灵活度不由函数决定,由模板决定。

SDBC使用OCI,CLI和数据库的直接接口,今后支持ODBC。效率比PRO*C要高一些,测试过一个例子大约是2.5倍的性能。

在模板里你通常可以看到列名、表名,殊不知,它是列表达式,表表达式,所以可以写出任意复杂的SQL,如:
TEMPLATE cube 6
unit:=CH_CHAR 9
(select tabname from $DB.dict where tabname=:tabname) tabname:=CH_CHAR 9
flg:=CH_SHORT
count(*) count:=CH_INT
sum(dat1) s:=CH_INT64
avg(dat1) ag:=CH_DOUBLE
tjrb    tjdate|unit|tabname|flg|
>mktpl
输入元数据文件名: tcube.meta

T_PkgType cube_tpl[]={
        {CH_CHAR,9,"unit",0,-1},
        {CH_CHAR,9,"(select tabname from $DB.dict where tabname=:tabname) tabname"},
        {CH_SHORT,sizeof(short),"flg"},
        {CH_INT,sizeof(int),"count(*) count"},
        {CH_INT64,sizeof(INT64),"sum(dat1) s"},
        {CH_DOUBLE,sizeof(double),"avg(dat1) ag","%.2lf"},
        {-1,0,"tjrb","tjdate|unit|tabname|flg|"}
};

extern T_PkgType cube_tpl[];
typedef struct {
        char unit[9];
        char tabname[9];
        short flg;
        int count;
        INT64 s;
        double ag;
} cube_stu;

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
44 [报告]
发表于 2014-10-13 14:16 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
45 [报告]
发表于 2014-10-13 14:17 |只看该作者
本帖最后由 yulihua49 于 2014-10-13 14:36 编辑
BetonArmEE 发表于 2014-10-13 14:16
所以说,工具之间有交集,也有相当大的差集,需求不同,应用场景不同,采用的设计和接口风格也不同,即使相 ...

我还不知道这个平台。
登陆了,建立一个SDBC账户,还没有干什么。

同意。。。。
我看出来,你在这个领域很多年了,我也是做这类软件多年。不然的话,不会对这个问题有如此深入的思考。
所以,与你交流才有知音的感觉。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
46 [报告]
发表于 2014-10-13 14:32 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
47 [报告]
发表于 2014-10-13 14:37 |只看该作者
本帖最后由 yulihua49 于 2014-10-13 15:14 编辑
BetonArmEE 发表于 2014-10-13 14:32
回复 43# yulihua49

我更懒,根本不想写SQL,所以让工具框架去写。


  1. //插入一个表

  2. static int insert_a_table(T_SQL_Connect *db_conn,FILE *xfd)
  3. {
  4. char cols[4096],stmt[4096],*p,*savep;
  5. char *tabname;
  6. int ret,i,n;
  7. t_node node;
  8. ctx_stu ctx;
  9. T_Tree *cols_list=NULL;
  10. SdbcDAO *dao;
  11. //取出表名、列名
  12.     if(NULL==fgets(cols,sizeof(cols),xfd)) {
  13.           ShowLog(1," 没有数据!",__FUNCTION__);
  14.           return -1;
  15.     }
  16.     TRIM(cols);
  17.     tabname=strtok_r(cols,":",&savep);
  18.     if(!tabname) {
  19.           ShowLog(1,"%s: tabname is emypt!",__FUNCTION__);
  20.           return -1;
  21.     }
  22.      
  23.     strupper(tabname);
  24.     try {
  25.         dao=new SdbcDAO(db_conn,tabname);
  26.     } catch( ... ) {
  27.           ShowLog(1,"%s:%s Table not found!",__FUNCTION__,tabname);
  28.           return -2;
  29.     }
  30.     dao->Data_init();
  31.     ctx.dp=dao;
  32.     node.n=0;
  33. //生成加载列名表
  34.     while(NULL != (p=strtok_r(NULL,",",&savep))) {
  35.         if((255&*p) <= ' ') break;
  36.         node.tp=dao->getTemplate(p);
  37.         if(!node.tp) { //这个列的数据将被跳过
  38.           ShowLog(1,"%s:%s column [%s] not found!",__FUNCTION__,tabname,p);
  39.         }
  40.         node.n++;
  41.         cols_list=BB_Tree_Add(cols_list,&node,sizeof(node),node_cmp,NULL);
  42.     }
  43. //加载数据
  44.     char gbkbuf[4096];
  45.     for(i=0;fgets(stmt,sizeof(stmt),xfd);i++) {
  46. /*
  47.         if(has_cc(stmt)) {
  48.             ret=utf8togbk(stmt, sizeof(stmt), gbkbuf, sizeof(gbkbuf));
  49.             ctx.data=ctx.p=gbkbuf;
  50.         } else {
  51.             ctx.data=ctx.p=stmt;
  52.         }
  53. */
  54.         TRIM(stmt);
  55.         ctx.data=ctx.p=stmt;
  56.         ret=BB_Tree_Count(cols_list,&ctx,fill_cols);//每列值按列名定义的次序填充到dao。
  57.         *stmt=0;
  58.         ret=dao->insert(stmt);
  59.         if(ret<0) {
  60.             ShowLog(1,"%s:insert %s fault,i=%d,err=%d,%s",__FUNCTION__,stmt,i,
  61.                     db_conn->Errno,db_conn->ErrMsg);
  62.             break;
  63.             i--;
  64.         }
  65.     }

  66.     BB_Tree_Free(&cols_list,NULL);
  67.     delete dao;
  68.     return i;
  69. }
复制代码
完全泛型,只处理了文件中第一行第一列,是个表名。通篇没有SQL语句。但是,那个stmt,在插入第一条记录时,会有一个语句。后来就没有了,只是用游标,绑定变量进行操作,语句只解析一次,所以效率极高。
26行,特化dao为一个表,这个比较费时间,大约需要几毫秒至几十毫秒,但是只做一次,这对于要加载的数据量而言微不足道了。
但是在做OLTP时,这个开销就很可观。所以在OLTP环境,我们尽量事先生成模板,并显式的使用结构。
这里也可以看出,我们既需要序列化/反序列化功能,也需要数据库映射功能。
对于SRM,相当于JAVA的两种ORM:你的方法,类似于ibatis,我的类似Hibernate。都有自己的应用场景。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
48 [报告]
发表于 2014-10-13 16:45 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
49 [报告]
发表于 2014-10-13 21:12 |只看该作者
本帖最后由 大众推荐 于 2014-10-13 21:14 编辑

1.粗略浏览了2位的帖子,还没有仔细看你们的东西的具体用途,初步感觉是,
A. @BetonArmEE 的偏向于不同语言之间的序列化(类似于google protocol buffer?而据说这个不支持C),特别地,比较适合应用于网络传输?
B. @yulihua49 的偏向于不同语言之间的数据库操作?(其他方面暂时还没有仔细看)

2. 这段时间在实现一个APP的后台,是居于之前写的后台上修改的,主要的工作量在几个地方:
A.修改数据操作部分,占40%左右的工作量。之前用C来解析JASON,STRUCT <-->JSON 之间的代码改动最大。
B.数据库设计和操作,占30%左右的工作量。数据库<-->STRUCT的转换,改动很大。
C.其他流程/新功能改动,占30%左右的工作量。这个是针对新功能需求而改,几乎是无法避免。
D.以上改动的编码总时间大约不超过40个小时。

3.之前用C写了一个比较适应于短链接的服务器后台,貌似有如下优点:
A.单进程+线程池。自测比python tornado高效30%左右。
B.占用内存小,相对来说也比较稳定(上线1年还没有自动崩溃过,当然,不排除高压下长期跑,可能会发现有问题)。
C.自带部分DATA CACHE策略和管理。
D.新功能只需要添加一个call back就可以。也就是说服务器框架和具体的应用耦合比较小。

突发奇想,如果能把两位的优势也集合起来,貌似要实现一个:
A.运行高效
B.开发效率比较高
C.支持不同语言之间的数据传输
D.支持不同的数据库
的应用服务器,似乎并不是不可能的事情。。。。
下一个项目真的要好好看一下两位的作品了!



BetonArmEE 发表于 2014-10-13 16:45
回复 47# yulihua49

论坛徽章:
0
50 [报告]
发表于 2014-10-13 21:45 |只看该作者
好像YY多了。。。还是先做事吧。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP