[tracker/tracker-tag-and-operator-fix] wip
- From: Martyn James Russell <mr src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/tracker-tag-and-operator-fix] wip
- Date: Thu, 20 Mar 2014 12:19:54 +0000 (UTC)
commit 83b631cd9f607d50719f7c2b22d9c9f0e935d284
Author: Martyn Russell <martyn lanedo com>
Date: Mon Mar 10 13:01:19 2014 +0000
wip
docs/manpages/tracker-tag.1 | 21 +++-
src/tracker-utils/tracker-tag.c | 221 ++++++++++++++++++++++++++++++---------
2 files changed, 186 insertions(+), 56 deletions(-)
---
diff --git a/docs/manpages/tracker-tag.1 b/docs/manpages/tracker-tag.1
index 73519a4..8b7b8d3 100644
--- a/docs/manpages/tracker-tag.1
+++ b/docs/manpages/tracker-tag.1
@@ -29,8 +29,18 @@ Limit search to N results. The default is 512.
Offset the search results by N. For example, start at item number 10
in the results. The default is 0.
.TP
-.B \-r, \-\-or-operator
-Use OR for search terms instead of AND (the default)
+.B \-r, \-\-and-operator
+Use AND operator for search terms instead of OR(the default). For
+example:
+
+.nf
+$ tracker-tag -s -t sliff sloff
+.fi
+
+Should show files in the database that have both the \fIsliff\fR
+.B AND
+\fIsloff\fR tags.
+
.TP
.B \-t, \-\-list
List all tags. Results include the number of files associated with
@@ -39,10 +49,11 @@ associated with each tag by using --show-files.
The \fITAG\fR arguments are optional. If no \fITAG\fR argument
is specified, all tags are listed. If one or more \fITAG\fRs are
-given, all matching tags are listed. For example, this will match any
-tags named either \fIfoo\fR, \fIbar\fR or \fIbaz\fR:
+given, either matching tags are listed (OR condition). For example,
+this will match any tags named either \fIfoo\fR, \fIbar\fR or
+\fIbaz\fR:
+
.nf
-.BR
$ tracker-tag -t foo bar baz
.fi
diff --git a/src/tracker-utils/tracker-tag.c b/src/tracker-utils/tracker-tag.c
index 42c4b95..ba88792 100644
--- a/src/tracker-utils/tracker-tag.c
+++ b/src/tracker-utils/tracker-tag.c
@@ -42,7 +42,7 @@
static gint limit = 512;
static gint offset;
static gchar **files;
-static gboolean or_operator;
+static gboolean and_operator;
static gchar *add_tag;
static gchar *remove_tag;
static gchar *description;
@@ -59,8 +59,8 @@ static GOptionEntry entries[] = {
N_("Offset the results"),
"0"
},
- { "or-operator", 'r', 0, G_OPTION_ARG_NONE, &or_operator,
- N_("Use OR for search terms instead of AND (the default)"),
+ { "and-operator", 'n', 0, G_OPTION_ARG_NONE, &and_operator,
+ N_("Use AND for search terms instead of OR (the default)"),
NULL
},
{ "list", 't', 0, G_OPTION_ARG_NONE, &list,
@@ -150,7 +150,9 @@ get_escaped_sparql_string (const gchar *str)
static gchar *
get_filter_string (GStrv files,
+ const gchar *subject,
gboolean files_are_urns,
+ gboolean and_operator,
const gchar *tag)
{
GString *filter;
@@ -176,13 +178,17 @@ get_filter_string (GStrv files,
for (i = 0; i < len; i++) {
if (files_are_urns) {
- g_string_append_printf (filter, "?urn = <%s>", files[i]);
+ g_string_append_printf (filter, "%s = <%s>", subject, files[i]);
} else {
- g_string_append_printf (filter, "?f = \"%s\"", files[i]);
+ g_string_append_printf (filter, "%s = \"%s\"", subject, files[i]);
}
if (i < len - 1) {
- g_string_append (filter, " || ");
+ if (G_UNLIKELY (and_operator)) {
+ g_string_append (filter, " && ");
+ } else {
+ g_string_append (filter, " || ");
+ }
}
}
@@ -233,7 +239,7 @@ get_file_urns (TrackerSparqlConnection *connection,
gchar *query, *filter;
GError *error = NULL;
- filter = get_filter_string (uris, FALSE, tag);
+ filter = get_filter_string (uris, "?f", FALSE, FALSE, tag);
query = g_strdup_printf ("SELECT ?urn ?f "
"WHERE { "
" ?urn "
@@ -337,61 +343,170 @@ get_all_tags_show_tag_id (TrackerSparqlConnection *connection,
g_object_unref (cursor);
}
+static inline gchar *
+get_filter_in_for_strv (GStrv files,
+ const gchar *subject)
+{
+ gchar *filter, *filter_in;
+
+ /* e.g. '?label IN ("foo", "bar")' */
+ filter_in = g_strjoinv ("\",\"", files);
+ filter = g_strdup_printf ("FILTER (%s IN (\"%s\"))", subject, filter_in);
+ g_free (filter_in);
+
+ return filter;
+}
+
+static gboolean
+get_all_files (TrackerSparqlConnection *connection,
+ GStrv files,
+ gint search_offset,
+ gint search_limit)
+{
+ TrackerSparqlCursor *cursor;
+ GError *error = NULL;
+ GStrv tags;
+ gchar *filter, *query;
+
+ /* First, get matching tags */
+ filter = get_filter_in_for_strv (files, "?label");
+ query = g_strdup_printf ("SELECT ?t"
+ "WHERE { "
+ " ?t a nao:Tag ;"
+ " nao:prefLabel ?label ."
+ " %s"
+ "}",
+ filter);
+ g_free (filter);
+
+ cursor = tracker_sparql_connection_query (connection, query, NULL, &error);
+ g_free (query);
+
+ if (error) {
+ g_printerr ("%s, %s\n",
+ _("Could not get all tags in the database"),
+ error->message);
+ g_error_free (error);
+
+ return FALSE;
+ }
+
+ tags = result_to_strv (cursor, 0);
+ if (!tags) {
+ g_print ("%s\n",
+ _("No files have been tagged"));
+
+ if (cursor) {
+ g_object_uref (cursor);
+ }
+
+ return TRUE;
+ }
+
+ filter = get_filter_in_for_strv (tags, "?t")
+ g_strv_free (tags);
+
+ query = g_strdup_printf ("SELECT DISTINCT nie:url(?f) "
+ "WHERE {"
+ " ?r a rdfs:Resource ;"
+ " nao:hasTag ?t ."
+ " %s"
+ "}"
+ "OFFSET %d "
+ "LIMIT %d",
+ filter,
+ search_offset,
+ search_limit);
+ g_free (filter);
+
+ cursor = tracker_sparql_connection_query (connection, query, NULL, &error);
+ g_free (query);
+
+ if (error) {
+ g_printerr ("%s, %s\n",
+ _("Could not get files for matching tags"),
+ error->message);
+ g_error_free (error);
+
+ return FALSE;
+ }
+
+ if (!cursor) {
+ g_print ("%s\n",
+ _("No files were found matching ALL of those tags"));
+ } else {
+ gint count = 0;
+
+ g_print ("%s:\n", _("Files"));
+
+ while (tracker_sparql_cursor_next (cursor, NULL, NULL)) {
+ g_print (" %s\n",
+ tracker_sparql_cursor_get_string (cursor, 0, NULL));
+ count++;
+ }
+
+ if (count == 0) {
+ /* To translators: This is to say there are no
+ * files found associated with multiple tags, e.g.:
+ *
+ * Files:
+ * None
+ *
+ */
+ g_print (" %s\n", _("None"));
+ }
+
+ g_print ("\n");
+
+ if (count >= search_limit) {
+ show_limit_warning ();
+ }
+
+ g_object_unref (cursor);
+ }
+
+ return TRUE;
+}
+
+
static gboolean
get_all_tags (TrackerSparqlConnection *connection,
GStrv files,
gint search_offset,
gint search_limit,
- gboolean use_or_operator,
gboolean show_files)
{
TrackerSparqlCursor *cursor;
GError *error = NULL;
gchar *query;
+ gchar *filter = NULL;
if (files && g_strv_length (files) > 0) {
- gchar *filter;
+ filter = get_filter_in_for_label (files);
+ }
- /* e.g. '?label IN ("foo", "bar")' */
- filter = g_strjoinv ("\",\"", files);
- /* You might be asking, why not logical AND here, why
- * logical OR for FILTER, well, tags can't have
- * multiple labels is the simple answer.
- */
- query = g_strdup_printf ("SELECT ?tag ?label nao:description(?tag) COUNT(?urns) AS urns "
- "WHERE {"
- " ?tag a nao:Tag ;"
- " nao:prefLabel ?label ."
- " OPTIONAL {"
- " ?urns nao:hasTag ?tag"
- " } ."
- " FILTER (?label IN (\"%s\"))"
- "} "
- "GROUP BY ?tag "
- "ORDER BY ASC(?label) "
- "OFFSET %d "
- "LIMIT %d",
- filter,
- search_offset,
- search_limit);
- g_free (filter);
- } else {
- query = g_strdup_printf ("SELECT ?tag ?label nao:description(?tag) COUNT(?urns) AS urns "
- "WHERE {"
- " ?tag a nao:Tag ;"
- " nao:prefLabel ?label ."
- " OPTIONAL {"
- " ?urns nao:hasTag ?tag"
- " }"
- "} "
- "GROUP BY ?tag "
- "ORDER BY ASC(?label) "
- "OFFSET %d "
- "LIMIT %d",
- search_offset,
- search_limit);
- }
+ /* You might be asking, why not logical AND here, why
+ * logical OR for FILTER, well, tags can't have
+ * multiple labels is the simple answer.
+ */
+ query = g_strdup_printf ("SELECT ?tag ?label nao:description(?tag) COUNT(?urns) AS urns "
+ "WHERE {"
+ " ?tag a nao:Tag ;"
+ " nao:prefLabel ?label ."
+ " OPTIONAL {"
+ " ?urns nao:hasTag ?tag"
+ " } ."
+ " %s"
+ "} "
+ "GROUP BY ?tag "
+ "ORDER BY ASC(?label) "
+ "OFFSET %d "
+ "LIMIT %d",
+ filter ? filter : "",
+ search_offset,
+ search_limit);
+ g_free (filter);
cursor = tracker_sparql_connection_query (connection, query, NULL, &error);
g_free (query);
@@ -618,7 +733,7 @@ add_tag_for_urns (TrackerSparqlConnection *connection,
if (urns_strv) {
gchar *filter;
- filter = get_filter_string (urns_strv, TRUE, NULL);
+ filter = get_filter_string (urns_strv, "?urn", TRUE, FALSE, NULL);
/* Add tag to specific urns */
query = g_strdup_printf ("INSERT { "
@@ -738,7 +853,7 @@ remove_tag_for_urns (TrackerSparqlConnection *connection,
}
urns_strv = result_to_strv (urns_cursor, 0);
- filter = get_filter_string (urns_strv, TRUE, urn);
+ filter = get_filter_string (urns_strv, "?urn", TRUE, FALSE, urn);
g_strfreev (urns_strv);
query = g_strdup_printf ("DELETE { "
@@ -921,7 +1036,11 @@ main (int argc, char **argv)
if (list) {
gboolean success;
- success = get_all_tags (connection, files, offset, limit, or_operator, show_files);
+ if (G_UNLIKELY (and_operator)) {
+ success = get_all_files (connection, files, offset, limit);
+ } else {
+ success = get_all_tags (connection, files, offset, limit, show_files);
+ }
g_object_unref (connection);
return success ? EXIT_SUCCESS : EXIT_FAILURE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]