[tracker] Fix fts:offsets()



commit 8456f52f4a37b445d9ae82f616d419702ac86179
Author: Sam Thursfield <sam thursfield codethink co uk>
Date:   Thu Jan 9 17:45:17 2014 +0000

    Fix fts:offsets()
    
    Since the fts4 branch was merged, the fts:offsets() function has been
    broken, because it assumed that properties were stored in the 'fts' table
    in ID order but this was no longer the case.
    
    The property names list is now created on init as static data, but this
    requires having the 'fulltext_indexed' property available in all cases
    where previously it has only been available if the ontologies were loaded
    directly rather than from the GVDB cache.
    
    tests/functional-tests/03-fts-functions.py has been improved to test the
    fts:offsets() function more thoroughly.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=721880

 src/libtracker-data/tracker-db-interface-sqlite.c |   10 +--
 src/libtracker-data/tracker-ontologies.c          |    4 +
 src/libtracker-data/tracker-property.c            |   15 ++++
 src/libtracker-fts/tracker-fts.c                  |   79 ++++++++-------------
 src/libtracker-fts/tracker-fts.h                  |    3 +-
 tests/functional-tests/03-fts-functions.py        |    6 +-
 6 files changed, 58 insertions(+), 59 deletions(-)
---
diff --git a/src/libtracker-data/tracker-db-interface-sqlite.c 
b/src/libtracker-data/tracker-db-interface-sqlite.c
index 1fabf1b..7c121fc 100644
--- a/src/libtracker-data/tracker-db-interface-sqlite.c
+++ b/src/libtracker-data/tracker-db-interface-sqlite.c
@@ -1146,13 +1146,9 @@ tracker_db_interface_sqlite_fts_init (TrackerDBInterface  *db_interface,
                                       gboolean             create)
 {
 #if HAVE_TRACKER_FTS
-       GStrv fts_columns = NULL;
+       GStrv fts_columns;
 
-       tracker_fts_init_db (db_interface->db);
-
-       if (properties) {
-               fts_columns = _fts_create_properties (properties);
-       }
+       tracker_fts_init_db (db_interface->db, properties);
 
        if (create &&
            !tracker_fts_create_table (db_interface->db, "fts",
@@ -1160,6 +1156,8 @@ tracker_db_interface_sqlite_fts_init (TrackerDBInterface  *db_interface,
                g_warning ("FTS tables creation failed");
        }
 
+       fts_columns = _fts_create_properties (properties);
+
        if (fts_columns) {
                GString *insert, *select;
                gint i = 0;
diff --git a/src/libtracker-data/tracker-ontologies.c b/src/libtracker-data/tracker-ontologies.c
index bed8210..b581372 100644
--- a/src/libtracker-data/tracker-ontologies.c
+++ b/src/libtracker-data/tracker-ontologies.c
@@ -556,6 +556,10 @@ tracker_ontologies_write_gvdb (const gchar  *filename,
                        gvdb_hash_table_insert_variant (table, item, uri, "inverse-functional", 
g_variant_new_boolean (TRUE));
                }
 
+               if (tracker_property_get_fulltext_indexed (property)) {
+                       gvdb_hash_table_insert_variant (table, item, uri, "fulltext-indexed", 
g_variant_new_boolean (TRUE));
+               }
+
                domain_indexes = tracker_property_get_domain_indexes (property);
                if (domain_indexes) {
                        g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
diff --git a/src/libtracker-data/tracker-property.c b/src/libtracker-data/tracker-property.c
index 551251d..f79e2c8 100644
--- a/src/libtracker-data/tracker-property.c
+++ b/src/libtracker-data/tracker-property.c
@@ -469,6 +469,21 @@ tracker_property_get_fulltext_indexed (TrackerProperty *property)
 
        priv = GET_PRIV (property);
 
+       if (priv->use_gvdb) {
+               GVariant *value;
+               gboolean result;
+
+               value = tracker_ontologies_get_property_value_gvdb (priv->uri, "fulltext-indexed");
+               if (value != NULL) {
+                       result = g_variant_get_boolean (value);
+                       g_variant_unref (value);
+               } else {
+                       result = FALSE;
+               }
+
+               return result;
+       }
+
        return priv->fulltext_indexed;
 }
 
diff --git a/src/libtracker-fts/tracker-fts.c b/src/libtracker-fts/tracker-fts.c
index 446a4a6..bb31df4 100644
--- a/src/libtracker-fts/tracker-fts.c
+++ b/src/libtracker-fts/tracker-fts.c
@@ -28,6 +28,8 @@
 #  include "fts3.h"
 #endif
 
+static gchar **property_names;
+
 gboolean
 tracker_fts_init (void) {
 #ifdef HAVE_BUILTIN_FTS
@@ -178,54 +180,7 @@ function_property_names (sqlite3_context *context,
                          int              argc,
                          sqlite3_value   *argv[])
 {
-       static gchar **names = NULL;
-       static GMutex mutex;
-       int rc = SQLITE_DONE;
-
-       g_mutex_lock (&mutex);
-
-       if (G_UNLIKELY (names == NULL)) {
-               GPtrArray *names_array;
-               sqlite3_stmt *stmt;
-               sqlite3 *db;
-
-               names_array = g_ptr_array_new ();
-               db = sqlite3_context_db_handle (context);
-               rc = sqlite3_prepare_v2 (db,
-                                        "SELECT Uri "
-                                        "FROM Resource "
-                                        "JOIN \"rdf:Property\" "
-                                        "ON Resource.ID = \"rdf:Property\".ID "
-                                        "WHERE \"rdf:Property\".\"tracker:fulltextIndexed\" = 1 "
-                                        "ORDER BY \"rdf:Property\".ID ",
-                                        -1, &stmt, NULL);
-
-               while ((rc = sqlite3_step (stmt)) != SQLITE_DONE) {
-                       if (rc == SQLITE_ROW) {
-                               const gchar *name;
-
-                               name = sqlite3_column_text (stmt, 0);
-                               g_ptr_array_add (names_array, g_strdup (name));
-                       } else if (rc != SQLITE_BUSY) {
-                               break;
-                       }
-               }
-
-               sqlite3_finalize (stmt);
-
-               if (rc == SQLITE_DONE) {
-                       names = (gchar **) g_ptr_array_free (names_array, FALSE);
-               } else {
-                       g_ptr_array_free (names_array, TRUE);
-               }
-       }
-
-       g_mutex_unlock (&mutex);
-
-       if (rc == SQLITE_DONE)
-               sqlite3_result_blob (context, names, sizeof (names), NULL);
-       else
-               sqlite3_result_error_code (context, rc);
+       sqlite3_result_blob (context, property_names, sizeof (property_names), NULL);
 }
 
 static void
@@ -245,12 +200,38 @@ tracker_fts_register_functions (sqlite3 *db)
                                 NULL, NULL);
 }
 
+static void
+tracker_fts_init_property_names (GHashTable *tables)
+{
+       GHashTableIter iter;
+       GList *columns;
+       GList *table_columns;
+       gchar **ptr;
+
+       columns = NULL;
+       g_hash_table_iter_init (&iter, tables);
+       while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &table_columns)) {
+               columns = g_list_concat (columns, g_list_copy (table_columns));
+       }
+
+       ptr = property_names = g_new0 (gchar *, g_list_length (columns));
+       while (columns) {
+               *ptr = g_strdup (columns->data);
+               ptr ++;
+               columns = columns->next;
+       }
+}
+
 gboolean
-tracker_fts_init_db (sqlite3 *db) {
+tracker_fts_init_db (sqlite3 *db,
+                     GHashTable *tables)
+{
        if (!tracker_tokenizer_initialize (db)) {
                return FALSE;
        }
 
+       tracker_fts_init_property_names (tables);
+
        tracker_fts_register_functions (db);
        return TRUE;
 }
diff --git a/src/libtracker-fts/tracker-fts.h b/src/libtracker-fts/tracker-fts.h
index c020af2..7fdc0dc 100644
--- a/src/libtracker-fts/tracker-fts.h
+++ b/src/libtracker-fts/tracker-fts.h
@@ -28,7 +28,8 @@
 G_BEGIN_DECLS
 
 gboolean    tracker_fts_init             (void);
-gboolean    tracker_fts_init_db          (sqlite3    *db);
+gboolean    tracker_fts_init_db          (sqlite3    *db,
+                                          GHashTable *tables);
 gboolean    tracker_fts_create_table     (sqlite3    *db,
                                           gchar      *table_name,
                                           GHashTable *tables,
diff --git a/tests/functional-tests/03-fts-functions.py b/tests/functional-tests/03-fts-functions.py
index 07b6af2..f9434e6 100755
--- a/tests/functional-tests/03-fts-functions.py
+++ b/tests/functional-tests/03-fts-functions.py
@@ -117,9 +117,9 @@ class TestFTSFunctions (CommonTrackerStoreTest):
         results = self.tracker.query (query)
 
         self.assertEquals (len(results), 3)
-        self.assertEquals (len (results[0][0].split(",")), 4) # (u'151,1,161,1')
-        self.assertEquals (len (results[1][0].split(",")), 2) # (u'161,1')
-        self.assertEquals (len (results[2][0].split(",")), 6) # (u'151,1,151,2,161,1')
+        self.assertEquals (results[0][0], 'nco:fullname,0,nco:nickname,0')
+        self.assertEquals (results[1][0], 'nco:fullname,0')
+        self.assertEquals (results[2][0], 'nco:fullname,0,nco:nickname,0,nco:nickname,10')
 
         delete_sparql = """
         DELETE {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]