Commit d5af4058 authored by Martyn Russell's avatar Martyn Russell

libtracker-sparql: Added TRACKER_SPARQL_BACKEND environment variable

- Added to the documentation so we know what values can be used and how
- Added debugging so we know what backends are in use.
- Fixed the plugin loader so we require the plugins before we call their Tracker.Sparql.Connection implementations (to avoid segfaulting)
parent 9a3a3ace
......@@ -25,8 +25,8 @@
* @include: tracker-sparql.h
*
* <para>
* #TrackerSparqlConnection is an object which allows setting up
* connections to the Tracker Store.
* #TrackerSparqlConnection is an object which sets up connections to the
* Tracker Store.
* </para>
*/
......@@ -90,6 +90,20 @@ public abstract class Tracker.Sparql.Connection : Object {
* available to connect to the Tracker Store (direct-access for Read-Only
* queries, and D-Bus otherwise).
*
* There are 2 environment variables which can be used to control which
* backends are used to set up the connection. If no environment variables are
* provided, then both backends are loaded and chosen based on their merits.
*
* The TRACKER_BUS_BACKEND environment variable can be set to "dbus-glib" to
* force the D-Bus backend to use non-FD (File Descriptor) passing (the
* original communication method Tracker used).
*
* The TRACKER_SPARQL_BACKEND environment variable also allows the caller to
* switch between "auto" (the default), "direct" (for direct access) and
* "bus" for D-Bus backends. If you force a backend which does not support
* what you're doing (for example, using the "direct" backend for a SPARQL
* update) then you will see critical warnings in your code.
*
* Returns: a new #TrackerSparqlConnection. Call g_object_unref() on the
* object when no longer used.
*/
......@@ -115,6 +129,10 @@ public abstract class Tracker.Sparql.Connection : Object {
* to connect to the Tracker Store. Note that this connection will only be
* able to perform Read-Only queries in the store.
*
* If the TRACKER_SPARQL_BACKEND environment variable is set, it may
* override the choice to use a direct access connection here, for more
* details, see tracker_sparql_connection_get().
*
* Returns: a new #TrackerSparqlConnection. Call g_object_unref() on the
* object when no longer used.
*/
......
......@@ -21,6 +21,11 @@ class Tracker.Sparql.PluginLoader : Connection {
static bool initialized = false;
static Tracker.Sparql.Connection direct = null;
static Tracker.Sparql.Connection bus = null;
static enum Backend {
AUTO,
DIRECT,
BUS
}
private delegate Tracker.Sparql.Connection ModuleInitFunc ();
......@@ -39,7 +44,8 @@ class Tracker.Sparql.PluginLoader : Connection {
initialized = true;
}
public override Cursor query (string sparql, Cancellable? cancellable = null) throws Sparql.Error, IOError {
public override Cursor query (string sparql, Cancellable? cancellable = null) throws Sparql.Error, IOError
requires (bus != null || direct != null) {
if (direct != null) {
return direct.query (sparql, cancellable);
} else {
......@@ -47,7 +53,8 @@ class Tracker.Sparql.PluginLoader : Connection {
}
}
public async override Cursor query_async (string sparql, Cancellable? cancellable = null) throws Sparql.Error, IOError {
public async override Cursor query_async (string sparql, Cancellable? cancellable = null) throws Sparql.Error, IOError
requires (bus != null || direct != null) {
if (direct != null) {
return yield direct.query_async (sparql, cancellable);
} else {
......@@ -55,35 +62,43 @@ class Tracker.Sparql.PluginLoader : Connection {
}
}
public override void update (string sparql, int priority = GLib.Priority.DEFAULT, Cancellable? cancellable = null) throws Sparql.Error, IOError {
public override void update (string sparql, int priority = GLib.Priority.DEFAULT, Cancellable? cancellable = null) throws Sparql.Error, IOError
requires (bus != null) {
bus.update (sparql, priority, cancellable);
}
public override GLib.Variant? update_blank (string sparql, int priority = GLib.Priority.DEFAULT, Cancellable? cancellable = null) throws Sparql.Error, IOError {
public override GLib.Variant? update_blank (string sparql, int priority = GLib.Priority.DEFAULT, Cancellable? cancellable = null) throws Sparql.Error, IOError
requires (bus != null) {
return bus.update_blank (sparql, priority, cancellable);
}
public async override void update_async (string sparql, int priority = GLib.Priority.DEFAULT, Cancellable? cancellable = null) throws Sparql.Error, IOError {
public async override void update_async (string sparql, int priority = GLib.Priority.DEFAULT, Cancellable? cancellable = null) throws Sparql.Error, IOError
requires (bus != null) {
yield bus.update_async (sparql, priority, cancellable);
}
public async override GLib.Variant? update_blank_async (string sparql, int priority = GLib.Priority.DEFAULT, Cancellable? cancellable = null) throws Sparql.Error, IOError {
public async override GLib.Variant? update_blank_async (string sparql, int priority = GLib.Priority.DEFAULT, Cancellable? cancellable = null) throws Sparql.Error, IOError
requires (bus != null) {
return yield bus.update_blank_async (sparql, priority, cancellable);
}
public override void load (File file, Cancellable? cancellable = null) throws Sparql.Error, IOError {
public override void load (File file, Cancellable? cancellable = null) throws Sparql.Error, IOError
requires (bus != null) {
bus.load (file, cancellable);
}
public async override void load_async (File file, Cancellable? cancellable = null) throws Sparql.Error, IOError {
public async override void load_async (File file, Cancellable? cancellable = null) throws Sparql.Error, IOError
requires (bus != null) {
yield bus.load_async (file, cancellable);
}
public override Cursor? statistics (Cancellable? cancellable = null) throws Sparql.Error, IOError {
public override Cursor? statistics (Cancellable? cancellable = null) throws Sparql.Error, IOError
requires (bus != null) {
return bus.statistics (cancellable);
}
public async override Cursor? statistics_async (Cancellable? cancellable = null) throws Sparql.Error, IOError {
public async override Cursor? statistics_async (Cancellable? cancellable = null) throws Sparql.Error, IOError
requires (bus != null) {
return yield bus.statistics_async (cancellable);
}
......@@ -100,26 +115,67 @@ class Tracker.Sparql.PluginLoader : Connection {
File dir = File.new_for_path (path);
string dir_path = dir.get_path ();
string env_backend = Environment.get_variable ("TRACKER_SPARQL_BACKEND");
Backend backend = Backend.AUTO;
if (env_backend != null) {
if (env_backend.ascii_casecmp ("direct") == 0) {
backend = Backend.DIRECT;
debug ("Using backend = 'DIRECT'");
} else if (env_backend.ascii_casecmp ("bus") == 0) {
backend = Backend.BUS;
debug ("Using backend = 'BUS'");
} else {
warning ("Environment variable TRACKER_SPARQL_BACKEND set to unknown value '%s'", env_backend);
}
}
if (backend == Backend.AUTO) {
if (direct_only && backend == Backend.AUTO) {
backend = Backend.DIRECT;
debug ("Using backend = 'DIRECT'");
} else {
debug ("Using backend = 'AUTO'");
}
}
if (direct_only && backend == Backend.BUS) {
debug ("Backend set in environment contradicts requested connection type, using environment to override");
}
debug ("Searching for modules in folder '%s' ..", dir_path);
// First get direct library details
string direct_path = Module.build_path (dir_path, "tracker-direct");
direct = load_plugins_from_path (direct_path, direct_only /* required */);
Tracker.Sparql.Connection connection;
switch (backend) {
case backend.AUTO:
string direct_path = Module.build_path (dir_path, "tracker-direct");
direct = load_plugins_from_path (direct_path, false /* required */);
if (!direct_only) {
// Second get bus library details
string bus_path = Module.build_path (dir_path, "tracker-bus");
bus = load_plugins_from_path (bus_path, true /* required */);
}
debug ("Finished searching for modules in folder '%s'", dir_path);
connection = bus;
break;
if (direct_only) {
return direct != null;
} else {
return bus != null;
case backend.DIRECT:
string direct_path = Module.build_path (dir_path, "tracker-direct");
connection = direct = load_plugins_from_path (direct_path, true /* required */);
break;
case backend.BUS:
string bus_path = Module.build_path (dir_path, "tracker-bus");
connection = bus = load_plugins_from_path (bus_path, true /* required */);
break;
default:
assert_not_reached ();
}
debug ("Finished searching for modules");
return connection != null;
}
private Tracker.Sparql.Connection? load_plugins_from_path (string path, bool required) throws GLib.Error {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment