/* Opening or Creating a database */ DB *db_open(const char *pathname, int oflag, int mode) { DB *db; int i, len; char asciiptr[PTR_SZ + 1], hash[(NHASH_DEF + 1) * PTR_SZ +2]; /* +2 for newline and NULL */ struct stat statbuff; /* Allocating a Database structure and the buffer it requires. */ len = strlen(pathname); if((db = _db_alloc(len)) == NULL) err_dump("error"); db->oflag = oflag; /* saving a copy of the open flags */ /* Opening index file */ strcpy(db->name, pathname); strcat(db->name, ".idx"); if((db->idxfd = open(db->name, oflag, mode)) < 0) { _db_free(db); return(NULL); } /* Opening data file */ strcpy(db->name + len, ".dat"); if((db->datfd = open(db->name, oflag, mode)) < 0) { _db_free(db); return(NULL); } /* If the database was created, then initialize it */ if((oflag & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) { /* write lock the entire file and so that, we can stat the file, check it's size & initialize it */ if(writew_lock(db->idxfd, 0, SEEK_SET, 0) < 0) err_dump("error"); if(fstat(db->idxfd, &statbuff) < 0) err_sys("error"); if(statbuff.st_size==0) { /* We gotta build a list of (NHASH_DEF + 1) chain ptr with a value of 0. The +1 is for free list pointer that precedes the hash table. */ sprintf(asciiptr, "%*d", PTR_SZ, 0); hash[0] = 0; for(i=0;i<(NHASH_DEF + 1);i++) strcat(hash, asciiptr); strcat(hash, "\n"); i = strlen(hash); if(write(db->idxfd, hash, i) != i) err_dump("error"); } if(un_lock(db->idxfd, 0, SEEK_SET, 0) < 0) err_dump("error"); } db->nhash = NHASH_DEF; /* hash table size */ db->hashoff = HASH_OFF; /* offset in index file of hash table */ /* free list ptr always at FREE_OFF */ db_rewind(db); return(db); }
int ag_db_rewind(unsigned dbh) { return db_rewind(h2p(dbh)); }
int main(int argc, char **argv) { DBHANDLE db; int rc,c, flags, len; char *ptr_command, *ptr_key, *find; char *command, *key, *value; command = key = value = NULL; char *help_cmd = "command list:\n [add | update] key value \n [del | find] key \n [open | close] dbname\n [help count iterate exit]"; flags = O_RDWR; while ((c = getopt(argc, argv, "nt?")) != -1) { switch (c) { case 'n': flags |= O_CREAT; break; case 't': flags |= O_TRUNC; break; case '?': err_quit("usage: [-n] create new file [-t] truncate db <filename>"); break; } } if (optind != argc - 1) { err_quit("usage: [-n] create new file [-t] truncate db <filename>"); } if ((db = db_open(argv[optind], flags, FILE_MODE)) == NULL) { err_sys("db_open %s error", argv[optind]); } for (;;) { char buf[MAX_LEN]; printf("APUEDB> "); if (fgets(buf, MAX_LEN, stdin) == NULL) { printf("Bye~\n"); exit(1); } to_lowercase(buf); len = strlen(buf); if ((ptr_command = strchr(buf,COMMAND_SEP)) == NULL) { buf[len-1] = '\0'; if (strcmp(buf,"help") == 0) { printf("%s\n", help_cmd); continue; } else if (strcmp(buf, "count") == 0) { printf("%d\n", db_count(db)); } else if (strcmp(buf, "iterate") == 0) { char *ptr; db_rewind(db); while ((ptr = db_nextrec(db, NULL)) != NULL) { printf("%s\n", ptr); } continue; } else if (strcmp(buf, "exit") == 0) { printf("Bye~\n"); exit(1); } else { printf("invalid command, use command help for help\n"); continue; } } command = strndup(buf, ptr_command - buf); if (strcmp(command, "add") == 0) { if ((ptr_key = strchr(ptr_command+1, COMMAND_SEP)) == NULL) { printf("invalid add command, usage: add key value\n"); } else { key = strndup(ptr_command+1, ptr_key - ptr_command - 1); value = strndup(ptr_key+1, buf + len - 1 - ptr_key - 1); rc = db_store(db, key, value, DB_INSERT); if (rc == 0) { printf("add +OK\n"); } else { printf("key %s already exist\n", key); } } } else if (strcmp(command, "update") == 0) { if ((ptr_key = strchr(ptr_command+1, COMMAND_SEP)) == NULL) { printf("invalid add command, usage: add key value\n"); } else { key = strndup(ptr_command+1, ptr_key - ptr_command - 1); value = strndup(ptr_key+1, buf + len - 1 - ptr_key - 1); rc = db_store(db, key, value, DB_REPLACE); if (rc == 0) { printf("update +OK\n"); } else { printf("key %s not found\n", key); } } } else if (strcmp(command, "del") == 0) { if ((ptr_key = strchr(ptr_command+1, COMMAND_SEP)) != NULL) { printf("invalid del command, usage: del key\n"); continue; } key = strndup(ptr_command+1, buf + len - 1 - ptr_command -1); rc = db_delete(db, key); if (rc == 0) { printf("del +OK\n"); } else { printf("key %s not found\n", key); } } else if (strcmp(command, "find") == 0) { if ((ptr_key = strchr(ptr_command+1, COMMAND_SEP)) != NULL) { printf("invalid find command, usage: find key\n"); continue; } key = strndup(ptr_command+1, buf + len - 1 - ptr_command -1); find = db_fetch(db, key); if (find != NULL) { printf("%d,%s\n", strlen(find), find); } else { printf("key %s not found\n", key); } } if (key != NULL) { free(key); key = NULL; } if (command != NULL) { free(command); command = NULL; } if (value != NULL) { free(value); value = NULL; } } }