2013-08-11 10:41:22 -04:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
#include <error.h>
|
2013-12-10 17:38:42 -05:00
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
2014-03-09 14:58:06 -04:00
|
|
|
Database<T> :: Database(std::string filepath, bool autosave)
|
|
|
|
: _size(0), _autosave(autosave), _file(filepath, FILE_TYPE_DATA)
|
2013-08-11 10:41:22 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
|
|
|
Database<T> :: ~Database()
|
2013-08-11 10:41:22 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
|
|
|
void Database<T> :: save()
|
2013-08-14 21:09:11 -04:00
|
|
|
{
|
2014-03-09 14:58:06 -04:00
|
|
|
if (_file.open(OPEN_WRITE) == false)
|
2013-08-14 21:50:08 -04:00
|
|
|
return;
|
2013-08-14 21:09:11 -04:00
|
|
|
|
2014-03-09 14:58:06 -04:00
|
|
|
_file << _db.size() << std::endl;
|
|
|
|
for (unsigned int i = 0; i < _db.size(); i++) {
|
2014-04-09 19:20:12 -04:00
|
|
|
_file << _db[i].valid;
|
|
|
|
if (_db[i].valid == true) {
|
|
|
|
_file << " ";
|
2014-03-09 14:58:06 -04:00
|
|
|
_db[i].write(_file);
|
2014-04-09 19:20:12 -04:00
|
|
|
}
|
2014-03-09 14:58:06 -04:00
|
|
|
_file << std::endl;
|
2013-08-14 21:09:11 -04:00
|
|
|
}
|
|
|
|
|
2014-03-09 14:58:06 -04:00
|
|
|
_file.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
void Database<T> :: autosave()
|
|
|
|
{
|
|
|
|
if (_autosave == true)
|
|
|
|
save();
|
2013-08-14 21:09:11 -04:00
|
|
|
}
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
|
|
|
void Database<T> :: load()
|
2013-08-14 21:09:11 -04:00
|
|
|
{
|
|
|
|
unsigned int db_size;
|
2013-12-30 18:18:23 -05:00
|
|
|
|
2014-03-09 14:58:06 -04:00
|
|
|
if (_file.exists() == false)
|
2014-01-22 19:31:31 -05:00
|
|
|
return;
|
2014-03-09 14:58:06 -04:00
|
|
|
else if (_file.open(OPEN_READ) == false)
|
2013-08-14 21:50:08 -04:00
|
|
|
return;
|
2013-08-14 21:09:11 -04:00
|
|
|
|
2014-03-09 14:58:06 -04:00
|
|
|
_file >> db_size;
|
|
|
|
_db.resize(db_size);
|
2013-08-14 21:09:11 -04:00
|
|
|
for (unsigned int i = 0; i < db_size; i++) {
|
2014-03-09 14:58:06 -04:00
|
|
|
_file >> _db[i].valid;
|
|
|
|
if (_db[i].valid == true) {
|
|
|
|
_db[i].read(_file);
|
2014-03-16 18:32:20 -04:00
|
|
|
_db[i].id = i;
|
2014-03-09 14:58:06 -04:00
|
|
|
_keys.insert(std::pair<std::string, unsigned int>(_db[i].primary_key(), i));
|
2013-08-14 21:09:11 -04:00
|
|
|
_size++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-09 14:58:06 -04:00
|
|
|
_file.close();
|
2013-10-27 17:36:22 -04:00
|
|
|
}
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
|
|
|
unsigned int Database<T> :: insert(T val)
|
2013-08-11 10:41:22 -04:00
|
|
|
{
|
2013-11-27 16:34:31 -05:00
|
|
|
unsigned int id;
|
2014-03-09 14:58:06 -04:00
|
|
|
iterator it = find(val.primary_key());
|
2013-11-27 16:34:31 -05:00
|
|
|
|
2014-03-09 14:58:06 -04:00
|
|
|
if (it != end())
|
|
|
|
return it - _db.begin();
|
2013-11-27 16:34:31 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check primary key stuff here
|
|
|
|
*/
|
2014-03-09 14:58:06 -04:00
|
|
|
id = _db.size();
|
|
|
|
_db.push_back(val);
|
|
|
|
_keys[val.primary_key()] = id;
|
|
|
|
_db[id].valid = true;
|
2014-03-16 18:32:20 -04:00
|
|
|
_db[id].id = id;
|
2013-08-11 10:41:22 -04:00
|
|
|
_size++;
|
2014-03-09 14:58:06 -04:00
|
|
|
autosave();
|
2013-11-27 16:34:31 -05:00
|
|
|
return id;
|
2013-08-11 10:41:22 -04:00
|
|
|
}
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
|
|
|
void Database<T> :: remove(unsigned int id)
|
2013-08-11 21:09:11 -04:00
|
|
|
{
|
2014-03-09 14:58:06 -04:00
|
|
|
if (id >= actual_size())
|
|
|
|
return;
|
2014-03-23 13:16:22 -04:00
|
|
|
if (_db[id].valid == false)
|
|
|
|
return;
|
2014-03-09 14:58:06 -04:00
|
|
|
_keys.erase(_db[id].primary_key());
|
|
|
|
_db[id].valid = false;
|
2013-08-11 21:09:11 -04:00
|
|
|
_size--;
|
2014-03-09 14:58:06 -04:00
|
|
|
autosave();
|
2013-08-11 21:09:11 -04:00
|
|
|
}
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
|
|
|
unsigned int Database<T> :: size()
|
2013-08-11 10:41:22 -04:00
|
|
|
{
|
|
|
|
return _size;
|
|
|
|
}
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
2014-03-09 14:58:06 -04:00
|
|
|
unsigned int Database<T> :: actual_size()
|
2013-08-11 20:18:51 -04:00
|
|
|
{
|
2014-03-09 14:58:06 -04:00
|
|
|
return _db.size();
|
2013-08-11 20:18:51 -04:00
|
|
|
}
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
2014-03-09 14:58:06 -04:00
|
|
|
typename Database<T>::iterator Database<T> :: begin()
|
2013-08-11 20:18:51 -04:00
|
|
|
{
|
2014-03-23 14:45:47 -04:00
|
|
|
if (size() == 0)
|
|
|
|
return end();
|
|
|
|
|
2014-03-09 14:58:06 -04:00
|
|
|
iterator it = _db.begin();
|
|
|
|
if ( (*it).valid == true )
|
|
|
|
return it;
|
|
|
|
return next(it);
|
2013-08-11 20:18:51 -04:00
|
|
|
}
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
2014-03-09 14:58:06 -04:00
|
|
|
typename Database<T>::iterator Database<T> :: end()
|
2013-08-11 20:18:51 -04:00
|
|
|
{
|
2014-03-09 14:58:06 -04:00
|
|
|
return _db.end();
|
2013-08-11 20:18:51 -04:00
|
|
|
}
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
2014-03-09 14:58:06 -04:00
|
|
|
typename Database<T>::iterator Database<T> :: next(iterator &it)
|
2013-12-30 18:18:23 -05:00
|
|
|
{
|
2014-03-09 14:58:06 -04:00
|
|
|
do {
|
|
|
|
it++;
|
|
|
|
} while ((it != end()) && ((*it).valid == false));
|
|
|
|
return it;
|
2013-12-30 18:18:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
2014-03-09 14:58:06 -04:00
|
|
|
typename Database<T>::iterator Database<T> :: at(unsigned int id)
|
2013-12-01 22:31:35 -05:00
|
|
|
{
|
2014-03-09 14:58:06 -04:00
|
|
|
if (id >= actual_size())
|
|
|
|
return end();
|
2013-12-01 22:31:35 -05:00
|
|
|
|
2014-03-09 14:58:06 -04:00
|
|
|
if (_db[id].valid == false)
|
|
|
|
return end();
|
|
|
|
return _db.begin() + id;
|
2013-12-01 22:31:35 -05:00
|
|
|
}
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
2014-03-09 14:58:06 -04:00
|
|
|
typename Database<T>::iterator Database<T> :: find(const std::string &key)
|
2013-08-11 20:18:51 -04:00
|
|
|
{
|
2014-03-09 14:58:06 -04:00
|
|
|
std::map<const std::string, unsigned int>::iterator it;
|
|
|
|
it = _keys.find(key);
|
|
|
|
if (it == _keys.end())
|
|
|
|
return end();
|
|
|
|
return _db.begin() + it->second;
|
2013-08-11 20:18:51 -04:00
|
|
|
}
|
2013-08-11 10:41:22 -04:00
|
|
|
#endif /* OCARINA_DATABASE_HPP */
|