From 81f3ef458f161ed45fdc01ea27742ed79cff80e9 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Sun, 16 Mar 2014 18:32:20 -0400 Subject: [PATCH] database: Each DatabaseEntry should know its id This will let me set up a Track class that has pointers to the corresponding artist, album and genre information without needing to know their IDs directly. Having this information available means I won't need to keep a "join struct" when doing lookups - instead I can return a pointer to a Track class that already knows everything. Signed-off-by: Anna Schumaker --- DESIGN | 21 ++++++++++++++------- include/database.h | 1 + include/database.hpp | 2 ++ lib/database.cpp | 2 +- tests/db_entry | 4 ++-- tests/src/database.cpp | 7 ++++++- tests/src/db_entry.cpp | 2 +- 7 files changed, 27 insertions(+), 12 deletions(-) diff --git a/DESIGN b/DESIGN index 9c22e0ac..79d3121f 100644 --- a/DESIGN +++ b/DESIGN @@ -193,13 +193,14 @@ On-disk files: Database Entry: The database entry class is a base class used for storing data inside - a database (below). The valid flag will be managed by the database - itself, and should be initialized to false. + a database (below). The valid flag and id counter will be managed by + the database itself, and should be initialized to false and 0. - DatabaseEntry: class DatabaseEntry { public: bool valid; + unsigned int id; DatabaseEntry(); virtual void ~DatabaseEntry() = 0; @@ -211,7 +212,7 @@ Database Entry: - API: DatabaseEntry :: DatabaseEntry(): - Set valid = false. + Set valid = false and id = 0. const std::string DatabaseEntry :: primary_key(); This function should return a unique string representing this @@ -239,23 +240,28 @@ Database: include/database.hpp, which will be included by database.h. Any function not relying on a template can be written in lib/database.cpp. -- Automatic saving +- Automatic saving: Databases can save automatically whenever a new value is inserted or deleted. This will be more efficient for Databases that do not change often but will be a huge performance hit for Databases that have many changes at once. All databases will be loaded automatically from disk. -- Primary keys +- Primary keys: Databases use the primary_key() function of a DatabaseEntry to enforce uniqueness. This key is used when inserting a new value into the Database, and will not be updated after. -- Valid bit +- Valid bit: The "valid" bit of a DatabaseEntry is completely managed by the entry's Database container. It will be set to true when an entry is inserted and false when deleted. The Database is also in charge of writing the valid bit to file. +- Id: + The "id" field of a DatabaseEntry is also managed by the entry's + Database container It will be set to the entry's ID when the entry is + inserted into the database. + - Database: template class Database { @@ -313,9 +319,10 @@ Database: - Add the new item to the end of the _db. - Add the new item to _keys. - Set item.valid = true. + - Set item.id to the index of the new item. _ Increment _size. - If autosave == true: save(). - - Return the index of the new item. + - Return item.id. unsigned int Database :: remove(); - Remove the item from the _keys map. diff --git a/include/database.h b/include/database.h index 41dc3a35..a0c5f55d 100644 --- a/include/database.h +++ b/include/database.h @@ -14,6 +14,7 @@ class DatabaseEntry { public: bool valid; + unsigned int id; DatabaseEntry(); virtual const std::string primary_key() = 0; diff --git a/include/database.hpp b/include/database.hpp index 2555634f..f6c4b4f1 100644 --- a/include/database.hpp +++ b/include/database.hpp @@ -60,6 +60,7 @@ void Database :: load() _file >> _db[i].valid; if (_db[i].valid == true) { _db[i].read(_file); + _db[i].id = i; _keys.insert(std::pair(_db[i].primary_key(), i)); _size++; } @@ -84,6 +85,7 @@ unsigned int Database :: insert(T val) _db.push_back(val); _keys[val.primary_key()] = id; _db[id].valid = true; + _db[id].id = id; _size++; autosave(); return id; diff --git a/lib/database.cpp b/lib/database.cpp index 0b1b125d..a68af4ae 100644 --- a/lib/database.cpp +++ b/lib/database.cpp @@ -5,6 +5,6 @@ DatabaseEntry :: DatabaseEntry() - : valid(false) + : valid(false), id(0) { } diff --git a/tests/db_entry b/tests/db_entry index da5d42fd..33f97f49 100755 --- a/tests/db_entry +++ b/tests/db_entry @@ -10,7 +10,7 @@ function test_entry function test_print { - test_entry $1 $2 "Value: $1 Key: $2 Valid: 0" + test_entry $1 $2 "Value: $1 Key: $2 Valid: 0 Id: 0" } function test_primary_key @@ -30,7 +30,7 @@ function test_read rm $DATA_DIR/db_entry.txt 2>/dev/null || true echo 0 > $DATA_DIR/db_entry.txt echo $1 $2 >> $DATA_DIR/db_entry.txt - test_entry "-r $1" $2 "Value: $1 Key: $2 Valid: 0" + test_entry "-r $1" $2 "Value: $1 Key: $2 Valid: 0 Id: 0" } diff --git a/tests/src/database.cpp b/tests/src/database.cpp index ccd72ee1..e9291984 100644 --- a/tests/src/database.cpp +++ b/tests/src/database.cpp @@ -137,13 +137,15 @@ int main(int argc, char **argv) /** - * 7: Test iterating + * 7: Test iterating and setting ID */ Database::iterator it; unsigned int index = 1; for (it = db.begin(); it != db.end(); it = db.next(it)) { if ((*it).val != index) test_results(false, __LINE__); + if ((*it).id != index) + test_results(false, __LINE__); index+=2; }; test_results(true, __LINE__); @@ -212,9 +214,12 @@ int main(int argc, char **argv) if (it->valid == true) { if (it->val != it2->val) test_results(false, __LINE__); + if (it->id != it2->id) + test_results(false, __LINE__); } it2++; } test_results(true, __LINE__); + return 0; } diff --git a/tests/src/db_entry.cpp b/tests/src/db_entry.cpp index f8015dca..f5aac956 100644 --- a/tests/src/db_entry.cpp +++ b/tests/src/db_entry.cpp @@ -48,7 +48,7 @@ void IntEntry :: read(File &f) void IntEntry :: print() { - :: print("Value: %u Key: %s Valid: %d\n", val, key.c_str(), valid); + :: print("Value: %u Key: %s Valid: %d Id: %u\n", val, key.c_str(), valid, id); }