database: Add a way for databases to have unique keys

The library will need databases that have unique values (such as the
artist or album tables).  This patch adds support for that in my
existing database code.

Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This commit is contained in:
Anna Schumaker 2013-09-17 16:09:01 -04:00 committed by Anna Schumaker
parent b176a48c6c
commit dd92ee853f
5 changed files with 63 additions and 9 deletions

View File

@ -40,15 +40,22 @@ Database: (lib/database.cpp)
File << <CHILD_CLASS_DATA>
- Flags:
enum DatabaseFlags {
DB_NORMAL,
DB_UNIQUE,
}
- Database:
template <class T>
class Database {
private:
unsigned int _size; /* Number of valid rows */
File filename;
DatabaseFlags flags;
vector<T> db;
public:
Database::Database(filename);
Database::Database(filename, flags);
void load();
void save();
@ -69,8 +76,9 @@ Database: (lib/database.cpp)
...
- API:
Database : Database(filename);
Database : Database(filename, flags);
Initializes database to use ~/.ocarina{-debug}/filename.
Set up flags.
void Database : load();
Reads data from file.
@ -81,6 +89,8 @@ Database: (lib/database.cpp)
template <class T>
unsigned int Database : insert(T &);
Adds a new item to the db, returns the id of the item.
if DB_UNIQUE is set, check if the item already exists in the
DB and return it's ID instead of adding a new item.
void Database : delete(unsigned int index);
Mark db[index] as invalid (quick deletion).

View File

@ -20,15 +20,21 @@ public:
};
enum DatabaseFlags {
DB_NORMAL,
DB_UNIQUE,
};
template <class T>
class Database {
private:
std::vector<T> db;
unsigned int _size;
File file;
DatabaseFlags flags;
public:
Database(std::string);
Database(std::string, DatabaseFlags);
~Database();
void save();
void load();

View File

@ -8,8 +8,8 @@
#define OCARINA_DATABASE_HPP
template <class T>
Database<T> :: Database(std::string filepath)
: _size(0), file(filepath, FILE_TYPE_DATA)
Database<T> :: Database(std::string filepath, DatabaseFlags f)
: _size(0), file(filepath, FILE_TYPE_DATA), flags(f)
{
}
@ -58,6 +58,12 @@ void Database<T> :: load()
template <class T>
unsigned int Database<T> :: insert(T val)
{
if (flags == DB_UNIQUE) {
for (unsigned int i = first(); i < size(); i = next(i)) {
if (val == db[i])
return i;
}
}
db.push_back(val);
_size++;
return db.size() - 1;

View File

@ -12,6 +12,7 @@ public:
DBTest(unsigned int);
void write(File &);
void read(File &);
bool operator==(DBTest &);
};
DBTest :: DBTest()
@ -34,6 +35,11 @@ void DBTest :: read(File &file)
file >> value;
}
bool DBTest :: operator==(DBTest &rhs)
{
return value == rhs.value;
}
void print_db(Database<DBTest> &db)
@ -69,7 +75,7 @@ void test_deletion(Database<DBTest> &db)
void test_0()
{
print("Test 0\n");
Database<DBTest> db("test.db");
Database<DBTest> db("test.db", DB_NORMAL);
test_insertion(db);
test_deletion(db);
@ -84,7 +90,7 @@ void test_0()
void test_1()
{
print("Test 1\n");
Database<DBTest> db("test.db");
Database<DBTest> db("test.db", DB_NORMAL);
db.load();
print_db(db);
}
@ -95,7 +101,7 @@ void test_1()
void test_2()
{
print("Test 2\n");
Database<DBTest> db("");
Database<DBTest> db("", DB_NORMAL);
test_insertion(db);
db.save();
@ -107,16 +113,31 @@ void test_2()
void test_3()
{
print("Test 3\n");
Database<DBTest> db("");
Database<DBTest> db("", DB_NORMAL);
db.load();
}
/*
* Test unique insertion
*/
void test_4()
{
print("Test 4\n");
Database<DBTest> db("", DB_UNIQUE);
for (unsigned int i = 0; i < 100; i++)
db.insert(DBTest(i % 5));
print_db(db);
}
int main(int argc, char **argv)
{
test_0();
test_1();
test_2();
test_3();
test_4();
return 0;
}

View File

@ -300029,3 +300029,14 @@ db[99999] = 100000
ERROR: A file with hint = FILE_TYPE_INVALID cannot be opened
Test 3
ERROR: A file with hint = FILE_TYPE_INVALID cannot be opened
Test 4
Database size: 5
Num rows: 5
First: 0
Last: 4
db[0] = 0
db[1] = 1
db[2] = 2
db[3] = 3
db[4] = 4