/* * Copyright 2013 (c) Anna Schumaker. * * DO NOT INCLUDE THIS FILE DIRECTLY. THIS IS A TEMPLATE DEFINITION FILE * AND ONLY MEANT TO BE INCLUDED BY include/database.h! */ #ifndef OCARINA_DATABASE_HPP #define OCARINA_DATABASE_HPP #include template Database :: Database(std::string filepath) : _size(0), file(filepath, FILE_TYPE_DATA) { } template Database :: ~Database() { } template void Database :: save() { try { file.open(OPEN_WRITE); } catch (int error) { return; } file << db.size() << std::endl; for (unsigned int i = 0; i < db.size(); i++) { file << db[i].valid << " "; if (db[i].valid == true) db[i].write(file); file << std::endl; } file.close(); } template void Database :: load() { unsigned int db_size; if (file.exists() == false) return; try { file.open(OPEN_READ); } catch (int error) { return; } file >> db_size; db.resize(db_size); for (unsigned int i = 0; i < db_size; i++) { file >> db[i].valid; if (db[i].valid == true) { db[i].read(file); keys.insert(std::pair(db[i].primary_key(), i)); _size++; } } file.close(); } #ifdef CONFIG_TEST template void Database :: clear() { db.clear(); keys.clear(); _size = 0; } template void Database :: print() { :: print("Allocated rows: %u\n", db.size()); :: print("Valid rows: %u\n", _size); for (unsigned int i = 0; i < db.size(); i++) { if (db[i].valid == true) { :: print("db[%u] = ", i); db[i].print(); :: print("\n"); } } } template void Database :: print_keys() { std::map::iterator it; :: print("Found keys:"); for (it = keys.begin(); it != keys.end(); it++) :: print(" %s", it->first.c_str()); :: print("\n"); } #endif /* CONFIG_TEST */ template unsigned int Database :: insert(T val) { unsigned int id; typename std::map::iterator it; it = keys.find(val.primary_key()); if (it != keys.end()) return it->second; /* * Check primary key stuff here */ id = db.size(); db.push_back(val); keys.insert(std::pair(val.primary_key(), id)); db[id].valid = true; _size++; return id; } template void Database :: remove(unsigned int id) { keys.erase(db[id].primary_key()); db[id].valid = false; _size--; } template unsigned int Database :: size() { return _size; } template unsigned int Database :: num_rows() { return db.size(); } template unsigned int Database :: first() { for (unsigned int i = 0; i < db.size(); i++) { if (db[i].valid == true) return i; } return db.size(); } template unsigned int Database :: last() { if (_size == 0) return db.size(); for (unsigned int i = db.size() - 1; i >= 0; i--) { if (db[i].valid == true) return i; } return db.size(); } template unsigned int Database :: next(unsigned int id) { for (unsigned int i = id + 1; i < db.size(); i++) { if (db[i].valid == true) return i; } return db.size(); } template bool Database :: has_key(const std::string &key) { std::map::iterator it; it = keys.find(key); return it != keys.end(); } template unsigned int Database :: find_index(const std::string &key) { std::map::iterator it; it = keys.find(key); if (it == keys.end()) throw -E_EXIST; return it->second; } template T &Database :: find(const std::string &key) { unsigned int index = find_index(key); if (db[index].valid == false) throw -E_INVAL; return db[index]; } template T &Database :: operator[](unsigned int id) { if (id >= db.size()) throw -E_EXIST; else if (db[id].valid == false) throw -E_INVAL; return db[id]; } #endif /* OCARINA_DATABASE_HPP */