mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-28 08:05:56 -05:00
[db/filescanner] Upgrade database to v19.08 and support limit/order by
in smart playlist files
This commit is contained in:
parent
5189fe2305
commit
6bdcda1524
62
src/db.c
62
src/db.c
@ -178,6 +178,8 @@ static const struct col_type_map pli_cols_map[] =
|
||||
{ pli_offsetof(virtual_path), DB_TYPE_STRING },
|
||||
{ pli_offsetof(parent_id), DB_TYPE_INT },
|
||||
{ pli_offsetof(directory_id), DB_TYPE_INT },
|
||||
{ pli_offsetof(query_orderby),DB_TYPE_STRING },
|
||||
{ pli_offsetof(query_limit), DB_TYPE_INT },
|
||||
|
||||
/* items is computed on the fly */
|
||||
};
|
||||
@ -268,6 +270,8 @@ static const ssize_t dbpli_cols_map[] =
|
||||
dbpli_offsetof(virtual_path),
|
||||
dbpli_offsetof(parent_id),
|
||||
dbpli_offsetof(directory_id),
|
||||
dbpli_offsetof(query_orderby),
|
||||
dbpli_offsetof(query_limit),
|
||||
|
||||
/* items is computed on the fly */
|
||||
};
|
||||
@ -1584,18 +1588,54 @@ db_build_query_plitems_plain(struct query_params *qp)
|
||||
}
|
||||
|
||||
static char *
|
||||
db_build_query_plitems_smart(struct query_params *qp, char *smartpl_query)
|
||||
db_build_query_plitems_smart(struct query_params *qp, struct playlist_info *pli)
|
||||
{
|
||||
struct query_clause *qc;
|
||||
char *count;
|
||||
char *query;
|
||||
bool free_orderby = false;
|
||||
|
||||
if (pli->query_limit > 0)
|
||||
{
|
||||
if (qp->idx_type == I_SUB)
|
||||
{
|
||||
if (pli->query_limit > qp->offset + qp->limit)
|
||||
qp->limit = pli->query_limit;
|
||||
}
|
||||
else if (qp->idx_type == I_NONE)
|
||||
{
|
||||
qp->idx_type = I_SUB;
|
||||
qp->limit = pli->query_limit;
|
||||
qp->offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF(E_WARN, L_DB, "Cannot append limit from smart playlist '%s' to query\n", pli->path);
|
||||
}
|
||||
}
|
||||
|
||||
if (pli->query_orderby)
|
||||
{
|
||||
if (!qp->orderby && qp->sort == S_NONE)
|
||||
{
|
||||
qp->orderby = strdup(pli->query_orderby);
|
||||
free_orderby = true;
|
||||
}
|
||||
else
|
||||
DPRINTF(E_WARN, L_DB, "Cannot append order by from smart playlist '%s' to query\n", pli->path);
|
||||
}
|
||||
|
||||
qc = db_build_query_clause(qp);
|
||||
if (free_orderby)
|
||||
{
|
||||
free(qp->orderby);
|
||||
qp->orderby = NULL;
|
||||
}
|
||||
if (!qc)
|
||||
return NULL;
|
||||
|
||||
count = sqlite3_mprintf("SELECT COUNT(*) FROM files f %s AND %s;", qc->where, smartpl_query);
|
||||
query = sqlite3_mprintf("SELECT f.* FROM files f %s AND %s %s %s;", qc->where, smartpl_query, qc->order, qc->index);
|
||||
count = sqlite3_mprintf("SELECT COUNT(*) FROM files f %s AND %s LIMIT %d;", qc->where, pli->query, pli->query_limit);
|
||||
query = sqlite3_mprintf("SELECT f.* FROM files f %s AND %s %s %s;", qc->where, pli->query, qc->order, qc->index);
|
||||
|
||||
db_free_query_clause(qc);
|
||||
|
||||
@ -1622,7 +1662,7 @@ db_build_query_plitems(struct query_params *qp)
|
||||
{
|
||||
case PL_SPECIAL:
|
||||
case PL_SMART:
|
||||
query = db_build_query_plitems_smart(qp, pli->query);
|
||||
query = db_build_query_plitems_smart(qp, pli);
|
||||
break;
|
||||
|
||||
case PL_PLAIN:
|
||||
@ -3376,8 +3416,9 @@ int
|
||||
db_pl_add(struct playlist_info *pli, int *id)
|
||||
{
|
||||
#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, directory_id)" \
|
||||
" VALUES (TRIM(%Q), %d, '%q', %" PRIi64 ", %d, '%q', %d, %d, %d, '%q', %d);"
|
||||
#define QADD_TMPL "INSERT INTO playlists (title, type, query, db_timestamp, disabled, path, idx, special_id, " \
|
||||
" parent_id, virtual_path, directory_id, query_orderby, query_limit)" \
|
||||
" VALUES (TRIM(%Q), %d, '%q', %" PRIi64 ", %d, '%q', %d, %d, %d, '%q', %d, %Q, %d);"
|
||||
char *query;
|
||||
char *errmsg;
|
||||
int ret;
|
||||
@ -3403,7 +3444,8 @@ db_pl_add(struct playlist_info *pli, int *id)
|
||||
/* Add */
|
||||
query = sqlite3_mprintf(QADD_TMPL,
|
||||
pli->title, pli->type, pli->query, (int64_t)time(NULL), pli->disabled, STR(pli->path),
|
||||
pli->index, pli->special_id, pli->parent_id, pli->virtual_path, pli->directory_id);
|
||||
pli->index, pli->special_id, pli->parent_id, pli->virtual_path, pli->directory_id,
|
||||
pli->query_orderby, pli->query_limit);
|
||||
|
||||
if (!query)
|
||||
{
|
||||
@ -3468,14 +3510,16 @@ int
|
||||
db_pl_update(struct playlist_info *pli)
|
||||
{
|
||||
#define Q_TMPL "UPDATE playlists SET title = TRIM(%Q), type = %d, query = '%q', db_timestamp = %" PRIi64 ", disabled = %d, " \
|
||||
" path = '%q', idx = %d, special_id = %d, parent_id = %d, virtual_path = '%q', directory_id = %d " \
|
||||
" path = '%q', idx = %d, special_id = %d, parent_id = %d, virtual_path = '%q', directory_id = %d, " \
|
||||
" query_orderby = %Q, query_limit = %d " \
|
||||
" WHERE id = %d;"
|
||||
char *query;
|
||||
int ret;
|
||||
|
||||
query = sqlite3_mprintf(Q_TMPL,
|
||||
pli->title, pli->type, pli->query, (int64_t)time(NULL), pli->disabled, STR(pli->path),
|
||||
pli->index, pli->special_id, pli->parent_id, pli->virtual_path, pli->directory_id, pli->id);
|
||||
pli->index, pli->special_id, pli->parent_id, pli->virtual_path, pli->directory_id,
|
||||
pli->query_orderby, pli->query_limit, pli->id);
|
||||
|
||||
ret = db_query_run(query, 1, 0);
|
||||
|
||||
|
4
src/db.h
4
src/db.h
@ -247,6 +247,8 @@ struct playlist_info {
|
||||
char *virtual_path; /* virtual path of underlying playlist */
|
||||
uint32_t parent_id; /* Id of parent playlist if the playlist is nested */
|
||||
uint32_t directory_id; /* Id of directory */
|
||||
char *query_orderby; /* order by clause if it is a smart playlist */
|
||||
uint32_t query_limit; /* limit if it is a smart playlist */
|
||||
};
|
||||
|
||||
#define pli_offsetof(field) offsetof(struct playlist_info, field)
|
||||
@ -266,6 +268,8 @@ struct db_playlist_info {
|
||||
char *virtual_path;
|
||||
char *parent_id;
|
||||
char *directory_id;
|
||||
char *query_orderby;
|
||||
char *query_limit;
|
||||
};
|
||||
|
||||
#define dbpli_offsetof(field) offsetof(struct db_playlist_info, field)
|
||||
|
@ -109,7 +109,9 @@
|
||||
" special_id INTEGER DEFAULT 0," \
|
||||
" virtual_path VARCHAR(4096)," \
|
||||
" parent_id INTEGER DEFAULT 0," \
|
||||
" directory_id INTEGER DEFAULT 0" \
|
||||
" directory_id INTEGER DEFAULT 0," \
|
||||
" query_orderby VARCHAR(1024)," \
|
||||
" query_limit INTEGER DEFAULT 0" \
|
||||
");"
|
||||
|
||||
#define T_PLITEMS \
|
||||
|
@ -26,7 +26,7 @@
|
||||
* is a major upgrade. In other words minor version upgrades permit downgrading
|
||||
* forked-daapd after the database was upgraded. */
|
||||
#define SCHEMA_VERSION_MAJOR 19
|
||||
#define SCHEMA_VERSION_MINOR 07
|
||||
#define SCHEMA_VERSION_MINOR 8
|
||||
|
||||
int
|
||||
db_init_indices(sqlite3 *hdl);
|
||||
|
@ -1634,6 +1634,23 @@ static const struct db_upgrade_query db_upgrade_V1907_queries[] =
|
||||
};
|
||||
|
||||
|
||||
#define U_V1908_ALTER_PL_ADD_ORDERBY \
|
||||
"ALTER TABLE playlists ADD COLUMN query_orderby VARCHAR(1024);"
|
||||
#define U_V1908_ALTER_PL_ADD_LIMIT \
|
||||
"ALTER TABLE playlists ADD COLUMN query_limit INTEGER DEFAULT 0;"
|
||||
|
||||
#define U_V1908_SCVER_MINOR \
|
||||
"UPDATE admin SET value = '08' WHERE key = 'schema_version_minor';"
|
||||
|
||||
static const struct db_upgrade_query db_upgrade_v1908_queries[] =
|
||||
{
|
||||
{ U_V1908_ALTER_PL_ADD_ORDERBY, "alter table playlists add column query_orderby" },
|
||||
{ U_V1908_ALTER_PL_ADD_LIMIT, "alter table playlists add column query_limit" },
|
||||
|
||||
{ U_V1908_SCVER_MINOR, "set schema_version_minor to 08" },
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
db_upgrade(sqlite3 *hdl, int db_ver)
|
||||
{
|
||||
@ -1793,6 +1810,13 @@ db_upgrade(sqlite3 *hdl, int db_ver)
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 1907:
|
||||
ret = db_generic_upgrade(hdl, db_upgrade_v1908_queries, ARRAY_SIZE(db_upgrade_v1908_queries));
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -80,14 +80,17 @@ scan_smartpl(const char *file, time_t mtime, int dir_id)
|
||||
return;
|
||||
}
|
||||
|
||||
if (pli->title)
|
||||
free(pli->title);
|
||||
free(pli->title);
|
||||
pli->title = strdup(smartpl.title);
|
||||
|
||||
if (pli->query)
|
||||
free(pli->query);
|
||||
free(pli->query);
|
||||
pli->query = strdup(smartpl.query_where);
|
||||
|
||||
free(pli->query_orderby);
|
||||
pli->query_orderby = safe_strdup(smartpl.order_by);
|
||||
|
||||
pli->query_limit = smartpl.limit;
|
||||
|
||||
free_smartpl(&smartpl, 1);
|
||||
|
||||
if (pli->id)
|
||||
|
Loading…
Reference in New Issue
Block a user