summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/reference/libtracker-sparql/libtracker-sparql-docs.xml1
-rw-r--r--docs/reference/libtracker-sparql/libtracker-sparql-sections.txt1
-rw-r--r--examples/libtracker-sparql/async-connection.c5
-rw-r--r--src/libtracker-data/tracker-data-manager.c119
-rw-r--r--src/libtracker-data/tracker-data-manager.h2
-rw-r--r--src/libtracker-data/tracker-db-manager.c352
-rw-r--r--src/libtracker-data/tracker-db-manager.h23
-rw-r--r--src/libtracker-direct/tracker-direct.c19
-rw-r--r--src/libtracker-sparql-backend/tracker-backend.vala2
-rw-r--r--src/libtracker-sparql/meson.build1
-rw-r--r--src/libtracker-sparql/tracker-connection.c28
-rw-r--r--src/libtracker-sparql/tracker-utils.c13
-rw-r--r--src/libtracker-sparql/tracker-utils.h5
-rw-r--r--src/tracker/tracker-sql.c2
-rw-r--r--tests/libtracker-data/tracker-insert-or-replace-test.c2
-rw-r--r--tests/libtracker-data/tracker-ontology-change-test.c5
-rw-r--r--tests/libtracker-data/tracker-ontology-test.c10
-rw-r--r--tests/libtracker-data/tracker-sparql-blank-test.c4
-rw-r--r--tests/libtracker-data/tracker-sparql-test.c5
-rw-r--r--tests/libtracker-fts/tracker-fts-test.c4
20 files changed, 242 insertions, 361 deletions
diff --git a/docs/reference/libtracker-sparql/libtracker-sparql-docs.xml b/docs/reference/libtracker-sparql/libtracker-sparql-docs.xml
index 12a9c16ce..7e00c13bf 100644
--- a/docs/reference/libtracker-sparql/libtracker-sparql-docs.xml
+++ b/docs/reference/libtracker-sparql/libtracker-sparql-docs.xml
@@ -36,6 +36,7 @@
<xi:include href="xml/tracker-sparql-cursor.xml"/>
<xi:include href="xml/tracker-notifier.xml"/>
<xi:include href="xml/tracker-endpoint.xml"/>
+ <xi:include href="xml/tracker-ontologies.xml"/>
<xi:include href="xml/tracker-misc.xml"/>
<xi:include href="xml/tracker-version.xml"/>
</part>
diff --git a/docs/reference/libtracker-sparql/libtracker-sparql-sections.txt b/docs/reference/libtracker-sparql/libtracker-sparql-sections.txt
index 0856947f6..c12976073 100644
--- a/docs/reference/libtracker-sparql/libtracker-sparql-sections.txt
+++ b/docs/reference/libtracker-sparql/libtracker-sparql-sections.txt
@@ -7,6 +7,7 @@ tracker_sparql_escape_string
tracker_sparql_escape_uri
tracker_sparql_escape_uri_printf
tracker_sparql_escape_uri_vprintf
+tracker_sparql_get_ontology_nepomuk
<SUBSECTION Standard>
TRACKER_TYPE_URI
tracker_uri_get_type
diff --git a/examples/libtracker-sparql/async-connection.c b/examples/libtracker-sparql/async-connection.c
index 6d44cf607..40ae55a34 100644
--- a/examples/libtracker-sparql/async-connection.c
+++ b/examples/libtracker-sparql/async-connection.c
@@ -137,7 +137,7 @@ connection_cb (GObject *object,
gint
main (gint argc, gchar *argv[])
{
- GFile *store;
+ g_autoptr(GFile) store, ontology;
MyData *md;
if (argc > 1) {
@@ -152,9 +152,10 @@ main (gint argc, gchar *argv[])
md->timer = g_timer_new ();
md->cancellable = g_cancellable_new ();
+ ontology = tracker_sparql_get_ontology_nepomuk ();
tracker_sparql_connection_new_async (0,
store,
- NULL,
+ ontology,
md->cancellable,
connection_cb,
md);
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 3bf8223f3..6aa496118 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -69,8 +69,6 @@ struct _TrackerDataManager {
GFile *ontology_location;
GFile *cache_location;
guint initialized : 1;
- guint restoring_backup : 1;
- guint first_time_index : 1;
guint flags;
gint select_cache_size;
@@ -3853,7 +3851,6 @@ TrackerDataManager *
tracker_data_manager_new (TrackerDBManagerFlags flags,
GFile *cache_location,
GFile *ontology_location,
- gboolean restoring_backup,
guint select_cache_size,
guint update_cache_size)
{
@@ -3864,18 +3861,12 @@ tracker_data_manager_new (TrackerDBManagerFlags flags,
return NULL;
}
- if ((flags & TRACKER_DB_MANAGER_READONLY) == 0 && !ontology_location) {
- g_warning ("Ontology location must be provided");
- return NULL;
- }
-
manager = g_object_new (TRACKER_TYPE_DATA_MANAGER, NULL);
/* TODO: Make these properties */
g_set_object (&manager->cache_location, cache_location);
g_set_object (&manager->ontology_location, ontology_location);
manager->flags = flags;
- manager->restoring_backup = restoring_backup;
manager->select_cache_size = select_cache_size;
manager->update_cache_size = update_cache_size;
@@ -4064,7 +4055,7 @@ tracker_data_manager_initable_init (GInitable *initable,
{
TrackerDataManager *manager = TRACKER_DATA_MANAGER (initable);
TrackerDBInterface *iface;
- gboolean is_first_time_index, check_ontology, has_graph_table = FALSE;
+ gboolean is_create, has_graph_table = FALSE;
TrackerDBCursor *cursor;
TrackerDBStatement *stmt;
GHashTable *ontos_table;
@@ -4094,14 +4085,13 @@ tracker_data_manager_initable_init (GInitable *initable,
manager->db_manager = tracker_db_manager_new (manager->flags,
manager->cache_location,
- &is_first_time_index,
- manager->restoring_backup,
+ &is_create,
FALSE,
manager->select_cache_size,
manager->update_cache_size,
- busy_callback, manager, "",
+ busy_callback, manager,
G_OBJECT (manager),
- manager->ontologies,
+ manager->ontologies,
&internal_error);
if (!manager->db_manager) {
g_propagate_error (error, internal_error);
@@ -4113,8 +4103,6 @@ tracker_data_manager_initable_init (GInitable *initable,
g_signal_connect (manager->db_manager, "update-interface",
G_CALLBACK (update_interface_cb), manager);
- manager->first_time_index = is_first_time_index;
-
tracker_data_manager_update_status (manager, "Initializing data manager");
iface = tracker_db_manager_get_writable_db_interface (manager->db_manager);
@@ -4131,7 +4119,11 @@ tracker_data_manager_initable_init (GInitable *initable,
return FALSE;
}
- if (is_first_time_index && !read_only) {
+ if (is_create) {
+ TrackerOntology **ontologies;
+ guint n_ontologies, i;
+
+ g_info ("Applying ontologies from %s", g_file_peek_path (manager->ontology_location));
sorted = get_ontologies (manager, manager->ontology_location, &internal_error);
if (internal_error) {
@@ -4139,8 +4131,6 @@ tracker_data_manager_initable_init (GInitable *initable,
return FALSE;
}
- /* load ontology from files into memory (max_id starts at zero: first-time) */
-
for (l = sorted; l; l = l->next) {
GError *ontology_error = NULL;
GFile *ontology_file = l->data;
@@ -4177,7 +4167,7 @@ tracker_data_manager_initable_init (GInitable *initable,
if (!internal_error) {
tracker_data_ontology_import_into_db (manager, iface,
- FALSE,
+ FALSE,
&internal_error);
}
@@ -4208,59 +4198,61 @@ tracker_data_manager_initable_init (GInitable *initable,
write_ontologies_gvdb (manager, TRUE /* overwrite */, NULL);
- g_list_free_full (sorted, g_object_unref);
- sorted = NULL;
+ ontologies = tracker_ontologies_get_ontologies (manager->ontologies, &n_ontologies);
- /* First time, no need to check ontology */
- check_ontology = FALSE;
- } else {
- if (!read_only) {
- /* Load ontology from database into memory */
- db_get_static_data (iface, manager, &internal_error);
- check_ontology = (manager->flags & TRACKER_DB_MANAGER_DO_NOT_CHECK_ONTOLOGY) == 0;
+ for (i = 0; i < n_ontologies; i++) {
+ GError *n_error = NULL;
- if (internal_error) {
- g_propagate_error (error, internal_error);
- return FALSE;
+ update_ontology_last_modified (manager, iface, ontologies[i], &n_error);
+
+ if (n_error) {
+ g_critical ("%s", n_error->message);
+ g_clear_error (&n_error);
}
+ }
- write_ontologies_gvdb (manager, FALSE /* overwrite */, NULL);
- } else {
- GError *gvdb_error = NULL;
+ g_list_free_full (sorted, g_object_unref);
+ sorted = NULL;
+ } else {
+ GError *gvdb_error = NULL;
+ gboolean load_from_db = TRUE;
+ if (read_only) {
+ /* Not all ontology information is saved in the gvdb cache, so
+ * it can only be used for read-only connections. */
+ g_info ("Loading cached ontologies from gvdb cache");
load_ontologies_gvdb (manager, &gvdb_error);
- check_ontology = FALSE;
if (gvdb_error) {
+ g_debug ("Error loading ontology cache: %s. ", gvdb_error->message);
g_clear_error (&gvdb_error);
-
- /* fall back to loading ontology from database into memory */
- db_get_static_data (iface, manager, &internal_error);
- if (internal_error) {
- g_propagate_error (error, internal_error);
- return FALSE;
- }
+ } else {
+ load_from_db = FALSE;
}
}
- tracker_data_manager_initialize_iface (manager, iface, &internal_error);
- if (internal_error) {
- g_propagate_error (error, internal_error);
- return FALSE;
+ if (load_from_db) {
+ g_info ("Loading ontologies from database.");
+
+ db_get_static_data (iface, manager, &internal_error);
+ if (internal_error) {
+ g_propagate_error (error, internal_error);
+ return FALSE;
+ }
+
+ if (!read_only) {
+ write_ontologies_gvdb (manager, FALSE /* overwrite */, NULL);
+ }
}
- }
- if (!read_only) {
- has_graph_table = query_table_exists (iface, "Graph", &internal_error);
+ tracker_data_manager_initialize_iface (manager, iface, &internal_error);
if (internal_error) {
g_propagate_error (error, internal_error);
return FALSE;
}
-
- check_ontology |= !has_graph_table;
}
- if (check_ontology) {
+ if (!is_create && manager->ontology_location) {
GList *to_reload = NULL;
GList *ontos = NULL;
GPtrArray *seen_classes;
@@ -4271,6 +4263,8 @@ tracker_data_manager_initable_init (GInitable *initable,
seen_classes = g_ptr_array_new ();
seen_properties = g_ptr_array_new ();
+ g_info ("Applying ontologies from %s to existing database", g_file_peek_path (manager->ontology_location));
+
/* Get all the ontology files from ontology_location */
ontos = get_ontologies (manager, manager->ontology_location, &internal_error);
@@ -4355,6 +4349,7 @@ tracker_data_manager_initable_init (GInitable *initable,
GError *ontology_error = NULL;
gint val = GPOINTER_TO_INT (value);
+ has_graph_table = query_table_exists (iface, "Graph", &internal_error);
if (!has_graph_table) {
/* No graph table and no resource triggers,
* the table must be recreated.
@@ -4632,26 +4627,12 @@ tracker_data_manager_initable_init (GInitable *initable,
g_hash_table_unref (ontos_table);
g_list_free_full (ontos, g_object_unref);
- } else if (is_first_time_index && !read_only) {
- TrackerOntology **ontologies;
- guint n_ontologies, i;
-
- ontologies = tracker_ontologies_get_ontologies (manager->ontologies, &n_ontologies);
-
- for (i = 0; i < n_ontologies; i++) {
- GError *n_error = NULL;
- update_ontology_last_modified (manager, iface, ontologies[i], &n_error);
-
- if (n_error) {
- g_critical ("%s", n_error->message);
- g_clear_error (&n_error);
- }
- }
}
+
skip_ontology_check:
- if (!read_only && is_first_time_index) {
+ if (!read_only && is_create) {
tracker_db_manager_set_current_locale (manager->db_manager);
tracker_db_manager_tokenizer_update (manager->db_manager);
} else if (!read_only && tracker_db_manager_locale_changed (manager->db_manager, NULL)) {
diff --git a/src/libtracker-data/tracker-data-manager.h b/src/libtracker-data/tracker-data-manager.h
index c3dd32d6d..af558789c 100644
--- a/src/libtracker-data/tracker-data-manager.h
+++ b/src/libtracker-data/tracker-data-manager.h
@@ -59,10 +59,10 @@ typedef enum {
GType tracker_data_manager_get_type (void) G_GNUC_CONST;
GQuark tracker_data_ontology_error_quark (void);
+
TrackerDataManager * tracker_data_manager_new (TrackerDBManagerFlags flags,
GFile *cache_location,
GFile *ontology_location,
- gboolean restoring_backup,
guint select_cache_size,
guint update_cache_size);
diff --git a/src/libtracker-data/tracker-db-manager.c b/src/libtracker-data/tracker-db-manager.c
index 8292673aa..cca9350d7 100644
--- a/src/libtracker-data/tracker-db-manager.c
+++ b/src/libtracker-data/tracker-db-manager.c
@@ -240,28 +240,6 @@ db_set_params (TrackerDBInterface *iface,
g_debug (" Setting cache size to %d", cache_size);
}
-static void
-tracker_db_manager_remove_all (TrackerDBManager *db_manager)
-{
- gchar *filename;
-
- if ((db_manager->flags & TRACKER_DB_MANAGER_IN_MEMORY) != 0)
- return;
-
- g_info ("Removing all files for database %s", db_manager->db.abs_filename);
-
- g_unlink (db_manager->db.abs_filename);
-
- /* also delete shm and wal helper files */
- filename = g_strdup_printf ("%s-shm", db_manager->db.abs_filename);
- g_unlink (filename);
- g_free (filename);
-
- filename = g_strdup_printf ("%s-wal", db_manager->db.abs_filename);
- g_unlink (filename);
- g_free (filename);
-}
-
static gboolean
tracker_db_manager_get_metadata (TrackerDBManager *db_manager,
const gchar *key,
@@ -447,33 +425,6 @@ tracker_db_manager_set_current_locale (TrackerDBManager *db_manager)
}
static void
-db_recreate_all (TrackerDBManager *db_manager,
- GError **error)
-{
- GError *internal_error = NULL;
-
- /* We call an internal version of this function here
- * because at the time 'initialized' = FALSE and that
- * will cause errors and do nothing.
- */
- g_debug ("Cleaning up database files for reindex");
-
- tracker_db_manager_remove_all (db_manager);
-
- /* Now create the databases and close them */
- g_info ("Creating database files for %s...", db_manager->db.abs_filename);
-
- db_manager->db.iface = tracker_db_manager_create_db_interface (db_manager, FALSE, &internal_error);
- if (internal_error) {
- g_propagate_error (error, internal_error);
- return;
- }
-
- g_clear_object (&db_manager->db.iface);
- g_clear_object (&db_manager->db.wal_iface);
-}
-
-static void
tracker_db_manager_ensure_location (TrackerDBManager *db_manager,
GFile *cache_location)
{
@@ -497,57 +448,98 @@ tracker_db_manager_ensure_location (TrackerDBManager *db_manager,
g_free (dir);
}
-static void
-perform_recreate (TrackerDBManager *db_manager,
- gboolean *first_time,
- GError **error)
+gboolean
+tracker_db_manager_db_exists (GFile *cache_location)
+{
+ gchar *dir;
+ gchar *filename;
+ gboolean db_exists = FALSE;
+
+ dir = g_file_get_path (cache_location);
+ filename = g_build_filename (dir, db_base.file, NULL);
+
+ db_exists = g_file_test (filename, G_FILE_TEST_EXISTS);
+
+ g_free (dir);
+ g_free (filename);
+
+ return db_exists;
+}
+
+static gboolean
+db_check_integrity (TrackerDBManager *db_manager)
{
GError *internal_error = NULL;
+ TrackerDBStatement *stmt;
+ TrackerDBCursor *cursor = NULL;
- if (first_time) {
- *first_time = TRUE;
+ stmt = tracker_db_interface_create_statement (db_manager->db.iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE,
+ &internal_error,
+ "PRAGMA integrity_check(1)");
+
+ if (!stmt) {
+ if (internal_error) {
+ g_message ("Corrupt database: failed to create integrity_check statement: %s", internal_error->message);
+ }
+
+ g_clear_error (&internal_error);
+ return FALSE;
}
- g_clear_object (&db_manager->db.iface);
- g_clear_object (&db_manager->db.wal_iface);
+ cursor = tracker_db_statement_start_cursor (stmt, NULL);
+ g_object_unref (stmt);
- if ((db_manager->flags & TRACKER_DB_MANAGER_IN_MEMORY) == 0 &&
- !tracker_file_system_has_enough_space (db_manager->data_dir, TRACKER_DB_MIN_REQUIRED_SPACE, TRUE)) {
- g_set_error (error,
- TRACKER_DB_INTERFACE_ERROR,
- TRACKER_DB_OPEN_ERROR,
- "Filesystem has not enough space");
- return;
+ if (cursor) {
+ if (tracker_db_cursor_iter_next (cursor, NULL, NULL)) {
+ const gchar *check_result;
+
+ check_result = tracker_db_cursor_get_string (cursor, 0, NULL);
+ if (g_strcmp0 (check_result, "ok") != 0) {
+ g_message ("Corrupt database: sqlite integrity check returned '%s'", check_result);
+ return FALSE;
+ }
+ }
+ g_object_unref (cursor);
}
- db_recreate_all (db_manager, &internal_error);
+ /* ensure that database has been initialized by an earlier tracker-store start
+ by checking whether Resource table exists */
+ stmt = tracker_db_interface_create_statement (db_manager->db.iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE,
+ &internal_error,
+ "SELECT 1 FROM Resource");
+ if (!stmt) {
+ if (internal_error) {
+ g_message ("Corrupt database: failed to create resource check statement: %s", internal_error->message);
+ }
- if (internal_error) {
- g_propagate_error (error, internal_error);
+ g_clear_error (&internal_error);
+ return FALSE;
}
+
+ g_object_unref (stmt);
+
+ return TRUE;
}
TrackerDBManager *
tracker_db_manager_new (TrackerDBManagerFlags flags,
GFile *cache_location,
gboolean *first_time,
- gboolean restoring_backup,
gboolean shared_cache,
guint select_cache_size,
guint update_cache_size,
TrackerBusyCallback busy_callback,
gpointer busy_user_data,
- const gchar *busy_operation,
GObject *iface_data,
gpointer vtab_data,
GError **error)
{
TrackerDBManager *db_manager;
TrackerDBVersion version;
- gboolean need_reindex;
int in_use_file;
TrackerDBInterface *resources_iface;
GError *internal_error = NULL;
+ gboolean need_to_create = FALSE;
db_manager = g_object_new (TRACKER_TYPE_DB_MANAGER, NULL);
db_manager->vtab_data = vtab_data;
@@ -557,8 +549,6 @@ tracker_db_manager_new (TrackerDBManagerFlags flags,
*first_time = FALSE;
}
- need_reindex = FALSE;
-
/* Set up locations */
g_debug ("Setting database locations");
@@ -590,18 +580,12 @@ tracker_db_manager_new (TrackerDBManagerFlags flags,
g_debug ("Checking whether database files exist");
- /* Check we have the database in place, if it is
- * missing, we reindex.
- *
- * There's no need to check for files not existing (for
- * reindex) if reindexing is already needed.
- */
if ((db_manager->flags & TRACKER_DB_MANAGER_IN_MEMORY) != 0) {
- need_reindex = TRUE;
+ need_to_create = TRUE;
} else if (!g_file_test (db_manager->db.abs_filename, G_FILE_TEST_EXISTS)) {
if ((flags & TRACKER_DB_MANAGER_READONLY) == 0) {
- g_info ("Could not find database file:'%s', reindex will be forced", db_manager->db.abs_filename);
- need_reindex = TRUE;
+ g_info ("Could not find database file:'%s', will create it.", db_manager->db.abs_filename);
+ need_to_create = TRUE;
} else {
g_set_error (error,
TRACKER_DB_INTERFACE_ERROR,
@@ -612,29 +596,25 @@ tracker_db_manager_new (TrackerDBManagerFlags flags,
return NULL;
}
} else {
- g_info ("Checking database version");
+ g_debug ("Checking database version");
version = db_get_version (db_manager);
if (version < TRACKER_DB_VERSION_NOW) {
- g_info (" A reindex will be forced");
- need_reindex = TRUE;
+ g_set_error (error,
+ TRACKER_DB_INTERFACE_ERROR,
+ TRACKER_DB_OPEN_ERROR,
+ "Database version is too old: got version %i, but %i is needed",
+ version, TRACKER_DB_VERSION_NOW);
+
+ g_object_unref (db_manager);
+ return NULL;
}
}
-
db_manager->locations_initialized = TRUE;
- /* Don't do remove-dbs for readonly (direct-access) */
- if ((flags & TRACKER_DB_MANAGER_READONLY) == 0) {
-
- /* If we are just initializing to remove the databases,
- * return here.
- */
- if ((flags & TRACKER_DB_MANAGER_REMOVE_ALL) != 0) {
- return db_manager;
- }
- } else {
+ if ((flags & TRACKER_DB_MANAGER_READONLY) != 0) {
GValue value = G_VALUE_INIT;
TrackerDBManagerFlags fts_flags = 0;
@@ -655,160 +635,76 @@ tracker_db_manager_new (TrackerDBManagerFlags flags,
tracker_db_interface_sqlite_enable_shared_cache ();
}
- /* Should we reindex? If so, just remove all databases files,
- * NOT the paths, note, that these paths are also used for
- * other things like the nfs lock file.
- */
- if (flags & TRACKER_DB_MANAGER_FORCE_REINDEX || need_reindex) {
-
- if (flags & TRACKER_DB_MANAGER_READONLY) {
- /* no reindexing supported in read-only mode (direct access) */
+ if (need_to_create) {
+ *first_time = TRUE;
+ if ((db_manager->flags & TRACKER_DB_MANAGER_IN_MEMORY) == 0 &&
+ !tracker_file_system_has_enough_space (db_manager->data_dir, TRACKER_DB_MIN_REQUIRED_SPACE, TRUE)) {
g_set_error (error,
TRACKER_DB_INTERFACE_ERROR,
TRACKER_DB_OPEN_ERROR,
- "No reindexing supported in read-only mode (direct access)");
-
- g_object_unref (db_manager);
- return NULL;
+ "Filesystem does not have enough space");
+ return FALSE;
}
- perform_recreate (db_manager, first_time, &internal_error);
+ g_info ("Creating database files for %s...", db_manager->db.abs_filename);
+ db_manager->db.iface = tracker_db_manager_create_db_interface (db_manager, FALSE, &internal_error);
if (internal_error) {
g_propagate_error (error, internal_error);
g_object_unref (db_manager);
- return NULL;
+ return FALSE;
}
- tracker_db_manager_update_version (db_manager);
- } else if ((flags & TRACKER_DB_MANAGER_READONLY) == 0) {
- /* do not do shutdown check for read-only mode (direct access) */
- gboolean must_recreate = FALSE;
+ g_clear_object (&db_manager->db.iface);
- /* Load databases */
+ tracker_db_manager_update_version (db_manager);
+ } else {
g_info ("Loading files for database %s...", db_manager->db.abs_filename);
- if (!must_recreate && g_file_test (db_manager->in_use_filename, G_FILE_TEST_EXISTS)) {
- gsize size = 0;
- struct stat st;
- TrackerDBStatement *stmt;
+ if ((flags & TRACKER_DB_MANAGER_READONLY) == 0) {
+ /* Check that the database was closed cleanly and do a deeper integrity
+ * check if it wasn't, raising an error if we detect corruption. */
- g_info ("Didn't shut down cleanly last time, doing integrity checks");
+ if (g_file_test (db_manager->in_use_filename, G_FILE_TEST_EXISTS)) {
+ gsize size = 0;
+ struct stat st;
- if (g_stat (db_manager->db.abs_filename, &st) == 0) {
- size = st.st_size;
- }
+ g_info ("Didn't shut down cleanly last time, doing integrity checks");
- /* Size is 1 when using echo > file.db, none of our databases
- * are only one byte in size even initually. */
+ if (g_stat (db_manager->db.abs_filename, &st) == 0) {
+ size = st.st_size;
+ }
- if (size <= 1) {
- if (!restoring_backup) {
- must_recreate = TRUE;
- } else {
- g_set_error (error,
- TRACKER_DB_INTERFACE_ERROR,
- TRACKER_DB_OPEN_ERROR,
- "Corrupt db file");
- g_object_unref (db_manager);
- return NULL;
+ /* Size is 1 when using echo > file.db, none of our databases
+ * are only one byte in size even initually. */
+ if (size <= 1) {
+ g_info ("Database is corrupt: size is 1 byte or less.");
+ return FALSE;
}
- }
- if (!must_recreate) {
db_manager->db.iface = tracker_db_manager_create_db_interface (db_manager, FALSE, &internal_error);
if (internal_error) {
/* If this already doesn't succeed, then surely the file is
* corrupt. No need to check for integrity anymore. */
- if (!restoring_backup) {
- g_clear_error (&internal_error);
- must_recreate = TRUE;
- } else {
- g_propagate_error (error, internal_error);
- g_object_unref (db_manager);
- return NULL;
- }
+ g_propagate_error (error, internal_error);
+ g_object_unref (db_manager);
+ return NULL;
}
- }
- if (!must_recreate) {
- gchar *busy_status;
-
- /* Report OPERATION - STATUS */
- busy_status = g_strdup_printf ("%s - %s",
- busy_operation,
- "Integrity checking");
- busy_callback (busy_status, 0, busy_user_data);
- g_free (busy_status);
-
- stmt = tracker_db_interface_create_statement (db_manager->db.iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE,
- &internal_error,
- "PRAGMA integrity_check(1)");
-
- if (internal_error != NULL) {
- if (internal_error->domain == TRACKER_DB_INTERFACE_ERROR &&
- internal_error->code == TRACKER_DB_QUERY_ERROR) {
- must_recreate = TRUE;
- } else {
- g_critical ("%s", internal_error->message);
- }
- g_error_free (internal_error);
- internal_error = NULL;
- } else {
- TrackerDBCursor *cursor = NULL;
-
- if (stmt) {
- cursor = tracker_db_statement_start_cursor (stmt, NULL);
- g_object_unref (stmt);
- } else {
- g_critical ("Can't create stmt for integrity_check, no error given");
- }
-
- if (cursor) {
- if (tracker_db_cursor_iter_next (cursor, NULL, NULL)) {
- if (g_strcmp0 (tracker_db_cursor_get_string (cursor, 0, NULL), "ok") != 0) {
- must_recreate = TRUE;
- }
- }
- g_object_unref (cursor);
- }
- }
- }
+ busy_callback ("Integrity checking", 0, busy_user_data);
- if (!must_recreate) {
- /* ensure that database has been initialized by an earlier tracker-store start
- by checking whether Resource table exists */
- stmt = tracker_db_interface_create_statement (db_manager->db.iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE,
- &internal_error,
- "SELECT 1 FROM Resource");
- if (internal_error != NULL) {
- if (!restoring_backup) {
- must_recreate = TRUE;
- g_error_free (internal_error);
- internal_error = NULL;
- }
- } else {
- g_object_unref (stmt);
+ if (db_check_integrity (db_manager) == FALSE) {
+ g_set_error (error,
+ TRACKER_DB_INTERFACE_ERROR,
+ TRACKER_DB_OPEN_ERROR,
+ "Corrupt db file");
+ g_object_unref (db_manager);
+ return NULL;
}
}
}
-
- if (must_recreate) {
- g_info ("Database severely damaged. We will recreate it.");
-
- perform_recreate (db_manager, first_time, &internal_error);
- if (internal_error) {
- g_propagate_error (error, internal_error);
- return FALSE;
- }
- } else {
- if (internal_error) {
- g_propagate_error (error, internal_error);
- return FALSE;
- }
- }
}
if ((flags & (TRACKER_DB_MANAGER_READONLY | TRACKER_DB_MANAGER_IN_MEMORY)) == 0) {
@@ -827,25 +723,9 @@ tracker_db_manager_new (TrackerDBManagerFlags flags,
TRUE, &internal_error);
if (internal_error) {
- if ((!restoring_backup) && (flags & TRACKER_DB_MANAGER_READONLY) == 0) {
- GError *new_error = NULL;
-
- perform_recreate (db_manager, first_time, &new_error);
- if (!new_error) {
- resources_iface = tracker_db_manager_create_db_interface (db_manager, TRUE,
- &internal_error);
- } else {
- /* Most serious error is the recreate one here */
- g_clear_error (&internal_error);
- g_propagate_error (error, new_error);
- g_object_unref (db_manager);
- return NULL;
- }
- } else {
- g_propagate_error (error, internal_error);
- g_object_unref (db_manager);
- return NULL;
- }
+ g_propagate_error (error, internal_error);
+ g_object_unref (db_manager);
+ return NULL;
}
g_clear_object (&resources_iface);
diff --git a/src/libtracker-data/tracker-db-manager.h b/src/libtracker-data/tracker-db-manager.h
index 91136dc3a..486e337ba 100644
--- a/src/libtracker-data/tracker-db-manager.h
+++ b/src/libtracker-data/tracker-db-manager.h
@@ -38,30 +38,29 @@ G_DECLARE_FINAL_TYPE (TrackerDBManager, tracker_db_manager,
#define TRACKER_DB_CACHE_SIZE_UPDATE 2000
typedef enum {
- TRACKER_DB_MANAGER_FORCE_REINDEX = 1 << 1,
- TRACKER_DB_MANAGER_REMOVE_ALL = 1 << 2,
- TRACKER_DB_MANAGER_READONLY = 1 << 3,
- TRACKER_DB_MANAGER_DO_NOT_CHECK_ONTOLOGY = 1 << 4,
- TRACKER_DB_MANAGER_ENABLE_MUTEXES = 1 << 5,
- TRACKER_DB_MANAGER_FTS_ENABLE_STEMMER = 1 << 6,
- TRACKER_DB_MANAGER_FTS_ENABLE_UNACCENT = 1 << 7,
- TRACKER_DB_MANAGER_FTS_ENABLE_STOP_WORDS = 1 << 8,
- TRACKER_DB_MANAGER_FTS_IGNORE_NUMBERS = 1 << 9,
- TRACKER_DB_MANAGER_IN_MEMORY = 1 << 10,
+ TRACKER_DB_MANAGER_FLAGS_NONE = 0,
+ TRACKER_DB_MANAGER_READONLY = 1 << 1,
+ TRACKER_DB_MANAGER_DO_NOT_CHECK_ONTOLOGY = 1 << 2,
+ TRACKER_DB_MANAGER_ENABLE_MUTEXES = 1 << 3,
+ TRACKER_DB_MANAGER_FTS_ENABLE_STEMMER = 1 << 4,
+ TRACKER_DB_MANAGER_FTS_ENABLE_UNACCENT = 1 << 5,
+ TRACKER_DB_MANAGER_FTS_ENABLE_STOP_WORDS = 1 << 6,
+ TRACKER_DB_MANAGER_FTS_IGNORE_NUMBERS = 1 << 7,
+ TRACKER_DB_MANAGER_IN_MEMORY = 1 << 8,
} TrackerDBManagerFlags;
typedef struct _TrackerDBManager TrackerDBManager;
+gboolean tracker_db_manager_db_exists (GFile *cache_location);
+
TrackerDBManager *tracker_db_manager_new (TrackerDBManagerFlags flags,
GFile *cache_location,
gboolean *first_time,
- gboolean restoring_backup,
gboolean shared_cache,
guint select_cache_size,
guint update_cache_size,
TrackerBusyCallback busy_callback,
gpointer busy_user_data,
- const gchar *busy_operation,
GObject *iface_data,
gpointer vtab_data,
GError **error);
diff --git a/src/libtracker-direct/tracker-direct.c b/src/libtracker-direct/tracker-direct.c
index c625cee10..1994579ca 100644
--- a/src/libtracker-direct/tracker-direct.c
+++ b/src/libtracker-direct/tracker-direct.c
@@ -257,26 +257,13 @@ tracker_direct_connection_initable_init (GInitable *initable,
db_flags = translate_flags (priv->flags);
- if (!priv->store)
+ if (!priv->store) {
db_flags |= TRACKER_DB_MANAGER_IN_MEMORY;
-
- /* Init data manager */
- if (!priv->ontology &&
- (db_flags & TRACKER_DB_MANAGER_READONLY) == 0) {
- gchar *filename;
-
- /* If the connection is read/write, and no ontology is specified,
- * we use the Nepomuk one.
- */
- filename = g_build_filename (SHAREDIR, "tracker", "ontologies",
- "nepomuk", NULL);
- priv->ontology = g_file_new_for_path (filename);
- g_free (filename);
}
priv->data_manager = tracker_data_manager_new (db_flags, priv->store,
priv->ontology,
- FALSE, 100, 100);
+ 100, 100);
if (!g_initable_init (G_INITABLE (priv->data_manager), cancellable, error)) {
g_clear_object (&priv->data_manager);
return FALSE;
@@ -1034,7 +1021,7 @@ tracker_direct_connection_class_init (TrackerDirectConnectionClass *klass)
TrackerDirectConnection *
tracker_direct_connection_new (TrackerSparqlConnectionFlags flags,
- GFile *store,
+ GFile *store,
GFile *ontology,
GError **error)
{
diff --git a/src/libtracker-sparql-backend/tracker-backend.vala b/src/libtracker-sparql-backend/tracker-backend.vala
index 7e8ee79fb..79db936a1 100644
--- a/src/libtracker-sparql-backend/tracker-backend.vala
+++ b/src/libtracker-sparql-backend/tracker-backend.vala
@@ -44,7 +44,7 @@ public static Tracker.Sparql.Connection tracker_sparql_connection_new (Tracker.S
return conn;
}
-public static async Tracker.Sparql.Connection tracker_sparql_connection_new_async (Tracker.Sparql.ConnectionFlags flags, File store, File? ontology, Cancellable? cancellable = null) throws GLib.Error, Tracker.Sparql.Error, IOError {
+public static async Tracker.Sparql.Connection tracker_sparql_connection_new_async (Tracker.Sparql.ConnectionFlags flags, File store, File ontology, Cancellable? cancellable = null) throws GLib.Error, Tracker.Sparql.Error, IOError {
var conn = new Tracker.Direct.Connection (flags, store, ontology);
conn.init_async.begin (Priority.DEFAULT, cancellable);
yield;
diff --git a/src/libtracker-sparql/meson.build b/src/libtracker-sparql/meson.build
index 9ddbe51a6..21e22275b 100644
--- a/src/libtracker-sparql/meson.build
+++ b/src/libtracker-sparql/meson.build
@@ -30,6 +30,7 @@ libtracker_sparql_c_public_headers = files(
'tracker-endpoint-dbus.h',
'tracker-namespace-manager.h',
'tracker-notifier.h',
+ 'tracker-ontologies.h',
'tracker-resource.h',
'tracker-statement.h',
'tracker-utils.h',
diff --git a/src/libtracker-sparql/tracker-connection.c b/src/libtracker-sparql/tracker-connection.c
index 16c72d723..a528b5dcb 100644
--- a/src/libtracker-sparql/tracker-connection.c
+++ b/src/libtracker-sparql/tracker-connection.c
@@ -54,18 +54,33 @@ tracker_sparql_connection_class_init (TrackerSparqlConnectionClass *klass)
* tracker_sparql_connection_new:
* @flags: values from #TrackerSparqlConnectionFlags
* @store: the directory that contains the database as a #GFile, or %NULL
- * @ontology: (nullable): the directory that contains the database schemas as
- * a #GFile, or %NULL to use the default schemas.
+ * @ontology: the directory that contains the database schemas as a #GFile, or %NULL
* @cancellable: (nullable): a #GCancellable, or %NULL
* @error: pointer to a #GError
*
- * Opens a database. Use this for data managed by the current process.
+ * Creates or opens a database.
*
+ * This method should only be used for databases owned by the current process.
* To connect to databases managed by other processes, use
* tracker_sparql_connection_bus_new().
*
* If @store is %NULL, the database will be created in memory.
*
+ * The @ontologies parameter must point to a location containing suitable
+ * `.ontology` files in Turtle format. These control the database schema that
+ * is used. You can use the default Nepomuk ontologies by calling
+ * tracker_sparql_get_ontology_nepomuk ().
+ *
+ * If you open an existing database using a different @ontology to the one it
+ * was created with, Tracker will attempt to migrate the existing data to the
+ * new schema. This may raise an error. In particular, not all migrations are
+ * possible without causing data loss and Tracker will refuse to delete data
+ * during a migration.
+ *
+ * You can also pass %NULL for @ontologies to mean "use the ontologies that the
+ * database was created with". This will fail if the database doesn't already
+ * exist.
+ *
* Returns: (transfer full): a new #TrackerSparqlConnection. Call
* g_object_unref() on the object when no longer used.
*
@@ -75,9 +90,8 @@ tracker_sparql_connection_class_init (TrackerSparqlConnectionClass *klass)
/**
* tracker_sparql_connection_new_async:
* @flags: values from #TrackerSparqlConnectionFlags
- * @store: the directory that contains the database as a #GFile, or %NULL
- * @ontology: (nullable): the directory that contains the database schemas as
- * a #GFile, or %NULL to use the default schemas.
+ * @store: (nullable): the directory that contains the database as a #GFile, or %NULL
+ * @ontology: (nullable): the directory that contains the database schemas as a #GFile, or %NULL
* @cancellable: (nullable): a #GCancellable, or %NULL
* @callback: the #GAsyncReadyCallback called when the operation completes
* @user_data: data passed to @callback
@@ -101,7 +115,7 @@ tracker_sparql_connection_class_init (TrackerSparqlConnectionClass *klass)
* tracker_sparql_connection_bus_new:
* @service_name: The name of the D-Bus service to connect to.
* @object_path: (nullable): The path to the object, or %NULL to use the default.
- * @dbus_connection: (nullable): The #GDBusConnection to use, or %NULL to use the session bus.
+ * @dbus_connection: (nullable): The #GDBusConnection to use, or %NULL to use the session bus
* @error: pointer to a #GError
*
* Connects to a database owned by another process on the
diff --git a/src/libtracker-sparql/tracker-utils.c b/src/libtracker-sparql/tracker-utils.c
index e630b689a..774b7e52c 100644
--- a/src/libtracker-sparql/tracker-utils.c
+++ b/src/libtracker-sparql/tracker-utils.c
@@ -78,3 +78,16 @@ tracker_sparql_get_uuid_urn (void)
{
return tracker_generate_uuid ("urn:uuid");
}
+
+/**
+ * tracker_sparql_get_ontology_nepomuk:
+ *
+ * Returns a path to the built-in Nepomuk ontologies.
+ *
+ * Returns: (transfer full): a #GFile instance.
+ */
+GFile *
+tracker_sparql_get_ontology_nepomuk (void)
+{
+ return g_file_new_for_path (SHAREDIR "/tracker/ontologies/nepomuk");
+}
diff --git a/src/libtracker-sparql/tracker-utils.h b/src/libtracker-sparql/tracker-utils.h
index 6acfcaecf..36c7d1c8f 100644
--- a/src/libtracker-sparql/tracker-utils.h
+++ b/src/libtracker-sparql/tracker-utils.h
@@ -20,6 +20,7 @@
#define __TRACKER_UTILS_H__
#include <glib.h>
+#include <gio/gio.h>
#include <libtracker-sparql/tracker-version.h>
TRACKER_AVAILABLE_IN_ALL
@@ -36,4 +37,8 @@ gchar* tracker_sparql_escape_string (const gchar* literal);
TRACKER_AVAILABLE_IN_ALL
gchar* tracker_sparql_get_uuid_urn (void);
+TRACKER_AVAILABLE_IN_ALL
+GFile *
+tracker_sparql_get_ontology_nepomuk (void);
+
#endif /* __TRACKER_UTILS_H__ */
diff --git a/src/tracker/tracker-sql.c b/src/tracker/tracker-sql.c
index 2d9d37f7c..533b3ccc1 100644
--- a/src/tracker/tracker-sql.c
+++ b/src/tracker/tracker-sql.c
@@ -106,7 +106,7 @@ sql_by_query (void)
db_location = g_file_new_for_commandline_arg (database_path);
data_manager = tracker_data_manager_new (TRACKER_DB_MANAGER_READONLY,
db_location, NULL,
- FALSE, 100, 100);
+ 100, 100);
if (!g_initable_init (G_INITABLE (data_manager), NULL, &error)) {
g_printerr ("%s: %s\n",
diff --git a/tests/libtracker-data/tracker-insert-or-replace-test.c b/tests/libtracker-data/tracker-insert-or-replace-test.c
index 800016631..ad6f40721 100644
--- a/tests/libtracker-data/tracker-insert-or-replace-test.c
+++ b/tests/libtracker-data/tracker-insert-or-replace-test.c
@@ -145,7 +145,7 @@ main (int argc, char *argv[])
ontology = g_file_new_for_path (TEST_ONTOLOGIES_DIR);
manager = tracker_data_manager_new (0, cache, ontology,
- FALSE, 100, 100);
+ 100, 100);
g_initable_init (G_INITABLE (manager), NULL, &error);
g_assert_no_error (error);
diff --git a/tests/libtracker-data/tracker-ontology-change-test.c b/tests/libtracker-data/tracker-ontology-change-test.c
index 4d15e727d..64a7023c7 100644
--- a/tests/libtracker-data/tracker-ontology-change-test.c
+++ b/tests/libtracker-data/tracker-ontology-change-test.c
@@ -212,7 +212,7 @@ test_ontology_change (void)
g_assert_cmpint (g_chmod (ontology_file, 0666), ==, 0);
manager = tracker_data_manager_new (0, data_location, test_schemas,
- FALSE, 100, 100);
+ 100, 100);
g_initable_init (G_INITABLE (manager), NULL, &error);
g_assert_no_error (error);
@@ -253,8 +253,7 @@ test_ontology_change (void)
g_object_unref (manager);
}
- manager = tracker_data_manager_new (0, data_location, test_schemas,
- FALSE, 100, 100);
+ manager = tracker_data_manager_new (0, data_location, test_schemas, 100, 100);
g_initable_init (G_INITABLE (manager), NULL, &error);
g_assert_no_error (error);
diff --git a/tests/libtracker-data/tracker-ontology-test.c b/tests/libtracker-data/tracker-ontology-test.c
index 14f6dbe89..e22078364 100644
--- a/tests/libtracker-data/tracker-ontology-test.c
+++ b/tests/libtracker-data/tracker-ontology-test.c
@@ -184,9 +184,9 @@ test_ontology_init (TestInfo *test_info,
data_location = g_file_new_for_path (test_info->data_location);
/* first-time initialization */
- manager = tracker_data_manager_new (TRACKER_DB_MANAGER_FORCE_REINDEX,
+ manager = tracker_data_manager_new (TRACKER_DB_MANAGER_FLAGS_NONE,
data_location, data_location,
- FALSE, 100, 100);
+ 100, 100);
g_initable_init (G_INITABLE (manager), NULL, &error);
g_assert_no_error (error);
@@ -194,7 +194,7 @@ test_ontology_init (TestInfo *test_info,
/* initialization from existing database */
manager = tracker_data_manager_new (0, data_location, data_location,
- FALSE, 100, 100);
+ 100, 100);
g_initable_init (G_INITABLE (manager), NULL, &error);
g_assert_no_error (error);
@@ -227,9 +227,9 @@ test_query (TestInfo *test_info,
g_free (ontology_path);
/* initialization */
- manager = tracker_data_manager_new (TRACKER_DB_MANAGER_FORCE_REINDEX,
+ manager = tracker_data_manager_new (TRACKER_DB_MANAGER_FLAGS_NONE,
data_location, ontology_location,
- FALSE, 100, 100);
+ 100, 100);
g_initable_init (G_INITABLE (manager), NULL, &error);
g_assert_no_error (error);
diff --git a/tests/libtracker-data/tracker-sparql-blank-test.c b/tests/libtracker-data/tracker-sparql-blank-test.c
index 5c1b269de..c49f5e428 100644
--- a/tests/libtracker-data/tracker-sparql-blank-test.c
+++ b/tests/libtracker-data/tracker-sparql-blank-test.c
@@ -53,9 +53,9 @@ test_blank (TestInfo *info,
data_location = g_file_new_for_path (info->data_location);
/* initialization */
- manager = tracker_data_manager_new (TRACKER_DB_MANAGER_FORCE_REINDEX,
+ manager = tracker_data_manager_new (TRACKER_DB_MANAGER_FLAGS_NONE,
data_location, data_location, /* loc, domain and ontology_name */
- FALSE, 100, 100);
+ 100, 100);
g_initable_init (G_INITABLE (manager), NULL, &error);
g_assert_no_error (error);
diff --git a/tests/libtracker-data/tracker-sparql-test.c b/tests/libtracker-data/tracker-sparql-test.c
index acf413823..614fc516c 100644
--- a/tests/libtracker-data/tracker-sparql-test.c
+++ b/tests/libtracker-data/tracker-sparql-test.c
@@ -378,10 +378,9 @@ test_sparql_query (TestInfo *test_info,
test_schemas = g_file_get_parent (file);
g_object_unref (file);
- manager = tracker_data_manager_new (TRACKER_DB_MANAGER_FORCE_REINDEX |
- TRACKER_DB_MANAGER_IN_MEMORY,
+ manager = tracker_data_manager_new (TRACKER_DB_MANAGER_IN_MEMORY,
NULL, test_schemas, /* loc, domain and ontology_name */
- FALSE, 100, 100);
+ 100, 100);
g_initable_init (G_INITABLE (manager), NULL, &error);
g_assert_no_error (error);
diff --git a/tests/libtracker-fts/tracker-fts-test.c b/tests/libtracker-fts/tracker-fts-test.c
index 0cf090422..1dbc484ff 100644
--- a/tests/libtracker-fts/tracker-fts-test.c
+++ b/tests/libtracker-fts/tracker-fts-test.c
@@ -75,8 +75,8 @@ test_sparql_query (gconstpointer test_data)
data_location = g_file_new_for_path (datadir);
conn = tracker_sparql_connection_new (TRACKER_SPARQL_CONNECTION_FLAGS_NONE,
- data_location, ontology,
- NULL, &error);
+ data_location, ontology,
+ NULL, &error);
g_assert_no_error (error);
g_object_unref (ontology);