#include "flatfile_pool.h" #include #include #include #include #include #include "wutils.h" #include #include #include #include #include "stopos.h" // constructor flatfile_pool::flatfile_pool() { } int flatfile_pool::get_record(datarecord &r, const stopos_key &k) { off_t p; int rc; p = this->reclen*k.get(); std::string rec; rc = this->read_string(rec,p); if (rc !=0 ) return rc; if (rec[0] == this->deleted) return this->NOTFOUND; rec.erase(0,2); // remove first char plus separator r = datarecord(rec,dbsep); return 0; } int flatfile_pool::put_record(datarecord &r, const stopos_key &k) { std::string buf; buf = buf + this->exists + dbsep + r.str(dbsep); off_t p = this->reclen*k.get(); return this->write_string(buf,p); } int flatfile_pool::remove_record(const stopos_key &k) { int rc; off_t p = this->reclen*k.get(); std::string r; rc = this->read_string(r,p); if (rc != 0) return rc; r[0] = this->deleted; return this->write_string(r,p); } int flatfile_pool::read_string(std::string &r, off_t p) { //std:: cerr << "\nWTD: " << __LINE__ <<":"<< this->db_open<reclen]; off_t rc; rc = lseek(this->ff, p, SEEK_SET); if (rc == -1) return FETCHERROR; ssize_t rc1; rc1 = read(this->ff, b, this->reclen); if (rc1 != this->reclen) return FETCHERROR; r = b; return 0; } int flatfile_pool::get_status(void) { std::string r; int rc; off_t p = this->reclen*this->statuskey.get(); rc = this->read_string(r,p); if (rc != 0) return rc; this->status = statusrecord(r,dbsep); return 0; } int flatfile_pool::write_string(std::string &r, off_t p) { int rc; char b[this->reclen]; rc = lseek(this->ff,p,SEEK_SET); if (rc == -1) return STOREERROR; bzero(b, this->reclen); strncpy(b,r.c_str(),r.size()); ssize_t first = 0; ssize_t togo = this->reclen; ssize_t written; do { written = write(ff,&b[first],togo); if (written == -1) { perror("write:"); return 2; } togo -= written; first += written; } while(togo !=0); return 0; } int flatfile_pool::put_status(void) { std::string buf; buf = this->status.str(dbsep); if (buf.size() > this->reclen) return this->STATUSTOOLONG; off_t p = this->reclen*this->statuskey.get(); return write_string(buf,p); return 0; } int flatfile_pool::create_db(void) { int rc; rc = this->purge_db(); if (rc != 0) return rc; // The db_name can be composed of parts separated 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->open_db(); this->status.init(); rc = put_status(); if (rc != 0) { this->close_db(); return this->STOREERROR; } this->close_db(); return 0; } int flatfile_pool::purge_db(void) { int rc; if (this->db_name == 0) return NOFILENAME; this->close_db(); unlink(this->db_name); return 0; } int flatfile_pool::open_db(void) { int rc; if (this->db_name == 0) return NOFILENAME; if (this->db_open) return 0; this->ff = open(this->db_name, O_CREAT|O_RDWR,0644); if (this->ff < 0) return OPENERROR; struct flock lock; lock.l_type = F_RDLCK|F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; rc = fcntl(this->ff,F_SETLKW,&lock); if (rc < 0) return LOCKERROR; this->db_open = 1; return 0; } int flatfile_pool::close_db(void) { if (!this->db_open) return 0; int rc; struct flock lock; lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; rc = fcntl(this->ff,F_SETLKW,&lock); if (rc < 0) return UNLOCKERROR; rc = close(this->ff); if (rc == -1) return CLOSEERROR; this->db_open = 0; return 0; } void flatfile_pool::dump_db(void) { std::string r; off_t n = 1; while (read_string(r,n*this->reclen)==0) { std::cerr << r << std::endl; n++; } }