Blame src/gom-tracker.c

Packit f01ec2
/*
Packit f01ec2
 * GNOME Online Miners - crawls through your online content
Packit f01ec2
 * Copyright (c) 2011, 2012 Red Hat, Inc.
Packit f01ec2
 *
Packit f01ec2
 * This program is free software; you can redistribute it and/or
Packit f01ec2
 * modify it under the terms of the GNU General Public License
Packit f01ec2
 * as published by the Free Software Foundation; either version 2
Packit f01ec2
 * of the License, or (at your option) any later version.
Packit f01ec2
 *
Packit f01ec2
 * This program is distributed in the hope that it will be useful,
Packit f01ec2
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit f01ec2
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit f01ec2
 * GNU General Public License for more details.
Packit f01ec2
 *
Packit f01ec2
 * You should have received a copy of the GNU General Public License
Packit f01ec2
 * along with this program; if not, write to the Free Software
Packit f01ec2
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit f01ec2
 * 02110-1301, USA.
Packit f01ec2
 *
Packit f01ec2
 * Author: Cosimo Cecchi <cosimoc@redhat.com>
Packit f01ec2
 *
Packit f01ec2
 */
Packit f01ec2
Packit f01ec2
#include <glib.h>
Packit f01ec2
Packit f01ec2
#include "gom-tracker.h"
Packit f01ec2
#include "gom-utils.h"
Packit f01ec2
Packit f01ec2
static gchar *
Packit f01ec2
_tracker_utils_format_into_graph (const gchar *graph)
Packit f01ec2
{
Packit f01ec2
  return (graph != NULL) ? g_strdup_printf ("INTO <%s> ", graph) : g_strdup ("");
Packit f01ec2
}
Packit f01ec2
Packit f01ec2
static gboolean
Packit f01ec2
gom_tracker_sparql_connection_get_string_attribute (TrackerSparqlConnection *connection,
Packit f01ec2
                                                    GCancellable *cancellable,
Packit f01ec2
                                                    GError **error,
Packit f01ec2
                                                    const gchar *resource,
Packit f01ec2
                                                    const gchar *attribute,
Packit f01ec2
                                                    gchar **value)
Packit f01ec2
{
Packit f01ec2
  GString *select = g_string_new (NULL);
Packit f01ec2
  TrackerSparqlCursor *cursor;
Packit f01ec2
  const gchar *string_value = NULL;
Packit f01ec2
  gboolean res;
Packit f01ec2
Packit f01ec2
  g_string_append_printf (select, "SELECT ?val { <%s> %s ?val }",
Packit f01ec2
                          resource, attribute);
Packit f01ec2
  cursor = tracker_sparql_connection_query (connection,
Packit f01ec2
                                            select->str,
Packit f01ec2
                                            cancellable, error);
Packit f01ec2
  g_string_free (select, TRUE);
Packit f01ec2
Packit f01ec2
  if (*error != NULL)
Packit f01ec2
    goto out;
Packit f01ec2
Packit f01ec2
  res = tracker_sparql_cursor_next (cursor, cancellable, error);
Packit f01ec2
Packit f01ec2
  if (*error != NULL)
Packit f01ec2
    goto out;
Packit f01ec2
Packit f01ec2
  if (res)
Packit f01ec2
    {
Packit f01ec2
      string_value = tracker_sparql_cursor_get_string (cursor, 0, NULL);
Packit f01ec2
      goto out;
Packit f01ec2
    }
Packit f01ec2
Packit f01ec2
 out:
Packit f01ec2
  if (string_value != NULL && value != NULL)
Packit f01ec2
    *value = g_strdup (string_value);
Packit f01ec2
  else if (string_value == NULL)
Packit f01ec2
    res = FALSE;
Packit f01ec2
Packit f01ec2
  g_clear_object (&cursor);
Packit f01ec2
  return res;
Packit f01ec2
}
Packit f01ec2
Packit f01ec2
gchar *
Packit f01ec2
gom_tracker_sparql_connection_ensure_resource (TrackerSparqlConnection *connection,
Packit f01ec2
                                               GCancellable *cancellable,
Packit f01ec2
                                               GError **error,
Packit f01ec2
                                               gboolean *resource_exists,
Packit f01ec2
                                               const gchar *graph,
Packit f01ec2
                                               const gchar *identifier,
Packit f01ec2
                                               const gchar *class,
Packit f01ec2
                                               ...)
Packit f01ec2
{
Packit f01ec2
  GString *select, *insert, *inner;
Packit f01ec2
  va_list args;
Packit f01ec2
  const gchar *arg;
Packit f01ec2
  TrackerSparqlCursor *cursor;
Packit f01ec2
  gboolean res;
Packit f01ec2
  gchar *retval = NULL;
Packit f01ec2
  gchar *graph_str;
Packit f01ec2
  GVariant *insert_res;
Packit f01ec2
  GVariantIter *iter;
Packit f01ec2
  gchar *key = NULL, *val = NULL;
Packit f01ec2
  gboolean exists = FALSE;
Packit f01ec2
Packit f01ec2
  /* build the inner query with all the classes */
Packit f01ec2
  va_start (args, class);
Packit f01ec2
  inner = g_string_new (NULL);
Packit f01ec2
Packit f01ec2
  for (arg = class; arg != NULL; arg = va_arg (args, const gchar *))
Packit f01ec2
    g_string_append_printf (inner, " a %s; ", arg);
Packit f01ec2
Packit f01ec2
  g_string_append_printf (inner, "nao:identifier \"%s\"", identifier);
Packit f01ec2
Packit f01ec2
  va_end (args);
Packit f01ec2
Packit f01ec2
  /* query if such a resource is already in the DB */
Packit f01ec2
  select = g_string_new (NULL);
Packit f01ec2
  g_string_append_printf (select,
Packit f01ec2
                          "SELECT ?urn WHERE { ?urn %s }", inner->str);
Packit f01ec2
Packit f01ec2
  cursor = tracker_sparql_connection_query (connection,
Packit f01ec2
                                            select->str,
Packit f01ec2
                                            cancellable, error);
Packit f01ec2
Packit f01ec2
  g_string_free (select, TRUE);
Packit f01ec2
Packit f01ec2
  if (*error != NULL)
Packit f01ec2
    goto out;
Packit f01ec2
Packit f01ec2
  res = tracker_sparql_cursor_next (cursor, cancellable, error);
Packit f01ec2
Packit f01ec2
  if (*error != NULL)
Packit f01ec2
    goto out;
Packit f01ec2
Packit f01ec2
  if (res)
Packit f01ec2
    {
Packit f01ec2
      /* return the found resource */
Packit f01ec2
      retval = g_strdup (tracker_sparql_cursor_get_string (cursor, 0, NULL));
Packit f01ec2
      exists = TRUE;
Packit f01ec2
      g_debug ("Found resource in the store: %s", retval);
Packit f01ec2
      goto out;
Packit f01ec2
    }
Packit f01ec2
Packit f01ec2
  /* not found, create the resource */
Packit f01ec2
  insert = g_string_new (NULL);
Packit f01ec2
  graph_str = _tracker_utils_format_into_graph (graph);
Packit f01ec2
Packit f01ec2
  g_string_append_printf (insert, "INSERT %s { _:res %s }",
Packit f01ec2
                          graph_str, inner->str);
Packit f01ec2
  g_free (graph_str);
Packit f01ec2
  g_string_free (inner, TRUE);
Packit f01ec2
Packit f01ec2
  insert_res =
Packit f01ec2
    tracker_sparql_connection_update_blank (connection, insert->str,
Packit f01ec2
                                            G_PRIORITY_DEFAULT, NULL, error);
Packit f01ec2
Packit f01ec2
  g_string_free (insert, TRUE);
Packit f01ec2
Packit f01ec2
  if (*error != NULL)
Packit f01ec2
    goto out;
Packit f01ec2
Packit f01ec2
  /* the result is an "aaa{ss}" variant */
Packit f01ec2
  g_variant_get (insert_res, "aaa{ss}", &iter);
Packit f01ec2
  g_variant_iter_next (iter, "aa{ss}", &iter);
Packit f01ec2
  g_variant_iter_next (iter, "a{ss}", &iter);
Packit f01ec2
  g_variant_iter_next (iter, "{ss}", &key, &val;;
Packit f01ec2
Packit f01ec2
  g_variant_iter_free (iter);
Packit f01ec2
  g_variant_unref (insert_res);
Packit f01ec2
Packit f01ec2
  if (g_strcmp0 (key, "res") == 0)
Packit f01ec2
    {
Packit f01ec2
      retval = val;
Packit f01ec2
    }
Packit f01ec2
  else
Packit f01ec2
    {
Packit f01ec2
      g_free (val);
Packit f01ec2
      goto out;
Packit f01ec2
    }
Packit f01ec2
Packit f01ec2
  g_debug ("Created a new resource: %s", retval);
Packit f01ec2
Packit f01ec2
 out:
Packit f01ec2
  if (resource_exists)
Packit f01ec2
    *resource_exists = exists;
Packit f01ec2
Packit f01ec2
  g_clear_object (&cursor);
Packit f01ec2
  return retval;
Packit f01ec2
}
Packit f01ec2
Packit f01ec2
gboolean
Packit f01ec2
gom_tracker_sparql_connection_insert_or_replace_triple (TrackerSparqlConnection *connection,
Packit f01ec2
                                                        GCancellable *cancellable,
Packit f01ec2
                                                        GError **error,
Packit f01ec2
                                                        const gchar *graph,
Packit f01ec2
                                                        const gchar *resource,
Packit f01ec2
                                                        const gchar *property_name,
Packit f01ec2
                                                        const gchar *property_value)
Packit f01ec2
{
Packit f01ec2
  GString *insert;
Packit f01ec2
  gchar *graph_str, *quoted;
Packit f01ec2
  gboolean retval = TRUE;
Packit f01ec2
Packit f01ec2
  graph_str = _tracker_utils_format_into_graph (graph);
Packit f01ec2
Packit f01ec2
  /* the "null" value must not be quoted */
Packit f01ec2
  if (property_value == NULL)
Packit f01ec2
    quoted = g_strdup ("null");
Packit f01ec2
  else
Packit f01ec2
    quoted = g_strdup_printf ("\"%s\"", property_value);
Packit f01ec2
Packit f01ec2
  insert = g_string_new (NULL);
Packit f01ec2
  g_string_append_printf
Packit f01ec2
    (insert,
Packit f01ec2
     "INSERT OR REPLACE %s { <%s> a nie:InformationElement ; %s %s }",
Packit f01ec2
     graph_str, resource, property_name, quoted);
Packit f01ec2
  g_free (quoted);
Packit f01ec2
Packit f01ec2
  g_debug ("Insert or replace triple: query %s", insert->str);
Packit f01ec2
Packit f01ec2
  tracker_sparql_connection_update (connection, insert->str,
Packit f01ec2
                                    G_PRIORITY_DEFAULT, cancellable,
Packit f01ec2
                                    error);
Packit f01ec2
Packit f01ec2
  g_string_free (insert, TRUE);
Packit f01ec2
Packit f01ec2
  if (*error != NULL)
Packit f01ec2
    retval = FALSE;
Packit f01ec2
Packit f01ec2
  g_free (graph_str);
Packit f01ec2
Packit f01ec2
  return retval;
Packit f01ec2
}
Packit f01ec2
Packit f01ec2
gboolean
Packit f01ec2
gom_tracker_sparql_connection_set_triple (TrackerSparqlConnection *connection,
Packit f01ec2
                                          GCancellable *cancellable,
Packit f01ec2
                                          GError **error,
Packit f01ec2
                                          const gchar *graph,
Packit f01ec2
                                          const gchar *resource,
Packit f01ec2
                                          const gchar *property_name,
Packit f01ec2
                                          const gchar *property_value)
Packit f01ec2
{
Packit f01ec2
  GString *delete;
Packit f01ec2
  gboolean retval = TRUE;
Packit f01ec2
Packit f01ec2
  delete = g_string_new (NULL);
Packit f01ec2
  g_string_append_printf
Packit f01ec2
    (delete,
Packit f01ec2
     "DELETE { <%s> %s ?val } WHERE { <%s> %s ?val }", resource,
Packit f01ec2
     property_name, resource, property_name);
Packit f01ec2
Packit f01ec2
  tracker_sparql_connection_update (connection, delete->str,
Packit f01ec2
                                    G_PRIORITY_DEFAULT, cancellable,
Packit f01ec2
                                    error);
Packit f01ec2
Packit f01ec2
  g_string_free (delete, TRUE);
Packit f01ec2
  if (*error != NULL)
Packit f01ec2
    {
Packit f01ec2
      retval = FALSE;
Packit f01ec2
      goto out;
Packit f01ec2
    }
Packit f01ec2
Packit f01ec2
  retval =
Packit f01ec2
    gom_tracker_sparql_connection_insert_or_replace_triple (connection,
Packit f01ec2
                                                            cancellable, error,
Packit f01ec2
                                                            graph, resource,
Packit f01ec2
                                                            property_name, property_value);
Packit f01ec2
Packit f01ec2
 out:
Packit f01ec2
  return retval;
Packit f01ec2
}
Packit f01ec2
Packit f01ec2
gboolean
Packit f01ec2
gom_tracker_sparql_connection_toggle_favorite (TrackerSparqlConnection *connection,
Packit f01ec2
                                               GCancellable *cancellable,
Packit f01ec2
                                               GError **error,
Packit f01ec2
                                               const gchar *resource,
Packit f01ec2
                                               gboolean favorite)
Packit f01ec2
{
Packit f01ec2
  GString *update;
Packit f01ec2
  const gchar *op_str = NULL;
Packit f01ec2
  gboolean retval = TRUE;
Packit f01ec2
Packit f01ec2
  if (favorite)
Packit f01ec2
    op_str = "INSERT OR REPLACE";
Packit f01ec2
  else
Packit f01ec2
    op_str = "DELETE";
Packit f01ec2
Packit f01ec2
  update = g_string_new (NULL);
Packit f01ec2
  g_string_append_printf
Packit f01ec2
    (update,
Packit f01ec2
     "%s { <%s> nao:hasTag nao:predefined-tag-favorite }",
Packit f01ec2
     op_str, resource);
Packit f01ec2
Packit f01ec2
  g_debug ("Toggle favorite: query %s", update->str);
Packit f01ec2
Packit f01ec2
  tracker_sparql_connection_update (connection, update->str,
Packit f01ec2
                                    G_PRIORITY_DEFAULT, cancellable,
Packit f01ec2
                                    error);
Packit f01ec2
Packit f01ec2
  g_string_free (update, TRUE);
Packit f01ec2
Packit f01ec2
  if (*error != NULL)
Packit f01ec2
    retval = FALSE;
Packit f01ec2
Packit f01ec2
  return retval;
Packit f01ec2
}
Packit f01ec2
Packit f01ec2
gchar*
Packit f01ec2
gom_tracker_utils_ensure_contact_resource (TrackerSparqlConnection *connection,
Packit f01ec2
                                           GCancellable *cancellable,
Packit f01ec2
                                           GError **error,
Packit f01ec2
                                           const gchar *email,
Packit f01ec2
                                           const gchar *fullname)
Packit f01ec2
{
Packit f01ec2
  GString *select, *insert;
Packit f01ec2
  TrackerSparqlCursor *cursor = NULL;
Packit f01ec2
  gchar *retval = NULL, *mail_uri = NULL;
Packit f01ec2
  gboolean res;
Packit f01ec2
  GVariant *insert_res;
Packit f01ec2
  GVariantIter *iter;
Packit f01ec2
  gchar *key = NULL, *val = NULL;
Packit f01ec2
Packit f01ec2
  mail_uri = g_strconcat ("mailto:", email, NULL);
Packit f01ec2
  select = g_string_new (NULL);
Packit f01ec2
  g_string_append_printf (select,
Packit f01ec2
                          "SELECT ?urn WHERE { ?urn a nco:Contact . "
Packit f01ec2
                          "?urn nco:hasEmailAddress ?mail . "
Packit f01ec2
                          "FILTER (fn:contains(?mail, \"%s\" )) }", mail_uri);
Packit f01ec2
Packit f01ec2
  cursor = tracker_sparql_connection_query (connection,
Packit f01ec2
                                            select->str,
Packit f01ec2
                                            cancellable, error);
Packit f01ec2
Packit f01ec2
  g_string_free (select, TRUE);
Packit f01ec2
Packit f01ec2
  if (*error != NULL)
Packit f01ec2
    goto out;
Packit f01ec2
Packit f01ec2
  res = tracker_sparql_cursor_next (cursor, cancellable, error);
Packit f01ec2
Packit f01ec2
  if (*error != NULL)
Packit f01ec2
    goto out;
Packit f01ec2
Packit f01ec2
  if (res)
Packit f01ec2
    {
Packit f01ec2
      /* return the found resource */
Packit f01ec2
      retval = g_strdup (tracker_sparql_cursor_get_string (cursor, 0, NULL));
Packit f01ec2
      g_debug ("Found resource in the store: %s", retval);
Packit f01ec2
      goto out;
Packit f01ec2
    }
Packit f01ec2
Packit f01ec2
  /* not found, create the resource */
Packit f01ec2
  insert = g_string_new (NULL);
Packit f01ec2
Packit f01ec2
  g_string_append_printf (insert,
Packit f01ec2
                          "INSERT { <%s> a nco:EmailAddress ; nco:emailAddress \"%s\" . "
Packit f01ec2
                          "_:res a nco:Contact ; nco:hasEmailAddress <%s> ; nco:fullname \"%s\" . }",
Packit f01ec2
                          mail_uri, email,
Packit f01ec2
                          mail_uri, fullname);
Packit f01ec2
Packit f01ec2
  insert_res =
Packit f01ec2
    tracker_sparql_connection_update_blank (connection, insert->str,
Packit f01ec2
                                            G_PRIORITY_DEFAULT, cancellable, error);
Packit f01ec2
Packit f01ec2
  g_string_free (insert, TRUE);
Packit f01ec2
Packit f01ec2
  if (*error != NULL)
Packit f01ec2
    goto out;
Packit f01ec2
Packit f01ec2
  /* the result is an "aaa{ss}" variant */
Packit f01ec2
  g_variant_get (insert_res, "aaa{ss}", &iter);
Packit f01ec2
  g_variant_iter_next (iter, "aa{ss}", &iter);
Packit f01ec2
  g_variant_iter_next (iter, "a{ss}", &iter);
Packit f01ec2
  g_variant_iter_next (iter, "{ss}", &key, &val;;
Packit f01ec2
Packit f01ec2
  g_variant_iter_free (iter);
Packit f01ec2
  g_variant_unref (insert_res);
Packit f01ec2
Packit f01ec2
  if (g_strcmp0 (key, "res") == 0)
Packit f01ec2
    {
Packit f01ec2
      retval = val;
Packit f01ec2
    }
Packit f01ec2
  else
Packit f01ec2
    {
Packit f01ec2
      g_free (val);
Packit f01ec2
      goto out;
Packit f01ec2
    }
Packit f01ec2
Packit f01ec2
  g_debug ("Created a new contact resource: %s", retval);
Packit f01ec2
Packit f01ec2
 out:
Packit f01ec2
  g_clear_object (&cursor);
Packit f01ec2
  g_free (mail_uri);
Packit f01ec2
Packit f01ec2
  return retval;
Packit f01ec2
}
Packit f01ec2
Packit f01ec2
gchar *
Packit f01ec2
gom_tracker_utils_ensure_equipment_resource (TrackerSparqlConnection *connection,
Packit f01ec2
                                             GCancellable *cancellable,
Packit f01ec2
                                             GError **error,
Packit f01ec2
                                             const gchar *make,
Packit f01ec2
                                             const gchar *model)
Packit f01ec2
{
Packit f01ec2
  GError *local_error;
Packit f01ec2
  TrackerSparqlCursor *cursor = NULL;
Packit f01ec2
  gboolean res;
Packit f01ec2
  gchar *equip_uri = NULL;
Packit f01ec2
  gchar *insert = NULL;
Packit f01ec2
  gchar *retval = NULL;
Packit f01ec2
  gchar *select = NULL;
Packit f01ec2
Packit f01ec2
  g_return_val_if_fail (TRACKER_SPARQL_IS_CONNECTION (connection), NULL);
Packit f01ec2
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
Packit f01ec2
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
Packit f01ec2
  g_return_val_if_fail (make != NULL || model != NULL, NULL);
Packit f01ec2
Packit f01ec2
  equip_uri = tracker_sparql_escape_uri_printf ("urn:equipment:%s:%s:",
Packit f01ec2
                                                make != NULL ? make : "",
Packit f01ec2
                                                model != NULL ? model : "");
Packit f01ec2
  select = g_strdup_printf ("SELECT <%s> WHERE { }", equip_uri);
Packit f01ec2
Packit f01ec2
  local_error = NULL;
Packit f01ec2
  cursor = tracker_sparql_connection_query (connection, select, cancellable, &local_error);
Packit f01ec2
  if (local_error != NULL)
Packit f01ec2
    {
Packit f01ec2
      g_propagate_error (error, local_error);
Packit f01ec2
      goto out;
Packit f01ec2
    }
Packit f01ec2
Packit f01ec2
  local_error = NULL;
Packit f01ec2
  res = tracker_sparql_cursor_next (cursor, cancellable, &local_error);
Packit f01ec2
  if (local_error != NULL)
Packit f01ec2
    {
Packit f01ec2
      g_propagate_error (error, local_error);
Packit f01ec2
      goto out;
Packit f01ec2
    }
Packit f01ec2
Packit f01ec2
  if (res)
Packit f01ec2
    {
Packit f01ec2
      const gchar *cursor_uri;
Packit f01ec2
Packit f01ec2
      cursor_uri = tracker_sparql_cursor_get_string (cursor, 0, NULL);
Packit f01ec2
      if (g_strcmp0 (cursor_uri, equip_uri) == 0)
Packit f01ec2
        {
Packit f01ec2
          /* return the found resource */
Packit f01ec2
          retval = g_strdup (cursor_uri);
Packit f01ec2
          g_debug ("Found resource in the store: %s", retval);
Packit f01ec2
          goto out;
Packit f01ec2
        }
Packit f01ec2
    }
Packit f01ec2
Packit f01ec2
  /* not found, create the resource */
Packit f01ec2
  insert = g_strdup_printf ("INSERT { <%s> a nfo:Equipment ; nfo:manufacturer \"%s\" ; nfo:model \"%s\" }",
Packit f01ec2
                            equip_uri,
Packit f01ec2
                            make,
Packit f01ec2
                            model);
Packit f01ec2
Packit f01ec2
  local_error = NULL;
Packit f01ec2
  tracker_sparql_connection_update (connection, insert, G_PRIORITY_DEFAULT, cancellable, &local_error);
Packit f01ec2
  if (local_error != NULL)
Packit f01ec2
    {
Packit f01ec2
      g_propagate_error (error, local_error);
Packit f01ec2
      goto out;
Packit f01ec2
    }
Packit f01ec2
Packit f01ec2
  retval = equip_uri;
Packit f01ec2
  equip_uri = NULL;
Packit f01ec2
Packit f01ec2
  g_debug ("Created a new equipment resource: %s", retval);
Packit f01ec2
Packit f01ec2
 out:
Packit f01ec2
  g_clear_object (&cursor);
Packit f01ec2
  g_free (equip_uri);
Packit f01ec2
  g_free (insert);
Packit f01ec2
  g_free (select);
Packit f01ec2
Packit f01ec2
  return retval;
Packit f01ec2
}
Packit f01ec2
Packit f01ec2
void
Packit f01ec2
gom_tracker_update_datasource (TrackerSparqlConnection  *connection,
Packit f01ec2
                               const gchar              *datasource_urn,
Packit f01ec2
                               gboolean                  resource_exists,
Packit f01ec2
                               const gchar              *identifier,
Packit f01ec2
                               const gchar              *resource,
Packit f01ec2
                               GCancellable             *cancellable,
Packit f01ec2
                               GError                  **error)
Packit f01ec2
{
Packit f01ec2
  gboolean set_datasource;
Packit f01ec2
Packit f01ec2
  /* only set the datasource again if it has changed; this avoids touching the
Packit f01ec2
   * DB completely if the entry didn't change at all, since we later also check
Packit f01ec2
   * the mtime. */
Packit f01ec2
  set_datasource = TRUE;
Packit f01ec2
  if (resource_exists)
Packit f01ec2
    {
Packit f01ec2
      gboolean res;
Packit f01ec2
      gchar *old_value;
Packit f01ec2
Packit f01ec2
      res = gom_tracker_sparql_connection_get_string_attribute
Packit f01ec2
        (connection, cancellable, error,
Packit f01ec2
         resource, "nie:dataSource", &old_value);
Packit f01ec2
      g_clear_error (error);
Packit f01ec2
Packit f01ec2
      if (res)
Packit f01ec2
        {
Packit f01ec2
          res = g_str_equal (old_value, datasource_urn);
Packit f01ec2
          g_free (old_value);
Packit f01ec2
        }
Packit f01ec2
Packit f01ec2
      if (res)
Packit f01ec2
        set_datasource = FALSE;
Packit f01ec2
    }
Packit f01ec2
Packit f01ec2
  if (set_datasource)
Packit f01ec2
    gom_tracker_sparql_connection_set_triple
Packit f01ec2
      (connection, cancellable, error,
Packit f01ec2
       identifier, resource,
Packit f01ec2
       "nie:dataSource", datasource_urn);
Packit f01ec2
}
Packit f01ec2
Packit f01ec2
gboolean
Packit f01ec2
gom_tracker_update_mtime (TrackerSparqlConnection  *connection,
Packit f01ec2
                          gint64                    new_mtime,
Packit f01ec2
                          gboolean                  resource_exists,
Packit f01ec2
                          const gchar              *identifier,
Packit f01ec2
                          const gchar              *resource,
Packit f01ec2
                          GCancellable             *cancellable,
Packit f01ec2
                          GError                  **error)
Packit f01ec2
{
Packit f01ec2
  GTimeVal old_mtime;
Packit f01ec2
  gboolean res;
Packit f01ec2
  gchar *old_value;
Packit f01ec2
  gchar *date;
Packit f01ec2
Packit f01ec2
  if (resource_exists)
Packit f01ec2
    {
Packit f01ec2
      res = gom_tracker_sparql_connection_get_string_attribute
Packit f01ec2
        (connection, cancellable, error,
Packit f01ec2
         resource, "nie:contentLastModified", &old_value);
Packit f01ec2
      g_clear_error (error);
Packit f01ec2
Packit f01ec2
      if (res)
Packit f01ec2
        {
Packit f01ec2
          res = g_time_val_from_iso8601 (old_value, &old_mtime);
Packit f01ec2
          g_free (old_value);
Packit f01ec2
        }
Packit f01ec2
Packit f01ec2
      if (res && (new_mtime == old_mtime.tv_sec))
Packit f01ec2
        return FALSE;
Packit f01ec2
    }
Packit f01ec2
Packit f01ec2
  date = gom_iso8601_from_timestamp (new_mtime);
Packit f01ec2
  gom_tracker_sparql_connection_insert_or_replace_triple
Packit f01ec2
    (connection, cancellable, error,
Packit f01ec2
     identifier, resource,
Packit f01ec2
     "nie:contentLastModified", date);
Packit f01ec2
  g_free (date);
Packit f01ec2
Packit f01ec2
  return TRUE;
Packit f01ec2
}