2013-08-10 23:38:57 -04:00
|
|
|
/*
|
|
|
|
* Copyright 2013 (c) Anna Schumaker.
|
|
|
|
*/
|
|
|
|
#ifndef OCARINA_DATABASE_H
|
|
|
|
#define OCARINA_DATABASE_H
|
|
|
|
|
|
|
|
#include <file.h>
|
2013-08-14 21:09:11 -04:00
|
|
|
#include <print.h>
|
2013-08-10 23:38:57 -04:00
|
|
|
|
2013-11-27 16:34:31 -05:00
|
|
|
#include <map>
|
2013-12-01 22:31:35 -05:00
|
|
|
#include <set>
|
2013-08-11 10:41:22 -04:00
|
|
|
#include <vector>
|
|
|
|
|
2013-08-11 20:18:51 -04:00
|
|
|
|
|
|
|
class DatabaseEntry {
|
|
|
|
public:
|
|
|
|
bool valid;
|
|
|
|
|
|
|
|
DatabaseEntry();
|
2014-03-07 22:28:17 -05:00
|
|
|
virtual std::string primary_key() = 0;
|
2013-08-14 21:09:11 -04:00
|
|
|
virtual void write(File &) = 0;
|
|
|
|
virtual void read(File &) = 0;
|
2013-12-30 18:18:23 -05:00
|
|
|
#ifdef CONFIG_TEST
|
2013-09-29 22:32:08 -04:00
|
|
|
virtual void print() = 0;
|
2013-12-30 18:18:23 -05:00
|
|
|
#endif /* CONFIG_TEST */
|
2013-08-11 20:18:51 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
class IndexEntry : public DatabaseEntry {
|
2013-12-01 22:31:35 -05:00
|
|
|
public:
|
2014-03-07 22:28:17 -05:00
|
|
|
std::string key;
|
2013-12-01 22:31:35 -05:00
|
|
|
std::set<unsigned int> values;
|
|
|
|
|
|
|
|
IndexEntry();
|
|
|
|
IndexEntry(const std::string &, unsigned int);
|
|
|
|
~IndexEntry();
|
2014-03-07 22:28:17 -05:00
|
|
|
std::string primary_key();
|
2013-12-01 22:31:35 -05:00
|
|
|
void write(File &);
|
|
|
|
void read(File &);
|
2013-12-30 18:18:23 -05:00
|
|
|
#ifdef CONFIG_TEST
|
2013-12-01 22:31:35 -05:00
|
|
|
void print();
|
2013-12-30 18:18:23 -05:00
|
|
|
#endif /* CONFIG_TEST */
|
2013-12-01 22:31:35 -05:00
|
|
|
void insert(unsigned int);
|
|
|
|
void remove(unsigned int);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
2013-08-10 23:38:57 -04:00
|
|
|
class Database {
|
2013-08-11 10:41:22 -04:00
|
|
|
private:
|
|
|
|
std::vector<T> db;
|
2013-12-30 18:18:23 -05:00
|
|
|
std::map<const std::string, unsigned int> keys;
|
2013-08-11 10:41:22 -04:00
|
|
|
unsigned int _size;
|
|
|
|
File file;
|
|
|
|
|
|
|
|
public:
|
2013-11-27 16:34:31 -05:00
|
|
|
Database(std::string);
|
2013-08-11 10:41:22 -04:00
|
|
|
~Database();
|
2013-08-14 21:09:11 -04:00
|
|
|
void save();
|
|
|
|
void load();
|
2013-12-30 18:18:23 -05:00
|
|
|
#ifdef CONFIG_TEST
|
2013-10-27 17:36:22 -04:00
|
|
|
void clear();
|
2013-09-29 22:32:08 -04:00
|
|
|
void print();
|
2013-12-01 22:31:35 -05:00
|
|
|
void print_keys();
|
2013-12-30 18:18:23 -05:00
|
|
|
#endif /* CONFIG_TEST */
|
2013-08-10 23:38:57 -04:00
|
|
|
|
2013-08-11 10:41:22 -04:00
|
|
|
unsigned int insert(T);
|
2013-08-11 21:09:11 -04:00
|
|
|
void remove(unsigned int);
|
2013-08-11 20:18:51 -04:00
|
|
|
unsigned int size();
|
|
|
|
unsigned int num_rows();
|
|
|
|
|
|
|
|
unsigned int first();
|
|
|
|
unsigned int last();
|
|
|
|
unsigned int next(unsigned int);
|
2013-12-30 18:18:23 -05:00
|
|
|
bool has_key(const std::string &);
|
2013-12-01 22:31:35 -05:00
|
|
|
unsigned int find_index(const std::string &);
|
|
|
|
T &find(const std::string &);
|
2013-08-11 20:18:51 -04:00
|
|
|
T &operator[](unsigned int);
|
2013-08-10 23:38:57 -04:00
|
|
|
};
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
static inline void index_insert(Database<IndexEntry> &db,
|
2013-12-01 22:31:35 -05:00
|
|
|
const std::string &key,
|
|
|
|
unsigned int val)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
db.find(key).insert(val);
|
2013-12-31 16:58:40 -05:00
|
|
|
} catch (int error) {
|
2013-12-01 22:31:35 -05:00
|
|
|
db.insert(IndexEntry(key, val));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-30 18:18:23 -05:00
|
|
|
static inline void index_remove(Database<IndexEntry> &db,
|
2013-12-01 22:31:35 -05:00
|
|
|
const std::string &key,
|
|
|
|
unsigned int val)
|
|
|
|
{
|
|
|
|
unsigned int i = db.find_index(key);
|
|
|
|
db[i].remove(val);
|
|
|
|
if (db[i].values.size() == 0)
|
|
|
|
db.remove(db.find_index(key));
|
|
|
|
}
|
|
|
|
|
2013-08-11 10:41:22 -04:00
|
|
|
#include "database.hpp"
|
|
|
|
|
2013-08-10 23:38:57 -04:00
|
|
|
#endif /* OCARINA_DATABASE_H */
|