core/database: Introduce the dbe_setup() database operation

Track tags need to add themselves to the filter index and update the
library track count once added to the database.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2015-10-05 20:12:32 -04:00
parent c8021639ba
commit c77ca65630
10 changed files with 62 additions and 30 deletions

View File

@ -48,6 +48,7 @@ void index_entry :: read(file &file)
static const struct db_ops index_ops = {
index_alloc,
index_free,
NULL,
};

View File

@ -69,6 +69,7 @@ void album :: write(file &file)
static const struct db_ops album_ops = {
album_alloc,
album_free,
NULL,
};

View File

@ -55,6 +55,7 @@ void artist :: write(file &file)
static const struct db_ops artist_ops = {
artist_alloc,
artist_free,
NULL,
};

View File

@ -54,6 +54,7 @@ void genre :: write(file &file)
static const struct db_ops genre_ops = {
genre_alloc,
genre_free,
NULL,
};

View File

@ -53,6 +53,7 @@ void library :: write(file &file)
static const struct db_ops library_ops = {
library_alloc,
library_free,
NULL,
};

View File

@ -58,23 +58,17 @@ track :: track(const std::string &key)
tr_artist = artist_find(taglib_tag_artist(tag));
tr_genre = genre_find(taglib_tag_genre(tag));
tr_library = library;
tr_library->li_size++;
date_set(&tr_date, 0, 0, 0);
tr_count = 0;
tr_length = taglib_audioproperties_length(audio);
tr_track = taglib_tag_track(tag);
date_set(&tr_date, 0, 0, 0);
tr_path = path;
tr_title = taglib_tag_title(tag);
lower = string_lowercase(tr_title.c_str());
tr_lower = lower;
date_set(&tr_date, 0, 0, 0);
filter :: add(tr_title, dbe_index);
filter :: add(tr_artist->ar_name, dbe_index);
filter :: add(tr_album->al_name, dbe_index);
taglib_tag_free_strings();
taglib_file_free(file);
g_free(lower);
@ -91,6 +85,16 @@ static void track_free(struct db_entry *dbe)
delete track;
}
static void track_setup(struct db_entry *dbe)
{
struct track *track = (struct track *)dbe;
filter :: add(track->tr_title, track->dbe_index);
filter :: add(track->tr_artist->ar_name, track->dbe_index);
filter :: add(track->tr_album->al_name, track->dbe_index);
track->tr_library->li_size++;
}
const std::string track :: primary_key() const
{
return __track_key(tr_library, tr_path);
@ -120,11 +124,6 @@ void track :: read(file &file)
tr_artist = artist_get(artist_id);
tr_album = album_get(album_id);
tr_genre = genre_get(genre_id);
filter :: add(tr_title, dbe_index);
filter :: add(tr_artist->ar_name, dbe_index);
filter :: add(tr_album->al_name, dbe_index);
tr_library->li_size++;
}
void track :: write(file &file)
@ -141,6 +140,7 @@ void track :: write(file &file)
static const struct db_ops track_ops = {
NULL,
track_free,
track_setup,
};

View File

@ -56,6 +56,9 @@ struct db_ops {
/* Free a struct db_entry. */
void (*dbe_free)(struct db_entry *);
/* Set up a struct db_entry after adding to the database. */
void (*dbe_setup)(struct db_entry *);
};

View File

@ -19,6 +19,20 @@ static inline void __dbe_free(struct database<T> *db, struct db_entry *dbe)
}
}
template <class T>
static inline void __dbe_setup(struct database<T> *db, unsigned int index)
{
struct db_entry *dbe = db->db_entries[index];
if (dbe) {
dbe->dbe_index = index;
db->db_keys[dbe->primary_key()] = index;
db->db_size++;
if (db->db_ops->dbe_setup)
db->db_ops->dbe_setup(dbe);
}
}
template <class T>
void db_init(struct database<T> *db, const char *filepath, bool autosave,
const struct db_ops *ops)
@ -68,7 +82,6 @@ template <class T>
void db_load(struct database<T> *db)
{
unsigned int size;
std::string str;
int valid;
if (file_open(&db->db_file, OPEN_READ) == false)
@ -82,11 +95,8 @@ void db_load(struct database<T> *db)
db->db_entries[i] = NULL;
} else {
db->db_entries[i] = new T;
db->db_entries[i]->dbe_index = i;
db->db_entries[i]->read(db->db_file);
str = db->db_entries[i]->primary_key();
db->db_keys[str] = i;
db->db_size++;
__dbe_setup(db, i);
}
}
@ -96,16 +106,12 @@ void db_load(struct database<T> *db)
template <class T>
T *db_insert(struct database<T> *db, T *item)
{
if (!item)
return NULL;
item->dbe_index = db_actual_size(db);
db->db_entries.push_back(item);
db->db_keys[item->primary_key()] = item->dbe_index;
db->db_size++;
db_autosave(db);
return db->db_entries[item->dbe_index];
if (item) {
db->db_entries.push_back(item);
__dbe_setup(db, db_actual_size(db) - 1);
db_autosave(db);
}
return item;
}
template <class T>

View File

@ -30,7 +30,8 @@ struct int_entry : public db_entry {
void read(file &f) { file_readf(&f, "%u", &ie_val); }
};
unsigned int test_free_count = 0;
static unsigned int test_free_count = 0;
static unsigned int test_setup_count = 0;
static struct db_entry *int_alloc(const gchar *key)
{
@ -45,9 +46,15 @@ static void int_free(struct db_entry *dbe)
delete (struct int_entry *)dbe;
}
static void int_setup(struct db_entry *dbe)
{
test_setup_count++;
}
static const struct db_ops int_ops = {
int_alloc,
int_free,
int_setup,
};
@ -77,8 +84,11 @@ static void test_db_entry()
ent->read(f);
file_close(&f);
int_ops.dbe_setup(ent);
test_equal(ent->ie_val, 1);
test_equal(ent->primary_key(), "1");
test_equal(test_setup_count, 1);
int_ops.dbe_free(ent);
test_equal(test_free_count, 2);
}
@ -108,7 +118,8 @@ static void test_stress(unsigned int N)
unsigned int i;
gchar *key;
test_free_count = 0;
test_free_count = 0;
test_setup_count = 0;
db_init(&db, "stress.db", false, &int_ops);
/* db_insert() */
@ -124,6 +135,7 @@ static void test_stress(unsigned int N)
test_equal(dbe, NULL);
test_equal(db.db_size, N);
test_equal(db_actual_size(&db), N);
test_equal(test_setup_count, N);
/* db_at() */
for (i = 0; i < N; i++) {
@ -231,10 +243,13 @@ static void test_save_load()
for (i = 0; i < N; i += 2)
db_remove(&db1, db_at(&db1, i));
i = 1;
db_deinit(&db2);
test_setup_count = 0;
db_load(&db2);
test_equal(db2.db_size, N / 2);
test_equal(test_setup_count, N / 2);
i = 1;
db_for_each(dbe, next, &db2) {
test_loop_equal(dbe->ie_val, i, i);
i += 2;

View File

@ -94,6 +94,7 @@ static void test_track()
library = library_find("tests/Music");
track = new struct track("0/Hyrule Symphony/01 - Title Theme.ogg");
track_ops->dbe_setup(track);
test_verify_track(track);
test_equal(library->li_size, 1);
@ -109,12 +110,14 @@ static void test_track()
track = new struct track;
file_open(&f, OPEN_READ);
track->read(f);
track_ops->dbe_setup(track);
test_verify_notrack(track);
test_equal(library->li_size, 1);
track_ops->dbe_free(track);
track = new struct track;
track->read(f);
track_ops->dbe_setup(track);
test_verify_track(track);
test_equal(library->li_size, 1);
file_close(&f);