From 5cfbe75bae6497c0ae34d39b5f928c5f74b72520 Mon Sep 17 00:00:00 2001 From: Ace Jones Date: Sun, 10 Jan 2010 12:26:48 +0100 Subject: [PATCH] Add database code for groups queries --- src/db.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/db.h | 26 +++++++++++++- 2 files changed, 129 insertions(+), 1 deletion(-) diff --git a/src/db.c b/src/db.c index cf869c77..00b868bc 100644 --- a/src/db.c +++ b/src/db.c @@ -200,6 +200,18 @@ static ssize_t dbpli_cols_map[] = /* items is computed on the fly */ }; +/* This list must be kept in sync with + * - the order of fields in the Q_GROUPS query + * - the name of the fields in struct group_info + */ +static ssize_t dbgri_cols_map[] = + { + dbgri_offsetof(itemcount), + dbgri_offsetof(persistentid), + dbgri_offsetof(songalbumartist), + dbgri_offsetof(itemname), + }; + /* This list must be kept in sync with * - the order of the columns in the inotify table * - the name and type of the fields in struct watch_info @@ -607,6 +619,42 @@ db_build_query_plitems(struct query_params *qp, char **q) return 0; } +static int +db_build_query_groups(struct query_params *qp, char **q) +{ + char *query; + char *idx; + int ret; + + qp->results = db_get_count("SELECT COUNT(DISTINCT daap_songalbumid(album_artist, album)) FROM files WHERE disabled = 0;"); + if (qp->results < 0) + return -1; + + /* Get index clause */ + ret = db_build_query_index_clause(qp, &idx); + if (ret < 0) + return -1; + + if (idx && qp->filter) + query = sqlite3_mprintf("SELECT COUNT(*) AS items, daap_songalbumid(album_artist, album) AS persistentid, album_artist, album FROM files GROUP BY album_artist, album HAVING disabled = 0 AND %s %s;", qp->filter, idx); + else if (idx) + query = sqlite3_mprintf("SELECT COUNT(*) AS items, daap_songalbumid(album_artist, album) AS persistentid, album_artist, album FROM files GROUP BY album_artist, album HAVING disabled = 0 %s;", idx); + else if (qp->filter) + query = sqlite3_mprintf("SELECT COUNT(*) AS items, daap_songalbumid(album_artist, album) AS persistentid, album_artist, album FROM files GROUP BY album_artist, album HAVING disabled = 0 AND %s;", qp->filter); + else + query = sqlite3_mprintf("SELECT COUNT(*) AS items, daap_songalbumid(album_artist, album) AS persistentid, album_artist, album FROM files GROUP BY album_artist, album HAVING disabled = 0;"); + + if (!query) + { + DPRINTF(E_LOG, L_DB, "Out of memory for query string\n"); + return -1; + } + + *q = query; + + return 0; +} + static int db_build_query_browse(struct query_params *qp, char *field, char **q) { @@ -686,6 +734,10 @@ db_query_start(struct query_params *qp) ret = db_build_query_plitems(qp, &query); break; + case Q_GROUPS: + ret = db_build_query_groups(qp, &query); + break; + case Q_BROWSE_ALBUMS: ret = db_build_query_browse(qp, "album", &query); break; @@ -858,6 +910,58 @@ db_query_fetch_pl(struct query_params *qp, struct db_playlist_info *dbpli) return 0; } +int +db_query_fetch_group(struct query_params *qp, struct db_group_info *dbgri) +{ + int ncols; + char **strcol; + int i; + int ret; + + memset(dbgri, 0, sizeof(struct db_group_info)); + + if (!qp->stmt) + { + DPRINTF(E_LOG, L_DB, "Query not started!\n"); + return -1; + } + + if (qp->type != Q_GROUPS) + { + DPRINTF(E_LOG, L_DB, "Not a groups query!\n"); + return -1; + } + + ret = sqlite3_step(qp->stmt); + if (ret == SQLITE_DONE) + { + DPRINTF(E_INFO, L_DB, "End of query results\n"); + return 1; + } + else if (ret != SQLITE_ROW) + { + DPRINTF(E_LOG, L_DB, "Could not step: %s\n", sqlite3_errmsg(hdl)); + return -1; + } + + ncols = sqlite3_column_count(qp->stmt); + + if (sizeof(dbgri_cols_map) / sizeof(dbgri_cols_map[0]) != ncols) + { + DPRINTF(E_LOG, L_DB, "BUG: dbgri column map out of sync with schema\n"); + return -1; + } + + for (i = 0; i < ncols; i++) + { + strcol = (char **) ((char *)dbgri + dbgri_cols_map[i]); + + *strcol = (char *)sqlite3_column_text(qp->stmt, i); + } + + return 0; +} + int db_query_fetch_string(struct query_params *qp, char **string) { diff --git a/src/db.h b/src/db.h index 0a1cc57b..67b61fa4 100644 --- a/src/db.h +++ b/src/db.h @@ -25,7 +25,8 @@ enum query_type { Q_BROWSE_ARTISTS = Q_F_BROWSE | (1 << 3), Q_BROWSE_ALBUMS = Q_F_BROWSE | (1 << 4), Q_BROWSE_GENRES = Q_F_BROWSE | (1 << 5), - Q_BROWSE_COMPOSERS = Q_F_BROWSE | (1 << 6) + Q_BROWSE_COMPOSERS = Q_F_BROWSE | (1 << 6), + Q_GROUPS = (1 << 7), }; struct query_params { @@ -142,6 +143,26 @@ struct db_playlist_info { #define dbpli_offsetof(field) offsetof(struct db_playlist_info, field) +struct group_info { + uint32_t itemid; /* 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) */ + char *songalbumartist; /* song album artist (asaa) */ +}; + +#define gri_offsetof(field) offsetof(struct group_info, field) + +struct db_group_info { + char *itemid; + char *persistentid; + char *itemname; + char *itemcount; + char *songalbumartist; +}; + +#define dbgri_offsetof(field) offsetof(struct db_group_info, field) + struct db_media_file_info { char *id; char *path; @@ -242,6 +263,9 @@ db_query_fetch_file(struct query_params *qp, struct db_media_file_info *dbmfi); int db_query_fetch_pl(struct query_params *qp, struct db_playlist_info *dbpli); +int +db_query_fetch_group(struct query_params *qp, struct db_group_info *dbgri); + int db_query_fetch_string(struct query_params *qp, char **string);