[tracker/transient] libtracker-data: Reimplement transient properties to work with direct-access
- From: Philip Van Hoof <pvanhoof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/transient] libtracker-data: Reimplement transient properties to work with direct-access
- Date: Mon, 22 Nov 2010 15:33:10 +0000 (UTC)
commit 7f08d8788b3892dee4ff109e5b5294756686b342
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Nov 22 16:32:37 2010 +0100
libtracker-data: Reimplement transient properties to work with direct-access
src/libtracker-data/tracker-data-manager.c | 4 +-
src/libtracker-data/tracker-db-interface-sqlite.c | 35 ++++++++-
src/libtracker-data/tracker-db-interface-sqlite.h | 6 +-
src/libtracker-data/tracker-db-manager.c | 83 +++++++++++++++++++--
4 files changed, 115 insertions(+), 13 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 98b1ca3..78b28a1 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -2490,11 +2490,11 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
}
sql = g_string_new ("");
- g_string_append_printf (sql, "CREATE %sTABLE \"%s_%s\" ("
+ g_string_append_printf (sql, "CREATE TABLE %s\"%s_%s\" ("
"ID INTEGER NOT NULL, "
"\"%s\" %s NOT NULL, "
"\"%s:graph\" INTEGER",
- transient ? "TEMPORARY " : "",
+ transient ? "IF NOT EXISTS transient." : "",
service_name,
field_name,
field_name,
diff --git a/src/libtracker-data/tracker-db-interface-sqlite.c b/src/libtracker-data/tracker-db-interface-sqlite.c
index de7089f..9bf5464 100644
--- a/src/libtracker-data/tracker-db-interface-sqlite.c
+++ b/src/libtracker-data/tracker-db-interface-sqlite.c
@@ -51,6 +51,7 @@ struct TrackerDBInterface {
GObject parent_instance;
gchar *filename;
+ gchar *transient_filename;
sqlite3 *db;
GHashTable *dynamic_statements;
@@ -127,6 +128,7 @@ static gboolean db_cursor_iter_next (TrackerDBCursor
enum {
PROP_0,
PROP_FILENAME,
+ PROP_TRANSIENT_FILENAME,
PROP_RO
};
@@ -530,8 +532,10 @@ static void
open_database (TrackerDBInterface *db_interface)
{
int mode;
+ sqlite3 *transient = NULL;
g_assert (db_interface->filename != NULL);
+ g_assert (db_interface->transient_filename != NULL);
if (!db_interface->ro) {
mode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
@@ -539,6 +543,12 @@ open_database (TrackerDBInterface *db_interface)
mode = SQLITE_OPEN_READONLY;
}
+ if (sqlite3_open_v2 (db_interface->transient_filename, &transient, mode | SQLITE_OPEN_NOMUTEX, NULL) != SQLITE_OK) {
+ g_critical ("Could not open transient sqlite3 database:'%s'", db_interface->transient_filename);
+ } else {
+ sqlite3_close (transient);
+ }
+
if (sqlite3_open_v2 (db_interface->filename, &db_interface->db, mode | SQLITE_OPEN_NOMUTEX, NULL) != SQLITE_OK) {
g_critical ("Could not open sqlite3 database:'%s'", db_interface->filename);
} else {
@@ -626,6 +636,9 @@ tracker_db_interface_sqlite_set_property (GObject *object,
case PROP_RO:
db_iface->ro = g_value_get_boolean (value);
break;
+ case PROP_TRANSIENT_FILENAME:
+ db_iface->transient_filename = g_value_dup_string (value);
+ break;
case PROP_FILENAME:
db_iface->filename = g_value_dup_string (value);
break;
@@ -651,6 +664,9 @@ tracker_db_interface_sqlite_get_property (GObject *object,
case PROP_FILENAME:
g_value_set_string (value, db_iface->filename);
break;
+ case PROP_TRANSIENT_FILENAME:
+ g_value_set_string (value, db_iface->transient_filename);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -675,6 +691,7 @@ close_database (TrackerDBInterface *db_interface)
#endif
rc = sqlite3_close (db_interface->db);
+
g_warn_if_fail (rc == SQLITE_OK);
}
@@ -731,6 +748,7 @@ tracker_db_interface_sqlite_finalize (GObject *object)
g_message ("Closed sqlite3 database:'%s'", db_interface->filename);
+ g_free (db_interface->transient_filename);
g_free (db_interface->filename);
g_free (db_interface->busy_status);
@@ -758,6 +776,14 @@ tracker_db_interface_class_init (TrackerDBInterfaceClass *class)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
+ PROP_TRANSIENT_FILENAME,
+ g_param_spec_string ("transient-filename",
+ "DB transient-filename",
+ "DB transient-filename",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class,
PROP_RO,
g_param_spec_boolean ("read-only",
"Read only",
@@ -1107,6 +1133,7 @@ create_result_set_from_stmt (TrackerDBInterface *interface,
sqlite3_close (interface->db);
g_unlink (interface->filename);
+ g_unlink (interface->transient_filename);
g_error ("SQLite experienced an error with file:'%s'. "
"It is either NOT a SQLite database or it is "
@@ -1191,18 +1218,22 @@ tracker_db_interface_execute_vquery (TrackerDBInterface *db_interface,
}
TrackerDBInterface *
-tracker_db_interface_sqlite_new (const gchar *filename)
+tracker_db_interface_sqlite_new (const gchar *filename,
+ const gchar *transient_filename)
{
return g_object_new (TRACKER_TYPE_DB_INTERFACE,
"filename", filename,
+ "transient-filename", transient_filename,
NULL);
}
TrackerDBInterface *
-tracker_db_interface_sqlite_new_ro (const gchar *filename)
+tracker_db_interface_sqlite_new_ro (const gchar *filename,
+ const gchar *transient_filename)
{
return g_object_new (TRACKER_TYPE_DB_INTERFACE,
"filename", filename,
+ "transient-filename", filename,
"read-only", TRUE,
NULL);
}
diff --git a/src/libtracker-data/tracker-db-interface-sqlite.h b/src/libtracker-data/tracker-db-interface-sqlite.h
index 071a1b9..b5f5a22 100644
--- a/src/libtracker-data/tracker-db-interface-sqlite.h
+++ b/src/libtracker-data/tracker-db-interface-sqlite.h
@@ -32,8 +32,10 @@ G_BEGIN_DECLS
#define TRACKER_COLLATION_NAME "TRACKER"
-TrackerDBInterface *tracker_db_interface_sqlite_new (const gchar *filename);
-TrackerDBInterface *tracker_db_interface_sqlite_new_ro (const gchar *filename);
+TrackerDBInterface *tracker_db_interface_sqlite_new (const gchar *filename,
+ const gchar *transient_filename);
+TrackerDBInterface *tracker_db_interface_sqlite_new_ro (const gchar *filename,
+ const gchar *transient_filename);
gint64 tracker_db_interface_sqlite_get_last_insert_id (TrackerDBInterface *interface);
void tracker_db_interface_sqlite_enable_shared_cache (void);
void tracker_db_interface_sqlite_fts_init (TrackerDBInterface *interface,
diff --git a/src/libtracker-data/tracker-db-manager.c b/src/libtracker-data/tracker-db-manager.c
index 92d8d48..ee0bde2 100644
--- a/src/libtracker-data/tracker-db-manager.c
+++ b/src/libtracker-data/tracker-db-manager.c
@@ -19,6 +19,9 @@
#include "config.h"
+#include <sys/types.h>
+#include <pwd.h>
+
#include <string.h>
#include <stdlib.h>
#include <regex.h>
@@ -155,6 +158,7 @@ static gpointer db_type_enum_class_pointer;
static TrackerDBManagerFlags old_flags = 0;
static guint s_cache_size;
static guint u_cache_size;
+static gchar *transient_filename = NULL;
static GStaticPrivate interface_data_key = G_STATIC_PRIVATE_INIT;
@@ -215,11 +219,12 @@ db_set_params (TrackerDBInterface *iface,
pragmas_file = g_getenv ("TRACKER_PRAGMAS_FILE");
if (pragmas_file && g_file_get_contents (pragmas_file, &queries, NULL, NULL)) {
+ gchar *query;
g_debug ("PRAGMA's from file: %s", pragmas_file);
- gchar *query = strtok (queries, "\n");
+ query = strtok (queries, "\n");
while (query) {
g_debug (" INIT query: %s", query);
- tracker_db_interface_execute_query (iface, NULL, query);
+ tracker_db_interface_execute_query (iface, NULL, "%s", query);
query = strtok (NULL, "\n");
}
g_free (queries);
@@ -289,12 +294,16 @@ db_interface_get (TrackerDB type,
path,
db_type_to_string (type));
- iface = tracker_db_interface_sqlite_new (path);
+ iface = tracker_db_interface_sqlite_new (path, transient_filename);
db_set_params (iface,
dbs[type].cache_size,
dbs[type].page_size);
+ db_exec_no_reply (iface,
+ "ATTACH '%s' as 'transient'",
+ transient_filename);
+
return iface;
}
@@ -685,6 +694,50 @@ db_recreate_all (void)
db_set_locale (setlocale (LC_COLLATE, NULL));
}
+static void
+tracker_db_manager_prepare_transient (gboolean readonly)
+{
+ gchar *shm_path;
+ struct passwd *pwd;
+
+ shm_path = g_build_filename (G_DIR_SEPARATOR_S "dev", "shm", NULL);
+
+ g_free (transient_filename);
+
+ if (g_file_test (shm_path, G_FILE_TEST_IS_DIR)) {
+ g_free (shm_path);
+ shm_path = g_build_filename (G_DIR_SEPARATOR_S "dev", "shm", g_get_user_name (), NULL);
+ transient_filename = g_build_filename (shm_path,
+ "tracker-transient.db",
+ NULL);
+ } else {
+ g_free (shm_path);
+ shm_path = g_build_path (g_get_tmp_dir (), g_get_user_name (), NULL);
+ transient_filename = g_build_filename (g_get_tmp_dir (),
+ g_get_user_name (),
+ "tracker-transient.db",
+ NULL);
+ }
+
+ if (!readonly) {
+ if (!g_file_test (shm_path, G_FILE_TEST_IS_DIR)) {
+ g_mkdir_with_parents (shm_path, S_IRUSR | S_IWUSR | S_IXUSR |
+ S_IRGRP | S_IWGRP | S_IXGRP);
+ } else {
+ g_chmod (shm_path, S_IRUSR | S_IWUSR | S_IXUSR |
+ S_IRGRP | S_IWGRP | S_IXGRP);
+ }
+
+ pwd = getpwnam (g_get_user_name ());
+
+ if (pwd != NULL) {
+ chown (shm_path, pwd->pw_uid, -1);
+ }
+ }
+
+ g_free (shm_path);
+}
+
void
tracker_db_manager_init_locations (void)
{
@@ -710,6 +763,8 @@ tracker_db_manager_init_locations (void)
dbs[i].abs_filename = g_build_filename (dir, dbs[i].file, NULL);
}
+ tracker_db_manager_prepare_transient (TRUE);
+
locations_initialized = TRUE;
}
@@ -840,6 +895,8 @@ tracker_db_manager_init (TrackerDBManagerFlags flags,
}
}
+ tracker_db_manager_prepare_transient (flags & TRACKER_DB_MANAGER_READONLY);
+
locations_initialized = TRUE;
/* If we are just initializing to remove the databases,
@@ -1058,6 +1115,8 @@ tracker_db_manager_shutdown (void)
}
}
+ g_free (transient_filename);
+ transient_filename = NULL;
g_free (data_dir);
data_dir = NULL;
g_free (user_data_dir);
@@ -1416,12 +1475,16 @@ tracker_db_manager_get_db_interfaces (gint num, ...)
TrackerDB db = va_arg (args, TrackerDB);
if (!connection) {
- connection = tracker_db_interface_sqlite_new (dbs[db].abs_filename);
-
+ connection = tracker_db_interface_sqlite_new (dbs[db].abs_filename,
+ transient_filename);
db_set_params (connection,
dbs[db].cache_size,
dbs[db].page_size);
+ db_exec_no_reply (connection,
+ "ATTACH '%s' as 'transient'",
+ transient_filename);
+
} else {
db_exec_no_reply (connection,
"ATTACH '%s' as '%s'",
@@ -1439,7 +1502,7 @@ static TrackerDBInterface *
tracker_db_manager_get_db_interfaces_ro (gint num, ...)
{
gint n_args;
- va_list args;
+ va_list args;
TrackerDBInterface *connection = NULL;
g_return_val_if_fail (initialized != FALSE, NULL);
@@ -1449,10 +1512,16 @@ tracker_db_manager_get_db_interfaces_ro (gint num, ...)
TrackerDB db = va_arg (args, TrackerDB);
if (!connection) {
- connection = tracker_db_interface_sqlite_new_ro (dbs[db].abs_filename);
+ connection = tracker_db_interface_sqlite_new_ro (dbs[db].abs_filename,
+ transient_filename);
db_set_params (connection,
dbs[db].cache_size,
dbs[db].page_size);
+
+ db_exec_no_reply (connection,
+ "ATTACH '%s' as 'transient'",
+ transient_filename);
+
} else {
db_exec_no_reply (connection,
"ATTACH '%s' as '%s'",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]