来一份eXtremeDB使用笔记

1、准备工作:下载eXtremeDB安装包( http://www.leadingtek.com.cn/ )然后将安装或解压至磁盘。此时可以看到其目录下有host、include、platform和target等目录。

2、用你喜欢的文本编辑器构建一数据库结构,文本内容如下:(举例说明,保存文件名为test.mco)

#define int1      signed<1>
#define int2      signed<2>
#define int4      signed<4>
#define int8      signed<8>
#define uint8     unsigned<8>
#define uint4     unsigned<4>
#define uint2     unsigned<2>
#define uint1     unsigned<1>

// db over shm memory test

declare database shmdb;                          //数据名字

compact class MyClass                     //表名字
{
unsigned<4>        id;                     
string             str1;
char<20>           str2;

unique tree<id>    pkey;                    //索引
};

3、用hostin目录里的mcocomp.exe程序在DOS命令行模式下将test.mco编译生成,用法如:

》mcocomp test.mco

编译成功后将会生成shmdb.h和shmdb.c文件。当然了,可以根据需要生成所需的文件,具体请见mcocomp命令的参数(mcocomp -help)。至此,生成的文件里就含有数据库操作所需要API函数了。

4、新建一控制台程序工程为shmdb,在链接库里加上mcolib_shm.lib(此处为共享内存LIB库),此处需要注意LIB的路径,最简单的办法就是将eXtremeDB的库文件拷贝至工程目录下包含其就可以了。

5、将编译生成的shmdb.h和shmdb.c添加至此工程中。然后新建一C文件shmdemo.c(当然了,也可以是.cpp文件),下面将分别讲解shmdemo.c文件代码。先看此文件的全部代码:

/*标准库*/

#include <ctype.h>     /*ctype.h*/
#include <stdlib.h>   /*stdlib.h*/
#include <stdio.h>   /*stdio.h*/
#include <string.h>   /*string.h*/

#include "shmdb.h"      /*用mcocomp生成的shmdb.h文件*/

const char  * dbname   = "demoShmDb";                   //DB名称
const int   SEGSZ    = 1024 * 1024 * 10;                      //10M大小的数据库
const uint2 PAGESIZE = 90;                  //页面大小

const int MAP_ADDRESS =  0x20000000;                  //内存地址

void SH(void) {

char text[] = {
  "
This sample demonstrates eXtremeDB shared memory interfaces
"
};
char text1[] = {
  "Copyright (c) 2001-2005 McObject LLC. All Right Reserved.

"
};

printf("%s
eXtremeDB runtime version %d.%d, build %d
%s

Press Enter to start",
  text, MCO_COMP_VER_MAJOR, MCO_COMP_VER_MINOR, MCO_COMP_BUILD_NUM,text1);

getchar();

}


static int askNumber(const char *prompt) {
char buf[300];
printf("
%s ", prompt);
fgets(buf, sizeof (buf), stdin);
if(isdigit(buf[0]))
  return atoi(buf);
return -1;
}

/*16进制转换成10进制*/
static int hex2num(const char *s) {
unsigned int a = 0;

while(*s) {
  int n;
  if( *s >= '0' && *s <= '9' )
   n = *s - '0';
  else if( *s >='a' && *s <= 'f')
   n = *s - 'a' + 10;
  else if( *s >='A' && *s <= 'F')
   n = *s - 'A' + 10;
  else return a;

  a = (a << 4) | n;

  s++;
}
return a;
}


static int askHex(const char *prompt) {
char buf[300];
printf("
%s ", prompt);
fgets(buf, sizeof (buf), stdin);
return hex2num(buf);
}

/*插入记录*/
static void insertRec(mco_db_h db) {
MyClass       c;
MCO_RET       rc;
mco_trans_h     t;
int           id;
char          str1[100], str2[100];

id = askNumber("Enter new record's id:" ;
mco_trans_start( db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t );                  //事务start
MyClass_new(t, &c);               //新建一条记录
sprintf(str1,"String1: %d", id);
sprintf(str2,"String2: %d", id);
MyClass_id_put(&c,(uint4)id);               //插入
MyClass_str1_put(&c, str1, (uint2)strlen(str1) );
MyClass_str2_put(&c, str2, (uint2)strlen(str2) );
rc = mco_trans_commit(t);               //事务commit
if(rc==MCO_S_OK)
  printf("
insert done for %d (%s, %s)
",(int)id,str1,str2);
else
  printf("
insert failed (%d) for %d (%s, %s)
",rc,(int)id,str1,str2);
}

/*删除记录*/
static void deleteRec(mco_db_h db) {
MyClass       c;
MCO_RET       rc;
mco_trans_h     t;
int           id;
char          str1[100]= {0}
    , str2[100]= {0};

id = askNumber("deleting record, Enter record's id:" ;
mco_trans_start( db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t );
rc = MyClass_pkey_find(t, (uint4)id, &c);               //通过索引查找id
if(rc != MCO_S_OK) {
  printf("
Record with id = %d not found
", (int)id);
  mco_trans_rollback(t);               //如果没有找到回滚
  return;
}
MyClass_str1_get(&c,str1,(uint2)sizeof(str1),0);
MyClass_str2_get(&c,str2,(uint2)sizeof(str2) );
rc = MyClass_delete(&c);

if(rc == MCO_S_OK)
  rc = mco_trans_commit(t);
else
  mco_trans_rollback(t);
  
if(rc==MCO_S_OK)
  printf("
delete done for %d (%s, %s)
",id,str1,str2);
else
  printf("
delete failed (%d) for %d (%s, %s)
",rc,id,str1,str2);
}

/*查找记录*/
static void searchRec(mco_db_h db) {
MyClass       c;
MCO_RET       rc;
mco_trans_h     t;
int           id;
char          str1[100]= {0}
    , str2[100]= {0};

id = askNumber("searching record, Enter record's id:" ;
mco_trans_start( db, MCO_READ_ONLY, MCO_TRANS_FOREGROUND, &t );
rc = MyClass_pkey_find(t, (uint4)id, &c);               //通过索引查找id
if(rc != MCO_S_OK) {
  printf("
Record with id = %d not found
", id);
  mco_trans_rollback(t);
  return;
}
MyClass_str1_get(&c,str1,(uint2)sizeof(str1),0);
MyClass_str2_get(&c,str2,(uint2)sizeof(str2) );
mco_trans_rollback(t);
printf("
record found: %d (%s, %s)
",id,str1,str2);
}

/*显示数据库中的记录信息*/
static void listRecs(mco_db_h db) {
MyClass       c;
MCO_RET       rc;
mco_trans_h     t;
uint4         id;
char          str1[100]= {0}
    , str2[100]= {0};
mco_cursor_t  csr;

mco_trans_start( db, MCO_READ_ONLY, MCO_TRANS_FOREGROUND, &t );

/*用游标的方法遍历数据*/

MyClass_pkey_index_cursor( t, & csr );
rc = mco_cursor_first(t, &csr);               //置游标为第一条记录
printf("
----------- All records of type MyClass: -------- 
" );

/*遍历数据库*/
for( ; rc == MCO_S_OK; rc = mco_cursor_next(t, &csr) ) {
  rc = MyClass_from_cursor(t, &csr, &c);
  if(rc) {
   printf("
Unexpected error %d
",rc); break;
  }
  MyClass_id_get(&c, &id);
  MyClass_str1_get(&c,str1,(uint2)sizeof(str1),0);
  MyClass_str2_get(&c,str2,(uint2)sizeof(str2) );
  printf("record: %7d (%s, %s)
",(int)id,str1,str2);
}
printf(  "------------------------ end of list ------------ 
" ;
mco_trans_rollback(t);
}

/*数据库操作选择*/
static void menu( mco_db_h db ) {
char          ibuf[300];
int           ch;         // menu choice

for(;  {

  printf("
----------------------------
Menu:
"
   "0:   exit
"
   "1:   insert a record
"
   "2:   delete a record
"
   "3:   search a record
"
   "4:   list records
"
   "5:   print db statistics
"
   "$ "
   );

  fgets(ibuf, sizeof (ibuf), stdin);
  if( ! isdigit( ibuf[0] ) )
   continue;
  ch = atoi(ibuf);

  switch(ch) {
   default:
    break;
   case 0:
                                return;
   case 1:
    insertRec(db); break;
   case 2:
    deleteRec(db); break;
   case 3:
    searchRec(db); break;
   case 4:
    listRecs(db); break;
   case 5:
   {
    uint4 freepg, totalpg, nused;
    mco_db_free_pages   (db, &freepg);               //求数据库剩余空间大小
    mco_db_total_pages  (db, &totalpg);               //求数据库总大小

    nused = totalpg - freepg;

    printf("
Memory:
"
     "  %dKb available, %dKb used
",
     (int)(freepg * PAGESIZE / 1024), (int)(nused * PAGESIZE / 1024) );               //求最后大小需要乘以页面大小

   }
   break;
  }

}             // end for

}

/*出错处理*/
static void errhandler( int n ) {
printf( "
eXtremeDB fatal error: %d", n );
getchar();
exit( -1 );
}

/*主程序*/
int main( int na, char **aa) {
MCO_RET       rc;
mco_db_h      db;               //数据库句柄
void        * start_mem = 0;
char          prompt[300], buf[100];
mco_runtime_info_t info;               //数据库信息

SH();
mco_get_runtime_info( &info);               //获取可运行数据库信息
if ( !info.mco_shm_supported ) {               //是否有多线程支持
  printf("
This program requires shared memory database runtime
" ;
  exit(1);
};

mco_runtime_start();               //初始化运行环境

/* set fatal error handler */
mco_error_set_handler( &errhandler );

printf("
Would you like to create a new database [Y] or attach [N] -- [Y/N] ?" );
fgets(buf, sizeof (buf), stdin);

if(buf[0] == 'y' || buf[0] == 'Y') {

  sprintf(prompt,"Enter hint address (default is %x):",
   (int) MAP_ADDRESS );

  start_mem = (void*) askHex(prompt);
  if( start_mem == 0 )
   start_mem = (void*) MAP_ADDRESS;

  printf("
SHM Map address is %x
", (int) start_mem );

/*创建数据库*/

/*MCO_RET mco_db_open( IN const char * dbname, IN mco_dictionary_h dict, IN void * mem, IN uint4 total_size, IN uint2 page_size)*/

/*参数: */
/*  dbname  要打开的数据库名。 */
/*  h_dict   eXtremeDB模式处理器创建的字典句柄。通常,传递该句柄时传递dbname_getDictionary()函数。*/
/*  mem   用于容纳数据库的已分配堆内存。 */
/*  total_size  mem指向的内存的数量,以字节为单位。 */
/*  page_size  不连续的内存块,这些块由eXtremeDB页   管理器来管理。 */     

/*说明:
/*  该函数在mem表示的空间中创建数据库dbname,*/
/* 并指定初始尺寸为total_size(数据库的尺寸是可以扩展的),*/
/* 页尺寸为page_size。*/
/* 返回值:*/
/*  MCO_S_OK 数据库创建成功。 */
/*  MCO_E_PAGESIZE 非法页尺寸。 */
/*  MCO_E_NOMEM MCO_E_INSTANCE_DUPLICATE */
/*    数据库实例重复。 */
/*  MCO_ERR_DB_VER_MISMATCH */
/*  MCO_ERR_DB_NOMEM */
/*  MCO_ERR_DB_NAMELONG */
/*  MCO_ERR_DB_NUM_INSTANCES */
/*  MCO_ERR_DB MCO_ERR_PGMEM*/         

  rc = mco_db_open( dbname, shmdb_get_dictionary(), start_mem, SEGSZ, PAGESIZE );
  if ( rc ) {
   printf("
Could not create instance: %d
", rc);
   exit( 1 );
  }
}

/*连接数据库*/

/*MCO_RET mco_db_connect( IN const char * dbname, OUT mco_db_h *handle) */

/*参数: */
/*  dbname        要连接的数据库名称,该名称与调用            mco_db_open时指定的名称相同 */
/* handle          指向数据库句柄的指针,该函数将填充该句柄 */
/* 说明:*/
/*  该函数将应用程序(线程)连接到数据库。数据库必须已经由mco_db_open函数打开过。函数返回一个连接句柄,该句柄可以作为数据库的引用传给其它接口函数。  */
/* 返回值:*/
/*   MCO_S_OK 成功建立数据库连接。 */
/*  MCO_E_NOINSTANCE */
/*  MCO_ERR_TRN*/

rc = mco_db_connect( dbname, &db );
if ( rc ) {
  printf("
Could not attach to instance: %d
", rc);
  exit( 1 );
}

menu( db );

// shutdown

rc = mco_db_disconnect( db );                //断开连接
rc = mco_db_close( dbname );            //关闭数据库

mco_runtime_stop();            //释放

return 0;

}


6、需要注意的几点问题:

一、 如果初始化环境出错,将访问内存地址改大一些就可以了(特别在WIN XP上);

二、如果出现插入记录失败,查找是不是插入重复的ID了;

三、打开或创建数据库失败,查找是不是之前已经打开相同的数据库了,如果是创建数据库的话,最好在此之前加一函数mco_db_kill(db_name);

四、如果创建数据库失败,需要查看LIB库和用mcocomp编译出来的.h和.c文件的版本是否一致。一定要保证所使用的版本一致!
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值