19
static int dberr(const char* s, int err) {
20
//if(err != 0) std::cerr<<"DB ERROR("<<s<<"): "<<err<<std::endl;
20
bool FileRecord::dberr(const char* s, int err) {
21
if(err == 0) return true;
23
error_str_ = std::string(s)+": "+DbEnv::strerror(err);
24
FileRecord::FileRecord(const std::string& base):
27
FileRecord::FileRecord(const std::string& base, recovery recover):
26
29
db_rec_(NULL,DB_CXX_NO_EXCEPTIONS),
27
30
db_lock_(NULL,DB_CXX_NO_EXCEPTIONS),
28
31
db_locked_(NULL,DB_CXX_NO_EXCEPTIONS),
29
32
db_link_(NULL,DB_CXX_NO_EXCEPTIONS),
31
if(dberr("set 1",db_lock_.set_flags(DB_DUPSORT)) != 0) return;
32
if(dberr("set 2",db_locked_.set_flags(DB_DUPSORT)) != 0) return;
33
if(dberr("assoc1",db_link_.associate(NULL,&db_lock_,&locked_callback,0)) != 0) return;
34
if(dberr("assoc2",db_link_.associate(NULL,&db_locked_,&lock_callback,0)) != 0) return;
35
if(dberr("open 1",db_rec_.open(NULL,(basepath_+"/list").c_str(), "meta", DB_BTREE, DB_CREATE, S_IRUSR | S_IWUSR)) != 0) return;
36
if(dberr("open 2",db_link_.open(NULL,(basepath_+"/list").c_str(), "link", DB_RECNO, DB_CREATE, S_IRUSR | S_IWUSR)) != 0) return;
37
if(dberr("open 2",db_lock_.open(NULL,(basepath_+"/list").c_str(), "lock", DB_BTREE, DB_CREATE, S_IRUSR | S_IWUSR)) != 0) return;
38
if(dberr("open 3",db_locked_.open(NULL,(basepath_+"/list").c_str(), "locked", DB_BTREE, DB_CREATE, S_IRUSR | S_IWUSR)) != 0) return;
39
//if(db_rec_.associate(NULL,&db_uid_,&uid_callback,0) != 0) return;
40
//if(db_rec_.associate(NULL,&db_id_,&id_callback,0) != 0) return;
38
if(!dberr("Error setting flag DB_DUPSORT",db_lock_.set_flags(DB_DUPSORT))) return;
39
if(!dberr("Error setting flag DB_DUPSORT",db_locked_.set_flags(DB_DUPSORT))) return;
40
if(!dberr("Error associating databases",db_link_.associate(NULL,&db_lock_,&locked_callback,0))) return;
41
if(!dberr("Error associating databases",db_link_.associate(NULL,&db_locked_,&lock_callback,0))) return;
42
int oflags = DB_CREATE;
43
std::string dbpath = basepath_+"/list";
44
if(recover == ordinary_recovery) {
46
} else if(recover == catastrophic_recovery) {
47
oflags |= DB_RECOVER_FATAL;
48
} else if(recover == full_recovery) {
49
// Recreating all databases
50
if(::unlink(dbpath.c_str()) != 0) {
52
dberr("Error wiping database",errno);
57
if(!dberr("Error opening database 'meta'",db_rec_.open(NULL,dbpath.c_str(), "meta", DB_BTREE,oflags,S_IRUSR|S_IWUSR))) return;
58
if(!dberr("Error opening database 'link'",db_link_.open(NULL,dbpath.c_str(), "link", DB_RECNO,oflags,S_IRUSR|S_IWUSR))) return;
59
if(!dberr("Error opening database 'lock'",db_lock_.open(NULL,dbpath.c_str(), "lock", DB_BTREE,oflags,S_IRUSR|S_IWUSR))) return;
60
if(!dberr("Error opening database 'locked'",db_locked_.open(NULL,dbpath.c_str(),"locked",DB_BTREE,oflags,S_IRUSR|S_IWUSR))) return;
64
FileRecord::~FileRecord(void) {
44
71
static void* store_string(const std::string& str, void* buf) {
45
72
uint32_t l = str.length();
46
73
unsigned char* p = (unsigned char*)buf;
244
271
make_key(id,owner,key);
245
272
void* pkey = key.get_data();
246
if(dberr("remove:get1",db_locked_.get(NULL,&key,&data,0)) == 0) {
273
if(dberr("remove:get1",db_locked_.get(NULL,&key,&data,0))) {
248
275
return false; // have locks
250
if(dberr("remove:get2",db_rec_.get(NULL,&key,&data,0)) != 0) {
277
if(!dberr("remove:get2",db_rec_.get(NULL,&key,&data,0))) {
252
279
return ""; // No such record?
296
323
if(!valid_) return false;
297
324
Glib::Mutex::Lock lock(lock_);
299
if(dberr("removelock:cursor",db_lock_.cursor(NULL,&cur,0)) != 0) return false;
326
if(!dberr("removelock:cursor",db_lock_.cursor(NULL,&cur,0))) return false;
302
329
make_string(lock_id,key);
303
330
void* pkey = key.get_data();
304
if(dberr("removelock:get1",cur->get(&key,&data,DB_SET)) != 0) { // TODO: handle errors
331
if(!dberr("removelock:get1",cur->get(&key,&data,DB_SET))) { // TODO: handle errors
306
333
cur->close(); return false;
313
340
buf = parse_string(id,buf,size);
314
341
buf = parse_string(owner,buf,size);
315
342
ids.push_back(std::pair<std::string,std::string>(id,owner));
316
if(dberr("removelock:del",cur->del(0)) != 0) {
343
if(!dberr("removelock:del",cur->del(0))) {
318
345
cur->close(); return false;
320
347
db_lock_.sync(0);
321
if(dberr("removelock:get2",cur->get(&key,&data,DB_NEXT_DUP)) != 0) break;
348
if(!dberr("removelock:get2",cur->get(&key,&data,DB_NEXT_DUP))) break;