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:
ejurgensen 2015-03-14 22:34:03 +01:00
parent 9fdb8a5247
commit e68c6c4932
5 changed files with 101 additions and 53 deletions

View File

@ -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" },
};

View File

@ -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);

View File

@ -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);

View 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));

View File

@ -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++)