database: Implement updates to match my current design
- Force the primary key to be a string - Throw error codes rather than 0 Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This commit is contained in:
parent
ab8c15ecb7
commit
acd8bd7b23
31
design.txt
31
design.txt
|
@ -240,9 +240,10 @@ Database: (lib/database.cpp)
|
||||||
- DatabaseEntry:
|
- DatabaseEntry:
|
||||||
class DatabaseEntry { /* let database modify valid flag */
|
class DatabaseEntry { /* let database modify valid flag */
|
||||||
public:
|
public:
|
||||||
|
const std::string primary_key;
|
||||||
bool valid;
|
bool valid;
|
||||||
|
|
||||||
virtual const std::string &primary_key() = 0;
|
DatabaseEntry(const std::string &);
|
||||||
virtual void write(File &) = 0;
|
virtual void write(File &) = 0;
|
||||||
virtual void read(File &) = 0;
|
virtual void read(File &) = 0;
|
||||||
virtual void print() = 0;
|
virtual void print() = 0;
|
||||||
|
@ -253,13 +254,13 @@ Database: (lib/database.cpp)
|
||||||
- IndexEntry:
|
- IndexEntry:
|
||||||
class IndexEntry : public DatabaseEntry {
|
class IndexEntry : public DatabaseEntry {
|
||||||
public:
|
public:
|
||||||
string key;
|
|
||||||
set<unsigned int> values;
|
set<unsigned int> values;
|
||||||
|
|
||||||
const std::string &primary_key();
|
|
||||||
void write(File &);
|
void write(File &);
|
||||||
void read(File &);
|
void read(File &);
|
||||||
void print();
|
void print();
|
||||||
|
void insert(unsigned int);
|
||||||
|
void remove(unsigned int);
|
||||||
};
|
};
|
||||||
|
|
||||||
File << key << endl;
|
File << key << endl;
|
||||||
|
@ -283,7 +284,7 @@ Database: (lib/database.cpp)
|
||||||
void print_keys();
|
void print_keys();
|
||||||
|
|
||||||
unsigned int insert(T);
|
unsigned int insert(T);
|
||||||
void delete(unsigned int);
|
void remove(unsigned int);
|
||||||
unsigned int size();
|
unsigned int size();
|
||||||
unsigned int num_rows();
|
unsigned int num_rows();
|
||||||
|
|
||||||
|
@ -332,7 +333,7 @@ Database: (lib/database.cpp)
|
||||||
mapping is also created into the keys map to map the primary
|
mapping is also created into the keys map to map the primary
|
||||||
key back to the id of the newly added item.
|
key back to the id of the newly added item.
|
||||||
|
|
||||||
void Database :: delete(unsigned int index);
|
void Database :: remove(unsigned int index);
|
||||||
Mark db[index] as invalid (quick deletion).
|
Mark db[index] as invalid (quick deletion).
|
||||||
|
|
||||||
unsigned int Database :: size();
|
unsigned int Database :: size();
|
||||||
|
@ -342,14 +343,16 @@ Database: (lib/database.cpp)
|
||||||
Return db.size().
|
Return db.size().
|
||||||
|
|
||||||
unsigned int Database :: first();
|
unsigned int Database :: first();
|
||||||
Return the id to the first valid row.
|
Return the id to the first valid row. Return db.size() if
|
||||||
|
there are no valid rows.
|
||||||
|
|
||||||
unsigned int Database :: last();
|
unsigned int Database :: last();
|
||||||
Return the id of the last valid row.
|
Return the id of the last valid row. Return db.size() if
|
||||||
|
there are no valid rows.
|
||||||
|
|
||||||
unsigned int Database :: next(unsigned int &id);
|
unsigned int Database :: next(unsigned int &id);
|
||||||
Return the id of the next valid row or throw -EINVAL if there
|
Return the id of the next valid row or return db.size() if
|
||||||
are no remaining valid rows.
|
there are no valid rows.
|
||||||
|
|
||||||
bool Database :: has_key(const std::string &key);
|
bool Database :: has_key(const std::string &key);
|
||||||
Return true if an item with primary key "key" exists in the
|
Return true if an item with primary key "key" exists in the
|
||||||
|
@ -363,13 +366,15 @@ Database: (lib/database.cpp)
|
||||||
template <class T>
|
template <class T>
|
||||||
T &Database :: find(const std::string &key);
|
T &Database :: find(const std::string &key);
|
||||||
Search for primary key "key" in the database. The reverse
|
Search for primary key "key" in the database. The reverse
|
||||||
mapping should be used to make this operation faster. Throw
|
mapping should be used to make this operation faster.
|
||||||
-EEXIST if the key is not found in the mapping.
|
Throw -EEXIST if the key is not found in the mapping.
|
||||||
|
Throw -EINVAL if the key points to an invalid entry.
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
T &Database :: operator[](unsigned int index);
|
T &Database :: operator[](unsigned int index);
|
||||||
Return a reference to db[index]. Throw -EEXIST if index is out
|
Return a reference to db[index].
|
||||||
of range.
|
Throw -EEXIST if index is out of range.
|
||||||
|
Throw -EINVAL if index is invalid.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,10 @@ Database: (lib/database.cpp)
|
||||||
- DatabaseEntry:
|
- DatabaseEntry:
|
||||||
class DatabaseEntry { /* let database modify valid flag */
|
class DatabaseEntry { /* let database modify valid flag */
|
||||||
public:
|
public:
|
||||||
|
const std::string primary_key;
|
||||||
bool valid;
|
bool valid;
|
||||||
|
|
||||||
virtual const std::string &primary_key() = 0;
|
DatabaseEntry(const std::string &);
|
||||||
virtual void write(File &) = 0;
|
virtual void write(File &) = 0;
|
||||||
virtual void read(File &) = 0;
|
virtual void read(File &) = 0;
|
||||||
virtual void print() = 0;
|
virtual void print() = 0;
|
||||||
|
@ -45,13 +46,13 @@ Database: (lib/database.cpp)
|
||||||
- IndexEntry:
|
- IndexEntry:
|
||||||
class IndexEntry : public DatabaseEntry {
|
class IndexEntry : public DatabaseEntry {
|
||||||
public:
|
public:
|
||||||
string key;
|
|
||||||
set<unsigned int> values;
|
set<unsigned int> values;
|
||||||
|
|
||||||
const std::string &primary_key();
|
|
||||||
void write(File &);
|
void write(File &);
|
||||||
void read(File &);
|
void read(File &);
|
||||||
void print();
|
void print();
|
||||||
|
void insert(unsigned int);
|
||||||
|
void remove(unsigned int);
|
||||||
};
|
};
|
||||||
|
|
||||||
File << key << endl;
|
File << key << endl;
|
||||||
|
@ -75,7 +76,7 @@ Database: (lib/database.cpp)
|
||||||
void print_keys();
|
void print_keys();
|
||||||
|
|
||||||
unsigned int insert(T);
|
unsigned int insert(T);
|
||||||
void delete(unsigned int);
|
void remove(unsigned int);
|
||||||
unsigned int size();
|
unsigned int size();
|
||||||
unsigned int num_rows();
|
unsigned int num_rows();
|
||||||
|
|
||||||
|
@ -124,7 +125,7 @@ Database: (lib/database.cpp)
|
||||||
mapping is also created into the keys map to map the primary
|
mapping is also created into the keys map to map the primary
|
||||||
key back to the id of the newly added item.
|
key back to the id of the newly added item.
|
||||||
|
|
||||||
void Database :: delete(unsigned int index);
|
void Database :: remove(unsigned int index);
|
||||||
Mark db[index] as invalid (quick deletion).
|
Mark db[index] as invalid (quick deletion).
|
||||||
|
|
||||||
unsigned int Database :: size();
|
unsigned int Database :: size();
|
||||||
|
@ -134,14 +135,16 @@ Database: (lib/database.cpp)
|
||||||
Return db.size().
|
Return db.size().
|
||||||
|
|
||||||
unsigned int Database :: first();
|
unsigned int Database :: first();
|
||||||
Return the id to the first valid row.
|
Return the id to the first valid row. Return db.size() if
|
||||||
|
there are no valid rows.
|
||||||
|
|
||||||
unsigned int Database :: last();
|
unsigned int Database :: last();
|
||||||
Return the id of the last valid row.
|
Return the id of the last valid row. Return db.size() if
|
||||||
|
there are no valid rows.
|
||||||
|
|
||||||
unsigned int Database :: next(unsigned int &id);
|
unsigned int Database :: next(unsigned int &id);
|
||||||
Return the id of the next valid row or throw -EINVAL if there
|
Return the id of the next valid row or return db.size() if
|
||||||
are no remaining valid rows.
|
there are no valid rows.
|
||||||
|
|
||||||
bool Database :: has_key(const std::string &key);
|
bool Database :: has_key(const std::string &key);
|
||||||
Return true if an item with primary key "key" exists in the
|
Return true if an item with primary key "key" exists in the
|
||||||
|
@ -155,10 +158,12 @@ Database: (lib/database.cpp)
|
||||||
template <class T>
|
template <class T>
|
||||||
T &Database :: find(const std::string &key);
|
T &Database :: find(const std::string &key);
|
||||||
Search for primary key "key" in the database. The reverse
|
Search for primary key "key" in the database. The reverse
|
||||||
mapping should be used to make this operation faster. Throw
|
mapping should be used to make this operation faster.
|
||||||
-EEXIST if the key is not found in the mapping.
|
Throw -EEXIST if the key is not found in the mapping.
|
||||||
|
Throw -EINVAL if the key points to an invalid entry.
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
T &Database :: operator[](unsigned int index);
|
T &Database :: operator[](unsigned int index);
|
||||||
Return a reference to db[index]. Throw -EEXIST if index is out
|
Return a reference to db[index].
|
||||||
of range.
|
Throw -EEXIST if index is out of range.
|
||||||
|
Throw -EINVAL if index is invalid.
|
||||||
|
|
|
@ -12,43 +12,42 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
class DatabaseEntry {
|
class DatabaseEntry {
|
||||||
public:
|
public:
|
||||||
|
std::string primary_key;
|
||||||
bool valid;
|
bool valid;
|
||||||
|
|
||||||
DatabaseEntry();
|
DatabaseEntry();
|
||||||
virtual T &primary_key() = 0;
|
|
||||||
virtual void write(File &) = 0;
|
virtual void write(File &) = 0;
|
||||||
virtual void read(File &) = 0;
|
virtual void read(File &) = 0;
|
||||||
#ifdef CONFIG_DEBUG
|
#ifdef CONFIG_TEST
|
||||||
virtual void print() = 0;
|
virtual void print() = 0;
|
||||||
#endif /* CONFIG_DEBUG */
|
#endif /* CONFIG_TEST */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class IndexEntry : public DatabaseEntry<const std::string> {
|
class IndexEntry : public DatabaseEntry {
|
||||||
public:
|
public:
|
||||||
std::string key;
|
|
||||||
std::set<unsigned int> values;
|
std::set<unsigned int> values;
|
||||||
|
|
||||||
IndexEntry();
|
IndexEntry();
|
||||||
IndexEntry(const std::string &, unsigned int);
|
IndexEntry(const std::string &, unsigned int);
|
||||||
~IndexEntry();
|
~IndexEntry();
|
||||||
const std::string &primary_key();
|
|
||||||
void write(File &);
|
void write(File &);
|
||||||
void read(File &);
|
void read(File &);
|
||||||
|
#ifdef CONFIG_TEST
|
||||||
void print();
|
void print();
|
||||||
|
#endif /* CONFIG_TEST */
|
||||||
void insert(unsigned int);
|
void insert(unsigned int);
|
||||||
void remove(unsigned int);
|
void remove(unsigned int);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
class Database {
|
class Database {
|
||||||
private:
|
private:
|
||||||
std::vector<T> db;
|
std::vector<T> db;
|
||||||
std::map<U, unsigned int> keys;
|
std::map<const std::string, unsigned int> keys;
|
||||||
unsigned int _size;
|
unsigned int _size;
|
||||||
File file;
|
File file;
|
||||||
|
|
||||||
|
@ -57,11 +56,11 @@ public:
|
||||||
~Database();
|
~Database();
|
||||||
void save();
|
void save();
|
||||||
void load();
|
void load();
|
||||||
#ifdef CONFIG_DEBUG
|
#ifdef CONFIG_TEST
|
||||||
void clear();
|
void clear();
|
||||||
void print();
|
void print();
|
||||||
void print_keys();
|
void print_keys();
|
||||||
#endif /* CONFIG_DEBUG */
|
#endif /* CONFIG_TEST */
|
||||||
|
|
||||||
unsigned int insert(T);
|
unsigned int insert(T);
|
||||||
void remove(unsigned int);
|
void remove(unsigned int);
|
||||||
|
@ -71,13 +70,13 @@ public:
|
||||||
unsigned int first();
|
unsigned int first();
|
||||||
unsigned int last();
|
unsigned int last();
|
||||||
unsigned int next(unsigned int);
|
unsigned int next(unsigned int);
|
||||||
|
bool has_key(const std::string &);
|
||||||
unsigned int find_index(const std::string &);
|
unsigned int find_index(const std::string &);
|
||||||
T &find(const std::string &);
|
T &find(const std::string &);
|
||||||
T &operator[](unsigned int);
|
T &operator[](unsigned int);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
static inline void index_insert(Database<IndexEntry> &db,
|
||||||
static inline void index_insert(Database<IndexEntry, T> &db,
|
|
||||||
const std::string &key,
|
const std::string &key,
|
||||||
unsigned int val)
|
unsigned int val)
|
||||||
{
|
{
|
||||||
|
@ -88,8 +87,7 @@ static inline void index_insert(Database<IndexEntry, T> &db,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
static inline void index_remove(Database<IndexEntry> &db,
|
||||||
static inline void index_remove(Database<IndexEntry, T> &db,
|
|
||||||
const std::string &key,
|
const std::string &key,
|
||||||
unsigned int val)
|
unsigned int val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,30 +7,27 @@
|
||||||
#ifndef OCARINA_DATABASE_HPP
|
#ifndef OCARINA_DATABASE_HPP
|
||||||
#define OCARINA_DATABASE_HPP
|
#define OCARINA_DATABASE_HPP
|
||||||
|
|
||||||
|
#include <error.h>
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
DatabaseEntry<T> :: DatabaseEntry()
|
Database<T> :: Database(std::string filepath)
|
||||||
: valid(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class T, class U>
|
|
||||||
Database<T, U> :: Database(std::string filepath)
|
|
||||||
: _size(0), file(filepath, FILE_TYPE_DATA)
|
: _size(0), file(filepath, FILE_TYPE_DATA)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
Database<T, U> :: ~Database()
|
Database<T> :: ~Database()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
void Database<T, U> :: save()
|
void Database<T> :: save()
|
||||||
{
|
{
|
||||||
if (file.open(OPEN_WRITE) == false)
|
try {
|
||||||
|
file.open(OPEN_WRITE);
|
||||||
|
} catch (int error) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
file << db.size() << std::endl;
|
file << db.size() << std::endl;
|
||||||
for (unsigned int i = 0; i < db.size(); i++) {
|
for (unsigned int i = 0; i < db.size(); i++) {
|
||||||
|
@ -43,12 +40,16 @@ void Database<T, U> :: save()
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
void Database<T, U> :: load()
|
void Database<T> :: load()
|
||||||
{
|
{
|
||||||
unsigned int db_size;
|
unsigned int db_size;
|
||||||
if (file.open(OPEN_READ) == false)
|
|
||||||
|
try {
|
||||||
|
file.open(OPEN_READ);
|
||||||
|
} catch (int error) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
file >> db_size;
|
file >> db_size;
|
||||||
db.resize(db_size);
|
db.resize(db_size);
|
||||||
|
@ -56,7 +57,7 @@ void Database<T, U> :: load()
|
||||||
file >> db[i].valid;
|
file >> db[i].valid;
|
||||||
if (db[i].valid == true) {
|
if (db[i].valid == true) {
|
||||||
db[i].read(file);
|
db[i].read(file);
|
||||||
keys.insert(std::pair<std::string, unsigned int>(db[i].primary_key(), i));
|
keys.insert(std::pair<std::string, unsigned int>(db[i].primary_key, i));
|
||||||
_size++;
|
_size++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,17 +65,17 @@ void Database<T, U> :: load()
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG
|
#ifdef CONFIG_TEST
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
void Database<T, U> :: clear()
|
void Database<T> :: clear()
|
||||||
{
|
{
|
||||||
db.clear();
|
db.clear();
|
||||||
keys.clear();
|
keys.clear();
|
||||||
_size = 0;
|
_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
void Database<T, U> :: print()
|
void Database<T> :: print()
|
||||||
{
|
{
|
||||||
:: print("Allocated rows: %u\n", db.size());
|
:: print("Allocated rows: %u\n", db.size());
|
||||||
:: print("Valid rows: %u\n", _size);
|
:: print("Valid rows: %u\n", _size);
|
||||||
|
@ -87,8 +88,8 @@ void Database<T, U> :: print()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
void Database<T, U> :: print_keys()
|
void Database<T> :: print_keys()
|
||||||
{
|
{
|
||||||
std::map<const std::string, unsigned int>::iterator it;
|
std::map<const std::string, unsigned int>::iterator it;
|
||||||
:: print("Found keys:");
|
:: print("Found keys:");
|
||||||
|
@ -96,15 +97,15 @@ void Database<T, U> :: print_keys()
|
||||||
:: print(" %s", it->first.c_str());
|
:: print(" %s", it->first.c_str());
|
||||||
:: print("\n");
|
:: print("\n");
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_DEBUG */
|
#endif /* CONFIG_TEST */
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
unsigned int Database<T, U> :: insert(T val)
|
unsigned int Database<T> :: insert(T val)
|
||||||
{
|
{
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
typename std::map<U, unsigned int>::iterator it;
|
typename std::map<const std::string, unsigned int>::iterator it;
|
||||||
|
|
||||||
it = keys.find(val.primary_key());
|
it = keys.find(val.primary_key);
|
||||||
if (it != keys.end())
|
if (it != keys.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
|
|
||||||
|
@ -113,34 +114,34 @@ unsigned int Database<T, U> :: insert(T val)
|
||||||
*/
|
*/
|
||||||
id = db.size();
|
id = db.size();
|
||||||
db.push_back(val);
|
db.push_back(val);
|
||||||
keys.insert(std::pair<U, unsigned int>(val.primary_key(), id));
|
keys.insert(std::pair<const std::string, unsigned int>(val.primary_key, id));
|
||||||
db[id].valid = true;
|
db[id].valid = true;
|
||||||
_size++;
|
_size++;
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
void Database<T, U> :: remove(unsigned int id)
|
void Database<T> :: remove(unsigned int id)
|
||||||
{
|
{
|
||||||
keys.erase(db[id].primary_key());
|
keys.erase(db[id].primary_key);
|
||||||
db[id].valid = false;
|
db[id].valid = false;
|
||||||
_size--;
|
_size--;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
unsigned int Database<T, U> :: size()
|
unsigned int Database<T> :: size()
|
||||||
{
|
{
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
unsigned int Database<T, U> :: num_rows()
|
unsigned int Database<T> :: num_rows()
|
||||||
{
|
{
|
||||||
return db.size();
|
return db.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
unsigned int Database<T, U> :: first()
|
unsigned int Database<T> :: first()
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < db.size(); i++) {
|
for (unsigned int i = 0; i < db.size(); i++) {
|
||||||
if (db[i].valid == true)
|
if (db[i].valid == true)
|
||||||
|
@ -150,8 +151,8 @@ unsigned int Database<T, U> :: first()
|
||||||
return db.size();
|
return db.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
unsigned int Database<T, U> :: last()
|
unsigned int Database<T> :: last()
|
||||||
{
|
{
|
||||||
if (_size == 0)
|
if (_size == 0)
|
||||||
return db.size();
|
return db.size();
|
||||||
|
@ -164,8 +165,8 @@ unsigned int Database<T, U> :: last()
|
||||||
return db.size();
|
return db.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
unsigned int Database<T, U> :: next(unsigned int id)
|
unsigned int Database<T> :: next(unsigned int id)
|
||||||
{
|
{
|
||||||
for (unsigned int i = id + 1; i < db.size(); i++) {
|
for (unsigned int i = id + 1; i < db.size(); i++) {
|
||||||
if (db[i].valid == true)
|
if (db[i].valid == true)
|
||||||
|
@ -175,25 +176,40 @@ unsigned int Database<T, U> :: next(unsigned int id)
|
||||||
return db.size();
|
return db.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
unsigned int Database<T, U> :: find_index(const std::string &key)
|
bool Database<T> :: has_key(const std::string &key)
|
||||||
{
|
{
|
||||||
typename std::map<U, unsigned int>::iterator it;
|
std::map<const std::string, unsigned int>::iterator it;
|
||||||
|
it = keys.find(key);
|
||||||
|
return it != keys.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
unsigned int Database<T> :: find_index(const std::string &key)
|
||||||
|
{
|
||||||
|
std::map<const std::string, unsigned int>::iterator it;
|
||||||
it = keys.find(key);
|
it = keys.find(key);
|
||||||
if (it == keys.end())
|
if (it == keys.end())
|
||||||
throw 0;
|
throw -EEXIST;
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
T &Database<T, U> :: find(const std::string &key)
|
T &Database<T> :: find(const std::string &key)
|
||||||
{
|
{
|
||||||
return db[find_index(key)];
|
unsigned int index = find_index(key);
|
||||||
|
if (db[index].valid == false)
|
||||||
|
throw -EINVAL;
|
||||||
|
return db[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T>
|
||||||
T &Database<T, U> :: operator[](unsigned int id)
|
T &Database<T> :: operator[](unsigned int id)
|
||||||
{
|
{
|
||||||
|
if (id >= db.size())
|
||||||
|
throw -EEXIST;
|
||||||
|
else if (db[id].valid == false)
|
||||||
|
throw -EINVAL;
|
||||||
return db[id];
|
return db[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,21 @@
|
||||||
*/
|
*/
|
||||||
#include <database.h>
|
#include <database.h>
|
||||||
|
|
||||||
|
|
||||||
|
DatabaseEntry :: DatabaseEntry()
|
||||||
|
: primary_key(""), valid(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
IndexEntry :: IndexEntry()
|
IndexEntry :: IndexEntry()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexEntry :: IndexEntry(const std::string &k, unsigned int v)
|
IndexEntry :: IndexEntry(const std::string &key, unsigned int v)
|
||||||
: key(k)
|
|
||||||
{
|
{
|
||||||
|
primary_key = key;
|
||||||
insert(v);
|
insert(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,15 +25,10 @@ IndexEntry :: ~IndexEntry()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &IndexEntry :: primary_key()
|
|
||||||
{
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndexEntry :: write(File &f)
|
void IndexEntry :: write(File &f)
|
||||||
{
|
{
|
||||||
std::set<unsigned int>::iterator it;
|
std::set<unsigned int>::iterator it;
|
||||||
f << key << std::endl << values.size() << " ";
|
f << primary_key << std::endl << values.size() << " ";
|
||||||
for (it = values.begin(); it != values.end(); it++)
|
for (it = values.begin(); it != values.end(); it++)
|
||||||
f << *it << " ";
|
f << *it << " ";
|
||||||
}
|
}
|
||||||
|
@ -34,13 +37,14 @@ void IndexEntry :: read(File &f)
|
||||||
{
|
{
|
||||||
unsigned int num, val;
|
unsigned int num, val;
|
||||||
|
|
||||||
f >> key >> num;
|
f >> primary_key >> num;
|
||||||
for (unsigned int i = 0; i < num; i++) {
|
for (unsigned int i = 0; i < num; i++) {
|
||||||
f >> val;
|
f >> val;
|
||||||
values.insert(val);
|
values.insert(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_TEST
|
||||||
void IndexEntry :: print()
|
void IndexEntry :: print()
|
||||||
{
|
{
|
||||||
std::set<unsigned int>::iterator it;
|
std::set<unsigned int>::iterator it;
|
||||||
|
@ -52,6 +56,7 @@ void IndexEntry :: print()
|
||||||
}
|
}
|
||||||
:: print("}");
|
:: print("}");
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_TEST */
|
||||||
|
|
||||||
void IndexEntry :: insert(unsigned int val)
|
void IndexEntry :: insert(unsigned int val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,14 +6,12 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
class DBTest : public DatabaseEntry<const std::string> {
|
class DBTest : public DatabaseEntry {
|
||||||
public:
|
public:
|
||||||
unsigned int value;
|
unsigned int value;
|
||||||
std::string key;
|
|
||||||
|
|
||||||
DBTest();
|
DBTest();
|
||||||
DBTest(unsigned int);
|
DBTest(unsigned int);
|
||||||
const std::string &primary_key();
|
|
||||||
void write(File &);
|
void write(File &);
|
||||||
void read(File &);
|
void read(File &);
|
||||||
void print();
|
void print();
|
||||||
|
@ -29,7 +27,7 @@ DBTest :: DBTest(unsigned int val)
|
||||||
|
|
||||||
value = val;
|
value = val;
|
||||||
ss << value;
|
ss << value;
|
||||||
key = ss.str();
|
primary_key = ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBTest :: write(File &file)
|
void DBTest :: write(File &file)
|
||||||
|
@ -47,14 +45,9 @@ void DBTest :: print()
|
||||||
:: print("%u", value);
|
:: print("%u", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &DBTest :: primary_key()
|
|
||||||
{
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
void print_db(Database<DBTest> &db)
|
||||||
void print_db(Database<DBTest, const std::string> &db)
|
|
||||||
{
|
{
|
||||||
print("Database size: %u\n", db.size());
|
print("Database size: %u\n", db.size());
|
||||||
print("Num rows: %u\n", db.num_rows());
|
print("Num rows: %u\n", db.num_rows());
|
||||||
|
@ -65,14 +58,14 @@ void print_db(Database<DBTest, const std::string> &db)
|
||||||
print("db[%u] = %u\n", i, db[i].value);
|
print("db[%u] = %u\n", i, db[i].value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_insertion(Database<DBTest, const std::string> &db)
|
void test_insertion(Database<DBTest> &db)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 1; i <= 100000; i++)
|
for (unsigned int i = 1; i <= 100000; i++)
|
||||||
db.insert(DBTest(i));
|
db.insert(DBTest(i));
|
||||||
print_db(db);
|
print_db(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_deletion(Database<DBTest, const std::string> &db)
|
void test_deletion(Database<DBTest> &db)
|
||||||
{
|
{
|
||||||
for (unsigned int i = db.first(); i < db.num_rows(); i = db.next(i)) {
|
for (unsigned int i = db.first(); i < db.num_rows(); i = db.next(i)) {
|
||||||
db.remove(i);
|
db.remove(i);
|
||||||
|
@ -87,7 +80,7 @@ void test_deletion(Database<DBTest, const std::string> &db)
|
||||||
void test_0()
|
void test_0()
|
||||||
{
|
{
|
||||||
print("Test 0\n");
|
print("Test 0\n");
|
||||||
Database<DBTest, const std::string> db("test.db");
|
Database<DBTest> db("test.db");
|
||||||
|
|
||||||
test_insertion(db);
|
test_insertion(db);
|
||||||
test_deletion(db);
|
test_deletion(db);
|
||||||
|
@ -102,7 +95,7 @@ void test_0()
|
||||||
void test_1()
|
void test_1()
|
||||||
{
|
{
|
||||||
print("\nTest 1\n");
|
print("\nTest 1\n");
|
||||||
Database<DBTest, const std::string> db("test.db");
|
Database<DBTest> db("test.db");
|
||||||
db.load();
|
db.load();
|
||||||
print_db(db);
|
print_db(db);
|
||||||
}
|
}
|
||||||
|
@ -113,7 +106,7 @@ void test_1()
|
||||||
void test_2()
|
void test_2()
|
||||||
{
|
{
|
||||||
print("\nTest 2\n");
|
print("\nTest 2\n");
|
||||||
Database<DBTest, const std::string> db("");
|
Database<DBTest> db("");
|
||||||
|
|
||||||
test_insertion(db);
|
test_insertion(db);
|
||||||
db.save();
|
db.save();
|
||||||
|
@ -125,7 +118,7 @@ void test_2()
|
||||||
void test_3()
|
void test_3()
|
||||||
{
|
{
|
||||||
print("\nTest 3\n");
|
print("\nTest 3\n");
|
||||||
Database<DBTest, const std::string> db("");
|
Database<DBTest> db("");
|
||||||
db.load();
|
db.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +128,7 @@ void test_3()
|
||||||
void test_4()
|
void test_4()
|
||||||
{
|
{
|
||||||
print("\nTest 4\n");
|
print("\nTest 4\n");
|
||||||
Database<DBTest, const std::string> db("");
|
Database<DBTest> db("");
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 100; i++)
|
for (unsigned int i = 0; i < 100; i++)
|
||||||
db.insert(DBTest(i % 5));
|
db.insert(DBTest(i % 5));
|
||||||
|
@ -149,7 +142,7 @@ void test_4()
|
||||||
void test_5()
|
void test_5()
|
||||||
{
|
{
|
||||||
print("\nTest 5\n");
|
print("\nTest 5\n");
|
||||||
Database<DBTest, const std::string> db("");
|
Database<DBTest> db("");
|
||||||
for (unsigned int i = 0; i < 10; i++)
|
for (unsigned int i = 0; i < 10; i++)
|
||||||
db.insert(DBTest(i));
|
db.insert(DBTest(i));
|
||||||
db.print();
|
db.print();
|
||||||
|
@ -161,7 +154,7 @@ void test_5()
|
||||||
void test_6()
|
void test_6()
|
||||||
{
|
{
|
||||||
print("\nTest 6\n");
|
print("\nTest 6\n");
|
||||||
Database<DBTest, const std::string> db("");
|
Database<DBTest> db("");
|
||||||
for (unsigned int i = 0; i < 10; i++)
|
for (unsigned int i = 0; i < 10; i++)
|
||||||
db.insert(DBTest(i));
|
db.insert(DBTest(i));
|
||||||
print_db(db);
|
print_db(db);
|
||||||
|
@ -175,7 +168,7 @@ void test_6()
|
||||||
void test_7()
|
void test_7()
|
||||||
{
|
{
|
||||||
print("\nTest 7\n");
|
print("\nTest 7\n");
|
||||||
Database<DBTest, const std::string> db("");
|
Database<DBTest> db("");
|
||||||
print_db(db);
|
print_db(db);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 10; i++)
|
for (unsigned int i = 0; i < 10; i++)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <database.h>
|
#include <database.h>
|
||||||
#include <print.h>
|
#include <print.h>
|
||||||
|
|
||||||
void print_index(Database<IndexEntry, const std::string> &index)
|
void print_index(Database<IndexEntry> &index)
|
||||||
{
|
{
|
||||||
std::set<std::string>::iterator s_it;
|
std::set<std::string>::iterator s_it;
|
||||||
std::set<unsigned int>::iterator u_it;
|
std::set<unsigned int>::iterator u_it;
|
||||||
|
@ -13,7 +13,7 @@ void print_index(Database<IndexEntry, const std::string> &index)
|
||||||
index.print_keys();
|
index.print_keys();
|
||||||
|
|
||||||
for (unsigned int i = index.first(); i != index.num_rows(); i = index.next(i)) {
|
for (unsigned int i = index.first(); i != index.num_rows(); i = index.next(i)) {
|
||||||
print("index[%s] = ", index[i].key.c_str());
|
print("index[%s] = ", index[i].primary_key.c_str());
|
||||||
index[i].print();
|
index[i].print();
|
||||||
print("\n");
|
print("\n");
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ void print_index(Database<IndexEntry, const std::string> &index)
|
||||||
print("\n");
|
print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void populate_index(Database<IndexEntry, const std::string> &index)
|
void populate_index(Database<IndexEntry> &index)
|
||||||
{
|
{
|
||||||
std::string key_str;
|
std::string key_str;
|
||||||
|
|
||||||
|
@ -32,17 +32,19 @@ void populate_index(Database<IndexEntry, const std::string> &index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_keys(Database<IndexEntry, const std::string> &index)
|
void remove_keys(Database<IndexEntry> &index)
|
||||||
{
|
{
|
||||||
std::string key_str;
|
std::string key_str;
|
||||||
|
|
||||||
for (char key = 'a'; key <= 'z'; key+=2) {
|
for (char key = 'a'; key <= 'z'; key+=2) {
|
||||||
key_str = key;
|
key_str = key;
|
||||||
index.remove(index.find_index(key_str));
|
index.remove(index.find_index(key_str));
|
||||||
|
if (index.has_key(key_str))
|
||||||
|
print("Failed to remove key!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_values(Database<IndexEntry, const std::string> &index)
|
void remove_values(Database<IndexEntry> &index)
|
||||||
{
|
{
|
||||||
std::string key_str;
|
std::string key_str;
|
||||||
unsigned int limit = 0;
|
unsigned int limit = 0;
|
||||||
|
@ -52,8 +54,11 @@ void remove_values(Database<IndexEntry, const std::string> &index)
|
||||||
for (unsigned int i = 0; i < limit; i++)
|
for (unsigned int i = 0; i < limit; i++)
|
||||||
index_remove(index, key_str, i);
|
index_remove(index, key_str, i);
|
||||||
limit++;
|
limit++;
|
||||||
if (limit == 11)
|
if (limit == 11) {
|
||||||
limit = 0;
|
limit = 0;
|
||||||
|
if (index.has_key(key_str))
|
||||||
|
print("Failed to remove key!\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +68,7 @@ void remove_values(Database<IndexEntry, const std::string> &index)
|
||||||
void test_0()
|
void test_0()
|
||||||
{
|
{
|
||||||
print("Test 0\n");
|
print("Test 0\n");
|
||||||
Database<IndexEntry, const std::string> index("");
|
Database<IndexEntry> index("");
|
||||||
|
|
||||||
populate_index(index);
|
populate_index(index);
|
||||||
print_index(index);
|
print_index(index);
|
||||||
|
@ -75,7 +80,7 @@ void test_0()
|
||||||
void test_1()
|
void test_1()
|
||||||
{
|
{
|
||||||
print("Test 1\n");
|
print("Test 1\n");
|
||||||
Database<IndexEntry, const std::string> index("");
|
Database<IndexEntry> index("");
|
||||||
|
|
||||||
populate_index(index);
|
populate_index(index);
|
||||||
remove_keys(index);
|
remove_keys(index);
|
||||||
|
@ -88,7 +93,7 @@ void test_1()
|
||||||
void test_2()
|
void test_2()
|
||||||
{
|
{
|
||||||
print("Test 2\n");
|
print("Test 2\n");
|
||||||
Database<IndexEntry, const std::string> index("");
|
Database<IndexEntry> index("");
|
||||||
|
|
||||||
populate_index(index);
|
populate_index(index);
|
||||||
remove_values(index);
|
remove_values(index);
|
||||||
|
@ -101,7 +106,7 @@ void test_2()
|
||||||
void test_3()
|
void test_3()
|
||||||
{
|
{
|
||||||
print("Test 3\n");
|
print("Test 3\n");
|
||||||
Database<IndexEntry, const std::string> index("test.idx");
|
Database<IndexEntry> index("test.idx");
|
||||||
|
|
||||||
populate_index(index);
|
populate_index(index);
|
||||||
remove_values(index);
|
remove_values(index);
|
||||||
|
@ -114,7 +119,7 @@ void test_3()
|
||||||
void test_4()
|
void test_4()
|
||||||
{
|
{
|
||||||
print("Test 4\n");
|
print("Test 4\n");
|
||||||
Database<IndexEntry, const std::string> index("test.idx");
|
Database<IndexEntry> index("test.idx");
|
||||||
|
|
||||||
index.load();
|
index.load();
|
||||||
print_index(index);
|
print_index(index);
|
||||||
|
@ -126,7 +131,7 @@ void test_4()
|
||||||
void test_5()
|
void test_5()
|
||||||
{
|
{
|
||||||
print("Test 5\n");
|
print("Test 5\n");
|
||||||
Database<IndexEntry, const std::string> index("");
|
Database<IndexEntry> index("");
|
||||||
print("index[nokey].size() = ");
|
print("index[nokey].size() = ");
|
||||||
try {
|
try {
|
||||||
print("%u\n", index.find("nokey").values.size());
|
print("%u\n", index.find("nokey").values.size());
|
||||||
|
|
Loading…
Reference in New Issue