hdqqq

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  35 随笔 :: 0 文章 :: 104 评论 :: 0 Trackbacks

     c++在数据库开发这种需要进行快速开发的地方一直是以效率低下著称,borland 的c++ build 依赖vcl提供的组件勉强可以实现,但是由于用的是pascal的东西,根基不行,一直叫不响.再看看现在流行的数据库,sql server 和mysql 等虽然提供本地开发的头文件和库,但是对于一些可能使用不同数据库的应用来说,选择特定某种数据库开发显然是不妥,因此,象ado这种数据操作接口大行其道.这又给用c++开发带来了麻烦,象vb等工具可以自动转换variant类型,但是在vc使用的时候却很麻烦.网上那些使用ado接口的c++的例子,大多数都从#import 那个dll开始, 然后就是繁琐的创建instance,打开记录集,最后还要进行一个variant到c++类型的转换,确实是够麻烦的,难怪效率低下.
 
    在很多情况下,一些数据查询和数据操作往往是在开发的时候就确定下来了,比如说你有个用户表要操作,你在开发的时候就知道这个表中的所有字段名称和字段类型,但是你用ado,你却还是要和繁琐的variant打交道,把它转换为你想要的数据类型. 如果能实现一个类,在知晓数据表字段类型的情况下,可以方便地使用c++数据类型,并且可以进行诸如插入,删除,更新等操作,那就方便多了.  这就是本文想实现的目标.  但是对于那些在运行时候才确定的数据操作,如用户输入一个 sql 查询,然后再来进行操作,对于象c++ 这种强类型的语言来说,可能除了使用 variant别无他法, 对于这方面,本文没有给出解决办法.

本文中的代码在vc6下编译通过
需要的库 loki for vc6, boost

一. 构造记录结构

   通常来说,数据集由一条条的记录组成,记录下有字段,记录是数据操作的基本单元.照c++的习惯,最好是一条记录一个结构,字段就是这个结构的成员,然后用列表或者vector组合一下就是记录集了.但是一条记录的字段是有可能变动的,还好,有loki 的 typelist.

 

 1 #if !defined(INCLUDE_40697E96_B6DE_449D_A516_B0376650A488)
 2 #define INCLUDE_40697E96_B6DE_449D_A516_B0376650A488
 3 
 4 #if _MSC_VER > 1000
 5 #pragma once
 6 #endif
 7 
 8 #include <typelist.h>
 9 #include <functor.h>
10 #include <boost/preprocessor/dec.hpp>
11 
12 #define HELP_2(a , b) a(b)
13 
14 #define MEM_STRUCT_MAKE_IMPL(n) template <typename _tlist> \
15 struct In : public _str_impl_help<n>::template In<typename _tlist::Tail> \
16 { \
17     typedef _str_impl_help<n>::template In<typename _tlist::Tail> _Base; \
18     enum {    en_member_count = _Base::en_member_count+1, }; \
19     typedef typename ::Loki::TL::TypeAt<_tlist, 0>::Result _type##n; \
20     _type##n m_P##n; \
21     __declspec(property(get = GetF##n, put = PutF##n)) \
22     _type##n Field##n; \
23     _type##n GetF##n() { return m_P##n; } \
24     void PutF##n(const _type##n val) { m_P##n = val; } \
25 }; \
26 }
27 
28 #define MEM_STRUCT_MAKE(n) template <> \
29     struct _str_impl_help<n> { \
30     HELP_2(MEM_STRUCT_MAKE_IMPL, BOOST_PP_DEC(n))
31     
32 
33 namespace impl_help
34 {
35     template <int _p>
36     struct _str_impl_help;
37 
38     template <>
39     struct _str_impl_help<0> {};
40     template <>
41     struct _str_impl_help<1> {
42         template <typename _tlist> 
43         struct In {
44             enum {
45                 en_member_count = 1,
46             };
47 
48             typename ::Loki::TL::TypeAt<_tlist, 0>::Result m_P0;
49 
50             __declspec(property(get=GetF0, put=PutF0))
51             typename ::Loki::TL::TypeAt<_tlist, 0>::Result Field0;
52 
53             typename ::Loki::TL::TypeAt<_tlist, 0>::Result GetF0() { 
54                 return m_P0; 
55             }
56 
57             void PutF0(const typename ::Loki::TL::TypeAt<_tlist, 0>::Result val) {
58                 m_P0 = val;
59             }
60         };
61     };
62 
63     MEM_STRUCT_MAKE(2);
64     MEM_STRUCT_MAKE(3);
65     MEM_STRUCT_MAKE(4);
66     MEM_STRUCT_MAKE(5);
67     MEM_STRUCT_MAKE(6);
68     MEM_STRUCT_MAKE(7);
69     MEM_STRUCT_MAKE(8);
70     MEM_STRUCT_MAKE(9);
71     MEM_STRUCT_MAKE(10);
72     MEM_STRUCT_MAKE(11);
73     MEM_STRUCT_MAKE(12);
74     MEM_STRUCT_MAKE(13);
75     MEM_STRUCT_MAKE(14);
76     MEM_STRUCT_MAKE(15);
77 }
78 
79 template <typename _tlist>
80 struct struct_mem : public impl_help::_str_impl_help< ::Loki::TL::Length<_tlist>::value >:: 
81     template In< ::Loki::TL::Reverse<_tlist>::Result >
82 {
83 };
84 
85 
86 #endif //!defined(INCLUDE_40697E96_B6DE_449d_A516_B0376650A488)

上面是模板实现根据指定typelist,生成拥有相应成员的结构.

typedef struct_mem< TYPELIST_6(DB_STRING, DB_STRING, DB_STRING, DB_STRING, DB_STRING, DB_STRING) > CustomerRow; 就可以声明一个有6个成员的结构了.
上面的代码使用template的特化到有15个成员的结构,全部写出来的话,重复而且麻烦,所以使用了宏来帮助生成.


 

posted on 2007-01-19 10:35 hdqqq 阅读(957) 评论(0)  编辑 收藏 引用 所属分类: c/c++

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理