mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-15 16:53:18 -05:00
Make album groups persistent
Store groups (only album groups supported at the moment) in the DB, so their ids are persistent for the duration of the forked-daapd session. Those ids are used to, among other things, retrieve artwork, so we must provide ourselves some persistence here. This brings us to schema version 8.
This commit is contained in:
parent
88dde32fc7
commit
224ef48137
66
src/db.c
66
src/db.c
@ -42,6 +42,10 @@
|
||||
/* Inotify cookies are uint32_t */
|
||||
#define INOTIFY_FAKE_COOKIE ((int64_t)1 << 32)
|
||||
|
||||
enum group_type {
|
||||
G_ALBUMS = 1,
|
||||
};
|
||||
|
||||
#define DB_TYPE_CHAR 1
|
||||
#define DB_TYPE_INT 2
|
||||
#define DB_TYPE_INT64 3
|
||||
@ -211,6 +215,7 @@ static ssize_t dbpli_cols_map[] =
|
||||
static ssize_t dbgri_cols_map[] =
|
||||
{
|
||||
dbgri_offsetof(itemcount),
|
||||
dbgri_offsetof(id),
|
||||
dbgri_offsetof(persistentid),
|
||||
dbgri_offsetof(songalbumartist),
|
||||
dbgri_offsetof(itemname),
|
||||
@ -731,13 +736,13 @@ db_build_query_groups(struct query_params *qp, char **q)
|
||||
return -1;
|
||||
|
||||
if (idx && qp->filter)
|
||||
query = sqlite3_mprintf("SELECT COUNT(*) AS items, songalbumid AS persistentid, album_artist, album FROM files GROUP BY album_artist, album HAVING disabled = 0 AND %s %s;", qp->filter, idx);
|
||||
query = sqlite3_mprintf("SELECT COUNT(*), g.id, g.persistentid, f.album_artist, g.name FROM files f JOIN groups g ON f.songalbumid = g.persistentid GROUP BY f.album_artist, g.name HAVING g.type = %d AND disabled = 0 AND %s %s;", G_ALBUMS, qp->filter, idx);
|
||||
else if (idx)
|
||||
query = sqlite3_mprintf("SELECT COUNT(*) AS items, songalbumid AS persistentid, album_artist, album FROM files GROUP BY album_artist, album HAVING disabled = 0 %s;", idx);
|
||||
query = sqlite3_mprintf("SELECT COUNT(*), g.id, g.persistentid, f.album_artist, g.name FROM files f JOIN groups g ON f.songalbumid = g.persistentid GROUP BY f.album_artist, g.name HAVING g.type = %d AND disabled = 0 %s;", G_ALBUMS, idx);
|
||||
else if (qp->filter)
|
||||
query = sqlite3_mprintf("SELECT COUNT(*) AS items, songalbumid AS persistentid, album_artist, album FROM files GROUP BY album_artist, album HAVING disabled = 0 AND %s;", qp->filter);
|
||||
query = sqlite3_mprintf("SELECT COUNT(*), g.id, g.persistentid, f.album_artist, g.name FROM files f JOIN groups g ON f.songalbumid = g.persistentid GROUP BY f.album_artist, g.name HAVING g.type = %d AND disabled = 0 AND %s;", G_ALBUMS, qp->filter);
|
||||
else
|
||||
query = sqlite3_mprintf("SELECT COUNT(*) AS items, songalbumid AS persistentid, album_artist, album FROM files GROUP BY album_artist, album HAVING disabled = 0;");
|
||||
query = sqlite3_mprintf("SELECT COUNT(*), g.id, g.persistentid, f.album_artist, g.name FROM files f JOIN groups g ON f.songalbumid = g.persistentid GROUP BY f.album_artist, g.name HAVING g.type = %d AND disabled = 0;", G_ALBUMS);
|
||||
|
||||
if (!query)
|
||||
{
|
||||
@ -2443,6 +2448,30 @@ db_pl_enable_bycookie(uint32_t cookie, char *path)
|
||||
}
|
||||
|
||||
|
||||
/* Groups */
|
||||
int
|
||||
db_groups_clear(void)
|
||||
{
|
||||
char *query = "DELETE FROM groups;";
|
||||
char *errmsg;
|
||||
int ret;
|
||||
|
||||
DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query);
|
||||
|
||||
errmsg = NULL;
|
||||
ret = sqlite3_exec(hdl, query, NULL, NULL, &errmsg);
|
||||
if (ret != SQLITE_OK)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DB, "Query error: %s\n", errmsg);
|
||||
|
||||
sqlite3_free(errmsg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Remotes */
|
||||
static int
|
||||
db_pairing_delete_byremote(char *remote_id)
|
||||
@ -3212,6 +3241,15 @@ db_perthread_deinit(void)
|
||||
" filepath VARCHAR(4096) NOT NULL" \
|
||||
");"
|
||||
|
||||
#define T_GROUPS \
|
||||
"CREATE TABLE IF NOT EXISTS groups (" \
|
||||
" id INTEGER PRIMARY KEY NOT NULL," \
|
||||
" type INTEGER NOT NULL," \
|
||||
" name VARCHAR(1024) NOT NULL," \
|
||||
" persistentid INTEGER NOT NULL," \
|
||||
"CONSTRAINT groups_type_unique_persistentid UNIQUE (type, persistentid)" \
|
||||
");"
|
||||
|
||||
#define T_PAIRINGS \
|
||||
"CREATE TABLE IF NOT EXISTS pairings(" \
|
||||
" remote VARCHAR(64) PRIMARY KEY NOT NULL," \
|
||||
@ -3239,6 +3277,18 @@ db_perthread_deinit(void)
|
||||
#define I_PAIRING \
|
||||
"CREATE INDEX IF NOT EXISTS idx_pairingguid ON pairings(guid);"
|
||||
|
||||
#define TRG_GROUPS_INSERT_FILES \
|
||||
"CREATE TRIGGER update_groups_new_file AFTER INSERT ON files FOR EACH ROW" \
|
||||
" BEGIN" \
|
||||
" INSERT OR IGNORE INTO groups (type, name, persistentid) VALUES (1, NEW.album, NEW.songalbumid);" \
|
||||
" END;"
|
||||
|
||||
#define TRG_GROUPS_UPDATE_FILES \
|
||||
"CREATE TRIGGER update_groups_update_file AFTER UPDATE OF songalbumid ON files FOR EACH ROW" \
|
||||
" BEGIN" \
|
||||
" INSERT OR IGNORE INTO groups (type, name, persistentid) VALUES (1, NEW.album, NEW.songalbumid);" \
|
||||
" END;"
|
||||
|
||||
#define Q_PL1 \
|
||||
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
||||
" VALUES(1, 'Library', 1, '1 = 1', 0, '', 0, 0);"
|
||||
@ -3264,9 +3314,9 @@ db_perthread_deinit(void)
|
||||
*/
|
||||
|
||||
|
||||
#define SCHEMA_VERSION 7
|
||||
#define SCHEMA_VERSION 8
|
||||
#define Q_SCVER \
|
||||
"INSERT INTO admin (key, value) VALUES ('schema_version', '7');"
|
||||
"INSERT INTO admin (key, value) VALUES ('schema_version', '8');"
|
||||
|
||||
struct db_init_query {
|
||||
char *query;
|
||||
@ -3279,6 +3329,7 @@ static struct db_init_query db_init_queries[] =
|
||||
{ T_FILES, "create table files" },
|
||||
{ T_PL, "create table playlists" },
|
||||
{ T_PLITEMS, "create table playlistitems" },
|
||||
{ T_GROUPS, "create table groups" },
|
||||
{ T_PAIRINGS, "create table pairings" },
|
||||
{ T_INOTIFY, "create table inotify" },
|
||||
|
||||
@ -3287,6 +3338,9 @@ static struct db_init_query db_init_queries[] =
|
||||
{ I_PLITEMID, "create playlist id index" },
|
||||
{ I_PAIRING, "create pairing guid index" },
|
||||
|
||||
{ TRG_GROUPS_INSERT_FILES, "create trigger update_groups_new_file" },
|
||||
{ TRG_GROUPS_UPDATE_FILES, "create trigger update_groups_update_file" },
|
||||
|
||||
{ Q_PL1, "create default playlist" },
|
||||
{ Q_PL2, "create default smart playlist 'Music'" },
|
||||
{ Q_PL3, "create default smart playlist 'Movies'" },
|
||||
|
8
src/db.h
8
src/db.h
@ -160,7 +160,7 @@ struct db_playlist_info {
|
||||
#define dbpli_offsetof(field) offsetof(struct db_playlist_info, field)
|
||||
|
||||
struct group_info {
|
||||
uint32_t itemid; /* integer id (miid) */
|
||||
uint32_t id; /* integer id (miid) */
|
||||
uint64_t persistentid; /* ulonglong id (mper) */
|
||||
char *itemname; /* playlist name as displayed in iTunes (minm) */
|
||||
uint32_t itemcount; /* number of items (mimc) */
|
||||
@ -170,7 +170,7 @@ struct group_info {
|
||||
#define gri_offsetof(field) offsetof(struct group_info, field)
|
||||
|
||||
struct db_group_info {
|
||||
char *itemid;
|
||||
char *id;
|
||||
char *persistentid;
|
||||
char *itemname;
|
||||
char *itemcount;
|
||||
@ -374,6 +374,10 @@ db_pl_disable_bymatch(char *path, char *strip, uint32_t cookie);
|
||||
int
|
||||
db_pl_enable_bycookie(uint32_t cookie, char *path);
|
||||
|
||||
/* Groups */
|
||||
int
|
||||
db_groups_clear(void);
|
||||
|
||||
/* Remotes */
|
||||
int
|
||||
db_pairing_add(struct pairing_info *pi);
|
||||
|
@ -697,8 +697,17 @@ filescanner(void *arg)
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
ret = db_groups_clear();
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SCAN, "Error: could not clear old groups from DB\n");
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
/* Recompute all songalbumids, in case the SQLite DB got transferred
|
||||
* to a different host; the hash is not portable.
|
||||
* It will also rebuild the groups we just cleared.
|
||||
*/
|
||||
db_files_update_songalbumid();
|
||||
|
||||
|
@ -2044,7 +2044,10 @@ daap_reply_groups(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
|
||||
dmap_add_string(group, "asaa", dbgri.songalbumartist);
|
||||
|
||||
/* Item id (miid) */
|
||||
dmap_add_int(group, "miid", ngrp);
|
||||
val = 0;
|
||||
ret = safe_atoi32(dbgri.id, &val);
|
||||
if ((ret == 0) && (val > 0))
|
||||
dmap_add_int(group, "miid", val);
|
||||
|
||||
DPRINTF(E_DBG, L_DAAP, "Done with group\n");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user