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文件的版本是否一致。一定要保证所使用的版本一致!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/183675.html原文链接:https://javaforall.cn