ocarina/include/database.hpp

167 lines
3.0 KiB
C++

/*
* 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 <error.h>
template <class T>
Database<T> :: Database(std::string filepath, bool autosave)
: _size(0), _autosave(autosave), _file(filepath, FILE_TYPE_DATA)
{
}
template <class T>
Database<T> :: ~Database()
{
}
template <class T>
void Database<T> :: save()
{
if (_file.open(OPEN_WRITE) == false)
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 <class T>
void Database<T> :: autosave()
{
if (_autosave == true)
save();
}
template <class T>
void Database<T> :: load()
{
unsigned int db_size;
if (_file.exists() == false)
return;
else if (_file.open(OPEN_READ) == false)
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);
_db[i].id = i;
_keys.insert(std::pair<std::string, unsigned int>(_db[i].primary_key(), i));
_size++;
}
}
_file.close();
}
template <class T>
unsigned int Database<T> :: insert(T val)
{
unsigned int id;
iterator it = find(val.primary_key());
if (it != end())
return it - _db.begin();
/*
* Check primary key stuff here
*/
id = _db.size();
_db.push_back(val);
_keys[val.primary_key()] = id;
_db[id].valid = true;
_db[id].id = id;
_size++;
autosave();
return id;
}
template <class T>
void Database<T> :: remove(unsigned int id)
{
if (id >= actual_size())
return;
if (_db[id].valid == false)
return;
_keys.erase(_db[id].primary_key());
_db[id].valid = false;
_size--;
autosave();
}
template <class T>
unsigned int Database<T> :: size()
{
return _size;
}
template <class T>
unsigned int Database<T> :: actual_size()
{
return _db.size();
}
template <class T>
typename Database<T>::iterator Database<T> :: begin()
{
if (size() == 0)
return end();
iterator it = _db.begin();
if ( (*it).valid == true )
return it;
return next(it);
}
template <class T>
typename Database<T>::iterator Database<T> :: end()
{
return _db.end();
}
template <class T>
typename Database<T>::iterator Database<T> :: next(iterator &it)
{
do {
it++;
} while ((it != end()) && ((*it).valid == false));
return it;
}
template <class T>
typename Database<T>::iterator Database<T> :: at(unsigned int id)
{
if (id >= actual_size())
return end();
if (_db[id].valid == false)
return end();
return _db.begin() + id;
}
template <class T>
typename Database<T>::iterator Database<T> :: find(const std::string &key)
{
std::map<const std::string, unsigned int>::iterator it;
it = _keys.find(key);
if (it == _keys.end())
return end();
return _db.begin() + it->second;
}
#endif /* OCARINA_DATABASE_HPP */