diff --git a/core/tags/album.c b/core/tags/album.c index 887774d6..c0b24ea3 100644 --- a/core/tags/album.c +++ b/core/tags/album.c @@ -15,7 +15,10 @@ #define OCARINA_AGENT OCARINA_NAME #endif +#define ALBUM_DB_MIN 0 /* Ocarina 6.0 */ +#define ALBUM_DB_CUR 1 /* Ocarina 6.5 */ static struct database album_db; +static bool album_db_upgraded = false; static inline void __album_init_file(struct album *al, struct cache_file *f) @@ -185,7 +188,7 @@ static struct album *__album_alloc(struct artist *artist, struct genre *genre, album->al_artist = artist; album->al_genre = genre; - if (!album_artwork_exists(album)) + if (!album_artwork_exists(album) && artist && genre) idle_schedule(IDLE_ASYNC, IDLE_FUNC(__album_fetch_artwork), album); return album; } @@ -229,22 +232,49 @@ static gchar *album_key(struct db_entry *dbe) ALBUM(dbe)->al_name, ALBUM(dbe)->al_year); } -static struct db_entry *album_read(struct file *file) +static struct album *__album_parse_v0(gchar *line) { unsigned int year; + gchar *name; + + if (sscanf(line, "%u %m[^\n]", &year, &name) == 1) + name = g_strdup(""); + return __album_alloc(NULL, NULL, name, year); +} + +static struct db_entry *album_read(struct file *file) +{ + unsigned int year, artist_id, genre_id, n; + struct album *album; gchar *line, *name; line = file_readl(file); - if (sscanf(line, "%u %m[^\n]", &year, &name) == 1) + if (file_version(file) == 0) { + album = __album_parse_v0(line); + album_db_upgraded = true; + goto out; + } + + n = sscanf(line, "%u %u %u %m[^\n]", &artist_id, &genre_id, &year, &name); + if (n == 3) name = g_strdup(""); + album = __album_alloc(artist_get(artist_id), + genre_get(genre_id), name, year); +out: g_free(line); - return &__album_alloc(NULL, NULL, name, year)->al_dbe; + return &album->al_dbe; } static void album_write(struct file *file, struct db_entry *dbe) { - file_writef(file, "%u %s", ALBUM(dbe)->al_year, ALBUM(dbe)->al_name); + struct album *album = ALBUM(dbe); + struct artist *artist = album->al_artist; + struct genre *genre = album->al_genre; + + file_writef(file, "%u %u %u %s", artist ? artist_index(artist) : 0, + genre ? genre_index(genre) : 0, + album->al_year, album->al_name); } @@ -260,7 +290,8 @@ static const struct db_ops album_ops = { void album_db_init() { - db_init(&album_db, "album.db", true, &album_ops, 0, 0); + db_init(&album_db, "album.db", true, &album_ops, ALBUM_DB_MIN, + ALBUM_DB_CUR); db_load_idle(&album_db); } @@ -269,6 +300,21 @@ void album_db_deinit() db_deinit(&album_db); } +bool album_db_upgrade_done() +{ + struct db_entry *dbe, *next; + + if (album_db_upgraded == false) + return false; + + db_for_each(dbe, next, &album_db) { + if (!ALBUM(dbe)->al_artist && !ALBUM(dbe)->al_genre) + db_remove(&album_db, dbe); + } + + return true; +} + struct album *album_find(struct artist *artist, struct genre *genre, const gchar *name, unsigned int year) { diff --git a/core/tags/tags.c b/core/tags/tags.c index 9c7e38bb..112d7ace 100644 --- a/core/tags/tags.c +++ b/core/tags/tags.c @@ -1,6 +1,7 @@ /* * Copyright 2014 (c) Anna Schumaker. */ +#include #include #include #include @@ -8,13 +9,22 @@ #include #include +static bool tags_upgrade_done(void *data) +{ + if (album_db_upgrade_done()) + track_db_commit(); + return true; +} + void tags_init() { artist_db_init(); - album_db_init(); genre_db_init(); + album_db_init(); library_db_init(); track_db_init(); + + idle_schedule(IDLE_SYNC, tags_upgrade_done, NULL); } void tags_deinit() diff --git a/include/core/tags/album.h b/include/core/tags/album.h index 7409496f..ec411ac7 100644 --- a/include/core/tags/album.h +++ b/include/core/tags/album.h @@ -4,12 +4,12 @@ * The album tag is used to store the name and year of albums * added to the tag database. * - * When writing an album tag to disk, write out the album_year field - * followed by the album_name on the same line: + * When writing an album tag to disk, write out the album_artist, album_genre, + * and album_year fields followed by the album_name on the same line: * - * ... 1998 Hyrule Symphony - * ... 2006 Twilight Princess - * ... 2011 Skyward Sword + * ...0 0 1998 Hyrule Symphony + * ...0 0 2006 Twilight Princess + * ...0 0 2011 Skyward Sword */ #ifndef OCARINA_CORE_TAGS_ALBUM_H #define OCARINA_CORE_TAGS_ALBUM_H @@ -36,6 +36,9 @@ void album_db_init(); /* Called to clean up the album database. */ void album_db_deinit(); +/* Called to clean up the album database after an upgrade. */ +bool album_db_upgrade_done(); + /* Called to find an album tag by artist, name and year. */ struct album *album_find(struct artist *, struct genre *, const gchar *, unsigned int); diff --git a/tests/core/tags/album.c b/tests/core/tags/album.c index d00b1081..687c4bf1 100644 --- a/tests/core/tags/album.c +++ b/tests/core/tags/album.c @@ -12,9 +12,10 @@ static void test_verify_empty(struct album *album) g_assert_cmpstr(album->al_name, ==, ""); g_assert_null(album->al_tokens[0]); g_assert_null(album->al_alts[0]); - g_assert_null(album->al_artist); + g_assert(album->al_artist == artist_get(0)); + g_assert(album->al_genre == genre_get(0)); g_assert_cmpuint(album->al_year, ==, 0); - g_assert_cmpstr_free(album_ops->dbe_key(&album->al_dbe), ==, "0/"); + g_assert_cmpstr_free(album_ops->dbe_key(&album->al_dbe), ==, "0/0/0/"); } static void test_verify_hyrule(struct album *album, struct artist *artist, @@ -51,16 +52,15 @@ static void test_album() koji = artist_find("Koji Kondo"); genre = genre_find("Video Game Music"); - album = ALBUM(album_ops->dbe_alloc("0/0/1998/Hyrule Symphony")); test_verify_hyrule(album, koji, genre); g_assert_true( album_match_token(album, "hyrule")); g_assert_true( album_match_token(album, "symphony")); g_assert_false(album_match_token(album, "skyward")); - file_init(&f, "album_tag", 0, 0); + file_init(&f, "album_tag", 1, 1); file_open(&f, OPEN_WRITE); - file_writef(&f, "0 \n"); + file_writef(&f, "0 0 0 \n"); album_ops->dbe_write(&f, &album->al_dbe); file_close(&f); album_ops->dbe_free(&album->al_dbe); @@ -72,7 +72,7 @@ static void test_album() album = ALBUM(album_ops->dbe_read(&f)); file_close(&f); - test_verify_hyrule(album, NULL, NULL); + test_verify_hyrule(album, koji, genre); album_ops->dbe_free(&album->al_dbe); } @@ -109,25 +109,17 @@ static void test_album_db() struct genre *genre; struct album *album; - album = album_find(NULL, NULL, "Hyrule Symphony", 1998); - test_verify_hyrule(album, NULL, NULL); - g_assert(album_find(NULL, NULL, "Hyrule Symphony", 1998) == album); - g_assert(album_get(0) == album); - g_assert_null(album_get(1)); - koji = artist_find("Koji Kondo"); genre = genre_find("Video Game Music"); album = album_find(koji, genre, "Hyrule Symphony", 1998); test_verify_hyrule(album, koji, genre); - g_assert(album_find(NULL, NULL, "Hyrule Symphony", 1998) != album); g_assert(album_find(koji, genre, "Hyrule Symphony", 1998) == album); - g_assert(album_get(0) != album); - g_assert(album_get(1) == album); - g_assert_null(album_get(2)); + g_assert(album_get(0) == album); + g_assert_null(album_get(1)); - db_init(&album_db, "album.db", false, album_ops, 0, 0); + db_init(&album_db, "album.db", false, album_ops, 1, 1); db_load(&album_db); - g_assert_cmpuint(album_db.db_size, ==, 2); + g_assert_cmpuint(album_db.db_size, ==, 1); db_deinit(&album_db); } @@ -138,6 +130,7 @@ static void test_album_artwork() struct album *ocarina, *majora, *wind, *ocarina_3d; gchar *o_path, *m_path, *w_path; struct artist *koji; + struct genre *genre; const gchar *cache; idle_deinit(); @@ -149,9 +142,10 @@ static void test_album_artwork() w_path = g_build_filename(cache, "ocarina-test", "core", "tags", "album", "0", "Wind Waker.jpg", NULL); koji = artist_find("Koji Kondo"); - ocarina = album_find(koji, NULL, "Ocarina of Time", 1998); - majora = album_find(NULL, NULL, "Majora's Mask", 2000); - wind = album_find(NULL, NULL, "Wind Waker", 0); + genre = genre_find("Video Game Music"); + ocarina = album_find(koji, genre, "Ocarina of Time", 1998); + majora = album_find(koji, genre, "Majora's Mask", 2000); + wind = album_find(koji, genre, "Wind Waker", 0); ocarina->al_artist = koji; g_assert_false(album_artwork_exists(ocarina)); @@ -171,7 +165,7 @@ static void test_album_artwork() g_assert_cmpstr_free(album_artwork_path(wind), ==, w_path); /* Import the original Ocarina of Time album art. */ - ocarina_3d = album_find(NULL, NULL, "Ocarina of Time 3D", 2011); + ocarina_3d = album_find(koji, genre, "Ocarina of Time 3D", 2011); g_assert_false(album_artwork_exists(ocarina_3d)); album_artwork_import(ocarina_3d, NULL); g_assert_false(album_artwork_exists(ocarina_3d));