遍历数据库要有两个函数来配合使用:
- db_rewind用来是文件指针回到第一条索引记录的开头处。
- db_nextrec读取该索引对应的实际数据。
两个函数的代码如下:
/* 将索引文件的文件偏移量定位在索引文件的第一条索引记录开头 */
void db_rewind(DBHANDLE h)
{
DB *db = h;
off_t offset;
/* db->nhash = 137 */
offset = (db->nhash + 1) * PTR_SZ; /* +1表示空闲链表 */
if ((db->idxoff = lseek(db->idxfd, offset + 1, SEEK_SET)) == -1) /* +1跳过换行符 */
{
printf("%d\n", __LINE__);
exit(-1);
}
}
/* 返回数据库的下一条记录,返回值指向数据记录
* 对应记录的key放到参数key中,key的空间由用户提供
*/
char *db_nextrec(DBHANDLE h, char *key)
{
DB *db = h;
char c;
char *ptr;
/* 锁住空闲链表,防止删除记录 */
if (readw_lock(db->idxfd, FREE_OFF, SEEK_SET, 1) < 0)
{
printf("%d\n", __LINE__);
exit(-1);
}
do {
if (_db_readidx(db, 0) < 0) /* 0表示从当前位置开始读 */
{
ptr = NULL;
goto doreturn;
}
ptr = db->idxbuf; /* ptr现在指向key字段开头 */
while ((c = *ptr++) != 0 && c == SPACE)
; /* key为空则跳过 */
} while (c == 0); /* 跳过空记录 */
if (key != NULL)
strcpy(key, db->idxbuf); /* 只复制key字段 */
/* db->idxbuf = "key \0 datoff \0 datlen \0" */
ptr = _db_readdat(db); /* 读实际数据 */
db->cnt_nextrec++;
doreturn:
if (un_lock(db->idxfd, FREE_OFF, SEEK_SET, 1) < 0)
{
printf("%d\n", __LINE__);
exit(-1);
}
return ptr;
}
以上两个函数很简单,这里不再详述。下面是一个综合测试例程:
#include <stdio.h>
#include <fcntl.h>
#include "my_db.h"
int main()
{
DBHANDLE db; /* 数据库句柄 */
char *str;
char key[IDXLEN_MAX];
/* 打开数据库 */
db = db_open("my_db", O_RDWR | O_CREAT | O_TRUNC);
db_store(db, "a", "hello", DB_INSERT);
db_store(db, "b", "good", DB_INSERT);
db_store(db, "c", "google", DB_INSERT);
db_store(db, "d", "world", DB_INSERT);
db_store(db, "e", "people", DB_INSERT);
db_store(db, "f", "Nestle", DB_INSERT);
printf("print all:\n");
db_rewind(db);
while ((str = db_nextrec(db, key)) != NULL) /* 遍历数据库,key保存一条记录的键值 */
printf("%s\n", str);
db_delete(db, "b"); // 删除一条记录
db_delete(db, "e"); // 删除一条记录
printf("print all:\n");
db_rewind(db);
while ((str = db_nextrec(db, key)) != NULL) /* 遍历数据库,key保存一条记录的键值 */
printf("%s\n", str);
if ((str = db_fetch(db, "a")) != NULL)
printf("key = a, data = %s\n", str);
else
printf("Not found!\n");
if ((str = db_fetch(db, "b")) != NULL)
printf("key = b, data = %s\n", str);
else
printf("Not found!\n");
if ((str = db_fetch(db, "f")) != NULL)
printf("key = f, data = %s\n", str);
else
printf("Not found!\n");
// 关闭数据库
db_close(db);
return 0;
}
运行结果: