mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-28 08:05:56 -05:00
Change db_pl_add/db_pl_update so input is playlist struct
- so they work like db_file_add/update and can accept all the struct data (incl. parent_id)
This commit is contained in:
parent
9fdb8a5247
commit
e68c6c4932
38
src/db.c
38
src/db.c
@ -158,8 +158,8 @@ static const struct col_type_map pli_cols_map[] =
|
||||
{ pli_offsetof(path), DB_TYPE_STRING },
|
||||
{ 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 },
|
||||
{ pli_offsetof(virtual_path), DB_TYPE_STRING },
|
||||
|
||||
/* items is computed on the fly */
|
||||
};
|
||||
@ -245,8 +245,8 @@ static const ssize_t dbpli_cols_map[] =
|
||||
dbpli_offsetof(path),
|
||||
dbpli_offsetof(index),
|
||||
dbpli_offsetof(special_id),
|
||||
dbpli_offsetof(virtual_path),
|
||||
dbpli_offsetof(parent_id),
|
||||
dbpli_offsetof(virtual_path),
|
||||
|
||||
/* items is computed on the fly */
|
||||
};
|
||||
@ -3127,17 +3127,17 @@ db_pl_fetch_bytitlepath(char *title, char *path)
|
||||
}
|
||||
|
||||
int
|
||||
db_pl_add(char *title, char *path, char *virtual_path, int *id)
|
||||
db_pl_add(struct playlist_info *pli, int *id)
|
||||
{
|
||||
#define QDUP_TMPL "SELECT COUNT(*) FROM playlists p WHERE p.title = '%q' AND p.path = '%q';"
|
||||
#define QADD_TMPL "INSERT INTO playlists (title, type, query, db_timestamp, disabled, path, idx, special_id, virtual_path)" \
|
||||
" VALUES ('%q', 0, NULL, %" PRIi64 ", 0, '%q', 0, 0, '%q');"
|
||||
#define QDUP_TMPL "SELECT COUNT(*) FROM playlists p WHERE p.title = TRIM(%Q) AND p.path = '%q';"
|
||||
#define QADD_TMPL "INSERT INTO playlists (title, type, query, db_timestamp, disabled, path, idx, special_id, parent_id, virtual_path)" \
|
||||
" VALUES (TRIM(%Q), %d, NULL, %" PRIi64 ", %d, '%q', %d, %d, %d, '%q');"
|
||||
char *query;
|
||||
char *errmsg;
|
||||
int ret;
|
||||
|
||||
/* Check duplicates */
|
||||
query = sqlite3_mprintf(QDUP_TMPL, title, path);
|
||||
query = sqlite3_mprintf(QDUP_TMPL, pli->title, STR(pli->path));
|
||||
if (!query)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
||||
@ -3150,12 +3150,15 @@ db_pl_add(char *title, char *path, char *virtual_path, int *id)
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
DPRINTF(E_WARN, L_DB, "Duplicate playlist with title '%s' path '%s'\n", title, path);
|
||||
DPRINTF(E_WARN, L_DB, "Duplicate playlist with title '%s' path '%s'\n", pli->title, pli->path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Add */
|
||||
query = sqlite3_mprintf(QADD_TMPL, title, (int64_t)time(NULL), path, virtual_path);
|
||||
query = sqlite3_mprintf(QADD_TMPL,
|
||||
pli->title, pli->type, (int64_t)time(NULL), pli->disabled, STR(pli->path),
|
||||
pli->index, pli->special_id, pli->parent_id, pli->virtual_path);
|
||||
|
||||
if (!query)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
||||
@ -3183,7 +3186,7 @@ db_pl_add(char *title, char *path, char *virtual_path, int *id)
|
||||
return -1;
|
||||
}
|
||||
|
||||
DPRINTF(E_DBG, L_DB, "Added playlist %s (path %s) with id %d\n", title, path, *id);
|
||||
DPRINTF(E_DBG, L_DB, "Added playlist %s (path %s) with id %d\n", pli->title, pli->path, *id);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -3216,13 +3219,17 @@ db_pl_add_item_byid(int plid, int fileid)
|
||||
}
|
||||
|
||||
int
|
||||
db_pl_update(char *title, char *path, char *virtual_path, int id)
|
||||
db_pl_update(struct playlist_info *pli)
|
||||
{
|
||||
#define Q_TMPL "UPDATE playlists SET title = '%q', db_timestamp = %" PRIi64 ", disabled = 0, path = '%q', virtual_path = '%q' WHERE id = %d;"
|
||||
#define Q_TMPL "UPDATE playlists SET title = TRIM(%Q), type = %d, db_timestamp = %" PRIi64 ", disabled = %d, path = '%q', " \
|
||||
" idx = %d, special_id = %d, parent_id = %d, virtual_path = '%q' " \
|
||||
" WHERE id = %d;"
|
||||
char *query;
|
||||
int ret;
|
||||
|
||||
query = sqlite3_mprintf(Q_TMPL, title, (int64_t)time(NULL), path, virtual_path, id);
|
||||
query = sqlite3_mprintf(Q_TMPL,
|
||||
pli->title, pli->type, (int64_t)time(NULL), pli->disabled, STR(pli->path),
|
||||
pli->index, pli->special_id, pli->parent_id, pli->virtual_path, pli->id);
|
||||
|
||||
ret = db_query_run(query, 1, 0);
|
||||
|
||||
@ -4507,8 +4514,8 @@ db_perthread_deinit(void)
|
||||
" path VARCHAR(4096)," \
|
||||
" idx INTEGER NOT NULL," \
|
||||
" special_id INTEGER DEFAULT 0," \
|
||||
" virtual_path VARCHAR(4096)," \
|
||||
" parent_id INTEGER DEFAULT 0" \
|
||||
" parent_id INTEGER DEFAULT 0," \
|
||||
" virtual_path VARCHAR(4096)" \
|
||||
");"
|
||||
|
||||
#define T_PLITEMS \
|
||||
@ -4638,7 +4645,6 @@ static const struct db_init_query db_init_table_queries[] =
|
||||
{ Q_PL5, "create default smart playlist 'Podcasts'" },
|
||||
{ Q_PL6, "create default smart playlist 'Audiobooks'" },
|
||||
|
||||
{ Q_SCVER, "set schema version" },
|
||||
{ Q_SCVER_MAJOR, "set schema version major" },
|
||||
{ Q_SCVER_MINOR, "set schema version minor" },
|
||||
};
|
||||
|
10
src/db.h
10
src/db.h
@ -165,7 +165,7 @@ struct media_file_info {
|
||||
#define mfi_offsetof(field) offsetof(struct media_file_info, field)
|
||||
|
||||
enum pl_type {
|
||||
PL_PLAIN,
|
||||
PL_PLAIN = 0,
|
||||
PL_SMART,
|
||||
PL_MAX
|
||||
};
|
||||
@ -181,8 +181,8 @@ struct playlist_info {
|
||||
char *path; /* path of underlying playlist */
|
||||
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 */
|
||||
char *virtual_path; /* virtual path of underlying playlist */
|
||||
};
|
||||
|
||||
#define pli_offsetof(field) offsetof(struct playlist_info, field)
|
||||
@ -198,8 +198,8 @@ struct db_playlist_info {
|
||||
char *path;
|
||||
char *index;
|
||||
char *special_id;
|
||||
char *virtual_path;
|
||||
char *parent_id;
|
||||
char *virtual_path;
|
||||
};
|
||||
|
||||
#define dbpli_offsetof(field) offsetof(struct db_playlist_info, field)
|
||||
@ -463,7 +463,7 @@ struct playlist_info *
|
||||
db_pl_fetch_bytitlepath(char *title, char *path);
|
||||
|
||||
int
|
||||
db_pl_add(char *title, char *path, char *virtual_path, int *id);
|
||||
db_pl_add(struct playlist_info *pli, int *id);
|
||||
|
||||
int
|
||||
db_pl_add_item_bypath(int plid, char *path);
|
||||
@ -475,7 +475,7 @@ void
|
||||
db_pl_clear_items(int id);
|
||||
|
||||
int
|
||||
db_pl_update(char *title, char *path, char *virtual_path, int id);
|
||||
db_pl_update(struct playlist_info *pli);
|
||||
|
||||
void
|
||||
db_pl_delete(int id);
|
||||
|
@ -759,8 +759,22 @@ process_pls(plist_t playlists, char *file)
|
||||
|
||||
if (pl_id == 0)
|
||||
{
|
||||
pli = (struct playlist_info *)malloc(sizeof(struct playlist_info));
|
||||
if (!pli)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SCAN, "Out of memory\n");
|
||||
|
||||
return;
|
||||
}
|
||||
memset(pli, 0, sizeof(struct playlist_info));
|
||||
|
||||
pli->title = strdup(name);
|
||||
pli->path = strdup(file);
|
||||
snprintf(virtual_path, PATH_MAX, "/file:%s", file);
|
||||
ret = db_pl_add(name, file, virtual_path, &pl_id);
|
||||
pli->virtual_path = strdup(virtual_path);
|
||||
|
||||
ret = db_pl_add(pli, &pl_id);
|
||||
free_pli(pli, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SCAN, "Error adding iTunes playlist '%s' (%s)\n", name, file);
|
||||
|
@ -96,14 +96,6 @@ scan_playlist(char *file, time_t mtime)
|
||||
|
||||
DPRINTF(E_LOG, L_SCAN, "Processing static playlist: %s\n", file);
|
||||
|
||||
ret = stat(file, &sb);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SCAN, "Could not stat() '%s': %s\n", file, strerror(errno));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ptr = strrchr(file, '.');
|
||||
if (!ptr)
|
||||
return;
|
||||
@ -121,21 +113,13 @@ scan_playlist(char *file, time_t mtime)
|
||||
else
|
||||
filename++;
|
||||
|
||||
pli = db_pl_fetch_bypath(file);
|
||||
|
||||
if (pli)
|
||||
ret = stat(file, &sb);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_DBG, L_SCAN, "Playlist found, updating\n");
|
||||
DPRINTF(E_LOG, L_SCAN, "Could not stat() '%s': %s\n", file, strerror(errno));
|
||||
|
||||
pl_id = pli->id;
|
||||
|
||||
free_pli(pli, 0);
|
||||
|
||||
db_pl_ping(pl_id);
|
||||
db_pl_clear_items(pl_id);
|
||||
return;
|
||||
}
|
||||
else
|
||||
pl_id = 0;
|
||||
|
||||
fp = fopen(file, "r");
|
||||
if (!fp)
|
||||
@ -145,33 +129,58 @@ scan_playlist(char *file, time_t mtime)
|
||||
return;
|
||||
}
|
||||
|
||||
if (pl_id == 0)
|
||||
/* Fetch or create playlist */
|
||||
pli = db_pl_fetch_bypath(file);
|
||||
if (pli)
|
||||
{
|
||||
/* Get only the basename, to be used as the playlist name */
|
||||
DPRINTF(E_DBG, L_SCAN, "Found playlist '%s', updating\n", file);
|
||||
|
||||
pl_id = pli->id;
|
||||
|
||||
db_pl_ping(pl_id);
|
||||
db_pl_clear_items(pl_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
pli = (struct playlist_info *)malloc(sizeof(struct playlist_info));
|
||||
if (!pli)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SCAN, "Out of memory\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
memset(pli, 0, sizeof(struct playlist_info));
|
||||
|
||||
/* Get only the basename, to be used as the playlist title */
|
||||
ptr = strrchr(filename, '.');
|
||||
if (ptr)
|
||||
*ptr = '\0';
|
||||
|
||||
/* Safe: filename is a subset of file which is <= PATH_MAX already */
|
||||
strncpy(buf, filename, sizeof(buf));
|
||||
pli->title = strdup(filename);
|
||||
|
||||
/* Restore the full filename */
|
||||
if (ptr)
|
||||
*ptr = '.';
|
||||
|
||||
pli->path = strdup(file);
|
||||
snprintf(virtual_path, PATH_MAX, "/file:%s", file);
|
||||
pli->virtual_path = strdup(virtual_path);
|
||||
|
||||
ret = db_pl_add(buf, file, virtual_path, &pl_id);
|
||||
ret = db_pl_add(pli, &pl_id);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SCAN, "Error adding playlist '%s'\n", file);
|
||||
|
||||
free_pli(pli, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
DPRINTF(E_INFO, L_SCAN, "Added playlist as id %d\n", pl_id);
|
||||
}
|
||||
|
||||
free_pli(pli, 0);
|
||||
|
||||
extinf = 0;
|
||||
memset(&mfi, 0, sizeof(struct media_file_info));
|
||||
|
||||
|
@ -645,8 +645,6 @@ spotify_playlist_save(sp_playlist *pl)
|
||||
}
|
||||
fptr_sp_link_release(link);
|
||||
|
||||
// sleep(1); // Primitive way of preventing database locking (the mutex wasn't working)
|
||||
|
||||
pli = db_pl_fetch_bypath(url);
|
||||
|
||||
// The starred playlist has an empty name, set it manually to "Starred"
|
||||
@ -663,30 +661,51 @@ spotify_playlist_save(sp_playlist *pl)
|
||||
|
||||
plid = pli->id;
|
||||
|
||||
free_pli(pli, 0);
|
||||
free(pli->title);
|
||||
pli->title = strdup(title);
|
||||
free(pli->virtual_path);
|
||||
pli->virtual_path = strdup(virtual_path);
|
||||
|
||||
ret = db_pl_update(title, url, virtual_path, plid);
|
||||
ret = db_pl_update(pli);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SPOTIFY, "Error updating playlist ('%s', link %s)\n", name, url);
|
||||
|
||||
free_pli(pli, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
db_pl_ping(plid);
|
||||
db_pl_clear_items(plid);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF(E_DBG, L_SPOTIFY, "Adding playlist ('%s', link %s)\n", name, url);
|
||||
|
||||
ret = db_pl_add(title, url, virtual_path, &plid);
|
||||
pli = (struct playlist_info *)malloc(sizeof(struct playlist_info));
|
||||
if (!pli)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SCAN, "Out of memory\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(pli, 0, sizeof(struct playlist_info));
|
||||
pli->title = strdup(title);
|
||||
pli->path = strdup(url);
|
||||
pli->virtual_path = strdup(virtual_path);
|
||||
|
||||
ret = db_pl_add(pli, &plid);
|
||||
if ((ret < 0) || (plid < 1))
|
||||
{
|
||||
DPRINTF(E_LOG, L_SPOTIFY, "Error adding playlist ('%s', link %s, ret %d, plid %d)\n", name, url, ret, plid);
|
||||
|
||||
free_pli(pli, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
free_pli(pli, 0);
|
||||
|
||||
/* Save tracks and playlistitems (files and playlistitems table) */
|
||||
num_tracks = fptr_sp_playlist_num_tracks(pl);
|
||||
for (i = 0; i < num_tracks; i++)
|
||||
|
Loading…
Reference in New Issue
Block a user