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 <schumaker.anna@gmail.com>
This commit is contained in:
parent
14879b03fd
commit
81f3ef458f
21
DESIGN
21
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 T>
|
||||
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.
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
class DatabaseEntry {
|
||||
public:
|
||||
bool valid;
|
||||
unsigned int id;
|
||||
|
||||
DatabaseEntry();
|
||||
virtual const std::string primary_key() = 0;
|
||||
|
|
|
@ -60,6 +60,7 @@ void Database<T> :: load()
|
|||
_file >> _db[i].valid;
|
||||
if (_db[i].valid == true) {
|
||||
_db[i].read(_file);
|
||||
_db[i].id = i;
|
||||
_keys.insert(std::pair<std::string, unsigned int>(_db[i].primary_key(), i));
|
||||
_size++;
|
||||
}
|
||||
|
@ -84,6 +85,7 @@ unsigned int Database<T> :: insert(T val)
|
|||
_db.push_back(val);
|
||||
_keys[val.primary_key()] = id;
|
||||
_db[id].valid = true;
|
||||
_db[id].id = id;
|
||||
_size++;
|
||||
autosave();
|
||||
return id;
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
|
||||
|
||||
DatabaseEntry :: DatabaseEntry()
|
||||
: valid(false)
|
||||
: valid(false), id(0)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -137,13 +137,15 @@ int main(int argc, char **argv)
|
|||
|
||||
|
||||
/**
|
||||
* 7: Test iterating
|
||||
* 7: Test iterating and setting ID
|
||||
*/
|
||||
Database<IntEntry>::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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue