mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2024-11-14 10:03:45 +01:00
Merge branch 'history-io' into develop
This commit is contained in:
commit
9b1a037fe0
106
database-plain.c
106
database-plain.c
@ -1,6 +1,7 @@
|
|||||||
/* See LICENSE file for license and copyright information */
|
/* See LICENSE file for license and copyright information */
|
||||||
|
|
||||||
#define _POSIX_SOURCE
|
#define _POSIX_SOURCE
|
||||||
|
#define _XOPEN_SOURCE 500
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -10,11 +11,13 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <girara/utils.h>
|
#include <girara/utils.h>
|
||||||
#include <girara/datastructures.h>
|
#include <girara/datastructures.h>
|
||||||
|
#include <girara/input-history.h>
|
||||||
|
|
||||||
#include "database-plain.h"
|
#include "database-plain.h"
|
||||||
|
|
||||||
#define BOOKMARKS "bookmarks"
|
#define BOOKMARKS "bookmarks"
|
||||||
#define HISTORY "history"
|
#define HISTORY "history"
|
||||||
|
#define INPUT_HISTORY "input-history"
|
||||||
|
|
||||||
#define KEY_PAGE "page"
|
#define KEY_PAGE "page"
|
||||||
#define KEY_OFFSET "offset"
|
#define KEY_OFFSET "offset"
|
||||||
@ -37,9 +40,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void zathura_database_interface_init(ZathuraDatabaseInterface* iface);
|
static void zathura_database_interface_init(ZathuraDatabaseInterface* iface);
|
||||||
|
static void io_interface_init(GiraraInputHistoryIOInterface* iface);
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE(ZathuraPlainDatabase, zathura_plaindatabase, G_TYPE_OBJECT,
|
G_DEFINE_TYPE_WITH_CODE(ZathuraPlainDatabase, zathura_plaindatabase, G_TYPE_OBJECT,
|
||||||
G_IMPLEMENT_INTERFACE(ZATHURA_TYPE_DATABASE, zathura_database_interface_init))
|
G_IMPLEMENT_INTERFACE(ZATHURA_TYPE_DATABASE, zathura_database_interface_init)
|
||||||
|
G_IMPLEMENT_INTERFACE(GIRARA_TYPE_INPUT_HISTORY_IO, io_interface_init))
|
||||||
|
|
||||||
static void plain_finalize(GObject* object);
|
static void plain_finalize(GObject* object);
|
||||||
static bool plain_add_bookmark(zathura_database_t* db, const char* file,
|
static bool plain_add_bookmark(zathura_database_t* db, const char* file,
|
||||||
@ -54,6 +59,8 @@ static bool plain_get_fileinfo(zathura_database_t* db, const char* file,
|
|||||||
zathura_fileinfo_t* file_info);
|
zathura_fileinfo_t* file_info);
|
||||||
static void plain_set_property(GObject* object, guint prop_id,
|
static void plain_set_property(GObject* object, guint prop_id,
|
||||||
const GValue* value, GParamSpec* pspec);
|
const GValue* value, GParamSpec* pspec);
|
||||||
|
static void plain_io_append(GiraraInputHistoryIO* db, const char*);
|
||||||
|
static girara_list_t* plain_io_read(GiraraInputHistoryIO* db);
|
||||||
|
|
||||||
/* forward declaration */
|
/* forward declaration */
|
||||||
static bool zathura_db_check_file(const char* path);
|
static bool zathura_db_check_file(const char* path);
|
||||||
@ -70,6 +77,8 @@ typedef struct zathura_plaindatabase_private_s {
|
|||||||
char* history_path;
|
char* history_path;
|
||||||
GKeyFile* history;
|
GKeyFile* history;
|
||||||
GFileMonitor* history_monitor;
|
GFileMonitor* history_monitor;
|
||||||
|
|
||||||
|
char* input_history_path;
|
||||||
} zathura_plaindatabase_private_t;
|
} zathura_plaindatabase_private_t;
|
||||||
|
|
||||||
#define ZATHURA_PLAINDATABASE_GET_PRIVATE(obj) \
|
#define ZATHURA_PLAINDATABASE_GET_PRIVATE(obj) \
|
||||||
@ -105,6 +114,14 @@ zathura_database_interface_init(ZathuraDatabaseInterface* iface)
|
|||||||
iface->get_fileinfo = plain_get_fileinfo;
|
iface->get_fileinfo = plain_get_fileinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
io_interface_init(GiraraInputHistoryIOInterface* iface)
|
||||||
|
{
|
||||||
|
/* initialize interface */
|
||||||
|
iface->append = plain_io_append;
|
||||||
|
iface->read = plain_io_read;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zathura_plaindatabase_class_init(ZathuraPlainDatabaseClass* class)
|
zathura_plaindatabase_class_init(ZathuraPlainDatabaseClass* class)
|
||||||
{
|
{
|
||||||
@ -132,6 +149,7 @@ zathura_plaindatabase_init(ZathuraPlainDatabase* db)
|
|||||||
priv->history_path = NULL;
|
priv->history_path = NULL;
|
||||||
priv->history_monitor = NULL;
|
priv->history_monitor = NULL;
|
||||||
priv->history = NULL;
|
priv->history = NULL;
|
||||||
|
priv->input_history_path = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
zathura_database_t*
|
zathura_database_t*
|
||||||
@ -208,6 +226,12 @@ plain_db_init(ZathuraPlainDatabase* db, const char* dir)
|
|||||||
goto error_free;
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* input history */
|
||||||
|
priv->input_history_path = g_build_filename(dir, INPUT_HISTORY, NULL);
|
||||||
|
if (zathura_db_check_file(priv->input_history_path) == false) {
|
||||||
|
goto error_free;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error_free:
|
error_free:
|
||||||
@ -239,6 +263,10 @@ error_free:
|
|||||||
g_key_file_free(priv->history);
|
g_key_file_free(priv->history);
|
||||||
priv->history = NULL;
|
priv->history = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* input history */
|
||||||
|
g_free(priv->input_history_path);
|
||||||
|
priv->input_history_path = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -283,6 +311,9 @@ plain_finalize(GObject* object)
|
|||||||
g_key_file_free(priv->history);
|
g_key_file_free(priv->history);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* input history */
|
||||||
|
g_free(priv->input_history_path);
|
||||||
|
|
||||||
G_OBJECT_CLASS(zathura_plaindatabase_parent_class)->finalize(object);
|
G_OBJECT_CLASS(zathura_plaindatabase_parent_class)->finalize(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,3 +626,76 @@ cb_zathura_db_watch_file(GFileMonitor* UNUSED(monitor), GFile* file, GFile* UNUS
|
|||||||
|
|
||||||
g_free(path);
|
g_free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static girara_list_t*
|
||||||
|
plain_io_read(GiraraInputHistoryIO* db)
|
||||||
|
{
|
||||||
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
||||||
|
|
||||||
|
/* open file */
|
||||||
|
FILE* file = fopen(priv->input_history_path, "r");
|
||||||
|
if (file == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read input history file */
|
||||||
|
file_lock_set(fileno(file), F_RDLCK);
|
||||||
|
char* content = girara_file_read2(file);
|
||||||
|
file_lock_set(fileno(file), F_UNLCK);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
girara_list_t* res = girara_list_new2(g_free);
|
||||||
|
char** tmp = g_strsplit(content, "\n", 0);
|
||||||
|
for (size_t i = 0; tmp[i] != NULL; ++i) {
|
||||||
|
if (strlen(tmp[i]) == 0 || strchr(":/", tmp[i][0]) == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
girara_list_append(res, g_strdup(tmp[i]));
|
||||||
|
}
|
||||||
|
g_strfreev(tmp);
|
||||||
|
free(content);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
plain_io_append(GiraraInputHistoryIO* db, const char* input)
|
||||||
|
{
|
||||||
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
||||||
|
|
||||||
|
/* open file */
|
||||||
|
FILE* file = fopen(priv->input_history_path, "r+");
|
||||||
|
if (file == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read input history file */
|
||||||
|
file_lock_set(fileno(file), F_WRLCK);
|
||||||
|
char* content = girara_file_read2(file);
|
||||||
|
|
||||||
|
rewind(file);
|
||||||
|
if (ftruncate(fileno(file), 0) != 0) {
|
||||||
|
free(content);
|
||||||
|
file_lock_set(fileno(file), F_UNLCK);
|
||||||
|
fclose(file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char** tmp = g_strsplit(content, "\n", 0);
|
||||||
|
free(content);
|
||||||
|
|
||||||
|
/* write input history file */
|
||||||
|
for (size_t i = 0; tmp[i] != NULL; ++i) {
|
||||||
|
if (strlen(tmp[i]) == 0 || strchr(":/", tmp[i][0]) == NULL || strcmp(tmp[i], input) == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fprintf(file, "%s\n", tmp[i]);
|
||||||
|
}
|
||||||
|
g_strfreev(tmp);
|
||||||
|
fprintf(file, "%s\n", input);
|
||||||
|
|
||||||
|
file_lock_set(fileno(file), F_UNLCK);
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
@ -3,14 +3,17 @@
|
|||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
#include <girara/utils.h>
|
#include <girara/utils.h>
|
||||||
#include <girara/datastructures.h>
|
#include <girara/datastructures.h>
|
||||||
|
#include <girara/input-history.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "database-sqlite.h"
|
#include "database-sqlite.h"
|
||||||
|
|
||||||
static void zathura_database_interface_init(ZathuraDatabaseInterface* iface);
|
static void zathura_database_interface_init(ZathuraDatabaseInterface* iface);
|
||||||
|
static void io_interface_init(GiraraInputHistoryIOInterface* iface);
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE(ZathuraSQLDatabase, zathura_sqldatabase, G_TYPE_OBJECT,
|
G_DEFINE_TYPE_WITH_CODE(ZathuraSQLDatabase, zathura_sqldatabase, G_TYPE_OBJECT,
|
||||||
G_IMPLEMENT_INTERFACE(ZATHURA_TYPE_DATABASE, zathura_database_interface_init))
|
G_IMPLEMENT_INTERFACE(ZATHURA_TYPE_DATABASE, zathura_database_interface_init)
|
||||||
|
G_IMPLEMENT_INTERFACE(GIRARA_TYPE_INPUT_HISTORY_IO, io_interface_init))
|
||||||
|
|
||||||
static void sqlite_finalize(GObject* object);
|
static void sqlite_finalize(GObject* object);
|
||||||
static bool sqlite_add_bookmark(zathura_database_t* db, const char* file,
|
static bool sqlite_add_bookmark(zathura_database_t* db, const char* file,
|
||||||
@ -25,6 +28,8 @@ static bool sqlite_get_fileinfo(zathura_database_t* db, const char* file,
|
|||||||
zathura_fileinfo_t* file_info);
|
zathura_fileinfo_t* file_info);
|
||||||
static void sqlite_set_property(GObject* object, guint prop_id,
|
static void sqlite_set_property(GObject* object, guint prop_id,
|
||||||
const GValue* value, GParamSpec* pspec);
|
const GValue* value, GParamSpec* pspec);
|
||||||
|
static void sqlite_io_append(GiraraInputHistoryIO* db, const char*);
|
||||||
|
static girara_list_t* sqlite_io_read(GiraraInputHistoryIO* db);
|
||||||
|
|
||||||
typedef struct zathura_sqldatabase_private_s {
|
typedef struct zathura_sqldatabase_private_s {
|
||||||
sqlite3* session;
|
sqlite3* session;
|
||||||
@ -49,6 +54,14 @@ zathura_database_interface_init(ZathuraDatabaseInterface* iface)
|
|||||||
iface->get_fileinfo = sqlite_get_fileinfo;
|
iface->get_fileinfo = sqlite_get_fileinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
io_interface_init(GiraraInputHistoryIOInterface* iface)
|
||||||
|
{
|
||||||
|
/* initialize interface */
|
||||||
|
iface->append = sqlite_io_append;
|
||||||
|
iface->read = sqlite_io_read;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zathura_sqldatabase_class_init(ZathuraSQLDatabaseClass* class)
|
zathura_sqldatabase_class_init(ZathuraSQLDatabaseClass* class)
|
||||||
{
|
{
|
||||||
@ -132,6 +145,12 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path)
|
|||||||
static const char SQL_FILEINFO_ALTER2[] =
|
static const char SQL_FILEINFO_ALTER2[] =
|
||||||
"ALTER TABLE fileinfo ADD COLUMN first_page_column INTEGER;";
|
"ALTER TABLE fileinfo ADD COLUMN first_page_column INTEGER;";
|
||||||
|
|
||||||
|
static const char SQL_HISTORY_INIT[] =
|
||||||
|
"CREATE TABLE IF NOT EXISTS history ("
|
||||||
|
"time TIMESTAMP,"
|
||||||
|
"line TEXT,"
|
||||||
|
"PRIMARY KEY(line));";
|
||||||
|
|
||||||
sqlite3* session = NULL;
|
sqlite3* session = NULL;
|
||||||
if (sqlite3_open(path, &session) != SQLITE_OK) {
|
if (sqlite3_open(path, &session) != SQLITE_OK) {
|
||||||
girara_error("Could not open database: %s\n", path);
|
girara_error("Could not open database: %s\n", path);
|
||||||
@ -150,6 +169,12 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sqlite3_exec(session, SQL_HISTORY_INIT, NULL, 0, NULL) != SQLITE_OK) {
|
||||||
|
girara_error("Failed to initialize database: %s\n", path);
|
||||||
|
sqlite3_close(session);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const char* data_type = NULL;
|
const char* data_type = NULL;
|
||||||
if (sqlite3_table_column_metadata(session, NULL, "fileinfo", "pages_per_row", &data_type, NULL, NULL, NULL, NULL) != SQLITE_OK) {
|
if (sqlite3_table_column_metadata(session, NULL, "fileinfo", "pages_per_row", &data_type, NULL, NULL, NULL, NULL) != SQLITE_OK) {
|
||||||
girara_debug("old database table layout detected; updating ...");
|
girara_debug("old database table layout detected; updating ...");
|
||||||
@ -380,3 +405,51 @@ sqlite_get_fileinfo(zathura_database_t* db, const char* file,
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sqlite_io_append(GiraraInputHistoryIO* db, const char* input)
|
||||||
|
{
|
||||||
|
static const char SQL_HISTORY_SET[] =
|
||||||
|
"REPLACE INTO history (line, time) VALUES (?, DATETIME('now'));";
|
||||||
|
|
||||||
|
zathura_sqldatabase_private_t* priv = ZATHURA_SQLDATABASE_GET_PRIVATE(db);
|
||||||
|
sqlite3_stmt* stmt = prepare_statement(priv->session, SQL_HISTORY_SET);
|
||||||
|
if (stmt == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sqlite3_bind_text(stmt, 1, input, -1, NULL) != SQLITE_OK) {
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
girara_error("Failed to bind arguments.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_step(stmt);
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static girara_list_t*
|
||||||
|
sqlite_io_read(GiraraInputHistoryIO* db)
|
||||||
|
{
|
||||||
|
static const char SQL_HISTORY_GET[] =
|
||||||
|
"SELECT line FROM history ORDER BY time";
|
||||||
|
|
||||||
|
zathura_sqldatabase_private_t* priv = ZATHURA_SQLDATABASE_GET_PRIVATE(db);
|
||||||
|
sqlite3_stmt* stmt = prepare_statement(priv->session, SQL_HISTORY_GET);
|
||||||
|
if (stmt == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
girara_list_t* list = girara_list_new2((girara_free_function_t) g_free);
|
||||||
|
if (list == NULL) {
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||||
|
girara_list_append(list, g_strdup((const char*) sqlite3_column_text(stmt, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
@ -229,6 +229,8 @@ zathura_init(zathura_t* zathura)
|
|||||||
|
|
||||||
if (zathura->database == NULL) {
|
if (zathura->database == NULL) {
|
||||||
girara_error("Unable to initialize database. Bookmarks won't be available.");
|
girara_error("Unable to initialize database. Bookmarks won't be available.");
|
||||||
|
} else {
|
||||||
|
g_object_set(zathura->ui.session->command_history, "io", zathura->database, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bookmarks */
|
/* bookmarks */
|
||||||
|
Loading…
Reference in New Issue
Block a user