core/database: Add operations vector
I intend to replace C++ inheritance with this struct of function pointers. Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
parent
847e4c1925
commit
ab1572ed34
|
@ -42,11 +42,14 @@ void index_entry :: read(file &file)
|
|||
}
|
||||
|
||||
|
||||
static const struct db_ops index_ops = {
|
||||
};
|
||||
|
||||
|
||||
void index_init(database<index_entry> *index, const gchar *filepath,
|
||||
bool autosave)
|
||||
{
|
||||
db_init(index, filepath, autosave);
|
||||
db_init(index, filepath, autosave, &index_ops);
|
||||
}
|
||||
|
||||
index_entry *index_insert(database<index_entry> *index, const gchar *key,
|
||||
|
@ -77,3 +80,7 @@ bool index_has(database<index_entry> *index, const gchar *key, unsigned int valu
|
|||
return false;
|
||||
return set_has(&it->ie_set, value);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TESTING
|
||||
const struct db_ops *test_index_ops() { return &index_ops; }
|
||||
#endif /* CONFIG_TESTING */
|
||||
|
|
|
@ -59,9 +59,13 @@ void album :: write(file &file)
|
|||
}
|
||||
|
||||
|
||||
static const struct db_ops album_ops = {
|
||||
};
|
||||
|
||||
|
||||
void album_db_init()
|
||||
{
|
||||
db_init(&album_db, "album.db", true);
|
||||
db_init(&album_db, "album.db", true, &album_ops);
|
||||
db_load(&album_db);
|
||||
}
|
||||
|
||||
|
@ -84,3 +88,7 @@ int album_compare(struct album *lhs, struct album *rhs)
|
|||
{
|
||||
return string_compare(lhs->al_lower.c_str(), rhs->al_lower.c_str());
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TESTING
|
||||
const struct db_ops *test_album_ops() { return &album_ops; }
|
||||
#endif /* CONFIG_TESTING */
|
||||
|
|
|
@ -45,9 +45,13 @@ void artist :: write(file &file)
|
|||
}
|
||||
|
||||
|
||||
static const struct db_ops artist_ops = {
|
||||
};
|
||||
|
||||
|
||||
void artist_db_init()
|
||||
{
|
||||
db_init(&artist_db, "artist.db", true);
|
||||
db_init(&artist_db, "artist.db", true, &artist_ops);
|
||||
db_load(&artist_db);
|
||||
}
|
||||
|
||||
|
@ -70,3 +74,7 @@ int artist_compare(struct artist *lhs, struct artist *rhs)
|
|||
{
|
||||
return string_compare(lhs->ar_lower.c_str(), rhs->ar_lower.c_str());
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TESTING
|
||||
const struct db_ops *test_artist_ops() { return &artist_ops; }
|
||||
#endif /* CONFIG_TESTING */
|
||||
|
|
|
@ -44,9 +44,13 @@ void genre :: write(file &file)
|
|||
}
|
||||
|
||||
|
||||
static const struct db_ops genre_ops = {
|
||||
};
|
||||
|
||||
|
||||
void genre_db_init()
|
||||
{
|
||||
db_init(&genre_db, "genre.db", true);
|
||||
db_init(&genre_db, "genre.db", true, &genre_ops);
|
||||
db_load(&genre_db);
|
||||
}
|
||||
|
||||
|
@ -69,3 +73,7 @@ int genre_compare(struct genre *lhs, struct genre *rhs)
|
|||
{
|
||||
return string_compare(lhs->ge_lower.c_str(), rhs->ge_lower.c_str());
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TESTING
|
||||
const struct db_ops *test_genre_ops() { return &genre_ops; }
|
||||
#endif /* CONFIG_TESTING */
|
||||
|
|
|
@ -41,9 +41,13 @@ void library :: write(file &file)
|
|||
}
|
||||
|
||||
|
||||
static const struct db_ops library_ops = {
|
||||
};
|
||||
|
||||
|
||||
void library_db_init()
|
||||
{
|
||||
db_init(&library_db, "library.db", true);
|
||||
db_init(&library_db, "library.db", true, &library_ops);
|
||||
db_load(&library_db);
|
||||
}
|
||||
|
||||
|
@ -83,3 +87,7 @@ std::string library_file(struct library *library, const std::string &path)
|
|||
{
|
||||
return library->li_path + "/" + path;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TESTING
|
||||
const struct db_ops *test_library_ops() { return &library_ops; }
|
||||
#endif /* CONFIG_TESTING */
|
||||
|
|
|
@ -135,9 +135,13 @@ void track :: write(file &file)
|
|||
}
|
||||
|
||||
|
||||
static const struct db_ops track_ops = {
|
||||
};
|
||||
|
||||
|
||||
void track_db_init()
|
||||
{
|
||||
db_init(&track_db, "track.db", false);
|
||||
db_init(&track_db, "track.db", false, &track_ops);
|
||||
db_load(&track_db);
|
||||
}
|
||||
|
||||
|
@ -217,3 +221,7 @@ const std::string track_last_play(struct track *track)
|
|||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TESTING
|
||||
const struct db_ops *test_track_ops() { return &track_ops; }
|
||||
#endif /* CONFIG_TESTING */
|
||||
|
|
|
@ -51,6 +51,10 @@ struct db_entry {
|
|||
};
|
||||
|
||||
|
||||
struct db_ops {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Databases are a generic store for information used by Ocarina. Users
|
||||
* need to inherit from a DatabaseEntry class to properly use a Database.
|
||||
|
@ -75,6 +79,7 @@ struct database {
|
|||
bool db_autosave; /* True if the database saves when changed. */
|
||||
struct file db_file; /* The database's associated file object. */
|
||||
|
||||
const struct db_ops *db_ops; /* The database's operations vector. */
|
||||
std::vector<T *> db_entries;
|
||||
std::map<const std::string, unsigned int> db_keys;
|
||||
};
|
||||
|
@ -85,7 +90,7 @@ struct database {
|
|||
* and autosave as a hint for if this database should be automatically saved.
|
||||
*/
|
||||
template <class T>
|
||||
void db_init(struct database<T> *, const char *, bool);
|
||||
void db_init(struct database<T> *, const char *, bool, const struct db_ops *);
|
||||
|
||||
/* Called to prevent memory leaks by freeing all remaining database entries. */
|
||||
template <class T>
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
#define OCARINA_DATABASE_HPP
|
||||
|
||||
template <class T>
|
||||
void db_init(struct database<T> *db, const char *filepath, bool autosave)
|
||||
void db_init(struct database<T> *db, const char *filepath, bool autosave,
|
||||
const struct db_ops *ops)
|
||||
{
|
||||
db->db_ops = ops;
|
||||
db->db_size = 0;
|
||||
db->db_autosave = autosave;
|
||||
file_init(&db->db_file, filepath, 0);
|
||||
|
|
|
@ -66,4 +66,7 @@ void index_remove(database<index_entry> *, const gchar *, unsigned int);
|
|||
/* Called to check if the index has the specified (key, value) pair. */
|
||||
bool index_has(database<index_entry> *, const gchar *, unsigned int);
|
||||
|
||||
#ifdef CONFIG_TESTING
|
||||
const struct db_ops *test_index_ops();
|
||||
#endif /* CONFIG_TESTING */
|
||||
#endif /* OCARINA_CORE_DATABASE_H */
|
||||
|
|
|
@ -69,4 +69,7 @@ struct album *album_get(const unsigned int);
|
|||
/* Called to compare two album tags. */
|
||||
int album_compare(struct album *, struct album *);
|
||||
|
||||
#ifdef CONFIG_TESTING
|
||||
const struct db_ops *test_album_ops();
|
||||
#endif /* CONFIG_TESTING */
|
||||
#endif /* OCARINA_CORE_TAGS_ALBUM_H */
|
||||
|
|
|
@ -44,4 +44,7 @@ struct artist *artist_get(const unsigned int);
|
|||
/* Called to compare two artist tags. */
|
||||
int artist_compare(struct artist *, struct artist *);
|
||||
|
||||
#ifdef CONFIG_TESTING
|
||||
const struct db_ops *test_artist_ops();
|
||||
#endif /* CONFIG_TESTING */
|
||||
#endif /* OCARINA_CORE_TAGS_ARTIST_H */
|
||||
|
|
|
@ -45,4 +45,7 @@ struct genre *genre_get(const unsigned int);
|
|||
/* Called to compare two genre tags. */
|
||||
int genre_compare(struct genre *, struct genre *);
|
||||
|
||||
#ifdef CONFIG_TESTING
|
||||
const struct db_ops *test_genre_ops();
|
||||
#endif /* CONFIG_TESTING */
|
||||
#endif /* OCARINA_CORE_TAGS_GENRE_H */
|
||||
|
|
|
@ -78,4 +78,7 @@ void library_set_enabled(struct library *, bool);
|
|||
/* Called to find the full path of files under the library directory. */
|
||||
std::string library_file(struct library *, const std::string &);
|
||||
|
||||
#ifdef CONFIG_TESTING
|
||||
const struct db_ops *test_library_ops();
|
||||
#endif /* CONFIG_TESTING */
|
||||
#endif /* OCARINA_CORE_TAGS_LIBRARY_H */
|
||||
|
|
|
@ -99,4 +99,7 @@ void track_played(struct track *);
|
|||
/* Called to find the date that this track was last played. */
|
||||
const std::string track_last_play(struct track *);
|
||||
|
||||
#ifdef CONFIG_TESTING
|
||||
const struct db_ops *test_track_ops();
|
||||
#endif /* CONFIG_TESTING */
|
||||
#endif /* OCARINA_CORE_TAGS_TRACK_H */
|
||||
|
|
|
@ -32,6 +32,10 @@ struct int_entry : public db_entry {
|
|||
};
|
||||
|
||||
|
||||
static const struct db_ops int_ops = {
|
||||
};
|
||||
|
||||
|
||||
static void test_db_entry()
|
||||
{
|
||||
struct int_entry *ent = new struct int_entry(1);
|
||||
|
@ -64,7 +68,7 @@ static void test_init()
|
|||
{
|
||||
database<struct int_entry> db;
|
||||
|
||||
db_init(&db, "init.db", false);
|
||||
db_init(&db, "init.db", false, &int_ops);
|
||||
|
||||
/* Check initial sizes. */
|
||||
test_equal(db.db_entries.size(), 0);
|
||||
|
@ -85,7 +89,7 @@ static void test_stress(unsigned int N)
|
|||
unsigned int i;
|
||||
gchar *key;
|
||||
|
||||
db_init(&db, "stress.db", false);
|
||||
db_init(&db, "stress.db", false, &int_ops);
|
||||
|
||||
/* db_insert() */
|
||||
for (i = 0; i < N; i++) {
|
||||
|
@ -185,8 +189,8 @@ static void test_save_load()
|
|||
const unsigned int N = 10;
|
||||
unsigned int i;
|
||||
|
||||
db_init(&db1, "save_load.db", true);
|
||||
db_init(&db2, "save_load.db", false);
|
||||
db_init(&db1, "save_load.db", true, &int_ops);
|
||||
db_init(&db2, "save_load.db", false, &int_ops);
|
||||
|
||||
/* 10 items should "autosave" when inserted */
|
||||
for (i = 0; i < N; i++)
|
||||
|
|
|
@ -62,6 +62,7 @@ static void test_album_compare()
|
|||
|
||||
static void test_album_db()
|
||||
{
|
||||
const struct db_ops *album_ops = test_album_ops();
|
||||
database<struct album> album_db;
|
||||
struct album *album;
|
||||
|
||||
|
@ -74,7 +75,7 @@ static void test_album_db()
|
|||
test_equal(album_get(0), album);
|
||||
test_equal(album_get(1), (struct album *)NULL);
|
||||
|
||||
db_init(&album_db, "album.db", false);
|
||||
db_init(&album_db, "album.db", false, album_ops);
|
||||
db_load(&album_db);
|
||||
test_equal(album_db.db_size, 1);
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ static void test_artist_compare()
|
|||
|
||||
static void test_artist_db()
|
||||
{
|
||||
const struct db_ops *artist_ops = test_artist_ops();
|
||||
database<struct artist> artist_db;
|
||||
struct artist *artist;
|
||||
|
||||
|
@ -75,7 +76,7 @@ static void test_artist_db()
|
|||
test_equal(artist_get(0), artist);
|
||||
test_equal(artist_get(1), (struct artist *)NULL);
|
||||
|
||||
db_init(&artist_db, "artist.db", false);
|
||||
db_init(&artist_db, "artist.db", false, artist_ops);
|
||||
db_load(&artist_db);
|
||||
test_equal(artist_db.db_size, 1);
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ static void test_genre_compare()
|
|||
|
||||
static void test_genere_db()
|
||||
{
|
||||
const struct db_ops *genre_ops = test_genre_ops();
|
||||
database<struct genre> genre_db;
|
||||
struct genre *genre;
|
||||
|
||||
|
@ -75,7 +76,7 @@ static void test_genere_db()
|
|||
test_equal(genre_get(0), genre);
|
||||
test_equal(genre_get(1), (struct genre *)NULL);
|
||||
|
||||
db_init(&genre_db, "genre.db", false);
|
||||
db_init(&genre_db, "genre.db", false, genre_ops);
|
||||
db_load(&genre_db);
|
||||
test_equal(genre_db.db_size, 1);
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ static void test_library()
|
|||
|
||||
static void test_library_db()
|
||||
{
|
||||
const struct db_ops *library_ops = test_library_ops();
|
||||
database<struct library> library_db;
|
||||
struct library *library, *library2;
|
||||
|
||||
|
@ -79,7 +80,7 @@ static void test_library_db()
|
|||
test_equal(library_get(0), library);
|
||||
test_equal(library_get(1), (struct library *)NULL);
|
||||
|
||||
db_init(&library_db, "library.db", false);
|
||||
db_init(&library_db, "library.db", false, library_ops);
|
||||
db_load(&library_db);
|
||||
test_equal(library_db.db_size, 1);
|
||||
test_equal(db_actual_size(&library_db), 1);
|
||||
|
|
|
@ -163,6 +163,7 @@ static void test_track_db()
|
|||
{
|
||||
std::string path = "tests/Music/Hyrule Symphony/01 - Title Theme.ogg";
|
||||
struct library *library = library_find("tests/Music");
|
||||
const struct db_ops *track_ops = test_track_ops();
|
||||
database<struct track> track_db;
|
||||
struct track *track;
|
||||
|
||||
|
@ -174,7 +175,7 @@ static void test_track_db()
|
|||
test_equal(track_get(1), NULL);
|
||||
test_equal(track_db_get()->db_size, 1);
|
||||
|
||||
db_init(&track_db, "track.db", false);
|
||||
db_init(&track_db, "track.db", false, track_ops);
|
||||
db_load(&track_db);
|
||||
test_equal(track_db.db_size, 0);
|
||||
|
||||
|
|
Loading…
Reference in New Issue