#include #include #include #include #include "gdbm_pool.h" #include "gdbm.h" #include #include #include "wutils.h" #include #include #include "stopos.h" #include "stopos_pool.h" gdbm_pool::gdbm_pool() { } gdbm_pool::~gdbm_pool() { } int gdbm_pool::create_db(void) { int rc; rc = this->purge_db(); if (rc != 0) return rc; // The db_name can be composed of parts separeted with '/' // we try to create this path until the last '/' size_t p = this->sdb_name.find_last_of('/'); rc = mkdir_p(this->sdb_name.substr(0,p+1),0755); if (rc != 0) return CREATEERROR; this->dbf = gdbm_open(this->db_name,0,GDBM_NEWDB|this->sync,0644,0); if (this->dbf == 0) return this->OPENERROR; this->status.init(); rc = put_status(); if (rc != 0) { this->close_db(); return this->STOREERROR; } this->close_db(); return 0; } int gdbm_pool::purge_db(void) { if (this->db_name == 0) return NOFILENAME; this->close_db(); unlink(db_name); return 0; } int gdbm_pool::get_status(void) { datum key, content; // create record with starting key key.dptr = str_to_charp(this->statuskey.str()); key.dsize = strlen(key.dptr)+1; content=gdbm_fetch(this->dbf,key); free(key.dptr); if (content.dptr == 0) return FETCHERROR; this->status = statusrecord(content.dptr,dbsep); free(content.dptr); return 0; } int gdbm_pool::put_status(void) { datum key, content; key.dptr = str_to_charp(this->statuskey.str()); key.dsize = strlen(key.dptr)+1; std::string buf; buf = this->status.str(dbsep); content.dptr = str_to_charp(buf); content.dsize = strlen(content.dptr) + 1; int rc = gdbm_store(this->dbf, key, content, GDBM_REPLACE); free(content.dptr); free(key.dptr); return rc; } int gdbm_pool::open_db(void) { int rc; if (this->db_open) return 0; if (this->db_name == 0) return this->NOFILENAME; char rw='w'; switch (rw) { case 'r': do { dbf = gdbm_open(this->db_name,0,GDBM_READER,0644,0); if (dbf == 0) usleep(1000); } while (dbf == 0); break; case 'w': do { dbf = gdbm_open(this->db_name,0,GDBM_WRCREAT|this->sync,0644,0); if (dbf == 0) usleep(1000); } while (dbf == 0); break; default: break; } this->db_open = 1; return 0; } int gdbm_pool::close_db(void) { if (db_open) gdbm_close(this->dbf); this->db_open = 0; return 0; } int gdbm_pool::get_record(datarecord &r, const stopos_key &k) { datum key,content; key.dptr = str_to_charp(k.str()); key.dsize = strlen(key.dptr) + 1; content=gdbm_fetch(this->dbf,key); free(key.dptr); if (content.dptr == 0) return this->FETCHERROR; r = datarecord(content.dptr,dbsep); free(content.dptr); return 0; } int gdbm_pool::put_record(datarecord &r, const stopos_key &k) { datum key, content; key.dptr = str_to_charp(k.str()); key.dsize = strlen(key.dptr) + 1; std::string buf; buf = r.str(dbsep); content.dptr = str_to_charp(buf); content.dsize = strlen(content.dptr)+ 1; int rc = gdbm_store(this->dbf, key, content, GDBM_REPLACE); free(content.dptr); free(key.dptr); return rc; } int gdbm_pool::remove_record(const stopos_key &key) { datum k; int rc; k.dptr = str_to_charp(key.str()); k.dsize = strlen(k.dptr) + 1; rc = gdbm_delete(this->dbf,k); if (rc !=0) return NOTFOUND; return 0; } bool comprecord(std::string a, std::string b) { int ia = StringToNumber(a); int ib = StringToNumber(b); return ia < ib; } void gdbm_pool::dump_db(void) { datum key, content,key1; key = gdbm_firstkey(this->dbf); std::vector vec; while ( key.dptr) { content = gdbm_fetch(this->dbf,key); vec.push_back(std::string(key.dptr)+":"+std::string(content.dptr)); key1 = gdbm_nextkey(dbf,key); free(key.dptr); free(content.dptr); key = key1; } std::sort(vec.begin(), vec.end(), ::comprecord); std::vector::iterator it; for (it=vec.begin(); it!=vec.end(); ++it) std::cerr << " " << *it << std::endl; }