/*********************************************************************** * libdba - A database agent library * * Copyright (C) 2000,2001 Michael Brownlow * * * * This program is free software; you can redistribute it and/or modify* * it under the terms of the GNU General Public License as published by* * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * * For questions and comments, please email the author at: * * mike@wsmake.org * ***********************************************************************/ #include #include #include "dba.h" #include "dba_pool.h" static int __dba_ready = 0; int dba_init(int debugging) { int err; if(__dba_ready == DBA_NOTREADY) { if((err=__dba_init(debugging))==0) { __dba_ready = DBA_READY; __dba_print_debug("libdba initialized\n"); return DBA_INIT_SUCCEED; } return err; } else { __dba_print_warning("attempt to initialize dba more than once\n"); } return DBA_INIT_INIT; } void dba_exit() { /* Internal exit */ __dba_exit(); __dba_ready = DBA_NOTREADY; } DBA *dba_open(DBA *dba, const char *filename, int db_type) { if(__dba_ready == DBA_READY) { switch(db_type) { #ifdef HAVE_TARGET_CSV case DBA_DB_CSV : break; #endif #ifdef HAVE_TARGET_DB case DBA_DB_DB : break; #endif default: __dba_print_error("database type %s not supported\n", __dba_db_string(db_type)); return NULL; } dba = __dba_find(filename); if(dba!=NULL) { /* FIXME: check for differing db_types */ __dba_print_debug("using previously defined database\n"); dba->refs++; __dba_print_debug("agent %#x has %d reference(s)\n", dba, dba->refs); return dba; } dba = (DBA *)malloc(sizeof(DBA)); if(!dba) return 0; dba->db = NULL; dba->filename = (char *)malloc(strlen(filename)+1); if(!dba->filename) { free(dba); return 0; } strncpy(dba->filename, filename, strlen(filename)+1); dba->db_type = db_type; dba->open = NULL; dba->close = NULL; dba->add = NULL; dba->set = NULL; dba->del = NULL; dba->get = NULL; dba->exists = NULL; dba->next = NULL; dba->prev = NULL; dba->refs = 0; if(__dba_add_db(dba) == 0) { dba_close(dba); return NULL; } dba->refs++; __dba_print_debug("agent %#x has %d reference(s)\n", dba, dba->refs); return dba; } else { __dba_print_error("libdba not initialized!\n"); return NULL; } } int dba_add(DBA *dba, int data_type, char *key, ...) { va_list ap; int ret; if(__dba_ready == DBA_READY) { if(key == NULL) { __dba_print_error("NULL key value\n"); return 0; } va_start(ap, key); switch(data_type) { case DBA_DT_LONG : ret = dba->add(dba, data_type, key, va_arg(ap, long)); break; case DBA_DT_STRING : ret = dba->add(dba, data_type, key, va_arg(ap, char *)); break; default : __dba_print_error("unknown type (%d)\n", data_type); va_end(ap); return 0; } va_end(ap); return ret; } else { __dba_print_error("libdba not initialized!\n"); return 0; } } int dba_set(DBA *dba, int data_type, char *key, ...) { va_list ap; int ret; if(__dba_ready == DBA_READY) { if(key == NULL) { __dba_print_error("NULL key value\n"); return 0; } va_start(ap, key); switch(data_type) { case DBA_DT_LONG : ret = dba->set(dba, data_type, key, va_arg(ap, long)); break; case DBA_DT_STRING : ret = dba->set(dba, data_type, key, va_arg(ap, char *)); break; default : __dba_print_error("unknown type (%d)\n", data_type); va_end(ap); return 0; } va_end(ap); return ret; } else { __dba_print_error("libdba not initialized!\n"); return 0; } } int dba_del(DBA *dba, char *key) { if(__dba_ready == DBA_READY) { if(key == NULL) { __dba_print_error("NULL key value\n"); return 0; } return dba->del(dba,key); } else { __dba_print_error("libdba not initialized!\n"); return 0; } } int dba_exists(DBA *dba, const char *key) { if(__dba_ready == DBA_READY) { if(key == NULL) { __dba_print_error("NULL key value\n"); return 0; } return dba->exists(dba, key); } else { __dba_print_error("libdba not initialized!\n"); return 0; } } void *dba_get(DBA *dba, int data_type, char *key, void *value) { if(__dba_ready == DBA_READY) { if(key == NULL) { __dba_print_error("key is NULL\n"); return 0; } /* note: the value of value is ignored and overwritten. cool. */ return dba->get(dba, data_type, key, value); } else { __dba_print_error("libdba not initialized!\n"); return 0; } } void dba_close(DBA *dba) { int err; if(__dba_ready == DBA_READY) { if(dba != NULL) { /* not a bogus dba */ if(dba->db != NULL) { /* not a dba gone bad */ if(dba->refs <= 1) { /* only one reference left? (or failed 1st) */ if(dba->refs == 1) { /* tell agent database to close if we are the last reference */ if((err=dba->close(dba)) != DBA_SUCCEED) { __dba_print_error("could not close database. reason: %s", strerror(err)); } /* Remove dba from pool if we are the last reference*/ if(__dba_remove_db(dba) != DBA_SUCCEED) { __dba_print_error("agent removal failed!\n"); return; } } if(dba->filename) { free(dba->filename); dba->filename = NULL; } __dba_print_debug("removed agent %#x\n", dba); free(dba); dba = NULL; } else { __dba_print_debug("agent still in use; closing reference only\n"); dba->refs--; __dba_print_debug("agent %#x has %d reference(s)\n", dba, dba->refs); } } else { __dba_print_warning("attempt to free agent with a undefined " "internal DB\n"); } } else { __dba_print_error("undefined agent\n"); } } else { __dba_print_error("libdba not initialized!\n"); return; } }