171 lines
3.4 KiB
C++
171 lines
3.4 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
|
|
|
|
template <class T>
|
|
void db_init(struct database<T> *db, const char *filepath, bool autosave)
|
|
{
|
|
db->db_size = 0;
|
|
db->db_autosave = autosave;
|
|
file_init(&db->db_file, filepath, 0);
|
|
}
|
|
|
|
template <class T>
|
|
void db_deinit(struct database<T> *db)
|
|
{
|
|
T *t, *u;
|
|
db_for_each(t, u, db) {
|
|
db->db_entries[t->index()] = NULL;
|
|
delete t;
|
|
db->db_size--;
|
|
}
|
|
}
|
|
|
|
template <class T>
|
|
void db_save(struct database<T> *db)
|
|
{
|
|
if (file_open(&db->db_file, OPEN_WRITE) == false)
|
|
return;
|
|
|
|
file_writef(&db->db_file, "%u\n", db_actual_size(db));
|
|
for (unsigned int i = 0; i < db_actual_size(db); i++) {
|
|
if (db->db_entries[i] == NULL)
|
|
file_writef(&db->db_file, "%d\n", false);
|
|
else {
|
|
file_writef(&db->db_file, "%d ", true);
|
|
db->db_entries[i]->write(db->db_file);
|
|
file_writef(&db->db_file, "\n");
|
|
}
|
|
}
|
|
|
|
file_close(&db->db_file);
|
|
}
|
|
|
|
template <class T>
|
|
void db_autosave(struct database<T> *db)
|
|
{
|
|
if (db->db_autosave == true)
|
|
db_save(db);
|
|
}
|
|
|
|
template <class T>
|
|
void db_load(struct database<T> *db)
|
|
{
|
|
unsigned int size;
|
|
std::string str;
|
|
int valid;
|
|
|
|
if (file_open(&db->db_file, OPEN_READ) == false)
|
|
return;
|
|
|
|
file_readf(&db->db_file, "%u", &size);
|
|
db->db_entries.resize(size);
|
|
for (unsigned int i = 0; i < size; i++) {
|
|
file_readf(&db->db_file, "%d", &valid);
|
|
if (valid == false) {
|
|
db->db_entries[i] = NULL;
|
|
} else {
|
|
db->db_entries[i] = new T;
|
|
db->db_entries[i]->_index = i;
|
|
db->db_entries[i]->read(db->db_file);
|
|
str = db->db_entries[i]->primary_key();
|
|
db->db_keys[str] = i;
|
|
db->db_size++;
|
|
}
|
|
}
|
|
|
|
file_close(&db->db_file);
|
|
}
|
|
|
|
template <class T>
|
|
T *db_insert(struct database<T> *db, T *item)
|
|
{
|
|
if (!item)
|
|
return NULL;
|
|
|
|
item->_index = db_actual_size(db);
|
|
db->db_entries.push_back(item);
|
|
|
|
db->db_keys[item->primary_key()] = item->index();
|
|
db->db_size++;
|
|
db_autosave(db);
|
|
return db->db_entries[item->_index];
|
|
}
|
|
|
|
template <class T>
|
|
void db_remove(struct database<T> *db, T *item)
|
|
{
|
|
if (item == NULL)
|
|
return;
|
|
if (db_at(db, item->index()) != item)
|
|
return;
|
|
db->db_entries[item->index()] = NULL;
|
|
db->db_keys.erase(item->primary_key());
|
|
delete item;
|
|
db->db_size--;
|
|
db_autosave(db);
|
|
}
|
|
|
|
template <class T>
|
|
unsigned int db_actual_size(const struct database<T> *db)
|
|
{
|
|
return db->db_entries.size();
|
|
}
|
|
|
|
template <class T>
|
|
T *__db_next(const struct database<T> *db, unsigned int index)
|
|
{
|
|
for (; index < db->db_entries.size(); index++) {
|
|
if (db->db_entries[index])
|
|
return db->db_entries[index];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
template <class T>
|
|
T *db_first(const struct database<T> *db)
|
|
{
|
|
return __db_next(db, 0);
|
|
}
|
|
|
|
template <class T>
|
|
T *db_next(const struct database<T> *db, T *ent)
|
|
{
|
|
if (ent)
|
|
return __db_next(db, ent->index() + 1);
|
|
return NULL;
|
|
}
|
|
|
|
template <class T>
|
|
T *db_at(struct database<T> *db, unsigned int index)
|
|
{
|
|
if (index >= db_actual_size(db))
|
|
return NULL;
|
|
return db->db_entries[index];
|
|
}
|
|
|
|
template <class T>
|
|
T *db_get(struct database<T> *db, const gchar *key)
|
|
{
|
|
std::map<const std::string, unsigned int>::iterator it;
|
|
it = db->db_keys.find(key);
|
|
if (it == db->db_keys.end())
|
|
return NULL;
|
|
return db->db_entries[it->second];
|
|
}
|
|
|
|
template <class T>
|
|
T *db_find(struct database<T> *db, const gchar *key)
|
|
{
|
|
T *dbe = db_get(db, key);
|
|
if (dbe)
|
|
return dbe;
|
|
return db_insert(db, new T(key));
|
|
}
|
|
#endif /* OCARINA_DATABASE_HPP */
|