diff --git a/src/db.c b/src/db.c index 5c4e296f..841129f5 100644 --- a/src/db.c +++ b/src/db.c @@ -159,6 +159,7 @@ static const struct col_type_map pli_cols_map[] = { pli_offsetof(index), DB_TYPE_INT }, { pli_offsetof(special_id), DB_TYPE_INT }, { pli_offsetof(virtual_path), DB_TYPE_STRING }, + { pli_offsetof(parent_id), DB_TYPE_INT }, /* items is computed on the fly */ }; @@ -245,6 +246,7 @@ static const ssize_t dbpli_cols_map[] = dbpli_offsetof(index), dbpli_offsetof(special_id), dbpli_offsetof(virtual_path), + dbpli_offsetof(parent_id), /* items is computed on the fly */ }; @@ -4505,7 +4507,8 @@ db_perthread_deinit(void) " path VARCHAR(4096)," \ " idx INTEGER NOT NULL," \ " special_id INTEGER DEFAULT 0," \ - " virtual_path VARCHAR(4096)" \ + " virtual_path VARCHAR(4096)," \ + " parent_id INTEGER DEFAULT 0" \ ");" #define T_PLITEMS \ @@ -4601,14 +4604,11 @@ db_perthread_deinit(void) */ #define SCHEMA_VERSION_MAJOR 16 -#define SCHEMA_VERSION_MINOR 00 -// Q_SCVER should be deprecated/removed at v16 -#define Q_SCVER \ - "INSERT INTO admin (key, value) VALUES ('schema_version', '16');" +#define SCHEMA_VERSION_MINOR 01 #define Q_SCVER_MAJOR \ "INSERT INTO admin (key, value) VALUES ('schema_version_major', '16');" #define Q_SCVER_MINOR \ - "INSERT INTO admin (key, value) VALUES ('schema_version_minor', '00');" + "INSERT INTO admin (key, value) VALUES ('schema_version_minor', '01');" struct db_init_query { char *query; @@ -5681,8 +5681,6 @@ static const struct db_init_query db_upgrade_v1501_queries[] = #define U_V16_ALTER_TBL_PL_ADD_COL \ "ALTER TABLE playlists ADD COLUMN virtual_path VARCHAR(4096) DEFAULT NULL;" -#define U_V16_SCVER \ - "UPDATE admin SET value = '16' WHERE key = 'schema_version';" #define U_V1600_SCVER_MAJOR \ "UPDATE admin SET value = '16' WHERE key = 'schema_version_major';" #define U_V1600_SCVER_MINOR \ @@ -5694,7 +5692,6 @@ static const struct db_init_query db_upgrade_v16_queries[] = { U_V16_ALTER_TBL_PL_ADD_COL, "alter table playlists add column virtual_path" }, { U_V16_CREATE_VIEW_FILELIST, "create new view filelist" }, - { U_V16_SCVER, "set schema_version to 16" }, { U_V1600_SCVER_MAJOR, "set schema_version_major to 16" }, { U_V1600_SCVER_MINOR, "set schema_version_minor to 00" }, }; @@ -5809,6 +5806,25 @@ db_upgrade_v16(void) return 0; } +/* Upgrade from schema v16.00 to v16.01 */ +/* Expand data model to allow for nested playlists */ + +#define U_V1601_PL_PARENTID_ADD \ + "ALTER TABLE playlists ADD COLUMN parent_id INTEGER DEFAULT 0;" + +#define U_V1601_SCVER_MAJOR \ + "UPDATE admin SET value = '16' WHERE key = 'schema_version_major';" +#define U_V1601_SCVER_MINOR \ + "UPDATE admin SET value = '01' WHERE key = 'schema_version_minor';" + +static const struct db_init_query db_upgrade_v1601_queries[] = + { + { U_V1601_PL_PARENTID_ADD,"expanding table playlists with parent_id column" }, + + { U_V1601_SCVER_MAJOR, "set schema_version_major to 16" }, + { U_V1601_SCVER_MINOR, "set schema_version_minor to 01" }, + }; + static int db_upgrade(int db_ver) { @@ -5885,6 +5901,11 @@ db_upgrade(int db_ver) if (ret < 0) return -1; + /* FALLTHROUGH */ + + case 1600: + ret = db_generic_upgrade(db_upgrade_v1601_queries, sizeof(db_upgrade_v1601_queries) / sizeof(db_upgrade_v1601_queries[0])); + break; default: diff --git a/src/db.h b/src/db.h index 7a8fc1d7..f9d65b49 100644 --- a/src/db.h +++ b/src/db.h @@ -182,6 +182,7 @@ struct playlist_info { uint32_t index; /* index of playlist for paths with multiple playlists */ uint32_t special_id; /* iTunes identifies certain 'special' playlists with special meaning */ char *virtual_path; /* virtual path of underlying playlist */ + uint32_t parent_id; /* Id of parent playlist if the playlist is nested */ }; #define pli_offsetof(field) offsetof(struct playlist_info, field) @@ -198,6 +199,7 @@ struct db_playlist_info { char *index; char *special_id; char *virtual_path; + char *parent_id; }; #define dbpli_offsetof(field) offsetof(struct db_playlist_info, field) diff --git a/src/httpd_daap.c b/src/httpd_daap.c index f4a9ce38..29bbe63b 100644 --- a/src/httpd_daap.c +++ b/src/httpd_daap.c @@ -1516,6 +1516,7 @@ daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char ** int32_t plid; int32_t pltype; int32_t plitems; + int32_t plparent; int i; int ret; @@ -1665,7 +1666,11 @@ daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char ** dmap_add_int(playlist, "mimc", plitems); /* Container ID (mpco) */ - dmap_add_int(playlist, "mpco", 0); + ret = safe_atoi32(dbpli.parent_id, &plparent); + if (ret == 0) + dmap_add_int(playlist, "mpco", plparent); + else + dmap_add_int(playlist, "mpco", 0); /* Base playlist (abpl), id = 1 */ if (plid == 1)