2014-10-17 17:15:02 -04:00
|
|
|
/**
|
2013-08-10 23:38:57 -04:00
|
|
|
* Copyright 2013 (c) Anna Schumaker.
|
|
|
|
*/
|
2014-06-21 09:37:47 -04:00
|
|
|
#ifndef OCARINA_CORE_DATABASE_H
|
|
|
|
#define OCARINA_CORE_DATABASE_H
|
2013-08-10 23:38:57 -04:00
|
|
|
|
2015-10-09 13:55:34 -04:00
|
|
|
extern "C" {
|
2014-06-05 10:19:22 -04:00
|
|
|
#include <core/file.h>
|
2015-10-09 13:55:34 -04:00
|
|
|
}
|
2013-08-10 23:38:57 -04:00
|
|
|
|
2013-11-27 16:34:31 -05:00
|
|
|
#include <map>
|
2015-09-08 09:39:35 -04:00
|
|
|
#include <string>
|
2013-08-11 10:41:22 -04:00
|
|
|
#include <vector>
|
|
|
|
|
2014-10-17 17:15:02 -04:00
|
|
|
/**
|
2014-11-02 09:29:13 -05:00
|
|
|
* The DatabaseEntry class is the base class for storing
|
|
|
|
* generic data inside a Database.
|
2014-10-17 17:15:02 -04:00
|
|
|
*/
|
2013-08-11 20:18:51 -04:00
|
|
|
class DatabaseEntry {
|
2015-09-17 08:12:25 -04:00
|
|
|
public:
|
2014-11-02 10:02:35 -05:00
|
|
|
unsigned int _index; /**< The location of an item in the Database. */
|
2013-08-11 20:18:51 -04:00
|
|
|
|
2014-11-02 10:02:35 -05:00
|
|
|
DatabaseEntry(); /**< Initialize _index to 0. */
|
2015-10-20 10:10:26 -04:00
|
|
|
DatabaseEntry(const std::string);
|
2014-11-02 09:29:13 -05:00
|
|
|
virtual ~DatabaseEntry() = 0; /**< Virtual destructor */
|
2014-10-17 17:15:02 -04:00
|
|
|
|
2014-11-02 10:02:35 -05:00
|
|
|
/**
|
|
|
|
* Called to access a DatabaseEntry's index.
|
|
|
|
*
|
|
|
|
* @return DatabaseEntry::_index
|
|
|
|
*/
|
|
|
|
const unsigned int index();
|
|
|
|
|
2014-10-17 17:15:02 -04:00
|
|
|
/**
|
2014-11-02 09:29:13 -05:00
|
|
|
* The primary key of a DatabaseEntry is a unique string representing
|
|
|
|
* a single DatabaseEntry instance. This is used for preventing
|
|
|
|
* duplicate entries in a Database. The primary key is not expected
|
|
|
|
* to change once a DatabaseEntry has been initialized.
|
|
|
|
*
|
|
|
|
* @return A unique string identifying a DatabaseEntry instance.
|
2014-10-17 17:15:02 -04:00
|
|
|
*/
|
2014-03-25 17:51:37 -04:00
|
|
|
virtual const std::string primary_key() const = 0;
|
2014-10-17 17:15:02 -04:00
|
|
|
|
|
|
|
/**
|
2014-11-02 09:29:13 -05:00
|
|
|
* This function is called by the Database to write a specific
|
|
|
|
* DatabaseEntry instance to disk.
|
|
|
|
*
|
2014-10-17 17:15:02 -04:00
|
|
|
* @param file File to use when writing data.
|
|
|
|
*/
|
2015-09-10 08:00:42 -04:00
|
|
|
virtual void write(file &) = 0;
|
2014-10-17 17:15:02 -04:00
|
|
|
|
|
|
|
/**
|
2014-11-02 09:29:13 -05:00
|
|
|
* This function is called by the Database to read a single
|
|
|
|
* DatabaseEntry instance from disk.
|
|
|
|
*
|
2014-10-17 17:15:02 -04:00
|
|
|
* @param file File to use when reading data.
|
|
|
|
*/
|
2015-09-10 08:00:42 -04:00
|
|
|
virtual void read(file &) = 0;
|
2013-08-11 20:18:51 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-10-17 17:15:02 -04:00
|
|
|
/**
|
2014-11-04 08:12:28 -05:00
|
|
|
* Databases are a generic store for information used by Ocarina. Users
|
|
|
|
* need to inherit from a DatabaseEntry class to properly use a Database.
|
|
|
|
*
|
|
|
|
* When writing a Database to disk, Databases need to store their size in
|
|
|
|
* addition to values and valid bits at each index. For example, let's say
|
|
|
|
* we have a Database with the following values: { 1, 2, NULL, 4 }. On
|
|
|
|
* disk this would look like:
|
|
|
|
*
|
|
|
|
* 4
|
|
|
|
* 0 true 1
|
|
|
|
* 1 true 2
|
|
|
|
* 2 false
|
|
|
|
* 3 true 4
|
|
|
|
* <index> <valid> <data>
|
|
|
|
*
|
|
|
|
* The Database class will add a newline after each DatabaseEntry.
|
2014-10-17 17:15:02 -04:00
|
|
|
*/
|
2013-12-30 18:18:23 -05:00
|
|
|
template <class T>
|
2015-10-17 10:07:58 -04:00
|
|
|
struct database {
|
|
|
|
unsigned int db_size; /* The database's count of valid entries. */
|
|
|
|
bool db_autosave; /* True if the database saves when changed. */
|
|
|
|
struct file db_file; /* The database's associated file object. */
|
2014-11-04 08:12:28 -05:00
|
|
|
|
2015-10-17 10:07:58 -04:00
|
|
|
std::vector<T *> db_entries;
|
|
|
|
std::map<const std::string, unsigned int> db_keys;
|
2014-11-04 08:12:28 -05:00
|
|
|
|
2014-10-17 17:15:02 -04:00
|
|
|
/** Iterator access for our backing std::vector */
|
2014-03-25 10:57:09 -04:00
|
|
|
typedef typename std::vector<T *>::iterator iterator;
|
2014-10-17 17:15:02 -04:00
|
|
|
/** Const iterator access for our backing std::vector */
|
2014-03-25 10:57:09 -04:00
|
|
|
typedef typename std::vector<T *>::const_iterator const_iterator;
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2014-10-17 17:15:02 -04:00
|
|
|
/**
|
2014-11-04 08:12:28 -05:00
|
|
|
* Initialize a Database using filepath as a location to store data
|
|
|
|
* on disk.
|
|
|
|
*
|
2014-10-17 17:15:02 -04:00
|
|
|
* @param filepath File on disk that will be written to.
|
2014-11-04 08:12:28 -05:00
|
|
|
* @param autosave Set to True if the Database should be saved upon
|
|
|
|
* every insertion and deletion. If this is set
|
|
|
|
* to False then the Database will have to be saved
|
|
|
|
* manually.
|
2014-10-17 17:15:02 -04:00
|
|
|
*/
|
2015-10-17 10:07:58 -04:00
|
|
|
database(std::string, bool);
|
2014-10-17 17:15:02 -04:00
|
|
|
|
|
|
|
/**
|
2014-11-04 08:12:28 -05:00
|
|
|
* Deletes all remaining entries in a Database to prevent memory leaks.
|
2014-10-17 17:15:02 -04:00
|
|
|
*/
|
2015-10-17 10:07:58 -04:00
|
|
|
~database();
|
2014-10-17 17:15:02 -04:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2014-11-04 08:12:28 -05:00
|
|
|
* @return An iterator pointing to the first valid entry in the Database.
|
|
|
|
* @return Return Database::end() if there are no valid entries.
|
2014-10-17 17:15:02 -04:00
|
|
|
*/
|
2014-03-09 14:58:06 -04:00
|
|
|
iterator begin();
|
2014-10-17 17:15:02 -04:00
|
|
|
|
|
|
|
/**
|
2014-11-04 08:12:28 -05:00
|
|
|
* @return An iterator pointing past the end of the database.
|
2014-10-17 17:15:02 -04:00
|
|
|
*/
|
2014-03-09 14:58:06 -04:00
|
|
|
iterator end();
|
2014-10-17 17:15:02 -04:00
|
|
|
|
|
|
|
/**
|
2014-11-04 08:12:28 -05:00
|
|
|
* @return An iterator pointing to the next valid item in the database.
|
2014-10-17 17:15:02 -04:00
|
|
|
*/
|
2014-03-09 14:58:06 -04:00
|
|
|
iterator next(iterator &);
|
2013-08-10 23:38:57 -04:00
|
|
|
};
|
|
|
|
|
2015-10-17 15:12:40 -04:00
|
|
|
|
2015-10-18 10:11:24 -04:00
|
|
|
/* Called to write the database to disk. */
|
|
|
|
template <class T>
|
|
|
|
void db_save(struct database<T> *);
|
|
|
|
|
|
|
|
/* Save the database to disk iff database->db_autosave is set to True */
|
|
|
|
template <class T>
|
|
|
|
void db_autosave(struct database<T> *);
|
|
|
|
|
2015-09-17 08:12:25 -04:00
|
|
|
/* Called to read the database from disk. */
|
|
|
|
template <class T>
|
|
|
|
void db_load(struct database<T> *);
|
|
|
|
|
2015-10-17 15:12:40 -04:00
|
|
|
/* Returns the size of the backing std::vector. */
|
|
|
|
template <class T>
|
|
|
|
unsigned int db_actual_size(const struct database<T> *);
|
|
|
|
|
2015-10-18 10:59:20 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Called to add a new item to the database. The caller MUST check if the
|
|
|
|
* database already contains a similar item before calling this function.
|
|
|
|
*/
|
|
|
|
template <class T>
|
|
|
|
T *db_insert(struct database<T> *, T *);
|
|
|
|
|
2015-10-20 08:05:13 -04:00
|
|
|
/* Called to remove an item from the database. */
|
|
|
|
template <class T>
|
|
|
|
void db_remove(struct database<T> *, T *);
|
2015-10-18 10:59:20 -04:00
|
|
|
|
2015-10-20 08:19:47 -04:00
|
|
|
|
|
|
|
/* Returns the database item at the requested index. */
|
|
|
|
template <class T>
|
|
|
|
T *db_at(struct database<T> *, unsigned int);
|
|
|
|
|
2015-10-20 10:10:26 -04:00
|
|
|
/* Returns the database item with the specified key. */
|
|
|
|
template <class T>
|
|
|
|
T *db_get(struct database<T> *, const gchar *);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Similar to db_get(), but allocate and return a new item if the
|
|
|
|
* database doesn't contain an item with the specified key.
|
|
|
|
*/
|
|
|
|
template <class T>
|
|
|
|
T *db_find(struct database<T> *, const gchar *);
|
|
|
|
|
2013-08-11 10:41:22 -04:00
|
|
|
#include "database.hpp"
|
|
|
|
|
2014-06-21 09:37:47 -04:00
|
|
|
#endif /* OCARINA_CORE_DATABASE_H */
|