Revert "Merge branch 'db' of git://github.com/chme/forked-daapd into chme-db"
This reverts commitb8d5e32160
, reversing changes made to5a02f926e3
.
This commit is contained in:
parent
b8d5e32160
commit
ad48ccb804
|
@ -69,7 +69,11 @@ expr returns [ pANTLR3_STRING result, int valid ]
|
||||||
@init { $result = NULL; $valid = 1; }
|
@init { $result = NULL; $valid = 1; }
|
||||||
: ^(OPAND a = expr b = expr)
|
: ^(OPAND a = expr b = expr)
|
||||||
{
|
{
|
||||||
if ($a.valid && $b.valid)
|
if (!$a.valid || !$b.valid)
|
||||||
|
{
|
||||||
|
$valid = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
$result = $a.result->factory->newRaw($a.result->factory);
|
$result = $a.result->factory->newRaw($a.result->factory);
|
||||||
$result->append8($result, "(");
|
$result->append8($result, "(");
|
||||||
|
@ -78,24 +82,14 @@ expr returns [ pANTLR3_STRING result, int valid ]
|
||||||
$result->appendS($result, $b.result);
|
$result->appendS($result, $b.result);
|
||||||
$result->append8($result, ")");
|
$result->append8($result, ")");
|
||||||
}
|
}
|
||||||
else if ($a.valid)
|
|
||||||
{
|
|
||||||
$result = $a.result->factory->newRaw($a.result->factory);
|
|
||||||
$result->appendS($result, $a.result);
|
|
||||||
}
|
|
||||||
else if ($b.valid)
|
|
||||||
{
|
|
||||||
$result = $b.result->factory->newRaw($b.result->factory);
|
|
||||||
$result->appendS($result, $b.result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$valid = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
| ^(OPOR a = expr b = expr)
|
| ^(OPOR a = expr b = expr)
|
||||||
{
|
{
|
||||||
if ($a.valid && $b.valid)
|
if (!$a.valid || !$b.valid)
|
||||||
|
{
|
||||||
|
$valid = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
$result = $a.result->factory->newRaw($a.result->factory);
|
$result = $a.result->factory->newRaw($a.result->factory);
|
||||||
$result->append8($result, "(");
|
$result->append8($result, "(");
|
||||||
|
@ -104,20 +98,6 @@ expr returns [ pANTLR3_STRING result, int valid ]
|
||||||
$result->appendS($result, $b.result);
|
$result->appendS($result, $b.result);
|
||||||
$result->append8($result, ")");
|
$result->append8($result, ")");
|
||||||
}
|
}
|
||||||
else if ($a.valid)
|
|
||||||
{
|
|
||||||
$result = $a.result->factory->newRaw($a.result->factory);
|
|
||||||
$result->appendS($result, $a.result);
|
|
||||||
}
|
|
||||||
else if ($b.valid)
|
|
||||||
{
|
|
||||||
$result = $b.result->factory->newRaw($b.result->factory);
|
|
||||||
$result->appendS($result, $b.result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$valid = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
| STR
|
| STR
|
||||||
{
|
{
|
||||||
|
@ -214,22 +194,13 @@ expr returns [ pANTLR3_STRING result, int valid ]
|
||||||
goto STR_result_valid_0; /* ABORT */
|
goto STR_result_valid_0; /* ABORT */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No need to exclude empty artist and album, as forked-daapd makes sure there always exists an artist/album. */
|
|
||||||
if (neg_op && op == ':'
|
|
||||||
&& (strcmp((char *)field, "daap.songalbumartist") == 0
|
|
||||||
|| strcmp((char *)field, "daap.songartist") == 0
|
|
||||||
|| strcmp((char *)field, "daap.songalbum") == 0))
|
|
||||||
{
|
|
||||||
DPRINTF(E_DBG, L_DAAP, "Ignoring clause '\%s\%s\%c'\n", field, (neg_op) ? "!" : "", op);
|
|
||||||
$valid = 0;
|
|
||||||
goto STR_result_valid_0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Need to check against NULL too */
|
/* Need to check against NULL too */
|
||||||
if (op == ':')
|
if (op == ':')
|
||||||
$result->append8($result, "(");
|
$result->append8($result, "(");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$result->append8($result, dqfm->db_col);
|
||||||
|
|
||||||
/* Int field: check integer conversion */
|
/* Int field: check integer conversion */
|
||||||
if (dqfm->as_int)
|
if (dqfm->as_int)
|
||||||
{
|
{
|
||||||
|
@ -254,16 +225,6 @@ expr returns [ pANTLR3_STRING result, int valid ]
|
||||||
}
|
}
|
||||||
|
|
||||||
*end = '\0'; /* Cut out potential garbage - we're being kind */
|
*end = '\0'; /* Cut out potential garbage - we're being kind */
|
||||||
|
|
||||||
/* forked-daapd only has media_kind = 1 for music - so remove media_kind = 32 to imporve select query performance. */
|
|
||||||
if (llval == 32
|
|
||||||
&& (strcmp((char *)field, "com.apple.itunes.mediakind") == 0
|
|
||||||
|| strcmp((char *)field, "com.apple.itunes.extended-media-kind") == 0))
|
|
||||||
{
|
|
||||||
DPRINTF(E_DBG, L_DAAP, "Ignoring clause '\%s\%s\%c\%s'\n", field, (neg_op) ? "!" : "", op, val);
|
|
||||||
$valid = 0;
|
|
||||||
goto STR_result_valid_0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* String field: escape string, check for '*' */
|
/* String field: escape string, check for '*' */
|
||||||
else
|
else
|
||||||
|
@ -298,8 +259,6 @@ expr returns [ pANTLR3_STRING result, int valid ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$result->append8($result, dqfm->db_col);
|
|
||||||
|
|
||||||
switch(op)
|
switch(op)
|
||||||
{
|
{
|
||||||
case ':':
|
case ':':
|
||||||
|
|
|
@ -1303,12 +1303,20 @@ artwork_get_item(int id, int max_w, int max_h, struct evbuffer *evbuf)
|
||||||
int
|
int
|
||||||
artwork_get_group(int id, int max_w, int max_h, struct evbuffer *evbuf)
|
artwork_get_group(int id, int max_w, int max_h, struct evbuffer *evbuf)
|
||||||
{
|
{
|
||||||
|
int64_t persistentid;
|
||||||
int format;
|
int format;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_ART, "Artwork request for group %d\n", id);
|
DPRINTF(E_DBG, L_ART, "Artwork request for group %d\n", id);
|
||||||
|
|
||||||
|
/* Get the persistent id for the given group id */
|
||||||
|
if (db_group_persistentid_byid(id, &persistentid) < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_ART, "Error fetching persistent id for group id %d\n", id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Load artwork image for the persistent id */
|
/* Load artwork image for the persistent id */
|
||||||
format = artwork_get_group_persistentid(id, max_w, max_h, evbuf);
|
format = artwork_get_group_persistentid(persistentid, max_w, max_h, evbuf);
|
||||||
if (format <= 0)
|
if (format <= 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_DBG, L_ART, "No artwork found for group %d\n", id);
|
DPRINTF(E_DBG, L_ART, "No artwork found for group %d\n", id);
|
||||||
|
|
551
src/db.c
551
src/db.c
|
@ -742,14 +742,12 @@ db_purge_cruft(time_t ref)
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
char *queries[5] = { NULL, NULL, NULL, NULL, NULL };
|
char *queries[3] = { NULL, NULL, NULL };
|
||||||
char *queries_tmpl[5] =
|
char *queries_tmpl[3] =
|
||||||
{
|
{
|
||||||
"DELETE FROM playlistitems WHERE playlistid IN (SELECT id FROM playlists p WHERE p.type <> 1 AND p.db_timestamp < %" PRIi64 ");",
|
"DELETE FROM playlistitems WHERE playlistid IN (SELECT id FROM playlists p WHERE p.type <> 1 AND p.db_timestamp < %" PRIi64 ");",
|
||||||
"DELETE FROM playlists WHERE type <> 1 AND db_timestamp < %" PRIi64 ";",
|
"DELETE FROM playlists WHERE type <> 1 AND db_timestamp < %" PRIi64 ";",
|
||||||
"DELETE FROM files WHERE db_timestamp < %" PRIi64 ";",
|
"DELETE FROM files WHERE db_timestamp < %" PRIi64 ";"
|
||||||
"DELETE FROM groups WHERE type = 1 AND id NOT IN (SELECT songalbumid FROM files);",
|
|
||||||
"DELETE FROM groups WHERE type = 2 AND id NOT IN (SELECT songartistid FROM files);"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (sizeof(queries) != sizeof(queries_tmpl))
|
if (sizeof(queries) != sizeof(queries_tmpl))
|
||||||
|
@ -760,11 +758,7 @@ db_purge_cruft(time_t ref)
|
||||||
|
|
||||||
for (i = 0; i < (sizeof(queries_tmpl) / sizeof(queries_tmpl[0])); i++)
|
for (i = 0; i < (sizeof(queries_tmpl) / sizeof(queries_tmpl[0])); i++)
|
||||||
{
|
{
|
||||||
if (i < 3)
|
|
||||||
queries[i] = sqlite3_mprintf(queries_tmpl[i], (int64_t)ref);
|
queries[i] = sqlite3_mprintf(queries_tmpl[i], (int64_t)ref);
|
||||||
else
|
|
||||||
queries[i] = sqlite3_mprintf(queries_tmpl[i]);
|
|
||||||
|
|
||||||
if (!queries[i])
|
if (!queries[i])
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
||||||
|
@ -1203,13 +1197,13 @@ db_build_query_group_albums(struct query_params *qp, char **q)
|
||||||
sort = sort_clause[qp->sort];
|
sort = sort_clause[qp->sort];
|
||||||
|
|
||||||
if (idx && qp->filter)
|
if (idx && qp->filter)
|
||||||
query = sqlite3_mprintf("SELECT f.songalbumid, f.songalbumid, f.album, f.album_sort, COUNT(f.id), 1, f.album_artist, f.songartistid FROM files f WHERE f.disabled = 0 AND %s GROUP BY f.songalbumid %s %s;", qp->filter, sort, idx);
|
query = sqlite3_mprintf("SELECT g.id, g.persistentid, f.album, f.album_sort, COUNT(f.id), 1, f.album_artist, f.songartistid FROM files f, groups g WHERE f.songalbumid = g.persistentid AND g.type = %d AND f.disabled = 0 AND %s GROUP BY f.album, g.name %s %s;", G_ALBUMS, qp->filter, sort, idx);
|
||||||
else if (idx)
|
else if (idx)
|
||||||
query = sqlite3_mprintf("SELECT f.songalbumid, f.songalbumid, f.album, f.album_sort, COUNT(f.id), 1, f.album_artist, f.songartistid FROM files f WHERE f.disabled = 0 GROUP BY f.songalbumid %s %s;", sort, idx);
|
query = sqlite3_mprintf("SELECT g.id, g.persistentid, f.album, f.album_sort, COUNT(f.id), 1, f.album_artist, f.songartistid FROM files f, groups g WHERE f.songalbumid = g.persistentid AND g.type = %d AND f.disabled = 0 GROUP BY f.album, g.name %s %s;", G_ALBUMS, sort, idx);
|
||||||
else if (qp->filter)
|
else if (qp->filter)
|
||||||
query = sqlite3_mprintf("SELECT f.songalbumid, f.songalbumid, f.album, f.album_sort, COUNT(f.id), 1, f.album_artist, f.songartistid FROM files f WHERE f.disabled = 0 AND %s GROUP BY f.songalbumid %s;", qp->filter, sort);
|
query = sqlite3_mprintf("SELECT g.id, g.persistentid, f.album, f.album_sort, COUNT(f.id), 1, f.album_artist, f.songartistid FROM files f, groups g WHERE f.songalbumid = g.persistentid AND g.type = %d AND f.disabled = 0 AND %s GROUP BY f.album, g.name %s;", G_ALBUMS, qp->filter, sort);
|
||||||
else
|
else
|
||||||
query = sqlite3_mprintf("SELECT f.songalbumid, f.songalbumid, f.album, f.album_sort, COUNT(f.id), 1, f.album_artist, f.songartistid FROM files f WHERE f.disabled = 0 GROUP BY f.songalbumid %s;", sort);
|
query = sqlite3_mprintf("SELECT g.id, g.persistentid, f.album, f.album_sort, COUNT(f.id), 1, f.album_artist, f.songartistid FROM files f, groups g WHERE f.songalbumid = g.persistentid AND g.type = %d AND f.disabled = 0 GROUP BY f.album, g.name %s;", G_ALBUMS, sort);
|
||||||
|
|
||||||
if (!query)
|
if (!query)
|
||||||
{
|
{
|
||||||
|
@ -1242,13 +1236,13 @@ db_build_query_group_artists(struct query_params *qp, char **q)
|
||||||
sort = sort_clause[qp->sort];
|
sort = sort_clause[qp->sort];
|
||||||
|
|
||||||
if (idx && qp->filter)
|
if (idx && qp->filter)
|
||||||
query = sqlite3_mprintf("SELECT f.songartistid, f.songartistid, f.album_artist, f.album_artist_sort, COUNT(f.id), COUNT(DISTINCT f.songalbumid), f.album_artist, f.songartistid FROM files f WHERE f.disabled = 0 AND %s GROUP BY f.songartistid %s %s;", qp->filter, sort, idx);
|
query = sqlite3_mprintf("SELECT g.id, g.persistentid, f.album_artist, f.album_artist_sort, COUNT(f.id), COUNT(DISTINCT f.songalbumid), f.album_artist, f.songartistid FROM files f, groups g WHERE f.songartistid = g.persistentid AND g.type = %d AND f.disabled = 0 AND %s GROUP BY f.album_artist, g.name %s %s;", G_ARTISTS, qp->filter, sort, idx);
|
||||||
else if (idx)
|
else if (idx)
|
||||||
query = sqlite3_mprintf("SELECT f.songartistid, f.songartistid, f.album_artist, f.album_artist_sort, COUNT(f.id), COUNT(DISTINCT f.songalbumid), f.album_artist, f.songartistid FROM files f WHERE f.disabled = 0 GROUP BY f.songartistid %s %s;", sort, idx);
|
query = sqlite3_mprintf("SELECT g.id, g.persistentid, f.album_artist, f.album_artist_sort, COUNT(f.id), COUNT(DISTINCT f.songalbumid), f.album_artist, f.songartistid FROM files f, groups g WHERE f.songartistid = g.persistentid AND g.type = %d AND f.disabled = 0 GROUP BY f.album_artist, g.name %s %s;", G_ARTISTS, sort, idx);
|
||||||
else if (qp->filter)
|
else if (qp->filter)
|
||||||
query = sqlite3_mprintf("SELECT f.songartistid, f.songartistid, f.album_artist, f.album_artist_sort, COUNT(f.id), COUNT(DISTINCT f.songalbumid), f.album_artist, f.songartistid FROM files f WHERE f.disabled = 0 AND %s GROUP BY f.songartistid %s;", qp->filter, sort);
|
query = sqlite3_mprintf("SELECT g.id, g.persistentid, f.album_artist, f.album_artist_sort, COUNT(f.id), COUNT(DISTINCT f.songalbumid), f.album_artist, f.songartistid FROM files f, groups g WHERE f.songartistid = g.persistentid AND g.type = %d AND f.disabled = 0 AND %s GROUP BY f.album_artist, g.name %s;", G_ARTISTS, qp->filter, sort);
|
||||||
else
|
else
|
||||||
query = sqlite3_mprintf("SELECT f.songartistid, f.songartistid, f.album_artist, f.album_artist_sort, COUNT(f.id), COUNT(DISTINCT f.songalbumid), f.album_artist, f.songartistid FROM files f WHERE f.disabled = 0 GROUP BY f.songartistid %s;", sort);
|
query = sqlite3_mprintf("SELECT g.id, g.persistentid, f.album_artist, f.album_artist_sort, COUNT(f.id), COUNT(DISTINCT f.songalbumid), f.album_artist, f.songartistid FROM files f, groups g WHERE f.songartistid = g.persistentid AND g.type = %d AND f.disabled = 0 GROUP BY f.album_artist, g.name %s;", G_ARTISTS, sort);
|
||||||
|
|
||||||
if (!query)
|
if (!query)
|
||||||
{
|
{
|
||||||
|
@ -1450,17 +1444,17 @@ db_build_query_browse(struct query_params *qp, char *field, char *sort_field, ch
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx && qp->filter)
|
if (idx && qp->filter)
|
||||||
query = sqlite3_mprintf("SELECT f.%s, f.%s FROM files f WHERE f.disabled = 0 AND f.%s != ''"
|
query = sqlite3_mprintf("SELECT DISTINCT f.%s, f.%s FROM files f WHERE f.disabled = 0 AND f.%s != ''"
|
||||||
" AND %s GROUP BY f.%s %s %s;", field, sort_field, field, qp->filter, field, sort, idx);
|
" AND %s %s %s;", field, sort_field, field, qp->filter, sort, idx);
|
||||||
else if (idx)
|
else if (idx)
|
||||||
query = sqlite3_mprintf("SELECT f.%s, f.%s FROM files f WHERE f.disabled = 0 AND f.%s != ''"
|
query = sqlite3_mprintf("SELECT DISTINCT f.%s, f.%s FROM files f WHERE f.disabled = 0 AND f.%s != ''"
|
||||||
" GROUP BY f.%s %s %s;", field, sort_field, field, field, sort, idx);
|
" %s %s;", field, sort_field, field, sort, idx);
|
||||||
else if (qp->filter)
|
else if (qp->filter)
|
||||||
query = sqlite3_mprintf("SELECT f.%s, f.%s FROM files f WHERE f.disabled = 0 AND f.%s != ''"
|
query = sqlite3_mprintf("SELECT DISTINCT f.%s, f.%s FROM files f WHERE f.disabled = 0 AND f.%s != ''"
|
||||||
" AND %s GROUP BY f.%s %s;", field, sort_field, field, qp->filter, field, sort);
|
" AND %s %s;", field, sort_field, field, qp->filter, sort);
|
||||||
else
|
else
|
||||||
query = sqlite3_mprintf("SELECT f.%s, f.%s FROM files f WHERE f.disabled = 0 AND f.%s != '' GROUP BY f.%s %s",
|
query = sqlite3_mprintf("SELECT DISTINCT f.%s, f.%s FROM files f WHERE f.disabled = 0 AND f.%s != '' %s",
|
||||||
field, sort_field, field, field, sort);
|
field, sort_field, field, sort);
|
||||||
|
|
||||||
free(sort);
|
free(sort);
|
||||||
|
|
||||||
|
@ -2365,101 +2359,6 @@ db_file_fetch_byid(int id)
|
||||||
#undef Q_TMPL
|
#undef Q_TMPL
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
db_group_get_id(enum group_type type, const char *artist, const char *album, uint32_t *id)
|
|
||||||
{
|
|
||||||
#define Q_TMPL "SELECT id FROM groups WHERE type = %d AND name = LOWER(TRIM(%Q)) || '==' || LOWER(TRIM(%Q));"
|
|
||||||
|
|
||||||
sqlite3_stmt *stmt;
|
|
||||||
char *query;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// Select artist and album from groups
|
|
||||||
query = sqlite3_mprintf(Q_TMPL, type, artist, (album ? album : ""));
|
|
||||||
if (!query)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query);
|
|
||||||
|
|
||||||
ret = db_blocking_prepare_v2(query, strlen(query) + 1, &stmt, NULL);
|
|
||||||
if (ret != SQLITE_OK)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
|
|
||||||
|
|
||||||
sqlite3_free(query);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = db_blocking_step(stmt);
|
|
||||||
|
|
||||||
if (ret == SQLITE_DONE)
|
|
||||||
{
|
|
||||||
DPRINTF(E_DBG, L_DB, "No results\n");
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
sqlite3_free(query);
|
|
||||||
|
|
||||||
*id = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (ret == SQLITE_ROW)
|
|
||||||
{
|
|
||||||
*id = sqlite3_column_int(stmt, 0);
|
|
||||||
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
sqlite3_free(query);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTF(E_LOG, L_DB, "Could not step: %s\n", sqlite3_errmsg(hdl));
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
sqlite3_free(query);
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
#undef Q_TMPL
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
db_group_add(enum group_type type, const char *artist, const char *album, uint32_t *id)
|
|
||||||
{
|
|
||||||
#define Q_TMPL "INSERT OR REPLACE INTO groups (type, name) VALUES (%d, LOWER(TRIM(%Q)) || '==' || LOWER(TRIM(%Q)));"
|
|
||||||
|
|
||||||
char *query;
|
|
||||||
char *errmsg;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// Select artist and album from groups
|
|
||||||
query = sqlite3_mprintf(Q_TMPL, type, artist, (album ? album : ""));
|
|
||||||
if (!query)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query);
|
|
||||||
|
|
||||||
ret = db_exec(query, &errmsg);
|
|
||||||
if (ret != SQLITE_OK)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Error '%s' while runnning '%s'\n", errmsg, query);
|
|
||||||
sqlite3_free(errmsg);
|
|
||||||
sqlite3_free(query);
|
|
||||||
*id = 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_free(errmsg);
|
|
||||||
sqlite3_free(query);
|
|
||||||
|
|
||||||
*id = sqlite3_last_insert_rowid(hdl);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#undef Q_TMPL
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
db_file_add(struct media_file_info *mfi)
|
db_file_add(struct media_file_info *mfi)
|
||||||
{
|
{
|
||||||
|
@ -2478,13 +2377,11 @@ db_file_add(struct media_file_info *mfi)
|
||||||
" %Q, %" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %d, %" PRIi64 "," \
|
" %Q, %" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %d, %" PRIi64 "," \
|
||||||
" %Q, %d, %d, %d, %d, TRIM(%Q)," \
|
" %Q, %d, %d, %d, %d, TRIM(%Q)," \
|
||||||
" %d, TRIM(%Q), TRIM(%Q), TRIM(%Q), %d, %d," \
|
" %d, TRIM(%Q), TRIM(%Q), TRIM(%Q), %d, %d," \
|
||||||
" %" PRIi64 ", %" PRIi64 ", " \
|
" daap_songalbumid(LOWER(TRIM(%Q)), ''), daap_songalbumid(LOWER(TRIM(%Q)), LOWER(TRIM(%Q))), " \
|
||||||
" TRIM(%Q), TRIM(%Q), TRIM(%Q), TRIM(%Q), TRIM(%Q));"
|
" TRIM(%Q), TRIM(%Q), TRIM(%Q), TRIM(%Q), TRIM(%Q));"
|
||||||
|
|
||||||
char *query;
|
char *query;
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
uint32_t albumid;
|
|
||||||
uint32_t artistid;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
||||||
|
@ -2494,43 +2391,6 @@ db_file_add(struct media_file_info *mfi)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select artist and album from groups
|
|
||||||
ret = db_group_get_id(G_ALBUMS, mfi->album_artist, mfi->album, &albumid);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Could not get albumid for artist '%s' album '%s'\n", mfi->album_artist, mfi->album);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (albumid == 0)
|
|
||||||
{
|
|
||||||
ret = db_group_add(G_ALBUMS, mfi->album_artist, mfi->album, &albumid);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Could not add artist '%s' album '%s'\n", mfi->album_artist, mfi->album);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = db_group_get_id(G_ARTISTS, mfi->album_artist, NULL, &artistid);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Could not get artistid for artist '%s'\n", mfi->album_artist);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (artistid == 0)
|
|
||||||
{
|
|
||||||
ret = db_group_add(G_ARTISTS, mfi->album_artist, NULL, &artistid);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Could not add artist '%s'\n", mfi->album_artist);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mfi->songalbumid = albumid;
|
|
||||||
mfi->songartistid = artistid;
|
|
||||||
mfi->db_timestamp = (uint64_t)time(NULL);
|
mfi->db_timestamp = (uint64_t)time(NULL);
|
||||||
mfi->time_added = mfi->db_timestamp;
|
mfi->time_added = mfi->db_timestamp;
|
||||||
|
|
||||||
|
@ -2550,8 +2410,7 @@ db_file_add(struct media_file_info *mfi)
|
||||||
mfi->contentrating, mfi->bits_per_sample, mfi->album_artist,
|
mfi->contentrating, mfi->bits_per_sample, mfi->album_artist,
|
||||||
mfi->media_kind, mfi->tv_series_name, mfi->tv_episode_num_str,
|
mfi->media_kind, mfi->tv_series_name, mfi->tv_episode_num_str,
|
||||||
mfi->tv_network_name, mfi->tv_episode_sort, mfi->tv_season_num,
|
mfi->tv_network_name, mfi->tv_episode_sort, mfi->tv_season_num,
|
||||||
mfi->songartistid, mfi->songalbumid,
|
mfi->album_artist, mfi->album_artist, mfi->album, mfi->title_sort, mfi->artist_sort, mfi->album_sort,
|
||||||
mfi->title_sort, mfi->artist_sort, mfi->album_sort,
|
|
||||||
mfi->composer_sort, mfi->album_artist_sort);
|
mfi->composer_sort, mfi->album_artist_sort);
|
||||||
|
|
||||||
if (!query)
|
if (!query)
|
||||||
|
@ -2595,15 +2454,11 @@ db_file_update(struct media_file_info *mfi)
|
||||||
" bits_per_sample = %d, album_artist = TRIM(%Q)," \
|
" bits_per_sample = %d, album_artist = TRIM(%Q)," \
|
||||||
" media_kind = %d, tv_series_name = TRIM(%Q), tv_episode_num_str = TRIM(%Q)," \
|
" media_kind = %d, tv_series_name = TRIM(%Q), tv_episode_num_str = TRIM(%Q)," \
|
||||||
" tv_network_name = TRIM(%Q), tv_episode_sort = %d, tv_season_num = %d," \
|
" tv_network_name = TRIM(%Q), tv_episode_sort = %d, tv_season_num = %d," \
|
||||||
" songartistid = %" PRIi64 ", songalbumid = %" PRIi64 "," \
|
" songartistid = daap_songalbumid(LOWER(TRIM(%Q)), ''), songalbumid = daap_songalbumid(LOWER(TRIM(%Q)), LOWER(TRIM(%Q)))," \
|
||||||
" title_sort = TRIM(%Q), artist_sort = TRIM(%Q), album_sort = TRIM(%Q), composer_sort = TRIM(%Q), album_artist_sort = TRIM(%Q)" \
|
" title_sort = TRIM(%Q), artist_sort = TRIM(%Q), album_sort = TRIM(%Q), composer_sort = TRIM(%Q), album_artist_sort = TRIM(%Q)" \
|
||||||
" WHERE id = %d;"
|
" WHERE id = %d;"
|
||||||
|
|
||||||
// struct media_file_info *oldmfi;
|
|
||||||
char *query;
|
char *query;
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
uint32_t albumid;
|
|
||||||
uint32_t artistid;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (mfi->id == 0)
|
if (mfi->id == 0)
|
||||||
|
@ -2612,55 +2467,6 @@ db_file_update(struct media_file_info *mfi)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
oldmfi = db_file_fetch_byid(mfi->id);
|
|
||||||
|
|
||||||
if (!oldmfi)
|
|
||||||
{
|
|
||||||
DPRINTF(E_WARN, L_DB, "File with id '%d' does not exist\n", mfi->id);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
free_mfi(oldmfi, 0);
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = db_group_get_id(G_ALBUMS, mfi->album_artist, mfi->album, &albumid);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Could not get albumid for artist '%s' album '%s'\n", mfi->album_artist, mfi->album);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (albumid == 0)
|
|
||||||
{
|
|
||||||
ret = db_group_add(G_ALBUMS, mfi->album_artist, mfi->album, &albumid);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Could not add artist '%s' album '%s'\n", mfi->album_artist, mfi->album);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = db_group_get_id(G_ARTISTS, mfi->album_artist, NULL, &artistid);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Could not get artistid for artist '%s'\n", mfi->album_artist);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (artistid == 0)
|
|
||||||
{
|
|
||||||
ret = db_group_add(G_ARTISTS, mfi->album_artist, NULL, &artistid);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Could not add artist '%s'\n", mfi->album_artist);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mfi->songalbumid = albumid;
|
|
||||||
mfi->songartistid = artistid;
|
|
||||||
|
|
||||||
mfi->db_timestamp = (uint64_t)time(NULL);
|
mfi->db_timestamp = (uint64_t)time(NULL);
|
||||||
|
|
||||||
if (mfi->time_modified == 0)
|
if (mfi->time_modified == 0)
|
||||||
|
@ -2678,7 +2484,7 @@ db_file_update(struct media_file_info *mfi)
|
||||||
mfi->bits_per_sample, mfi->album_artist,
|
mfi->bits_per_sample, mfi->album_artist,
|
||||||
mfi->media_kind, mfi->tv_series_name, mfi->tv_episode_num_str,
|
mfi->media_kind, mfi->tv_series_name, mfi->tv_episode_num_str,
|
||||||
mfi->tv_network_name, mfi->tv_episode_sort, mfi->tv_season_num,
|
mfi->tv_network_name, mfi->tv_episode_sort, mfi->tv_season_num,
|
||||||
mfi->songartistid, mfi->songalbumid,
|
mfi->album_artist, mfi->album_artist, mfi->album,
|
||||||
mfi->title_sort, mfi->artist_sort, mfi->album_sort,
|
mfi->title_sort, mfi->artist_sort, mfi->album_sort,
|
||||||
mfi->composer_sort, mfi->album_artist_sort,
|
mfi->composer_sort, mfi->album_artist_sort,
|
||||||
mfi->id);
|
mfi->id);
|
||||||
|
@ -3303,11 +3109,16 @@ db_pl_enable_bycookie(uint32_t cookie, char *path)
|
||||||
|
|
||||||
|
|
||||||
/* Groups */
|
/* Groups */
|
||||||
|
int
|
||||||
|
db_groups_clear(void)
|
||||||
|
{
|
||||||
|
return db_query_run("DELETE FROM groups;", 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
static enum group_type
|
static enum group_type
|
||||||
db_group_type_bypersistentid(int64_t persistentid)
|
db_group_type_bypersistentid(int64_t persistentid)
|
||||||
{
|
{
|
||||||
#define Q_TMPL "SELECT g.type FROM groups g WHERE g.id = %" PRIi64 ";"
|
#define Q_TMPL "SELECT g.type FROM groups g WHERE g.persistentid = %" PRIi64 ";"
|
||||||
char *query;
|
char *query;
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -3359,6 +3170,61 @@ db_group_type_bypersistentid(int64_t persistentid)
|
||||||
#undef Q_TMPL
|
#undef Q_TMPL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
db_group_persistentid_byid(int id, int64_t *persistentid)
|
||||||
|
{
|
||||||
|
#define Q_TMPL "SELECT g.persistentid FROM groups g WHERE g.id = %d;"
|
||||||
|
char *query;
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
query = sqlite3_mprintf(Q_TMPL, id);
|
||||||
|
if (!query)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query);
|
||||||
|
|
||||||
|
ret = db_blocking_prepare_v2(query, -1, &stmt, NULL);
|
||||||
|
if (ret != SQLITE_OK)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
|
||||||
|
|
||||||
|
sqlite3_free(query);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = db_blocking_step(stmt);
|
||||||
|
if (ret != SQLITE_ROW)
|
||||||
|
{
|
||||||
|
if (ret == SQLITE_DONE)
|
||||||
|
DPRINTF(E_DBG, L_DB, "No results\n");
|
||||||
|
else
|
||||||
|
DPRINTF(E_LOG, L_DB, "Could not step: %s\n", sqlite3_errmsg(hdl));
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
sqlite3_free(query);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*persistentid = sqlite3_column_int64(stmt, 0);
|
||||||
|
|
||||||
|
#ifdef DB_PROFILE
|
||||||
|
while (db_blocking_step(stmt) == SQLITE_ROW)
|
||||||
|
; /* EMPTY */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
sqlite3_free(query);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#undef Q_TMPL
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Remotes */
|
/* Remotes */
|
||||||
static int
|
static int
|
||||||
|
@ -4437,7 +4303,8 @@ db_perthread_deinit(void)
|
||||||
" id INTEGER PRIMARY KEY NOT NULL," \
|
" id INTEGER PRIMARY KEY NOT NULL," \
|
||||||
" type INTEGER NOT NULL," \
|
" type INTEGER NOT NULL," \
|
||||||
" name VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
" name VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
||||||
"CONSTRAINT groups_type_unique_name UNIQUE (type, name)" \
|
" persistentid INTEGER NOT NULL," \
|
||||||
|
"CONSTRAINT groups_type_unique_persistentid UNIQUE (type, persistentid)" \
|
||||||
");"
|
");"
|
||||||
|
|
||||||
#define T_PAIRINGS \
|
#define T_PAIRINGS \
|
||||||
|
@ -4468,7 +4335,7 @@ db_perthread_deinit(void)
|
||||||
"CREATE INDEX IF NOT EXISTS idx_sari ON files(songartistid);"
|
"CREATE INDEX IF NOT EXISTS idx_sari ON files(songartistid);"
|
||||||
|
|
||||||
#define I_SONGALBUMID \
|
#define I_SONGALBUMID \
|
||||||
"CREATE INDEX IF NOT EXISTS idx_sali ON files(songalbumid, disabled, media_kind, album_sort, disc, track);"
|
"CREATE INDEX IF NOT EXISTS idx_sali ON files(songalbumid);"
|
||||||
|
|
||||||
#define I_STATEMKINDSARI \
|
#define I_STATEMKINDSARI \
|
||||||
"CREATE INDEX IF NOT EXISTS idx_state_mkind_sari ON files(disabled, media_kind, songartistid);"
|
"CREATE INDEX IF NOT EXISTS idx_state_mkind_sari ON files(disabled, media_kind, songartistid);"
|
||||||
|
@ -4483,13 +4350,10 @@ db_perthread_deinit(void)
|
||||||
"CREATE INDEX IF NOT EXISTS idx_albumartist ON files(album_artist, album_artist_sort);"
|
"CREATE INDEX IF NOT EXISTS idx_albumartist ON files(album_artist, album_artist_sort);"
|
||||||
|
|
||||||
#define I_COMPOSER \
|
#define I_COMPOSER \
|
||||||
"CREATE INDEX IF NOT EXISTS idx_composer ON files(disabled, media_kind, composer, data_kind);"
|
"CREATE INDEX IF NOT EXISTS idx_composer ON files(composer, composer_sort);"
|
||||||
|
|
||||||
#define I_GENRE \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_genre ON files(disabled, media_kind, genre, data_kind);"
|
|
||||||
|
|
||||||
#define I_TITLE \
|
#define I_TITLE \
|
||||||
"CREATE INDEX IF NOT EXISTS idx_title ON files(disabled, media_kind, title_sort, data_kind);"
|
"CREATE INDEX IF NOT EXISTS idx_title ON files(title, title_sort);"
|
||||||
|
|
||||||
#define I_ALBUM \
|
#define I_ALBUM \
|
||||||
"CREATE INDEX IF NOT EXISTS idx_album ON files(album, album_sort);"
|
"CREATE INDEX IF NOT EXISTS idx_album ON files(album, album_sort);"
|
||||||
|
@ -4506,13 +4370,27 @@ db_perthread_deinit(void)
|
||||||
#define I_PLITEMID \
|
#define I_PLITEMID \
|
||||||
"CREATE INDEX IF NOT EXISTS idx_playlistid ON playlistitems(playlistid, filepath);"
|
"CREATE INDEX IF NOT EXISTS idx_playlistid ON playlistitems(playlistid, filepath);"
|
||||||
|
|
||||||
#define I_GRP_TYPE_NAME \
|
#define I_GRP_TYPE_PERSIST \
|
||||||
"CREATE INDEX IF NOT EXISTS idx_grp_type_name ON groups(type, name);"
|
"CREATE INDEX IF NOT EXISTS idx_grp_type_persist ON groups(type, persistentid);"
|
||||||
|
|
||||||
#define I_PAIRING \
|
#define I_PAIRING \
|
||||||
"CREATE INDEX IF NOT EXISTS idx_pairingguid ON pairings(guid);"
|
"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);" \
|
||||||
|
" INSERT OR IGNORE INTO groups (type, name, persistentid) VALUES (2, NEW.album_artist, NEW.songartistid);" \
|
||||||
|
" 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);" \
|
||||||
|
" INSERT OR IGNORE INTO groups (type, name, persistentid) VALUES (2, NEW.album_artist, NEW.songartistid);" \
|
||||||
|
" END;"
|
||||||
|
|
||||||
#define Q_PL1 \
|
#define Q_PL1 \
|
||||||
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
||||||
" VALUES(1, 'Library', 1, '1 = 1', 0, '', 0, 0);"
|
" VALUES(1, 'Library', 1, '1 = 1', 0, '', 0, 0);"
|
||||||
|
@ -4543,9 +4421,9 @@ db_perthread_deinit(void)
|
||||||
" VALUES(8, 'Purchased', 0, 'media_kind = 1024', 0, '', 0, 8);"
|
" VALUES(8, 'Purchased', 0, 'media_kind = 1024', 0, '', 0, 8);"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SCHEMA_VERSION 16
|
#define SCHEMA_VERSION 15
|
||||||
#define Q_SCVER \
|
#define Q_SCVER \
|
||||||
"INSERT INTO admin (key, value) VALUES ('schema_version', '16');"
|
"INSERT INTO admin (key, value) VALUES ('schema_version', '15');"
|
||||||
|
|
||||||
struct db_init_query {
|
struct db_init_query {
|
||||||
char *query;
|
char *query;
|
||||||
|
@ -4572,7 +4450,6 @@ static const struct db_init_query db_init_queries[] =
|
||||||
{ I_ARTIST, "create artist index" },
|
{ I_ARTIST, "create artist index" },
|
||||||
{ I_ALBUMARTIST, "create album_artist index" },
|
{ I_ALBUMARTIST, "create album_artist index" },
|
||||||
{ I_COMPOSER, "create composer index" },
|
{ I_COMPOSER, "create composer index" },
|
||||||
{ I_GENRE, "create genre index" },
|
|
||||||
{ I_TITLE, "create title index" },
|
{ I_TITLE, "create title index" },
|
||||||
{ I_ALBUM, "create album index" },
|
{ I_ALBUM, "create album index" },
|
||||||
|
|
||||||
|
@ -4582,10 +4459,13 @@ static const struct db_init_query db_init_queries[] =
|
||||||
{ I_FILEPATH, "create file path index" },
|
{ I_FILEPATH, "create file path index" },
|
||||||
{ I_PLITEMID, "create playlist id index" },
|
{ I_PLITEMID, "create playlist id index" },
|
||||||
|
|
||||||
{ I_GRP_TYPE_NAME, "create groups type/name index" },
|
{ I_GRP_TYPE_PERSIST, "create groups type/persistentid index" },
|
||||||
|
|
||||||
{ I_PAIRING, "create pairing guid 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_PL1, "create default playlist" },
|
||||||
{ Q_PL2, "create default smart playlist 'Music'" },
|
{ Q_PL2, "create default smart playlist 'Music'" },
|
||||||
{ Q_PL3, "create default smart playlist 'Movies'" },
|
{ Q_PL3, "create default smart playlist 'Movies'" },
|
||||||
|
@ -5588,190 +5468,6 @@ db_upgrade_v15(void)
|
||||||
#undef Q_DUMP
|
#undef Q_DUMP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Upgrade from schema v15 to v16 */
|
|
||||||
|
|
||||||
#define U_V16_DROP_IDX \
|
|
||||||
"DROP INDEX idx_grp_type_persist;"
|
|
||||||
|
|
||||||
#define U_V16_DROP_TRG_NEW \
|
|
||||||
"DROP TRIGGER update_groups_new_file;"
|
|
||||||
|
|
||||||
#define U_V16_DROP_TRG_UPDATE \
|
|
||||||
"DROP TRIGGER update_groups_update_file;"
|
|
||||||
|
|
||||||
#define U_V16_DROP_TBL_GROUPS \
|
|
||||||
"DROP TABLE groups;"
|
|
||||||
|
|
||||||
#define U_V16_CREATE_TBL_GROUPS \
|
|
||||||
"CREATE TABLE IF NOT EXISTS groups (" \
|
|
||||||
" id INTEGER PRIMARY KEY NOT NULL," \
|
|
||||||
" type INTEGER NOT NULL," \
|
|
||||||
" name VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
|
||||||
"CONSTRAINT groups_type_unique_name UNIQUE (type, name)" \
|
|
||||||
");"
|
|
||||||
|
|
||||||
#define U_V16_CREATE_IDX \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_grp_type_name ON groups(type, name);"
|
|
||||||
|
|
||||||
#define U_V16_DROP_IDX_TITLE \
|
|
||||||
"DROP INDEX idx_title;"
|
|
||||||
|
|
||||||
#define U_V16_CREATE_IDX_TITLE \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_title ON files(disabled, media_kind, title_sort, data_kind);"
|
|
||||||
|
|
||||||
#define U_V16_DROP_IDX_SONGALBUMID \
|
|
||||||
"DROP INDEX idx_sali;"
|
|
||||||
|
|
||||||
#define U_V16_CREATE_IDX_SONGALBUMID \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_sali ON files(songalbumid, disabled, media_kind, album_sort, disc, track);"
|
|
||||||
|
|
||||||
#define U_V16_CREATE_IDX_GENRE \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_genre ON files(disabled, media_kind, genre, data_kind);"
|
|
||||||
|
|
||||||
#define U_V16_DROP_IDX_COMPOSER \
|
|
||||||
"DROP INDEX idx_composer;"
|
|
||||||
|
|
||||||
#define U_V16_CREATE_IDX_COMPOSER \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_composer ON files(disabled, media_kind, composer, data_kind);"
|
|
||||||
|
|
||||||
#define U_V16_SCVER \
|
|
||||||
"UPDATE admin SET value = '16' WHERE key = 'schema_version';"
|
|
||||||
|
|
||||||
static const struct db_init_query db_upgrade_v16_queries[] =
|
|
||||||
{
|
|
||||||
{ U_V16_DROP_IDX, "drop index type/persistentid" },
|
|
||||||
{ U_V16_DROP_TRG_NEW, "drop trigger new files" },
|
|
||||||
{ U_V16_DROP_TRG_UPDATE, "drop trigger update files" },
|
|
||||||
{ U_V16_DROP_TBL_GROUPS, "drop table groups" },
|
|
||||||
{ U_V16_CREATE_TBL_GROUPS, "create table groups" },
|
|
||||||
{ U_V16_CREATE_IDX, "create index type/name" },
|
|
||||||
{ U_V16_DROP_IDX_TITLE, "drop index title on files" },
|
|
||||||
{ U_V16_CREATE_IDX_TITLE, "create index title on files" },
|
|
||||||
{ U_V16_DROP_IDX_SONGALBUMID, "drop index songalbumid on files" },
|
|
||||||
{ U_V16_CREATE_IDX_SONGALBUMID, "create index songalbumid on files" },
|
|
||||||
{ U_V16_CREATE_IDX_GENRE, "create index genre on files" },
|
|
||||||
{ U_V16_DROP_IDX_COMPOSER, "drop index composer on files" },
|
|
||||||
{ U_V16_CREATE_IDX_COMPOSER, "create index composer on files" },
|
|
||||||
{ U_V16_SCVER, "set schema_version to 16" },
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
db_upgrade_v16_persistentid(enum group_type type, char *artist, char *album)
|
|
||||||
{
|
|
||||||
sqlite3_stmt *stmt;
|
|
||||||
char *query;
|
|
||||||
char *errmsg;
|
|
||||||
int id;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
id = 0;
|
|
||||||
|
|
||||||
query = sqlite3_mprintf("SELECT id FROM groups WHERE type = %d AND name = LOWER(TRIM(%Q)) || '==' || LOWER(TRIM(%Q));", type, (artist ? artist : ""), (album ? album : ""));
|
|
||||||
|
|
||||||
ret = sqlite3_prepare_v2(hdl, query, -1, &stmt, NULL);
|
|
||||||
if (ret != SQLITE_OK)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = sqlite3_step(stmt);
|
|
||||||
if (ret == SQLITE_ROW)
|
|
||||||
{
|
|
||||||
id = sqlite3_column_int(stmt, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ret != SQLITE_DONE)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Could not step: %s\n", sqlite3_errmsg(hdl));
|
|
||||||
}
|
|
||||||
id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
sqlite3_free(query);
|
|
||||||
|
|
||||||
if (id > 0)
|
|
||||||
return id;
|
|
||||||
|
|
||||||
query = sqlite3_mprintf("INSERT INTO groups (type, name) VALUES (%d, LOWER(TRIM(%Q)) || '==' || LOWER(TRIM(%Q)));", type, (artist ? artist : ""), (album ? album : ""));
|
|
||||||
ret = sqlite3_exec(hdl, query, NULL, NULL, &errmsg);
|
|
||||||
if (ret == SQLITE_OK)
|
|
||||||
{
|
|
||||||
id = sqlite3_last_insert_rowid(hdl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Error adding group: %s\n", errmsg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_free(query);
|
|
||||||
sqlite3_free(errmsg);
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
db_upgrade_v16(void)
|
|
||||||
{
|
|
||||||
sqlite3_stmt *stmt;
|
|
||||||
char *query;
|
|
||||||
char *uquery;
|
|
||||||
char *errmsg;
|
|
||||||
char *artist;
|
|
||||||
char *album;
|
|
||||||
int id;
|
|
||||||
int artistid;
|
|
||||||
int albumid;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
query = "SELECT id, album_artist, album FROM files;";
|
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query);
|
|
||||||
|
|
||||||
ret = sqlite3_prepare_v2(hdl, query, -1, &stmt, NULL);
|
|
||||||
if (ret != SQLITE_OK)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((ret = sqlite3_step(stmt)) == SQLITE_ROW)
|
|
||||||
{
|
|
||||||
id = sqlite3_column_int(stmt, 0);
|
|
||||||
artist = (char *)sqlite3_column_text(stmt, 1);
|
|
||||||
album = (char *)sqlite3_column_text(stmt, 2);
|
|
||||||
|
|
||||||
artistid = db_upgrade_v16_persistentid(G_ARTISTS, artist, NULL);
|
|
||||||
albumid = db_upgrade_v16_persistentid(G_ALBUMS, artist, album);
|
|
||||||
|
|
||||||
if (artistid <= 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
if (albumid <= 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
uquery = sqlite3_mprintf("UPDATE files SET songartistid = %d, songalbumid = %d WHERE id = %d;", artistid, albumid, id);
|
|
||||||
ret = sqlite3_exec(hdl, uquery, NULL, NULL, &errmsg);
|
|
||||||
if (ret != SQLITE_OK)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Error updating files: %s\n", errmsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_free(uquery);
|
|
||||||
sqlite3_free(errmsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
db_check_version(void)
|
db_check_version(void)
|
||||||
{
|
{
|
||||||
|
@ -5814,14 +5510,6 @@ db_check_version(void)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Database schema outdated, schema upgrade needed v%d -> v%d\n", cur_ver, SCHEMA_VERSION);
|
DPRINTF(E_LOG, L_DB, "Database schema outdated, schema upgrade needed v%d -> v%d\n", cur_ver, SCHEMA_VERSION);
|
||||||
|
|
||||||
ret = sqlite3_exec(hdl, "BEGIN TRANSACTION;", NULL, NULL, &errmsg);
|
|
||||||
if (ret != SQLITE_OK)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Error starting transaction: %s\n", errmsg);
|
|
||||||
sqlite3_free(errmsg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cur_ver)
|
switch (cur_ver)
|
||||||
{
|
{
|
||||||
case 10:
|
case 10:
|
||||||
|
@ -5873,15 +5561,6 @@ db_check_version(void)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
case 15:
|
|
||||||
ret = db_generic_upgrade(db_upgrade_v16_queries, sizeof(db_upgrade_v16_queries) / sizeof(db_upgrade_v16_queries[0]));
|
|
||||||
if (ret < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
ret = db_upgrade_v16();
|
|
||||||
if (ret < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -5889,14 +5568,6 @@ db_check_version(void)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sqlite3_exec(hdl, "END TRANSACTION;", NULL, NULL, &errmsg);
|
|
||||||
if (ret != SQLITE_OK)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Error ending transaction: %s\n", errmsg);
|
|
||||||
sqlite3_free(errmsg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* What about some housekeeping work, eh? */
|
/* What about some housekeeping work, eh? */
|
||||||
DPRINTF(E_INFO, L_DB, "Now vacuuming database, this may take some time...\n");
|
DPRINTF(E_INFO, L_DB, "Now vacuuming database, this may take some time...\n");
|
||||||
|
|
||||||
|
|
7
src/db.h
7
src/db.h
|
@ -458,6 +458,13 @@ db_pl_disable_bymatch(char *path, char *strip, uint32_t cookie);
|
||||||
int
|
int
|
||||||
db_pl_enable_bycookie(uint32_t cookie, char *path);
|
db_pl_enable_bycookie(uint32_t cookie, char *path);
|
||||||
|
|
||||||
|
/* Groups */
|
||||||
|
int
|
||||||
|
db_groups_clear(void);
|
||||||
|
|
||||||
|
int
|
||||||
|
db_group_persistentid_byid(int id, int64_t *persistentid);
|
||||||
|
|
||||||
/* Remotes */
|
/* Remotes */
|
||||||
int
|
int
|
||||||
db_pairing_add(struct pairing_info *pi);
|
db_pairing_add(struct pairing_info *pi);
|
||||||
|
|
|
@ -1125,6 +1125,21 @@ filescanner(void *arg)
|
||||||
pthread_exit(NULL);
|
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 songartistids and 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_songartistid();
|
||||||
|
db_files_update_songalbumid();
|
||||||
|
|
||||||
if (cfg_getbool(cfg_getsec(cfg, "library"), "filescan_disable"))
|
if (cfg_getbool(cfg_getsec(cfg, "library"), "filescan_disable"))
|
||||||
bulk_scan(F_SCAN_BULK | F_SCAN_FAST);
|
bulk_scan(F_SCAN_BULK | F_SCAN_FAST);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue