2015-12-19 01:51:10 -05:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2015 Christian Meffert <christian.meffert@googlemail.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sqlite3.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
|
|
|
#include "logger.h"
|
|
|
|
#include "misc.h"
|
|
|
|
|
|
|
|
|
|
|
|
struct db_upgrade_query {
|
|
|
|
char *query;
|
|
|
|
char *desc;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int
|
2019-01-01 15:34:29 -05:00
|
|
|
db_drop_from_master(sqlite3 *hdl, const char *type, const char *prefix)
|
2015-12-19 01:51:10 -05:00
|
|
|
{
|
2019-01-01 15:34:29 -05:00
|
|
|
#define Q_TMPL_SELECT "SELECT name FROM sqlite_master WHERE type == lower('%s') AND name LIKE '%s_%%';"
|
|
|
|
#define Q_TMPL_DROP "DROP %s %q;"
|
2015-12-19 01:51:10 -05:00
|
|
|
sqlite3_stmt *stmt;
|
|
|
|
char *errmsg;
|
|
|
|
char *query;
|
2019-01-01 15:34:29 -05:00
|
|
|
char *name[256];
|
2015-12-19 01:51:10 -05:00
|
|
|
int ret;
|
|
|
|
int i;
|
|
|
|
int n;
|
|
|
|
|
2019-01-01 15:34:29 -05:00
|
|
|
query = sqlite3_mprintf(Q_TMPL_SELECT, type, prefix);
|
2015-12-19 01:51:10 -05:00
|
|
|
|
2019-01-01 15:34:29 -05:00
|
|
|
DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query);
|
|
|
|
|
|
|
|
ret = sqlite3_prepare_v2(hdl, query, -1, &stmt, NULL);
|
2015-12-19 01:51:10 -05:00
|
|
|
if (ret != SQLITE_OK)
|
|
|
|
{
|
2019-01-01 15:34:29 -05:00
|
|
|
DPRINTF(E_LOG, L_DB, "Could not prepare statement '%s': %s\n", query, sqlite3_errmsg(hdl));
|
|
|
|
sqlite3_free(query);
|
2015-12-19 01:51:10 -05:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
while ((ret = sqlite3_step(stmt)) == SQLITE_ROW)
|
|
|
|
{
|
2019-01-01 15:34:29 -05:00
|
|
|
name[n] = strdup((char *)sqlite3_column_text(stmt, 0));
|
2015-12-19 01:51:10 -05:00
|
|
|
n++;
|
|
|
|
}
|
|
|
|
|
2019-01-01 15:34:29 -05:00
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
2015-12-19 01:51:10 -05:00
|
|
|
if (ret != SQLITE_DONE)
|
|
|
|
{
|
2019-01-01 15:34:29 -05:00
|
|
|
DPRINTF(E_LOG, L_DB, "Could not step '%s': %s\n", query, sqlite3_errmsg(hdl));
|
|
|
|
sqlite3_free(query);
|
2018-12-17 02:35:43 -05:00
|
|
|
ret = -1;
|
|
|
|
goto out;
|
2015-12-19 01:51:10 -05:00
|
|
|
}
|
|
|
|
|
2019-01-01 15:34:29 -05:00
|
|
|
sqlite3_free(query);
|
2015-12-19 01:51:10 -05:00
|
|
|
|
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
{
|
2019-01-01 15:34:29 -05:00
|
|
|
query = sqlite3_mprintf(Q_TMPL_DROP, type, name[i]);
|
2015-12-19 01:51:10 -05:00
|
|
|
|
|
|
|
DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query);
|
|
|
|
|
|
|
|
ret = sqlite3_exec(hdl, query, NULL, NULL, &errmsg);
|
|
|
|
if (ret != SQLITE_OK)
|
|
|
|
{
|
|
|
|
DPRINTF(E_LOG, L_DB, "DB error while running '%s': %s\n", query, errmsg);
|
|
|
|
|
|
|
|
sqlite3_free(errmsg);
|
2018-12-17 02:35:43 -05:00
|
|
|
sqlite3_free(query);
|
|
|
|
|
|
|
|
ret = -1;
|
|
|
|
goto out;
|
2015-12-19 01:51:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
sqlite3_free(query);
|
|
|
|
}
|
|
|
|
|
2018-12-17 02:35:43 -05:00
|
|
|
out:
|
|
|
|
for (i = 0; i < n; i++)
|
2019-01-01 15:34:29 -05:00
|
|
|
free(name[i]);
|
2018-12-29 18:27:47 -05:00
|
|
|
|
2019-01-01 15:34:29 -05:00
|
|
|
return ret;
|
|
|
|
#undef Q_TMPL_DROP
|
|
|
|
#undef Q_TMPL_SELECT
|
2018-12-29 18:27:47 -05:00
|
|
|
}
|
|
|
|
|
2015-12-19 01:51:10 -05:00
|
|
|
static int
|
2018-09-04 14:07:05 -04:00
|
|
|
db_generic_upgrade(sqlite3 *hdl, const struct db_upgrade_query *queries, unsigned int nqueries)
|
2015-12-19 01:51:10 -05:00
|
|
|
{
|
|
|
|
char *errmsg;
|
|
|
|
int i;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
for (i = 0; i < nqueries; i++, queries++)
|
|
|
|
{
|
|
|
|
DPRINTF(E_DBG, L_DB, "DB upgrade query: %s\n", queries->desc);
|
|
|
|
|
|
|
|
ret = sqlite3_exec(hdl, queries->query, NULL, NULL, &errmsg);
|
|
|
|
if (ret != SQLITE_OK)
|
|
|
|
{
|
|
|
|
DPRINTF(E_FATAL, L_DB, "DB upgrade error: %s\n", errmsg);
|
|
|
|
|
|
|
|
sqlite3_free(errmsg);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-12-29 18:27:47 -05:00
|
|
|
/* The below implements relevant parts of SQLITE's recommended 12 steps to
|
|
|
|
* altering a table. It is not required to use this function if you just want to
|
|
|
|
* add a column). The steps:
|
|
|
|
* 1. If foreign key constraints are enabled, disable them using PRAGMA
|
|
|
|
* foreign_keys=OFF.
|
|
|
|
* 2. Start a transaction.
|
|
|
|
* 3. Remember the format of all indexes and triggers associated with table X.
|
|
|
|
* This information will be needed in step 8 below. One way to do this is to
|
|
|
|
* run a query like the following: SELECT type, sql FROM sqlite_master WHERE
|
|
|
|
* tbl_name='X'.
|
|
|
|
* 4. Use CREATE TABLE to construct a new table "new_X" that is in the desired
|
|
|
|
* revised format of table X. Make sure that the name "new_X" does not
|
|
|
|
* collide with any existing table name, of course.
|
|
|
|
* 5. Transfer content from X into new_X using a statement like: INSERT INTO
|
|
|
|
* new_X SELECT ... FROM X.
|
|
|
|
* 6. Drop the old table X: DROP TABLE X.
|
|
|
|
* 7. Change the name of new_X to X using: ALTER TABLE new_X RENAME TO X.
|
|
|
|
* 8. Use CREATE INDEX and CREATE TRIGGER to reconstruct indexes and triggers
|
|
|
|
* associated with table X. Perhaps use the old format of the triggers and
|
|
|
|
* indexes saved from step 3 above as a guide, making changes as appropriate
|
|
|
|
* for the alteration.
|
|
|
|
* 9. If any views refer to table X in a way that is affected by the schema
|
|
|
|
* change, then drop those views using DROP VIEW and recreate them with
|
|
|
|
* whatever changes are necessary to accommodate the schema change using
|
|
|
|
* CREATE VIEW.
|
|
|
|
* 10. If foreign key constraints were originally enabled then run PRAGMA
|
|
|
|
* foreign_key_check to verify that the schema change did not break any
|
|
|
|
* foreign key constraints.
|
|
|
|
* 11. Commit the transaction started in step 2.
|
|
|
|
* 12. If foreign keys constraints were originally enabled, reenable them now.
|
|
|
|
* Source: https://www.sqlite.org/lang_altertable.html
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
db_table_upgrade(sqlite3 *hdl, const char *name, const char *newtablequery)
|
|
|
|
{
|
|
|
|
sqlite3_stmt *stmt;
|
|
|
|
char *query;
|
|
|
|
char *errmsg;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
DPRINTF(E_LOG, L_DB, "Upgrading %s table...\n", name);
|
|
|
|
|
|
|
|
// Step 1: Skipped, no foreign key constraints
|
|
|
|
// Step 2: Skipped, we are already in a transaction
|
|
|
|
// Step 3: Nothing to do, we already know our indexes and triggers
|
|
|
|
// Step 4: Create the new table using table definition from db_init, but with
|
|
|
|
// new_ prefixed to the name
|
|
|
|
CHECK_NULL(L_DB, query = sqlite3_mprintf(newtablequery));
|
|
|
|
|
|
|
|
ret = sqlite3_exec(hdl, query, NULL, NULL, &errmsg);
|
|
|
|
if (ret != SQLITE_OK)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
sqlite3_free(query);
|
|
|
|
|
|
|
|
// Step 5: Transfer content - note: no support for changed column names or dropped columns!
|
|
|
|
// This will select the column names from our new table (which where given to us in newtablequery)
|
|
|
|
CHECK_NULL(L_DB, query = sqlite3_mprintf("SELECT group_concat(name) FROM pragma_table_info('new_%s');", name));
|
|
|
|
|
|
|
|
ret = sqlite3_prepare_v2(hdl, query, -1, &stmt, NULL);
|
|
|
|
if (ret != SQLITE_OK)
|
|
|
|
{
|
|
|
|
errmsg = sqlite3_mprintf("%s", sqlite3_errmsg(hdl));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = sqlite3_step(stmt);
|
|
|
|
if (ret != SQLITE_ROW)
|
|
|
|
{
|
|
|
|
if (ret == SQLITE_DONE)
|
|
|
|
errmsg = sqlite3_mprintf("Getting col names from pragma_table_info returned nothing");
|
|
|
|
else
|
|
|
|
errmsg = sqlite3_mprintf("%s", sqlite3_errmsg(hdl));
|
|
|
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
sqlite3_free(query);
|
|
|
|
|
|
|
|
CHECK_NULL(L_DB, query = sqlite3_mprintf("INSERT INTO new_%s SELECT %s FROM %s;", name, sqlite3_column_text(stmt, 0), name));
|
|
|
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
|
|
|
ret = sqlite3_exec(hdl, query, NULL, NULL, &errmsg);
|
|
|
|
if (ret != SQLITE_OK)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
sqlite3_free(query);
|
|
|
|
|
|
|
|
// Step 6: Drop old table
|
|
|
|
CHECK_NULL(L_DB, query = sqlite3_mprintf("DROP TABLE %s;", name));
|
|
|
|
|
|
|
|
ret = sqlite3_exec(hdl, query, NULL, NULL, &errmsg);
|
|
|
|
if (ret != SQLITE_OK)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
sqlite3_free(query);
|
|
|
|
|
|
|
|
// Step 7: Give the new table the final name
|
|
|
|
CHECK_NULL(L_DB, query = sqlite3_mprintf("ALTER TABLE new_%s RENAME TO %s;", name, name));
|
|
|
|
|
|
|
|
ret = sqlite3_exec(hdl, query, NULL, NULL, &errmsg);
|
|
|
|
if (ret != SQLITE_OK)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
sqlite3_free(query);
|
|
|
|
|
|
|
|
// Step 8: Skipped, will be done by db_check_version in db.c
|
|
|
|
// Step 9: Skipped, no views
|
|
|
|
// Step 10: Skipped, no foreign key constraints
|
|
|
|
// Step 11: Skipped, our caller takes care of COMMIT
|
|
|
|
// Step 12: Skipped, no foreign key constraints
|
|
|
|
|
|
|
|
DPRINTF(E_LOG, L_DB, "Upgrade of %s table complete!\n", name);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
DPRINTF(E_LOG, L_DB, "DB error %d running query '%s': %s\n", ret, query, errmsg);
|
|
|
|
sqlite3_free(query);
|
|
|
|
sqlite3_free(errmsg);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 17.00 -> 18.00 ------------------------------ */
|
|
|
|
|
2015-12-19 01:51:10 -05:00
|
|
|
/* Change playlist type enumeration and recreate filelist view (include smart
|
|
|
|
* playlists in view)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define U_V18_PL_TYPE_CHANGE_PLAIN \
|
|
|
|
"UPDATE playlists SET type = 3 WHERE type = 0;"
|
|
|
|
#define U_V18_PL_TYPE_CHANGE_SPECIAL \
|
|
|
|
"UPDATE playlists SET type = 0 WHERE type = 2;"
|
|
|
|
#define U_V18_DROP_VIEW_FILELIST \
|
|
|
|
"DROP VIEW IF EXISTS filelist;"
|
|
|
|
#define U_V18_CREATE_VIEW_FILELIST \
|
|
|
|
"CREATE VIEW IF NOT EXISTS filelist as" \
|
|
|
|
" SELECT " \
|
|
|
|
" virtual_path, time_modified, 3 as type " \
|
|
|
|
" FROM files WHERE disabled = 0" \
|
|
|
|
" UNION " \
|
|
|
|
" SELECT " \
|
|
|
|
" virtual_path, db_timestamp, 1 as type " \
|
|
|
|
" FROM playlists where disabled = 0 AND type IN (2, 3)" \
|
|
|
|
";"
|
|
|
|
|
|
|
|
#define U_V18_SCVER_MAJOR \
|
|
|
|
"UPDATE admin SET value = '18' WHERE key = 'schema_version_major';"
|
|
|
|
#define U_V18_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '00' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v18_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V18_PL_TYPE_CHANGE_PLAIN, "changing numbering of plain playlists 0 -> 3" },
|
|
|
|
{ U_V18_PL_TYPE_CHANGE_SPECIAL, "changing numbering of default playlists 2 -> 0" },
|
|
|
|
{ U_V18_DROP_VIEW_FILELIST, "dropping view filelist" },
|
|
|
|
{ U_V18_CREATE_VIEW_FILELIST, "creating view filelist" },
|
|
|
|
|
|
|
|
{ U_V18_SCVER_MAJOR, "set schema_version_major to 18" },
|
|
|
|
{ U_V18_SCVER_MINOR, "set schema_version_minor to 00" },
|
|
|
|
};
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 18.00 -> 18.01 ------------------------------ */
|
2015-12-19 01:51:10 -05:00
|
|
|
/* Change virtual_path for playlists: remove file extension
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define U_V1801_UPDATE_PLAYLISTS_M3U \
|
|
|
|
"UPDATE playlists SET virtual_path = replace(virtual_path, '.m3u', '');"
|
|
|
|
#define U_V1801_UPDATE_PLAYLISTS_PLS \
|
|
|
|
"UPDATE playlists SET virtual_path = replace(virtual_path, '.pls', '');"
|
|
|
|
#define U_V1801_UPDATE_PLAYLISTS_SMARTPL \
|
|
|
|
"UPDATE playlists SET virtual_path = replace(virtual_path, '.smartpl', '');"
|
|
|
|
|
|
|
|
#define U_V1801_SCVER_MAJOR \
|
|
|
|
"UPDATE admin SET value = '18' WHERE key = 'schema_version_major';"
|
|
|
|
#define U_V1801_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '01' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v1801_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V1801_UPDATE_PLAYLISTS_M3U, "update table playlists" },
|
|
|
|
{ U_V1801_UPDATE_PLAYLISTS_PLS, "update table playlists" },
|
|
|
|
{ U_V1801_UPDATE_PLAYLISTS_SMARTPL, "update table playlists" },
|
|
|
|
|
|
|
|
{ U_V1801_SCVER_MAJOR, "set schema_version_major to 18" },
|
|
|
|
{ U_V1801_SCVER_MINOR, "set schema_version_minor to 01" },
|
|
|
|
};
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 18.01 -> 19.00 ------------------------------ */
|
2015-12-27 01:16:50 -05:00
|
|
|
/* Replace 'filelist' view with new table 'directories'
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define U_V1900_CREATE_TABLE_DIRECTORIES \
|
|
|
|
"CREATE TABLE IF NOT EXISTS directories (" \
|
|
|
|
" id INTEGER PRIMARY KEY NOT NULL," \
|
|
|
|
" virtual_path VARCHAR(4096) NOT NULL," \
|
|
|
|
" db_timestamp INTEGER DEFAULT 0," \
|
|
|
|
" disabled INTEGER DEFAULT 0," \
|
|
|
|
" parent_id INTEGER DEFAULT 0" \
|
|
|
|
");"
|
|
|
|
|
|
|
|
#define U_V1900_DROP_VIEW_FILELIST \
|
|
|
|
"DROP VIEW IF EXISTS filelist;"
|
|
|
|
#define U_V1900_ALTER_PL_ADD_DIRECTORYID \
|
|
|
|
"ALTER TABLE playlists ADD COLUMN directory_id INTEGER DEFAULT 0;"
|
|
|
|
#define U_V1900_ALTER_FILES_ADD_DIRECTORYID \
|
|
|
|
"ALTER TABLE files ADD COLUMN directory_id INTEGER DEFAULT 0;"
|
2016-01-29 13:46:56 -05:00
|
|
|
#define U_V1900_ALTER_FILES_ADD_DATERELEASED \
|
|
|
|
"ALTER TABLE files ADD COLUMN date_released INTEGER DEFAULT 0;"
|
|
|
|
#define U_V1900_ALTER_SPEAKERS_ADD_NAME \
|
|
|
|
"ALTER TABLE speakers ADD COLUMN name VARCHAR(255) DEFAULT NULL;"
|
2015-12-27 01:16:50 -05:00
|
|
|
|
|
|
|
#define U_V1900_INSERT_DIR1 \
|
|
|
|
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \
|
|
|
|
" VALUES (1, '/', 0, 0, 0);"
|
2016-01-24 12:45:28 -05:00
|
|
|
#define U_V1900_INSERT_DIR2 \
|
|
|
|
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \
|
|
|
|
" VALUES (2, '/file:', 0, 0, 1);"
|
|
|
|
#define U_V1900_INSERT_DIR3 \
|
|
|
|
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \
|
|
|
|
" VALUES (3, '/http:', 0, 0, 1);"
|
|
|
|
#define U_V1900_INSERT_DIR4 \
|
|
|
|
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \
|
2016-01-30 01:27:20 -05:00
|
|
|
" VALUES (4, '/spotify:', 0, 4294967296, 1);"
|
2015-12-27 01:16:50 -05:00
|
|
|
|
|
|
|
#define U_V1900_SCVER_MAJOR \
|
|
|
|
"UPDATE admin SET value = '19' WHERE key = 'schema_version_major';"
|
|
|
|
#define U_V1900_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '00' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v1900_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V1900_CREATE_TABLE_DIRECTORIES, "create table directories" },
|
|
|
|
{ U_V1900_ALTER_PL_ADD_DIRECTORYID, "alter table pl add column directory_id" },
|
|
|
|
{ U_V1900_ALTER_FILES_ADD_DIRECTORYID, "alter table files add column directory_id" },
|
2016-01-29 13:46:56 -05:00
|
|
|
{ U_V1900_ALTER_FILES_ADD_DATERELEASED,"alter table files add column date_released" },
|
|
|
|
{ U_V1900_ALTER_SPEAKERS_ADD_NAME, "alter table speakers add column name" },
|
2015-12-27 01:16:50 -05:00
|
|
|
{ U_V1900_INSERT_DIR1, "insert root directory" },
|
2016-01-24 12:45:28 -05:00
|
|
|
{ U_V1900_INSERT_DIR2, "insert /file: directory" },
|
|
|
|
{ U_V1900_INSERT_DIR3, "insert /htttp: directory" },
|
|
|
|
{ U_V1900_INSERT_DIR4, "insert /spotify: directory" },
|
2015-12-27 01:16:50 -05:00
|
|
|
{ U_V1900_DROP_VIEW_FILELIST, "drop view directories" },
|
|
|
|
|
|
|
|
{ U_V1900_SCVER_MAJOR, "set schema_version_major to 19" },
|
|
|
|
{ U_V1900_SCVER_MINOR, "set schema_version_minor to 00" },
|
|
|
|
};
|
|
|
|
|
|
|
|
int
|
|
|
|
db_upgrade_v19_directory_id(sqlite3 *hdl, char *virtual_path)
|
|
|
|
{
|
|
|
|
sqlite3_stmt *stmt;
|
|
|
|
char *query;
|
|
|
|
int id;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
query = sqlite3_mprintf("SELECT d.id FROM directories d WHERE d.disabled = 0 AND d.virtual_path = '%q';", virtual_path);
|
|
|
|
if (!query)
|
|
|
|
{
|
|
|
|
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = sqlite3_prepare_v2(hdl, query, -1, &stmt, NULL);
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
DPRINTF(E_LOG, L_DB, "Error preparing query '%s'\n", query);
|
|
|
|
sqlite3_free(query);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = sqlite3_step(stmt);
|
|
|
|
|
|
|
|
if (ret == SQLITE_ROW)
|
|
|
|
id = sqlite3_column_int(stmt, 0);
|
|
|
|
else if (ret == SQLITE_DONE)
|
|
|
|
id = 0; // Not found
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINTF(E_LOG, L_DB, "Error stepping query '%s'\n", query);
|
|
|
|
sqlite3_free(query);
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sqlite3_free(query);
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
db_upgrade_v19_insert_directory(sqlite3 *hdl, char *virtual_path, int parent_id)
|
|
|
|
{
|
|
|
|
char *query;
|
|
|
|
char *errmsg;
|
|
|
|
int id;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
query = sqlite3_mprintf(
|
|
|
|
"INSERT INTO directories (virtual_path, db_timestamp, disabled, parent_id) VALUES (TRIM(%Q), %d, %d, %d);",
|
|
|
|
virtual_path, (uint64_t)time(NULL), 0, parent_id);
|
|
|
|
|
|
|
|
if (!query)
|
|
|
|
{
|
|
|
|
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = sqlite3_exec(hdl, query, NULL, NULL, &errmsg);
|
|
|
|
if (ret != SQLITE_OK)
|
|
|
|
{
|
|
|
|
DPRINTF(E_LOG, L_DB, "Query error: %s\n", errmsg);
|
|
|
|
|
|
|
|
sqlite3_free(errmsg);
|
|
|
|
sqlite3_free(query);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sqlite3_free(query);
|
|
|
|
|
|
|
|
id = (int)sqlite3_last_insert_rowid(hdl);
|
|
|
|
|
|
|
|
DPRINTF(E_DBG, L_DB, "Added directory %s with id %d\n", virtual_path, id);
|
|
|
|
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
db_upgrade_v19_insert_parent_directories(sqlite3 *hdl, char *virtual_path)
|
|
|
|
{
|
|
|
|
char *ptr;
|
|
|
|
int dir_id;
|
|
|
|
int parent_id;
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
|
|
|
|
// The root directoy ID
|
|
|
|
parent_id = 1;
|
|
|
|
|
|
|
|
ptr = virtual_path + 1; // Skip first '/'
|
|
|
|
while (ptr && (ptr = strchr(ptr, '/')))
|
|
|
|
{
|
|
|
|
strncpy(buf, virtual_path, (ptr - virtual_path));
|
|
|
|
buf[(ptr - virtual_path)] = '\0';
|
|
|
|
|
|
|
|
dir_id = db_upgrade_v19_directory_id(hdl, buf);
|
|
|
|
|
|
|
|
if (dir_id < 0)
|
|
|
|
{
|
|
|
|
DPRINTF(E_LOG, L_SCAN, "Select of directory failed '%s'\n", buf);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else if (dir_id == 0)
|
|
|
|
{
|
|
|
|
dir_id = db_upgrade_v19_insert_directory(hdl, buf, parent_id);
|
|
|
|
if (dir_id < 0)
|
|
|
|
{
|
|
|
|
DPRINTF(E_LOG, L_SCAN, "Insert of directory failed '%s'\n", buf);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
parent_id = dir_id;
|
|
|
|
ptr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
db_upgrade_v19(sqlite3 *hdl)
|
|
|
|
{
|
|
|
|
sqlite3_stmt *stmt;
|
|
|
|
char *query;
|
|
|
|
char *uquery;
|
|
|
|
char *errmsg;
|
|
|
|
int id;
|
|
|
|
char *virtual_path;
|
|
|
|
int dir_id;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
query = "SELECT id, virtual_path 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);
|
|
|
|
virtual_path = (char *)sqlite3_column_text(stmt, 1);
|
|
|
|
|
|
|
|
dir_id = db_upgrade_v19_insert_parent_directories(hdl, virtual_path);
|
|
|
|
if (dir_id < 0)
|
|
|
|
{
|
|
|
|
DPRINTF(E_LOG, L_DB, "Error processing parent directories for file: %s\n", virtual_path);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uquery = sqlite3_mprintf("UPDATE files SET directory_id = %d WHERE id = %d;", dir_id, 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);
|
|
|
|
|
|
|
|
|
|
|
|
query = "SELECT id, virtual_path FROM playlists WHERE type = 2 OR type = 3;"; //Only update normal and smart playlists
|
|
|
|
|
|
|
|
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);
|
|
|
|
virtual_path = (char *)sqlite3_column_text(stmt, 1);
|
|
|
|
|
|
|
|
dir_id = db_upgrade_v19_insert_parent_directories(hdl, virtual_path);
|
|
|
|
if (dir_id < 0)
|
|
|
|
{
|
|
|
|
DPRINTF(E_LOG, L_DB, "Error processing parent directories for file: %s\n", virtual_path);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uquery = sqlite3_mprintf("UPDATE files SET directory_id = %d WHERE id = %d;", dir_id, 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;
|
|
|
|
}
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 19.00 -> 19.01 ------------------------------ */
|
2016-11-04 10:09:24 -04:00
|
|
|
/* Create new table queue for persistent playqueue
|
|
|
|
*/
|
|
|
|
|
2016-12-09 01:07:05 -05:00
|
|
|
#define U_V1901_CREATE_TABLE_QUEUE \
|
2016-11-04 10:09:24 -04:00
|
|
|
"CREATE TABLE IF NOT EXISTS queue (" \
|
|
|
|
" id INTEGER PRIMARY KEY NOT NULL," \
|
|
|
|
" file_id INTEGER NOT NULL," \
|
|
|
|
" pos INTEGER NOT NULL," \
|
|
|
|
" shuffle_pos INTEGER NOT NULL," \
|
|
|
|
" data_kind INTEGER NOT NULL," \
|
|
|
|
" media_kind INTEGER NOT NULL," \
|
|
|
|
" song_length INTEGER NOT NULL," \
|
|
|
|
" path VARCHAR(4096) NOT NULL," \
|
|
|
|
" virtual_path VARCHAR(4096) NOT NULL," \
|
|
|
|
" title VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" artist VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" album_artist VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
|
|
|
" album VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
|
|
|
" genre VARCHAR(255) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" songalbumid INTEGER NOT NULL," \
|
|
|
|
" time_modified INTEGER DEFAULT 0," \
|
|
|
|
" artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" album_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" album_artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" year INTEGER DEFAULT 0," \
|
|
|
|
" track INTEGER DEFAULT 0," \
|
|
|
|
" disc INTEGER DEFAULT 0" \
|
|
|
|
");"
|
|
|
|
|
2016-12-09 01:07:05 -05:00
|
|
|
#define U_V1901_QUEUE_VERSION \
|
2016-12-03 01:00:28 -05:00
|
|
|
"INSERT INTO admin (key, value) VALUES ('queue_version', '0');"
|
2016-11-04 10:09:24 -04:00
|
|
|
|
2016-12-09 01:07:05 -05:00
|
|
|
#define U_V1901_SCVER_MAJOR \
|
|
|
|
"UPDATE admin SET value = '19' WHERE key = 'schema_version_major';"
|
|
|
|
#define U_V1901_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '01' WHERE key = 'schema_version_minor';"
|
2016-11-04 10:09:24 -04:00
|
|
|
|
2016-12-04 01:28:06 -05:00
|
|
|
static const struct db_upgrade_query db_upgrade_v1901_queries[] =
|
2016-11-04 10:09:24 -04:00
|
|
|
{
|
2016-12-09 01:07:05 -05:00
|
|
|
{ U_V1901_CREATE_TABLE_QUEUE, "create table directories" },
|
|
|
|
{ U_V1901_QUEUE_VERSION, "insert queue version" },
|
2016-11-04 10:09:24 -04:00
|
|
|
|
2016-12-09 01:07:05 -05:00
|
|
|
{ U_V1901_SCVER_MAJOR, "set schema_version_major to 19" },
|
|
|
|
{ U_V1901_SCVER_MINOR, "set schema_version_minor to 01" },
|
2016-11-04 10:09:24 -04:00
|
|
|
};
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 19.01 -> 19.02 ------------------------------ */
|
2016-12-09 01:07:33 -05:00
|
|
|
/* Set key column as primary key in the admin table
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define U_V1902_CREATE_TABLE_ADMINTMP \
|
|
|
|
"CREATE TEMPORARY TABLE IF NOT EXISTS admin_tmp(" \
|
|
|
|
" key VARCHAR(32) NOT NULL," \
|
|
|
|
" value VARCHAR(32) NOT NULL" \
|
|
|
|
");"
|
|
|
|
#define U_V1902_INSERT_ADMINTMP \
|
|
|
|
"INSERT INTO admin_tmp SELECT * FROM admin;"
|
|
|
|
#define U_V1902_DROP_TABLE_ADMIN \
|
|
|
|
"DROP TABLE admin;"
|
|
|
|
#define U_V1902_CREATE_TABLE_ADMIN \
|
|
|
|
"CREATE TABLE IF NOT EXISTS admin(" \
|
|
|
|
" key VARCHAR(32) PRIMARY KEY NOT NULL," \
|
|
|
|
" value VARCHAR(32) NOT NULL" \
|
|
|
|
");"
|
|
|
|
#define U_V1902_INSERT_ADMIN \
|
|
|
|
"INSERT OR IGNORE INTO admin SELECT * FROM admin_tmp;"
|
|
|
|
#define U_V1902_DROP_TABLE_ADMINTMP \
|
|
|
|
"DROP TABLE admin_tmp;"
|
|
|
|
|
|
|
|
#define U_V1902_SCVER_MAJOR \
|
|
|
|
"UPDATE admin SET value = '19' WHERE key = 'schema_version_major';"
|
|
|
|
#define U_V1902_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '02' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v1902_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V1902_CREATE_TABLE_ADMINTMP, "create temporary table admin_tmp" },
|
|
|
|
{ U_V1902_INSERT_ADMINTMP, "insert admin_tmp" },
|
|
|
|
{ U_V1902_DROP_TABLE_ADMIN, "drop table admin" },
|
|
|
|
{ U_V1902_CREATE_TABLE_ADMIN, "create table admin" },
|
|
|
|
{ U_V1902_INSERT_ADMIN, "insert admin" },
|
|
|
|
{ U_V1902_DROP_TABLE_ADMINTMP, "drop table admin_tmp" },
|
|
|
|
|
|
|
|
{ U_V1902_SCVER_MAJOR, "set schema_version_major to 19" },
|
|
|
|
{ U_V1902_SCVER_MINOR, "set schema_version_minor to 02" },
|
|
|
|
};
|
2016-11-04 10:09:24 -04:00
|
|
|
|
2017-01-22 17:08:26 -05:00
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 19.02 -> 19.03 ------------------------------ */
|
|
|
|
|
2017-01-22 17:08:26 -05:00
|
|
|
#define U_V1903_ALTER_QUEUE_ADD_ARTWORKURL \
|
|
|
|
"ALTER TABLE queue ADD COLUMN artwork_url VARCHAR(4096) DEFAULT NULL;"
|
|
|
|
|
|
|
|
#define U_V1903_SCVER_MAJOR \
|
|
|
|
"UPDATE admin SET value = '19' WHERE key = 'schema_version_major';"
|
|
|
|
#define U_V1903_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '03' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v1903_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V1903_ALTER_QUEUE_ADD_ARTWORKURL, "alter table queue add column artwork_url" },
|
|
|
|
|
|
|
|
{ U_V1903_SCVER_MAJOR, "set schema_version_major to 19" },
|
|
|
|
{ U_V1903_SCVER_MINOR, "set schema_version_minor to 03" },
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 19.03 -> 19.04 ------------------------------ */
|
|
|
|
|
2017-06-17 19:29:40 -04:00
|
|
|
#define U_V1904_ALTER_SPEAKERS_ADD_AUTHKEY \
|
2017-06-19 15:52:01 -04:00
|
|
|
"ALTER TABLE speakers ADD COLUMN auth_key VARCHAR(2048) DEFAULT NULL;"
|
2017-06-17 19:29:40 -04:00
|
|
|
|
|
|
|
#define U_V1904_SCVER_MAJOR \
|
|
|
|
"UPDATE admin SET value = '19' WHERE key = 'schema_version_major';"
|
|
|
|
#define U_V1904_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '04' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v1904_queries[] =
|
|
|
|
{
|
2017-06-19 15:52:01 -04:00
|
|
|
{ U_V1904_ALTER_SPEAKERS_ADD_AUTHKEY, "alter table speakers add column auth_key" },
|
2017-06-17 19:29:40 -04:00
|
|
|
|
|
|
|
{ U_V1904_SCVER_MAJOR, "set schema_version_major to 19" },
|
|
|
|
{ U_V1904_SCVER_MINOR, "set schema_version_minor to 04" },
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 19.04 -> 19.05 ------------------------------ */
|
|
|
|
|
2017-10-14 03:12:52 -04:00
|
|
|
#define U_V1905_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '05' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
// Purpose of this upgrade is to reset the indeces, so that I_FNAME gets added
|
|
|
|
static const struct db_upgrade_query db_upgrade_v1905_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V1905_SCVER_MINOR, "set schema_version_minor to 05" },
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 19.05 -> 19.06 ------------------------------ */
|
|
|
|
|
2017-11-24 09:32:30 -05:00
|
|
|
#define U_V1906_DROP_TABLE_QUEUE \
|
|
|
|
"DROP TABLE queue;"
|
|
|
|
|
|
|
|
#define U_V1906_CREATE_TABLE_QUEUE \
|
|
|
|
"CREATE TABLE IF NOT EXISTS queue (" \
|
|
|
|
" id INTEGER PRIMARY KEY AUTOINCREMENT," \
|
|
|
|
" file_id INTEGER NOT NULL," \
|
|
|
|
" pos INTEGER NOT NULL," \
|
|
|
|
" shuffle_pos INTEGER NOT NULL," \
|
|
|
|
" data_kind INTEGER NOT NULL," \
|
|
|
|
" media_kind INTEGER NOT NULL," \
|
|
|
|
" song_length INTEGER NOT NULL," \
|
|
|
|
" path VARCHAR(4096) NOT NULL," \
|
|
|
|
" virtual_path VARCHAR(4096) NOT NULL," \
|
|
|
|
" title VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" artist VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" album_artist VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
|
|
|
" album VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
|
|
|
" genre VARCHAR(255) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" songalbumid INTEGER NOT NULL," \
|
|
|
|
" time_modified INTEGER DEFAULT 0," \
|
|
|
|
" artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" album_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" album_artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" year INTEGER DEFAULT 0," \
|
|
|
|
" track INTEGER DEFAULT 0," \
|
|
|
|
" disc INTEGER DEFAULT 0," \
|
|
|
|
" artwork_url VARCHAR(4096) DEFAULT NULL," \
|
|
|
|
" queue_version INTEGER DEFAULT 0" \
|
|
|
|
");"
|
|
|
|
|
|
|
|
#define U_V1906_UPDATE_HTTP_VIRTUAL_PATH \
|
|
|
|
"UPDATE files SET virtual_path = '/' || path WHERE data_kind = 1;"
|
|
|
|
|
|
|
|
#define U_V1906_SCVER_MAJOR \
|
|
|
|
"UPDATE admin SET value = '19' WHERE key = 'schema_version_major';"
|
|
|
|
#define U_V1906_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '06' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_V1906_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V1906_DROP_TABLE_QUEUE, "drop queue table" },
|
|
|
|
{ U_V1906_CREATE_TABLE_QUEUE, "create queue table" },
|
|
|
|
{ U_V1906_UPDATE_HTTP_VIRTUAL_PATH, "update virtual path for http streams" },
|
|
|
|
|
|
|
|
{ U_V1906_SCVER_MAJOR, "set schema_version_major to 19" },
|
|
|
|
{ U_V1906_SCVER_MINOR, "set schema_version_minor to 06" },
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 19.06 -> 19.07 ------------------------------ */
|
|
|
|
|
2018-01-20 18:22:21 -05:00
|
|
|
#define U_V1907_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '07' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
// Purpose of this upgrade is to reset the indeces
|
|
|
|
static const struct db_upgrade_query db_upgrade_V1907_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V1907_SCVER_MINOR, "set schema_version_minor to 07" },
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 19.07 -> 19.08 ------------------------------ */
|
|
|
|
|
2018-04-15 02:03:42 -04:00
|
|
|
#define U_V1908_ALTER_PL_ADD_ORDER \
|
|
|
|
"ALTER TABLE playlists ADD COLUMN query_order VARCHAR(1024);"
|
2018-04-13 10:29:06 -04:00
|
|
|
#define U_V1908_ALTER_PL_ADD_LIMIT \
|
2018-04-15 02:39:43 -04:00
|
|
|
"ALTER TABLE playlists ADD COLUMN query_limit INTEGER DEFAULT -1;"
|
2018-04-13 10:29:06 -04:00
|
|
|
|
|
|
|
#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[] =
|
|
|
|
{
|
2018-04-15 02:03:42 -04:00
|
|
|
{ U_V1908_ALTER_PL_ADD_ORDER, "alter table playlists add column query_order" },
|
2018-04-13 10:29:06 -04:00
|
|
|
{ U_V1908_ALTER_PL_ADD_LIMIT, "alter table playlists add column query_limit" },
|
|
|
|
|
|
|
|
{ U_V1908_SCVER_MINOR, "set schema_version_minor to 08" },
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 19.08 -> 19.09 ------------------------------ */
|
|
|
|
|
2018-08-18 16:56:27 -04:00
|
|
|
#define U_V1909_ALTER_FILES_ADD_SKIP_COUNT \
|
|
|
|
"ALTER TABLE files ADD COLUMN skip_count INTEGER DEFAULT 0;"
|
|
|
|
#define U_V1909_ALTER_FILES_ADD_TIME_SKIPPED \
|
|
|
|
"ALTER TABLE files ADD COLUMN time_skipped INTEGER DEFAULT 0;"
|
|
|
|
|
|
|
|
#define U_V1909_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '09' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v1909_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V1909_ALTER_FILES_ADD_SKIP_COUNT, "alter table files add column skip_count" },
|
|
|
|
{ U_V1909_ALTER_FILES_ADD_TIME_SKIPPED, "alter table files add column time_skipped" },
|
|
|
|
|
|
|
|
{ U_V1909_SCVER_MINOR, "set schema_version_minor to 09" },
|
|
|
|
};
|
|
|
|
|
2018-09-23 16:24:24 -04:00
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 19.09 -> 19.10 ------------------------------ */
|
|
|
|
|
2018-09-19 13:40:45 -04:00
|
|
|
// Clean up after bug in commit fde0a281 (schema 19.09)
|
|
|
|
#define U_V1910_CLEANUP_TIME_SKIPPED \
|
|
|
|
"UPDATE files SET time_skipped = 0 WHERE time_skipped > 2000000000;"
|
|
|
|
|
|
|
|
#define U_V1910_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '10' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v1910_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V1910_CLEANUP_TIME_SKIPPED, "clean up time_skipped" },
|
|
|
|
|
|
|
|
{ U_V1910_SCVER_MINOR, "set schema_version_minor to 10" },
|
|
|
|
};
|
|
|
|
|
2018-09-23 16:24:24 -04:00
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 19.10 -> 19.11 ------------------------------ */
|
|
|
|
|
2018-11-21 07:52:13 -05:00
|
|
|
#define U_v1911_ALTER_QUEUE_ADD_COMPOSER \
|
|
|
|
"ALTER TABLE queue ADD COLUMN composer VARCHAR(1024) DEFAULT NULL;"
|
|
|
|
|
|
|
|
#define U_v1911_SCVER_MAJOR \
|
|
|
|
"UPDATE admin SET value = '19' WHERE key = 'schema_version_major';"
|
|
|
|
#define U_v1911_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '11' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v1911_queries[] =
|
|
|
|
{
|
|
|
|
{ U_v1911_ALTER_QUEUE_ADD_COMPOSER, "alter table queue add column composer" },
|
|
|
|
|
|
|
|
{ U_v1911_SCVER_MAJOR, "set schema_version_major to 19" },
|
|
|
|
{ U_v1911_SCVER_MINOR, "set schema_version_minor to 11" },
|
|
|
|
};
|
|
|
|
|
2018-08-18 16:56:27 -04:00
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 19.11 -> 19.12 ------------------------------ */
|
|
|
|
|
2018-11-24 03:23:32 -05:00
|
|
|
#define U_V1912_ALTER_DIRECTORIES_ADD_PATH \
|
|
|
|
"ALTER TABLE directories ADD COLUMN path VARCHAR(4096) DEFAULT NULL;"
|
|
|
|
|
|
|
|
#define U_V1912_UPDATE_FILE_DIRECTORIES_PATH \
|
|
|
|
"UPDATE directories SET path = SUBSTR(path, 7) WHERE virtual_path like '/file:/%';"
|
|
|
|
#define U_V1912_UPDATE_FILE_ROOT_PATH \
|
|
|
|
"UPDATE directories SET path = '/' WHERE virtual_path = '/file:';"
|
|
|
|
|
|
|
|
#define U_V1912_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '12' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v1912_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V1912_ALTER_DIRECTORIES_ADD_PATH, "alter table directories add column path" },
|
|
|
|
{ U_V1912_UPDATE_FILE_DIRECTORIES_PATH, "set paths for '/file:' directories" },
|
|
|
|
{ U_V1912_UPDATE_FILE_ROOT_PATH, "set path for '/file:' directory" },
|
|
|
|
|
|
|
|
{ U_V1912_SCVER_MINOR, "set schema_version_minor to 12" },
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* ---------------------------- 19.12 -> 20.00 ------------------------------ */
|
|
|
|
|
2018-12-29 18:27:47 -05:00
|
|
|
#define U_V20_NEW_FILES_TABLE \
|
|
|
|
"CREATE TABLE new_files (" \
|
|
|
|
" id INTEGER PRIMARY KEY NOT NULL," \
|
|
|
|
" path VARCHAR(4096) NOT NULL," \
|
|
|
|
" virtual_path VARCHAR(4096) DEFAULT NULL," \
|
|
|
|
" fname VARCHAR(255) NOT NULL," \
|
|
|
|
" directory_id INTEGER DEFAULT 0," \
|
|
|
|
" title VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" artist VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" album VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
|
|
|
" album_artist VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
|
|
|
" genre VARCHAR(255) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" comment VARCHAR(4096) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" type VARCHAR(255) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" composer VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" orchestra VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" conductor VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" grouping VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" url VARCHAR(1024) DEFAULT NULL," \
|
|
|
|
" bitrate INTEGER DEFAULT 0," \
|
|
|
|
" samplerate INTEGER DEFAULT 0," \
|
|
|
|
" song_length INTEGER DEFAULT 0," \
|
|
|
|
" file_size INTEGER DEFAULT 0," \
|
|
|
|
" year INTEGER DEFAULT 0," \
|
|
|
|
" date_released INTEGER DEFAULT 0," \
|
|
|
|
" track INTEGER DEFAULT 0," \
|
|
|
|
" total_tracks INTEGER DEFAULT 0," \
|
|
|
|
" disc INTEGER DEFAULT 0," \
|
|
|
|
" total_discs INTEGER DEFAULT 0," \
|
|
|
|
" bpm INTEGER DEFAULT 0," \
|
|
|
|
" compilation INTEGER DEFAULT 0," \
|
|
|
|
" artwork INTEGER DEFAULT 0," \
|
|
|
|
" rating INTEGER DEFAULT 0," \
|
|
|
|
" play_count INTEGER DEFAULT 0," \
|
|
|
|
" skip_count INTEGER DEFAULT 0," \
|
|
|
|
" seek INTEGER DEFAULT 0," \
|
|
|
|
" data_kind INTEGER DEFAULT 0," \
|
|
|
|
" media_kind INTEGER DEFAULT 0," \
|
|
|
|
" item_kind INTEGER DEFAULT 0," \
|
|
|
|
" description INTEGER DEFAULT 0," \
|
|
|
|
" db_timestamp INTEGER DEFAULT 0," \
|
|
|
|
" time_added INTEGER DEFAULT 0," \
|
|
|
|
" time_modified INTEGER DEFAULT 0," \
|
|
|
|
" time_played INTEGER DEFAULT 0," \
|
|
|
|
" time_skipped INTEGER DEFAULT 0," \
|
|
|
|
" disabled INTEGER DEFAULT 0," \
|
|
|
|
" sample_count INTEGER DEFAULT 0," \
|
|
|
|
" codectype VARCHAR(5) DEFAULT NULL," \
|
|
|
|
" idx INTEGER NOT NULL," \
|
|
|
|
" has_video INTEGER DEFAULT 0," \
|
|
|
|
" contentrating INTEGER DEFAULT 0," \
|
|
|
|
" bits_per_sample INTEGER DEFAULT 0," \
|
|
|
|
" tv_series_name VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" tv_episode_num_str VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" tv_network_name VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" tv_episode_sort INTEGER NOT NULL," \
|
|
|
|
" tv_season_num INTEGER NOT NULL," \
|
|
|
|
" songartistid INTEGER DEFAULT 0," \
|
|
|
|
" songalbumid INTEGER DEFAULT 0," \
|
|
|
|
" title_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" album_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" album_artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
|
|
" composer_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP" \
|
|
|
|
");"
|
|
|
|
|
|
|
|
static int
|
|
|
|
db_upgrade_v20(sqlite3 *hdl)
|
|
|
|
{
|
|
|
|
return db_table_upgrade(hdl, "files", U_V20_NEW_FILES_TABLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define U_V2000_DROP_TRG1 \
|
|
|
|
"DROP TRIGGER IF EXISTS update_groups_new_file;"
|
|
|
|
#define U_V2000_DROP_TRG2 \
|
|
|
|
"DROP TRIGGER IF EXISTS update_groups_update_file;"
|
2018-09-23 16:24:24 -04:00
|
|
|
|
|
|
|
#define U_V2000_SCVER_MAJOR \
|
|
|
|
"UPDATE admin SET value = '20' WHERE key = 'schema_version_major';"
|
|
|
|
#define U_V2000_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '00' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v2000_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V2000_DROP_TRG1, "drop trigger update_groups_new_file" },
|
|
|
|
{ U_V2000_DROP_TRG2, "drop trigger update_groups_update_file" },
|
|
|
|
|
|
|
|
{ U_V2000_SCVER_MAJOR, "set schema_version_major to 20" },
|
|
|
|
{ U_V2000_SCVER_MINOR, "set schema_version_minor to 00" },
|
|
|
|
};
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
|
|
|
|
/* ---------------------------- 20.00 -> 20.01 ------------------------------ */
|
|
|
|
|
2019-02-01 10:39:10 -05:00
|
|
|
#define U_V2001_ALTER_QUEUE_ADD_SONGARTISTID \
|
|
|
|
"ALTER TABLE queue ADD COLUMN songartistid INTEGER NOT NULL default 0;"
|
|
|
|
#define U_V2001_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '01' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v2001_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V2001_ALTER_QUEUE_ADD_SONGARTISTID, "add songartistid to queue" },
|
|
|
|
{ U_V2001_SCVER_MINOR, "set schema_version_minor to 01" },
|
|
|
|
};
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
|
|
|
|
/* ---------------------------- 20.01 -> 21.00 ------------------------------ */
|
|
|
|
|
2019-05-17 17:07:48 -04:00
|
|
|
#define U_V2100_SCVER_MAJOR \
|
|
|
|
"UPDATE admin SET value = '21' WHERE key = 'schema_version_major';"
|
|
|
|
#define U_V2100_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '00' WHERE key = 'schema_version_minor';"
|
2019-05-12 17:28:38 -04:00
|
|
|
|
2019-05-13 16:31:28 -04:00
|
|
|
// This upgrade just changes triggers (will be done automatically by db_drop...)
|
2019-05-17 17:07:48 -04:00
|
|
|
static const struct db_upgrade_query db_upgrade_v2100_queries[] =
|
2019-05-12 17:28:38 -04:00
|
|
|
{
|
2019-05-17 17:07:48 -04:00
|
|
|
{ U_V2100_SCVER_MAJOR, "set schema_version_major to 21" },
|
|
|
|
{ U_V2100_SCVER_MINOR, "set schema_version_minor to 00" },
|
2019-05-12 17:28:38 -04:00
|
|
|
};
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
|
|
|
|
/* ---------------------------- 21.00 -> 21.01 ------------------------------ */
|
|
|
|
|
2019-06-04 16:51:44 -04:00
|
|
|
#define U_v2101_ALTER_QUEUE_ADD_TYPE \
|
|
|
|
"ALTER TABLE queue ADD COLUMN type VARCHAR(8) DEFAULT NULL;"
|
|
|
|
#define U_v2101_ALTER_QUEUE_ADD_BITRATE \
|
|
|
|
"ALTER TABLE queue ADD COLUMN bitrate INTEGER DEFAULT 0;"
|
|
|
|
#define U_v2101_ALTER_QUEUE_ADD_SAMPLERATE \
|
|
|
|
"ALTER TABLE queue ADD COLUMN samplerate INTEGER DEFAULT 0;"
|
2019-06-07 04:53:37 -04:00
|
|
|
#define U_v2101_ALTER_QUEUE_ADD_CHANNELS \
|
|
|
|
"ALTER TABLE queue ADD COLUMN channels INTEGER DEFAULT 0;"
|
|
|
|
#define U_v2101_ALTER_FILES_ADD_CHANNELS \
|
|
|
|
"ALTER TABLE files ADD COLUMN channels INTEGER DEFAULT 0;"
|
2019-06-04 16:51:44 -04:00
|
|
|
|
|
|
|
#define U_v2101_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '01' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v2101_queries[] =
|
|
|
|
{
|
|
|
|
{ U_v2101_ALTER_QUEUE_ADD_TYPE, "alter table queue add column type" },
|
|
|
|
{ U_v2101_ALTER_QUEUE_ADD_BITRATE, "alter table queue add column bitrate" },
|
|
|
|
{ U_v2101_ALTER_QUEUE_ADD_SAMPLERATE, "alter table queue add column samplerate" },
|
2019-06-07 04:53:37 -04:00
|
|
|
{ U_v2101_ALTER_QUEUE_ADD_CHANNELS, "alter table queue add column channels" },
|
|
|
|
{ U_v2101_ALTER_FILES_ADD_CHANNELS, "alter table files add column channels" },
|
2019-06-04 16:51:44 -04:00
|
|
|
|
|
|
|
{ U_v2101_SCVER_MINOR, "set schema_version_minor to 01" },
|
|
|
|
};
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
|
|
|
|
/* ---------------------------- 21.01 -> 21.02 ------------------------------ */
|
|
|
|
|
[db] Make Apple Music on Catalina work - part 2 (fix for issue #834)
Extends the playlist table with media_kind to handle playlist queries like
this from Apple Music:
/databases/71/containers?session-id=12345678&revision-number=4&delta=0&query=('dmap.itemname:Library%20name','com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32','com.apple.itunes.extended-media-kind:128','com.apple.itunes.extended-media-kind:65537')&meta=dmap.itemid,dmap.itemname,dmap.persistentid,dmap.parentcontainerid,com.apple.itunes.is-podcast-playlist,com.apple.itunes.special-playlist,com.apple.itunes.smart-playlist,dmap.haschildcontainers,com.apple.itunes.saved-genius,dmap.objectextradata
2019-11-01 18:44:53 -04:00
|
|
|
// This column added because Apple Music makes a DAAP request for playlists
|
|
|
|
// that has a query condition on extended-media-kind. We set the default value
|
|
|
|
// to 1 to signify music.
|
|
|
|
#define U_v2102_ALTER_PLAYLISTS_ADD_MEDIA_KIND \
|
|
|
|
"ALTER TABLE playlists ADD COLUMN media_kind INTEGER DEFAULT 1;"
|
|
|
|
|
|
|
|
#define U_v2102_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '02' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v2102_queries[] =
|
|
|
|
{
|
|
|
|
{ U_v2102_ALTER_PLAYLISTS_ADD_MEDIA_KIND, "alter table playlists add column media_kind" },
|
|
|
|
|
|
|
|
{ U_v2102_SCVER_MINOR, "set schema_version_minor to 02" },
|
|
|
|
};
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
|
|
|
|
/* ---------------------------- 21.02 -> 21.03 ------------------------------ */
|
|
|
|
|
2020-02-23 15:26:00 -05:00
|
|
|
#define U_V2103_SCVER_MAJOR \
|
|
|
|
"UPDATE admin SET value = '21' WHERE key = 'schema_version_major';"
|
|
|
|
#define U_V2103_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '03' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
// This upgrade just changes triggers (will be done automatically by db_drop...)
|
|
|
|
static const struct db_upgrade_query db_upgrade_v2103_queries[] =
|
|
|
|
{
|
|
|
|
{ U_V2103_SCVER_MAJOR, "set schema_version_major to 21" },
|
|
|
|
{ U_V2103_SCVER_MINOR, "set schema_version_minor to 03" },
|
|
|
|
};
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
|
|
|
|
/* ---------------------------- 21.03 -> 21.04 ------------------------------ */
|
|
|
|
|
2020-04-26 12:11:03 -04:00
|
|
|
#define U_v2104_ALTER_PLAYLISTS_ADD_ARTWORK_URL \
|
|
|
|
"ALTER TABLE playlists ADD COLUMN artwork_url VARCHAR(4096) DEFAULT NULL;"
|
|
|
|
#define U_v2104_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '04' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v2104_queries[] =
|
|
|
|
{
|
|
|
|
{ U_v2104_ALTER_PLAYLISTS_ADD_ARTWORK_URL, "alter table playlists add column artwork_url" },
|
|
|
|
|
|
|
|
{ U_v2104_SCVER_MINOR, "set schema_version_minor to 04" },
|
|
|
|
};
|
2020-02-23 15:26:00 -05:00
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
|
|
|
|
/* ---------------------------- 21.04 -> 21.05 ------------------------------ */
|
|
|
|
|
2021-01-03 16:27:02 -05:00
|
|
|
// Previously, the auth_key contained the public key twice
|
|
|
|
#define U_v2105_UPDATE_SPEAKERS_AUTH_KEY \
|
|
|
|
"UPDATE speakers SET auth_key = SUBSTR(auth_key, LENGTH(auth_key) - 128 + 1, LENGTH(auth_key) + 1) WHERE LENGTH(auth_key) = 128 + 64;"
|
|
|
|
#define U_v2105_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '05' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v2105_queries[] =
|
|
|
|
{
|
|
|
|
{ U_v2105_UPDATE_SPEAKERS_AUTH_KEY, "update table speakers auth_key length" },
|
|
|
|
|
|
|
|
{ U_v2105_SCVER_MINOR, "set schema_version_minor to 05" },
|
|
|
|
};
|
|
|
|
|
2018-09-23 16:24:24 -04:00
|
|
|
|
2021-01-31 04:27:23 -05:00
|
|
|
/* ---------------------------- 21.05 -> 21.06 ------------------------------ */
|
|
|
|
|
|
|
|
// Reload table, required for changing the default of query_limit from -1 to 0
|
|
|
|
#define U_V2106_NEW_PLAYLISTS_TABLE \
|
|
|
|
"CREATE TABLE new_playlists (" \
|
|
|
|
" id INTEGER PRIMARY KEY NOT NULL," \
|
|
|
|
" title VARCHAR(255) NOT NULL COLLATE DAAP," \
|
|
|
|
" type INTEGER NOT NULL," \
|
|
|
|
" query VARCHAR(1024)," \
|
|
|
|
" db_timestamp INTEGER NOT NULL," \
|
|
|
|
" disabled INTEGER DEFAULT 0," \
|
|
|
|
" path VARCHAR(4096)," \
|
|
|
|
" idx INTEGER NOT NULL," \
|
|
|
|
" special_id INTEGER DEFAULT 0," \
|
|
|
|
" virtual_path VARCHAR(4096)," \
|
|
|
|
" parent_id INTEGER DEFAULT 0," \
|
|
|
|
" directory_id INTEGER DEFAULT 0," \
|
|
|
|
" query_order VARCHAR(1024)," \
|
|
|
|
" query_limit INTEGER DEFAULT 0," \
|
|
|
|
" media_kind INTEGER DEFAULT 1," \
|
|
|
|
" artwork_url VARCHAR(4096) DEFAULT NULL" \
|
|
|
|
");"
|
|
|
|
|
|
|
|
static int
|
|
|
|
db_upgrade_v2106(sqlite3 *hdl)
|
|
|
|
{
|
|
|
|
return db_table_upgrade(hdl, "playlists", U_V2106_NEW_PLAYLISTS_TABLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Previously, query_limit had multiple defaults: -1, 0 and UINT32_MAX
|
|
|
|
#define U_v2106_UPDATE_PLAYLISTS_QUERY_LIMIT \
|
|
|
|
"UPDATE playlists SET query_limit = 0 WHERE query_limit = -1 OR query_limit = 4294967295;"
|
|
|
|
#define U_v2106_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '06' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v2106_queries[] =
|
|
|
|
{
|
|
|
|
{ U_v2106_UPDATE_PLAYLISTS_QUERY_LIMIT, "update table playlists query_limit default" },
|
|
|
|
|
|
|
|
{ U_v2106_SCVER_MINOR, "set schema_version_minor to 06" },
|
|
|
|
};
|
|
|
|
|
2021-09-05 11:36:02 -04:00
|
|
|
/* ---------------------------- 21.06 -> 21.07 ------------------------------ */
|
2021-09-08 09:51:55 -04:00
|
|
|
#define U_v2107_ALTER_FILES_USERMARK \
|
|
|
|
"ALTER TABLE files ADD COLUMN usermark INTEGER DEFAULT 0;"
|
2021-09-05 11:36:02 -04:00
|
|
|
#define U_v2107_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '07' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v2107_queries[] =
|
|
|
|
{
|
2021-09-08 09:51:55 -04:00
|
|
|
{ U_v2107_ALTER_FILES_USERMARK, "update files adding usermark" },
|
2021-09-05 11:36:02 -04:00
|
|
|
|
|
|
|
{ U_v2107_SCVER_MINOR, "set schema_version_minor to 07" },
|
|
|
|
};
|
|
|
|
|
2021-01-31 04:27:23 -05:00
|
|
|
|
2021-12-28 03:19:44 -05:00
|
|
|
/* ---------------------------- 21.07 -> 22.00 ------------------------------ */
|
|
|
|
|
|
|
|
#define U_v2200_ALTER_FILES_ADD_SCAN_KIND \
|
|
|
|
"ALTER TABLE files ADD COLUMN scan_kind INTEGER DEFAULT 0;"
|
|
|
|
#define U_v2200_ALTER_PLAYLISTS_ADD_SCAN_KIND \
|
|
|
|
"ALTER TABLE playlists ADD COLUMN scan_kind INTEGER DEFAULT 0;"
|
|
|
|
#define U_v2200_ALTER_DIR_ADD_SCAN_KIND \
|
|
|
|
"ALTER TABLE directories ADD COLUMN scan_kind INTEGER DEFAULT 0;"
|
|
|
|
|
|
|
|
#define U_v2200_FILES_SET_SCAN_KIND_RSS \
|
|
|
|
"UPDATE files SET scan_kind = 3 WHERE path in (" \
|
|
|
|
" SELECT i.filepath from playlists p, playlistitems i WHERE p.id = i.playlistid AND p.type = 4);"
|
|
|
|
#define U_v2200_FILES_SET_SCAN_KIND_SPOTIFY \
|
|
|
|
"UPDATE files SET scan_kind = 2 WHERE virtual_path like '/spotify:/%';"
|
|
|
|
#define U_v2200_FILES_SET_SOURCE_FILE_SCANNER \
|
|
|
|
"UPDATE files SET scan_kind = 1 WHERE scan_kind = 0;"
|
|
|
|
|
|
|
|
#define U_v2200_PL_SET_SCAN_KIND_RSS \
|
|
|
|
"UPDATE playlists SET scan_kind = 3 WHERE type = 4;" // PL_RSS = 4
|
|
|
|
#define U_v2200_PL_SET_SCAN_KIND_SPOTIFY \
|
|
|
|
"UPDATE playlists SET scan_kind = 2 WHERE virtual_path like '/spotify:/%';"
|
|
|
|
#define U_v2200_PL_SET_SCAN_KIND_FILES \
|
|
|
|
"UPDATE playlists SET scan_kind = 1 WHERE scan_kind = 0;"
|
|
|
|
|
|
|
|
// Note: RSS feed items do not have their own directory structure (they use "http:/")
|
|
|
|
#define U_v2200_DIR_SET_SCAN_KIND_SPOTIFY \
|
|
|
|
"UPDATE directories SET scan_kind = 2 WHERE virtual_path like '/spotify:/%';"
|
|
|
|
#define U_v2200_DIR_SET_SCAN_KIND_FILES \
|
|
|
|
"UPDATE directories SET scan_kind = 1 WHERE virtual_path like '/file:/%';"
|
|
|
|
|
|
|
|
#define U_v2200_SCVER_MAJOR \
|
|
|
|
"UPDATE admin SET value = '22' WHERE key = 'schema_version_major';"
|
|
|
|
#define U_v2200_SCVER_MINOR \
|
|
|
|
"UPDATE admin SET value = '00' WHERE key = 'schema_version_minor';"
|
|
|
|
|
|
|
|
static const struct db_upgrade_query db_upgrade_v2200_queries[] =
|
|
|
|
{
|
|
|
|
{ U_v2200_ALTER_FILES_ADD_SCAN_KIND, "alter table files add column scan_kind" },
|
|
|
|
{ U_v2200_ALTER_PLAYLISTS_ADD_SCAN_KIND, "alter table playlists add column scan_kind" },
|
|
|
|
{ U_v2200_ALTER_DIR_ADD_SCAN_KIND, "alter table directories add column scan_kind" },
|
|
|
|
{ U_v2200_FILES_SET_SCAN_KIND_RSS, "update table files set scan_kind rss" },
|
|
|
|
{ U_v2200_FILES_SET_SCAN_KIND_SPOTIFY, "update table files set scan_kind spotify" },
|
|
|
|
{ U_v2200_FILES_SET_SOURCE_FILE_SCANNER, "update table files set scan_kind files" },
|
|
|
|
{ U_v2200_PL_SET_SCAN_KIND_RSS, "update table playlists set scan_kind rss" },
|
|
|
|
{ U_v2200_PL_SET_SCAN_KIND_SPOTIFY, "update table playlists set scan_kind spotify" },
|
|
|
|
{ U_v2200_PL_SET_SCAN_KIND_FILES, "update table playlists set scan_kind files" },
|
|
|
|
{ U_v2200_DIR_SET_SCAN_KIND_SPOTIFY, "update table directories set scan_kind spotify" },
|
|
|
|
{ U_v2200_DIR_SET_SCAN_KIND_FILES , "update table directories set scan_kind files" },
|
|
|
|
|
|
|
|
{ U_v2200_SCVER_MAJOR, "set schema_version_major to 22" },
|
|
|
|
{ U_v2200_SCVER_MINOR, "set schema_version_minor to 00" },
|
|
|
|
};
|
|
|
|
|
2021-01-31 04:37:16 -05:00
|
|
|
/* -------------------------- Main upgrade handler -------------------------- */
|
|
|
|
|
2015-12-19 01:51:10 -05:00
|
|
|
int
|
|
|
|
db_upgrade(sqlite3 *hdl, int db_ver)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2019-01-01 15:34:29 -05:00
|
|
|
ret = db_drop_from_master(hdl, "INDEX", "idx");
|
2015-12-19 01:51:10 -05:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2019-01-01 15:34:29 -05:00
|
|
|
ret = db_drop_from_master(hdl, "TRIGGER", "trg");
|
2018-12-29 18:27:47 -05:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2015-12-19 01:51:10 -05:00
|
|
|
switch (db_ver)
|
|
|
|
{
|
|
|
|
case 1700:
|
2018-08-18 16:56:27 -04:00
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v18_queries, ARRAY_SIZE(db_upgrade_v18_queries));
|
2015-12-19 01:51:10 -05:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
2021-01-16 02:23:50 -05:00
|
|
|
/* no break */
|
2015-12-19 01:51:10 -05:00
|
|
|
|
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 1800:
|
2018-08-18 16:56:27 -04:00
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v1801_queries, ARRAY_SIZE(db_upgrade_v1801_queries));
|
2015-12-19 01:51:10 -05:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2015-12-27 01:16:50 -05:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 1801:
|
2018-08-18 16:56:27 -04:00
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v1900_queries, ARRAY_SIZE(db_upgrade_v1900_queries));
|
2015-12-27 01:16:50 -05:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
ret = db_upgrade_v19(hdl);
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-11-04 10:09:24 -04:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 1900:
|
2018-08-18 16:56:27 -04:00
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v1901_queries, ARRAY_SIZE(db_upgrade_v1901_queries));
|
2016-11-04 10:09:24 -04:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2017-02-13 13:09:01 -05:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
2016-12-09 01:07:33 -05:00
|
|
|
case 1901:
|
2018-08-18 16:56:27 -04:00
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v1902_queries, ARRAY_SIZE(db_upgrade_v1902_queries));
|
2016-12-09 01:07:33 -05:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2017-02-13 13:09:01 -05:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
2017-01-22 17:08:26 -05:00
|
|
|
case 1902:
|
2018-08-18 16:56:27 -04:00
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v1903_queries, ARRAY_SIZE(db_upgrade_v1903_queries));
|
2017-01-22 17:08:26 -05:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2017-06-17 19:29:40 -04:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 1903:
|
2018-08-18 16:56:27 -04:00
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v1904_queries, ARRAY_SIZE(db_upgrade_v1904_queries));
|
2017-06-17 19:29:40 -04:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2017-10-14 03:12:52 -04:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 1904:
|
2018-08-18 16:56:27 -04:00
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v1905_queries, ARRAY_SIZE(db_upgrade_v1905_queries));
|
2017-10-14 03:12:52 -04:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2017-11-24 09:32:30 -05:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 1905:
|
2018-08-18 16:56:27 -04:00
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_V1906_queries, ARRAY_SIZE(db_upgrade_V1906_queries));
|
2017-11-24 09:32:30 -05:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2018-01-20 18:22:21 -05:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 1906:
|
2018-08-18 16:56:27 -04:00
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_V1907_queries, ARRAY_SIZE(db_upgrade_V1907_queries));
|
2018-01-20 18:22:21 -05:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2018-04-13 10:29:06 -04:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 1907:
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v1908_queries, ARRAY_SIZE(db_upgrade_v1908_queries));
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2018-08-18 16:56:27 -04:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 1908:
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v1909_queries, ARRAY_SIZE(db_upgrade_v1909_queries));
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2018-09-19 13:40:45 -04:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 1909:
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v1910_queries, ARRAY_SIZE(db_upgrade_v1910_queries));
|
2018-11-21 07:52:13 -05:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 1910:
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v1911_queries, ARRAY_SIZE(db_upgrade_v1911_queries));
|
2018-09-19 13:40:45 -04:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
2018-11-24 03:23:32 -05:00
|
|
|
|
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 1911:
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v1912_queries, ARRAY_SIZE(db_upgrade_v1912_queries));
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2018-09-23 16:24:24 -04:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 1912:
|
2018-12-29 18:27:47 -05:00
|
|
|
ret = db_upgrade_v20(hdl);
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2018-09-23 16:24:24 -04:00
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v2000_queries, ARRAY_SIZE(db_upgrade_v2000_queries));
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
2018-12-29 18:27:47 -05:00
|
|
|
|
2019-02-01 10:39:10 -05:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 2000:
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v2001_queries, ARRAY_SIZE(db_upgrade_v2001_queries));
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2019-05-12 17:28:38 -04:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 2001:
|
2019-05-17 17:07:48 -04:00
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v2100_queries, ARRAY_SIZE(db_upgrade_v2100_queries));
|
2019-05-12 17:28:38 -04:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2019-06-04 16:51:44 -04:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 2100:
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v2101_queries, ARRAY_SIZE(db_upgrade_v2101_queries));
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
[db] Make Apple Music on Catalina work - part 2 (fix for issue #834)
Extends the playlist table with media_kind to handle playlist queries like
this from Apple Music:
/databases/71/containers?session-id=12345678&revision-number=4&delta=0&query=('dmap.itemname:Library%20name','com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32','com.apple.itunes.extended-media-kind:128','com.apple.itunes.extended-media-kind:65537')&meta=dmap.itemid,dmap.itemname,dmap.persistentid,dmap.parentcontainerid,com.apple.itunes.is-podcast-playlist,com.apple.itunes.special-playlist,com.apple.itunes.smart-playlist,dmap.haschildcontainers,com.apple.itunes.saved-genius,dmap.objectextradata
2019-11-01 18:44:53 -04:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 2101:
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v2102_queries, ARRAY_SIZE(db_upgrade_v2102_queries));
|
2020-02-23 15:26:00 -05:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 2102:
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v2103_queries, ARRAY_SIZE(db_upgrade_v2103_queries));
|
2020-04-26 12:11:03 -04:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 2103:
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v2104_queries, ARRAY_SIZE(db_upgrade_v2104_queries));
|
[db] Make Apple Music on Catalina work - part 2 (fix for issue #834)
Extends the playlist table with media_kind to handle playlist queries like
this from Apple Music:
/databases/71/containers?session-id=12345678&revision-number=4&delta=0&query=('dmap.itemname:Library%20name','com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32','com.apple.itunes.extended-media-kind:128','com.apple.itunes.extended-media-kind:65537')&meta=dmap.itemid,dmap.itemname,dmap.persistentid,dmap.parentcontainerid,com.apple.itunes.is-podcast-playlist,com.apple.itunes.special-playlist,com.apple.itunes.smart-playlist,dmap.haschildcontainers,com.apple.itunes.saved-genius,dmap.objectextradata
2019-11-01 18:44:53 -04:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
2015-12-19 01:51:10 -05:00
|
|
|
|
2021-01-03 16:27:02 -05:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 2104:
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v2105_queries, ARRAY_SIZE(db_upgrade_v2105_queries));
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
2021-01-23 10:32:41 -05:00
|
|
|
|
2021-01-31 04:27:23 -05:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 2105:
|
|
|
|
ret = db_upgrade_v2106(hdl);
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v2106_queries, ARRAY_SIZE(db_upgrade_v2106_queries));
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2021-09-05 11:36:02 -04:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 2106:
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v2107_queries, ARRAY_SIZE(db_upgrade_v2107_queries));
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2021-12-28 03:19:44 -05:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
|
|
case 2107:
|
|
|
|
ret = db_generic_upgrade(hdl, db_upgrade_v2200_queries, ARRAY_SIZE(db_upgrade_v2200_queries));
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
2021-01-31 04:27:23 -05:00
|
|
|
|
2021-01-23 10:32:41 -05:00
|
|
|
/* Last case statement is the only one that ends with a break statement! */
|
2021-01-03 16:27:02 -05:00
|
|
|
break;
|
|
|
|
|
2015-12-19 01:51:10 -05:00
|
|
|
default:
|
|
|
|
DPRINTF(E_FATAL, L_DB, "No upgrade path from the current DB schema\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|