mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-12 15:33:23 -05:00
Enclose DB upgrade in a single transaction (improves performance and in
case of an error does a rollback, keeping the db in a valid state)
This commit is contained in:
parent
a9a8c6a3d4
commit
1bbfcf61a5
143
src/db.c
143
src/db.c
@ -5790,57 +5790,10 @@ db_upgrade_v16(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
db_check_version(void)
|
db_upgrade(int db_ver)
|
||||||
{
|
{
|
||||||
#define Q_VACUUM "VACUUM;"
|
|
||||||
char *buf;
|
|
||||||
char *errmsg;
|
|
||||||
int db_ver_major;
|
|
||||||
int db_ver_minor;
|
|
||||||
int db_ver;
|
|
||||||
int vacuum;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
vacuum = cfg_getbool(cfg_getsec(cfg, "sqlite"), "vacuum");
|
|
||||||
|
|
||||||
buf = db_admin_get("schema_version_major");
|
|
||||||
if (!buf)
|
|
||||||
buf = db_admin_get("schema_version"); // Pre schema v15.1
|
|
||||||
|
|
||||||
if (!buf)
|
|
||||||
return 1; // Will create new database
|
|
||||||
|
|
||||||
safe_atoi32(buf, &db_ver_major);
|
|
||||||
free(buf);
|
|
||||||
|
|
||||||
buf = db_admin_get("schema_version_minor");
|
|
||||||
if (buf)
|
|
||||||
{
|
|
||||||
safe_atoi32(buf, &db_ver_minor);
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
db_ver_minor = 0;
|
|
||||||
|
|
||||||
db_ver = db_ver_major * 100 + db_ver_minor;
|
|
||||||
|
|
||||||
if (db_ver_major < 10)
|
|
||||||
{
|
|
||||||
DPRINTF(E_FATAL, L_DB, "Database schema v%d too old, cannot upgrade\n", db_ver_major);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if (db_ver_major > SCHEMA_VERSION_MAJOR)
|
|
||||||
{
|
|
||||||
DPRINTF(E_FATAL, L_DB, "Database schema v%d is newer than the supported version\n", db_ver_major);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if (db_ver < (SCHEMA_VERSION_MAJOR * 100 + SCHEMA_VERSION_MINOR))
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DB, "Database schema outdated, upgrading schema v%d.%d -> v%d.%d...\n",
|
|
||||||
db_ver_major, db_ver_minor, SCHEMA_VERSION_MAJOR, SCHEMA_VERSION_MINOR);
|
|
||||||
|
|
||||||
ret = db_drop_indices();
|
ret = db_drop_indices();
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -5919,11 +5872,101 @@ db_check_version(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vacuum = 1;
|
|
||||||
|
|
||||||
ret = db_create_indices();
|
ret = db_create_indices();
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
db_check_version(void)
|
||||||
|
{
|
||||||
|
#define Q_VACUUM "VACUUM;"
|
||||||
|
char *buf;
|
||||||
|
char *errmsg;
|
||||||
|
int db_ver_major;
|
||||||
|
int db_ver_minor;
|
||||||
|
int db_ver;
|
||||||
|
int vacuum;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
vacuum = cfg_getbool(cfg_getsec(cfg, "sqlite"), "vacuum");
|
||||||
|
|
||||||
|
buf = db_admin_get("schema_version_major");
|
||||||
|
if (!buf)
|
||||||
|
buf = db_admin_get("schema_version"); // Pre schema v15.1
|
||||||
|
|
||||||
|
if (!buf)
|
||||||
|
return 1; // Will create new database
|
||||||
|
|
||||||
|
safe_atoi32(buf, &db_ver_major);
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
buf = db_admin_get("schema_version_minor");
|
||||||
|
if (buf)
|
||||||
|
{
|
||||||
|
safe_atoi32(buf, &db_ver_minor);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
db_ver_minor = 0;
|
||||||
|
|
||||||
|
db_ver = db_ver_major * 100 + db_ver_minor;
|
||||||
|
|
||||||
|
if (db_ver_major < 10)
|
||||||
|
{
|
||||||
|
DPRINTF(E_FATAL, L_DB, "Database schema v%d too old, cannot upgrade\n", db_ver_major);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (db_ver_major > SCHEMA_VERSION_MAJOR)
|
||||||
|
{
|
||||||
|
DPRINTF(E_FATAL, L_DB, "Database schema v%d is newer than the supported version\n", db_ver_major);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (db_ver < (SCHEMA_VERSION_MAJOR * 100 + SCHEMA_VERSION_MINOR))
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_DB, "Database schema outdated, upgrading schema v%d.%d -> v%d.%d...\n",
|
||||||
|
db_ver_major, db_ver_minor, SCHEMA_VERSION_MAJOR, SCHEMA_VERSION_MINOR);
|
||||||
|
|
||||||
|
ret = sqlite3_exec(hdl, "BEGIN TRANSACTION;", NULL, NULL, &errmsg);
|
||||||
|
if (ret != SQLITE_OK)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_DB, "DB error while running 'BEGIN TRANSACTION': %s\n", errmsg);
|
||||||
|
|
||||||
|
sqlite3_free(errmsg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = db_upgrade(db_ver);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_DB, "Database upgrade errored out, rolling back changes ...\n");
|
||||||
|
ret = sqlite3_exec(hdl, "ROLLBACK TRANSACTION;", NULL, NULL, &errmsg);
|
||||||
|
if (ret != SQLITE_OK)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_DB, "DB error while running 'ROLLBACK TRANSACTION': %s\n", errmsg);
|
||||||
|
|
||||||
|
sqlite3_free(errmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sqlite3_exec(hdl, "COMMIT TRANSACTION;", NULL, NULL, &errmsg);
|
||||||
|
if (ret != SQLITE_OK)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_DB, "DB error while running 'COMMIT TRANSACTION': %s\n", errmsg);
|
||||||
|
|
||||||
|
sqlite3_free(errmsg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINTF(E_LOG, L_DB, "Upgrading schema to v%d.%d completed\n", SCHEMA_VERSION_MAJOR, SCHEMA_VERSION_MINOR);
|
||||||
|
|
||||||
|
vacuum = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vacuum)
|
if (vacuum)
|
||||||
|
Loading…
Reference in New Issue
Block a user