mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2025-01-15 09:36:00 +01:00
Track layout version and only update if necessary
This commit is contained in:
parent
743f29323c
commit
cebfaf016d
1 changed files with 160 additions and 114 deletions
|
@ -10,6 +10,9 @@
|
||||||
#include "database-sqlite.h"
|
#include "database-sqlite.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
/* version of the database layout */
|
||||||
|
#define DATABASE_VERSION 1
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
sqlite3_column_text_dup(sqlite3_stmt* stmt, int col)
|
sqlite3_column_text_dup(sqlite3_stmt* stmt, int col)
|
||||||
{
|
{
|
||||||
|
@ -118,11 +121,48 @@ sqlite_finalize(GObject* object)
|
||||||
G_OBJECT_CLASS(zathura_sqldatabase_parent_class)->finalize(object);
|
G_OBJECT_CLASS(zathura_sqldatabase_parent_class)->finalize(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static sqlite3_stmt*
|
||||||
sqlite_db_init(ZathuraSQLDatabase* db, const char* path)
|
prepare_statement(sqlite3* session, const char* statement)
|
||||||
{
|
{
|
||||||
ZathuraSQLDatabasePrivate* priv = zathura_sqldatabase_get_instance_private(db);
|
if (session == NULL || statement == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* pz_tail = NULL;
|
||||||
|
sqlite3_stmt* pp_stmt = NULL;
|
||||||
|
|
||||||
|
if (sqlite3_prepare_v2(session, statement, -1, &pp_stmt, &pz_tail) != SQLITE_OK) {
|
||||||
|
girara_error("Failed to prepare query: %s", statement);
|
||||||
|
sqlite3_finalize(pp_stmt);
|
||||||
|
return NULL;
|
||||||
|
} else if (pz_tail && *pz_tail != '\0') {
|
||||||
|
girara_error("Unused portion of statement: %s", pz_tail);
|
||||||
|
sqlite3_finalize(pp_stmt);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pp_stmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sqlite_get_user_version(sqlite3* session)
|
||||||
|
{
|
||||||
|
sqlite3_stmt* stmt = prepare_statement(session, "PRAGMA user_version;");
|
||||||
|
if (stmt == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int version = -1;
|
||||||
|
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||||
|
version = sqlite3_column_int(stmt, 0);
|
||||||
|
}
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sqlite_db_check_layout(sqlite3* session, const int database_version, const bool new_db)
|
||||||
|
{
|
||||||
/* create bookmarks table */
|
/* create bookmarks table */
|
||||||
static const char SQL_BOOKMARK_INIT[] =
|
static const char SQL_BOOKMARK_INIT[] =
|
||||||
"CREATE TABLE IF NOT EXISTS bookmarks ("
|
"CREATE TABLE IF NOT EXISTS bookmarks ("
|
||||||
|
@ -200,66 +240,64 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path)
|
||||||
"ALTER TABLE bookmarks ADD COLUMN hadj_ratio FLOAT;"
|
"ALTER TABLE bookmarks ADD COLUMN hadj_ratio FLOAT;"
|
||||||
"ALTER TABLE bookmarks ADD COLUMN vadj_ratio FLOAT;";
|
"ALTER TABLE bookmarks ADD COLUMN vadj_ratio FLOAT;";
|
||||||
|
|
||||||
sqlite3* session = NULL;
|
|
||||||
if (sqlite3_open(path, &session) != SQLITE_OK) {
|
|
||||||
girara_error("Could not open database: %s\n", path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create tables if they don't exist */
|
/* create tables if they don't exist */
|
||||||
for (size_t s = 0; s < LENGTH(ALL_INIT); ++s) {
|
for (size_t s = 0; s < LENGTH(ALL_INIT); ++s) {
|
||||||
if (sqlite3_exec(session, ALL_INIT[s], NULL, 0, NULL) != SQLITE_OK) {
|
if (sqlite3_exec(session, ALL_INIT[s], NULL, 0, NULL) != SQLITE_OK) {
|
||||||
girara_error("Failed to initialize database: %s\n", path);
|
girara_error("Failed to initialize database");
|
||||||
sqlite3_close(session);
|
sqlite3_close(session);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (new_db == true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool all_updates_ok = true;
|
||||||
|
if (database_version < 1)
|
||||||
|
{
|
||||||
/* check existing tables for missing columns */
|
/* check existing tables for missing columns */
|
||||||
bool res1, res2, ret1, ret2;
|
bool res1, res2, ret1, ret2;
|
||||||
|
|
||||||
ret1 = check_column(session, "fileinfo", "pages_per_row", &res1);
|
ret1 = check_column(session, "fileinfo", "pages_per_row", &res1);
|
||||||
|
|
||||||
if (ret1 == true && res1 == false) {
|
if (ret1 == true && res1 == false) {
|
||||||
girara_debug("old database table layout detected; updating ...");
|
|
||||||
if (sqlite3_exec(session, SQL_FILEINFO_ALTER, NULL, 0, NULL) != SQLITE_OK) {
|
if (sqlite3_exec(session, SQL_FILEINFO_ALTER, NULL, 0, NULL) != SQLITE_OK) {
|
||||||
girara_warning("failed to update database table layout");
|
girara_warning("failed to update database table layout");
|
||||||
|
all_updates_ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret1 = check_column(session, "fileinfo", "first_page_column", &res1);
|
ret1 = check_column(session, "fileinfo", "first_page_column", &res1);
|
||||||
|
|
||||||
if (ret1 == true && res1 == false) {
|
if (ret1 == true && res1 == false) {
|
||||||
girara_debug("old database table layout detected; updating ...");
|
|
||||||
if (sqlite3_exec(session, SQL_FILEINFO_ALTER2, NULL, 0, NULL) != SQLITE_OK) {
|
if (sqlite3_exec(session, SQL_FILEINFO_ALTER2, NULL, 0, NULL) != SQLITE_OK) {
|
||||||
girara_warning("failed to update database table layout");
|
girara_warning("failed to update database table layout");
|
||||||
|
all_updates_ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret1 = check_column(session, "fileinfo", "time", &res1);
|
ret1 = check_column(session, "fileinfo", "time", &res1);
|
||||||
|
|
||||||
if (ret1 == true && res1 == false) {
|
if (ret1 == true && res1 == false) {
|
||||||
girara_debug("old database table layout detected; updating ...");
|
|
||||||
if (sqlite3_exec(session, SQL_FILEINFO_ALTER3, NULL, 0, NULL) != SQLITE_OK) {
|
if (sqlite3_exec(session, SQL_FILEINFO_ALTER3, NULL, 0, NULL) != SQLITE_OK) {
|
||||||
girara_warning("failed to update database table layout");
|
girara_warning("failed to update database table layout");
|
||||||
|
all_updates_ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret1 = check_column(session, "fileinfo", "zoom", &res1);
|
ret1 = check_column(session, "fileinfo", "zoom", &res1);
|
||||||
|
|
||||||
if (ret1 == true && res1 == false) {
|
if (ret1 == true && res1 == false) {
|
||||||
girara_debug("old database table layout detected; updating ...");
|
|
||||||
if (sqlite3_exec(session, SQL_FILEINFO_ALTER4, NULL, 0, NULL) != SQLITE_OK) {
|
if (sqlite3_exec(session, SQL_FILEINFO_ALTER4, NULL, 0, NULL) != SQLITE_OK) {
|
||||||
girara_warning("failed to update database table layout");
|
girara_warning("failed to update database table layout");
|
||||||
|
all_updates_ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret1 = check_column(session, "fileinfo", "page_right_to_left", &res1);
|
ret1 = check_column(session, "fileinfo", "page_right_to_left", &res1);
|
||||||
|
|
||||||
if (ret1 == true && res1 == false) {
|
if (ret1 == true && res1 == false) {
|
||||||
girara_debug("old database table layout detected; updating ...");
|
|
||||||
if (sqlite3_exec(session, SQL_FILEINFO_ALTER5, NULL, 0, NULL) != SQLITE_OK) {
|
if (sqlite3_exec(session, SQL_FILEINFO_ALTER5, NULL, 0, NULL) != SQLITE_OK) {
|
||||||
girara_warning("failed to update database table layout");
|
girara_warning("failed to update database table layout");
|
||||||
|
all_updates_ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,9 +305,9 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path)
|
||||||
ret2 = check_column(session, "bookmarks", "vadj_ratio", &res2);
|
ret2 = check_column(session, "bookmarks", "vadj_ratio", &res2);
|
||||||
|
|
||||||
if (ret1 == true && ret2 == true && res1 == false && res2 == false) {
|
if (ret1 == true && ret2 == true && res1 == false && res2 == false) {
|
||||||
girara_debug("old database table layout detected; updating ...");
|
|
||||||
if (sqlite3_exec(session, SQL_BOOKMARK_ALTER, NULL, 0, NULL) != SQLITE_OK) {
|
if (sqlite3_exec(session, SQL_BOOKMARK_ALTER, NULL, 0, NULL) != SQLITE_OK) {
|
||||||
girara_warning("failed to update database table layout");
|
girara_warning("failed to update database table layout");
|
||||||
|
all_updates_ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,8 +315,6 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path)
|
||||||
ret1 = check_column_type(session, "fileinfo", "first_page_column", "TEXT", &res1);
|
ret1 = check_column_type(session, "fileinfo", "first_page_column", "TEXT", &res1);
|
||||||
|
|
||||||
if (ret1 == true && res1 == false) {
|
if (ret1 == true && res1 == false) {
|
||||||
girara_debug("old database table layout detected; updating ...");
|
|
||||||
|
|
||||||
/* prepare transaction */
|
/* prepare transaction */
|
||||||
static const char tx_begin[] =
|
static const char tx_begin[] =
|
||||||
"BEGIN TRANSACTION;"
|
"BEGIN TRANSACTION;"
|
||||||
|
@ -296,8 +332,41 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path)
|
||||||
|
|
||||||
if (sqlite3_exec(session, transaction, NULL, 0, NULL) != SQLITE_OK) {
|
if (sqlite3_exec(session, transaction, NULL, 0, NULL) != SQLITE_OK) {
|
||||||
girara_warning("failed to update database table layout");
|
girara_warning("failed to update database table layout");
|
||||||
|
all_updates_ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update database version if all updates were successful */
|
||||||
|
if (all_updates_ok == true) {
|
||||||
|
sqlite3_exec(session, "PRAGMA user_version = " G_STRINGIFY(DATABASE_VERSION) ";", NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sqlite_db_init(ZathuraSQLDatabase* db, const char* path)
|
||||||
|
{
|
||||||
|
ZathuraSQLDatabasePrivate* priv = zathura_sqldatabase_get_instance_private(db);
|
||||||
|
|
||||||
|
const bool db_exists = g_file_test(path, G_FILE_TEST_EXISTS);
|
||||||
|
sqlite3* session = NULL;
|
||||||
|
if (sqlite3_open(path, &session) != SQLITE_OK) {
|
||||||
|
girara_error("Could not open database: %s\n", path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int database_version = sqlite_get_user_version(session);
|
||||||
|
if (database_version == -1) {
|
||||||
|
girara_error("Failed to query database version.");
|
||||||
|
sqlite3_close(session);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
girara_debug("database version: %d (current: %d)", database_version, DATABASE_VERSION);
|
||||||
|
if (database_version < DATABASE_VERSION) {
|
||||||
|
girara_debug("old database table layout detected; updating ...");
|
||||||
|
sqlite_db_check_layout(session, database_version, !db_exists);
|
||||||
|
}
|
||||||
|
|
||||||
priv->session = session;
|
priv->session = session;
|
||||||
}
|
}
|
||||||
|
@ -318,29 +387,6 @@ sqlite_set_property(GObject* object, guint prop_id, const GValue* value, GParamS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static sqlite3_stmt*
|
|
||||||
prepare_statement(sqlite3* session, const char* statement)
|
|
||||||
{
|
|
||||||
if (session == NULL || statement == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* pz_tail = NULL;
|
|
||||||
sqlite3_stmt* pp_stmt = NULL;
|
|
||||||
|
|
||||||
if (sqlite3_prepare_v2(session, statement, -1, &pp_stmt, &pz_tail) != SQLITE_OK) {
|
|
||||||
girara_error("Failed to prepare query: %s", statement);
|
|
||||||
sqlite3_finalize(pp_stmt);
|
|
||||||
return NULL;
|
|
||||||
} else if (pz_tail && *pz_tail != '\0') {
|
|
||||||
girara_error("Unused portion of statement: %s", pz_tail);
|
|
||||||
sqlite3_finalize(pp_stmt);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pp_stmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
check_column(sqlite3* session, const char* table, const char* col, bool* res)
|
check_column(sqlite3* session, const char* table, const char* col, bool* res)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue