diff --git a/core/index.cpp b/core/index.cpp index 83a2e844..13b1b927 100644 --- a/core/index.cpp +++ b/core/index.cpp @@ -48,6 +48,7 @@ void index_entry :: read(file &file) static const struct db_ops index_ops = { index_alloc, index_free, + NULL, }; diff --git a/core/tags/album.cpp b/core/tags/album.cpp index 03c96708..cc182cf5 100644 --- a/core/tags/album.cpp +++ b/core/tags/album.cpp @@ -69,6 +69,7 @@ void album :: write(file &file) static const struct db_ops album_ops = { album_alloc, album_free, + NULL, }; diff --git a/core/tags/artist.cpp b/core/tags/artist.cpp index 3c2b74b8..2853b586 100644 --- a/core/tags/artist.cpp +++ b/core/tags/artist.cpp @@ -55,6 +55,7 @@ void artist :: write(file &file) static const struct db_ops artist_ops = { artist_alloc, artist_free, + NULL, }; diff --git a/core/tags/genre.cpp b/core/tags/genre.cpp index 85f69aeb..29c15a15 100644 --- a/core/tags/genre.cpp +++ b/core/tags/genre.cpp @@ -54,6 +54,7 @@ void genre :: write(file &file) static const struct db_ops genre_ops = { genre_alloc, genre_free, + NULL, }; diff --git a/core/tags/library.cpp b/core/tags/library.cpp index c33fbc07..37f2ab4e 100644 --- a/core/tags/library.cpp +++ b/core/tags/library.cpp @@ -53,6 +53,7 @@ void library :: write(file &file) static const struct db_ops library_ops = { library_alloc, library_free, + NULL, }; diff --git a/core/tags/track.cpp b/core/tags/track.cpp index d6e54a2e..623e50b0 100644 --- a/core/tags/track.cpp +++ b/core/tags/track.cpp @@ -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, }; diff --git a/include/core/database.h b/include/core/database.h index 0ee98514..4ed21100 100644 --- a/include/core/database.h +++ b/include/core/database.h @@ -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 *); }; diff --git a/include/core/database.hpp b/include/core/database.hpp index 59e270b8..ba950e74 100644 --- a/include/core/database.hpp +++ b/include/core/database.hpp @@ -19,6 +19,20 @@ static inline void __dbe_free(struct database *db, struct db_entry *dbe) } } +template +static inline void __dbe_setup(struct database *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 void db_init(struct database *db, const char *filepath, bool autosave, const struct db_ops *ops) @@ -68,7 +82,6 @@ template void db_load(struct database *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 *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 *db) template T *db_insert(struct database *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 diff --git a/tests/core/database.cpp b/tests/core/database.cpp index e434f3b1..0c693d15 100644 --- a/tests/core/database.cpp +++ b/tests/core/database.cpp @@ -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; diff --git a/tests/core/tags/track.cpp b/tests/core/tags/track.cpp index ab64f489..701b4444 100644 --- a/tests/core/tags/track.cpp +++ b/tests/core/tags/track.cpp @@ -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);