← Back to team overview

zeitgeist team mailing list archive

[Branch ~zeitgeist/zeitgeist/bluebird] Rev 256: Update TableLookup caches upon event deletion.

 

------------------------------------------------------------
revno: 256
committer: Siegfried-Angel Gevatter Pujals <siegfried@xxxxxxxxxxxx>
branch nick: bluebird
timestamp: Sat 2011-09-17 21:38:43 +0200
message:
  Update TableLookup caches upon event deletion.
added:
  test/direct/table-lookup-test.vala
modified:
  .bzrignore
  src/engine.vala
  src/sql-schema.vala
  src/sql.vala
  src/table-lookup.vala
  src/zeitgeist-daemon.vala
  test/direct/Makefile.am
  test/direct/marshalling.vala


--
lp:~zeitgeist/zeitgeist/bluebird
https://code.launchpad.net/~zeitgeist/zeitgeist/bluebird

Your team Zeitgeist Framework Team is subscribed to branch lp:~zeitgeist/zeitgeist/bluebird.
To unsubscribe from this branch go to https://code.launchpad.net/~zeitgeist/zeitgeist/bluebird/+edit-subscription
=== modified file '.bzrignore'
--- .bzrignore	2011-08-31 11:02:37 +0000
+++ .bzrignore	2011-09-17 19:38:43 +0000
@@ -45,3 +45,4 @@
 extensions/*.lo
 test/direct/marshalling
 test/dbus/__pycache__
+test/direct/table-lookup-test

=== modified file 'src/engine.vala'
--- src/engine.vala	2011-09-17 09:22:23 +0000
+++ src/engine.vala	2011-09-17 19:38:43 +0000
@@ -38,16 +38,17 @@
     private ExtensionCollection extension_collection;
     private unowned Sqlite.Database db;
 
-    private TableLookup interpretations_table;
-    private TableLookup manifestations_table;
-    private TableLookup mimetypes_table;
-    private TableLookup actors_table;
+    protected TableLookup interpretations_table;
+    protected TableLookup manifestations_table;
+    protected TableLookup mimetypes_table;
+    protected TableLookup actors_table;
 
     private uint32 last_id;
 
     public Engine () throws EngineError
     {
         database = new Zeitgeist.SQLite.ZeitgeistDatabase ();
+        database.set_deletion_callback (delete_from_cache);
         db = database.database;
         last_id = database.get_last_id ();
 
@@ -106,9 +107,9 @@
                     stmt.column_int (EventViewRows.ACTOR));
                 event.origin = stmt.column_text (
                     EventViewRows.EVENT_ORIGIN_URI);
-                
+
                 // Load payload
-                unowned uint8[] data = (uint8[]) 
+                unowned uint8[] data = (uint8[])
                     stmt.column_blob(EventViewRows.PAYLOAD);
                 data.length = stmt.column_bytes(EventViewRows.PAYLOAD);
                 if (data != null)
@@ -1094,11 +1095,11 @@
                 }
             }
         }
-     }
+    }
 
-     private int64 store_payload (Event event)
-     {
-        /** 
+    private int64 store_payload (Event event)
+    {
+        /**
         * TODO: Right now payloads are not unique and every event has its
         * own one. We could optimize this to store those which are repeated
         * for different events only once, especially considering that
@@ -1110,7 +1111,7 @@
             unowned Sqlite.Statement payload_insertion_stmt =
                 database.payload_insertion_stmt;
             payload_insertion_stmt.reset ();
-            payload_insertion_stmt.bind_blob (1, event.payload.data, 
+            payload_insertion_stmt.bind_blob (1, event.payload.data,
                 event.payload.data.length);
             if ((rc = payload_insertion_stmt.step ()) != Sqlite.DONE)
                 if (rc != Sqlite.CONSTRAINT)
@@ -1119,7 +1120,25 @@
             return database.database.last_insert_rowid ();
         }
         return 0;
-     }
+    }
+
+    private void delete_from_cache (string table, int64 rowid)
+    {
+        TableLookup table_lookup;
+
+        if (table == "interpretation")
+            table_lookup = interpretations_table;
+        else if (table == "manifestation")
+            table_lookup = manifestations_table;
+        else if (table == "mimetype")
+            table_lookup = mimetypes_table;
+        else if (table == "actor")
+            table_lookup = actors_table;
+        else
+            return;
+
+        table_lookup.remove((int) rowid);
+    }
 
 }
 

=== modified file 'src/sql-schema.vala'
--- src/sql-schema.vala	2011-08-02 01:21:22 +0000
+++ src/sql-schema.vala	2011-09-17 19:38:43 +0000
@@ -36,13 +36,10 @@
         {
             // TODO: PRAGMA: WAL
 
-            // TODO: use http://www.sqlite.org/c3ref/update_hook.html instead
-            // of fix_cache tmp table
-
             //if (Constants.DATABASE_FILE_PATH != ":memory:" && !new_db)
             // assume temporary memory backed DBs are good
             // check_core_schema_upgrade
-            
+
             create_schema (database);
         }
 

=== modified file 'src/sql.vala'
--- src/sql.vala	2011-09-17 11:19:52 +0000
+++ src/sql.vala	2011-09-17 19:38:43 +0000
@@ -1,7 +1,7 @@
 /* sql.vala
  *
  * Copyright © 2011 Collabora Ltd.
- *             By Siegfried-Angel Gevatter Pujals <siegfried@xxxxxxxxxxxx> 
+ *             By Siegfried-Angel Gevatter Pujals <siegfried@xxxxxxxxxxxx>
  *             By Seif Lotfy <seif@xxxxxxxxx>
  * Copyright © 2011 Manish Sinha <manishsinha@xxxxxxxxxx>
  *
@@ -49,6 +49,8 @@
         SUBJECT_ID_CURRENT
     }
 
+    public delegate void DeletionCallback (string table, int64 rowid);
+
     public class ZeitgeistDatabase : Object
     {
 
@@ -61,6 +63,8 @@
         //  as well as allowing extensions to add tables to it.
         public Sqlite.Database database;
 
+        private DeletionCallback? deletion_callback = null;
+
         public ZeitgeistDatabase () throws EngineError
         {
             int rc = Sqlite.Database.open_v2 (
@@ -75,7 +79,6 @@
             // Register a data change notification callback to look for
             // deletions, so we can keep the TableLookups up to date.
             database.update_hook (update_callback);
-            //database.exec ("DELETE FROM event WHERE 1", null, null);
         }
 
         public uint32 get_last_id () throws EngineError
@@ -95,6 +98,11 @@
             return last_id;
         }
 
+        public void set_deletion_callback (DeletionCallback? callback)
+        {
+            deletion_callback = callback;
+        }
+
         /**
          * Join all given event_ids into a comma-separated string suitable
          * for use in a SQL query like "WHERE id IN (...)".
@@ -237,7 +245,7 @@
                 """;
             rc = database.prepare_v2 (sql, -1, out id_retrieval_stmt);
             assert_query_success (rc, "Event ID retrieval query error");
-            
+
             // Move handling statment
             sql = """
             UPDATE event
@@ -247,7 +255,7 @@
             """;
             rc = database.prepare_v2 (sql, -1, out move_handling_stmt);
             assert_query_success (rc, "Move handling error");
-            
+
             // Payload insertion statment
             sql = """
                 INSERT INTO payload (value) VALUES (?)
@@ -256,11 +264,18 @@
             assert_query_success (rc, "Payload insertion query error");
         }
 
-        protected static void update_callback (Sqlite.Action action,
+
+        protected void update_callback (Sqlite.Action action,
             string dbname, string table, int64 rowid)
         {
             if (action != Sqlite.Action.DELETE)
                 return;
+            if (deletion_callback != null)
+                deletion_callback (table, rowid);
+            //interpretations_table
+            // manifestations_
+            //mimetypes_table - mimetype table
+            // actors_  . actor table
             // FIXME!
             /*
             stdout.printf ("%s", dbname); // = main

=== modified file 'src/table-lookup.vala'
--- src/table-lookup.vala	2011-08-03 18:48:10 +0000
+++ src/table-lookup.vala	2011-09-17 19:38:43 +0000
@@ -29,10 +29,10 @@
 
         unowned Sqlite.Database db;
 
-        string table;
+        private string table;
         private HashTable<int, string> id_to_value;
         private HashTable<string, int> value_to_id;
-        Sqlite.Statement insertion_stmt;
+        private Sqlite.Statement insertion_stmt;
 
         public TableLookup (ZeitgeistDatabase database, string table_name)
         {
@@ -76,9 +76,9 @@
                 {
                     critical ("SQL error: %d, %s\n", rc, db.errmsg ());
                 }
-                
+
                 id = (int) db.last_insert_rowid ();
-                
+
                 id_to_value.insert (id, name);
                 value_to_id.insert (name, id);
             }

=== modified file 'src/zeitgeist-daemon.vala'
--- src/zeitgeist-daemon.vala	2011-09-15 22:15:58 +0000
+++ src/zeitgeist-daemon.vala	2011-09-17 19:38:43 +0000
@@ -113,11 +113,9 @@
 
         public Daemon ()
         {
-            stdout.printf("Hi!\n");
-
             try
             {
-                engine = new Engine();
+                engine = new Engine ();
             }
             catch (EngineError e)
             {
@@ -129,7 +127,6 @@
 
         ~Daemon ()
         {
-            stdout.printf ("BYE\n");
             engine.close ();
         }
 

=== modified file 'test/direct/Makefile.am'
--- test/direct/Makefile.am	2011-09-02 17:46:22 +0000
+++ test/direct/Makefile.am	2011-09-17 19:38:43 +0000
@@ -12,6 +12,7 @@
 	marshalling \
 	query-operators-test \
 	where-clause-test \
+	table-lookup-test \
 	$(NULL)
 
 SRC_FILES = \
@@ -40,6 +41,9 @@
 where-clause-test: where-clause-test.vala $(SRC_FILES)
 	$(VALAC) $(VALAFLAGS) -o $@ $^
 
+table-lookup-test: table-lookup-test.vala $(SRC_FILES)
+	$(VALAC) $(VALAFLAGS) -o $@ $^
+
 clean-local:
 	rm -f *.~[0-9]~
 
@@ -47,12 +51,14 @@
 	marshalling \
 	query-operators-test \
 	where-clause-test \
+	table-lookup-test \
 	$(NULL)
 
 EXTRA_DIST = \
 	marshalling.vala \
 	query-operators-test.vala \
 	where-clause-test.vala \
+	table-lookup-test.vala \
 	assertions.vapi \
 	$(NULL)
 

=== modified file 'test/direct/marshalling.vala'
--- test/direct/marshalling.vala	2011-08-12 14:22:14 +0000
+++ test/direct/marshalling.vala	2011-09-17 19:38:43 +0000
@@ -24,7 +24,7 @@
   e.manifestation = "manifestation_uri";
   e.actor = "test.desktop";
   e.origin = "source";
-  
+
   return e;
 }
 

=== added file 'test/direct/table-lookup-test.vala'
--- test/direct/table-lookup-test.vala	1970-01-01 00:00:00 +0000
+++ test/direct/table-lookup-test.vala	2011-09-17 19:38:43 +0000
@@ -0,0 +1,89 @@
+/* where-clause-test.vala
+ *
+ * Copyright © 2011 Collabora Ltd.
+ *             By Siegfried-Angel Gevatter Pujals <siegfried@xxxxxxxxxxxx>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using Zeitgeist;
+using Zeitgeist.SQLite;
+using Assertions;
+
+void main (string[] args)
+{
+    Test.init (ref args);
+
+    // Do not abort on warning()s.
+    Log.set_always_fatal (LogLevelFlags.LEVEL_CRITICAL);
+
+    // This test will use the database, make sure it won't mess up
+    // the system.
+    assert (Environment.set_variable(
+        "ZEITGEIST_DATA_PATH", "/tmp/zeitgeist-tests", true));
+    assert (Environment.set_variable(
+        "ZEITGEIST_DATABASE_PATH", ":memory:", true));
+
+    Test.add_func ("/WhereClause/basic", basic_test);
+    Test.add_func ("/WhereClause/delete_hook", engine_test);
+    Test.run ();
+}
+
+private class PublicEngine : Zeitgeist.Engine
+{
+    public TableLookup get_actors_table_lookup ()
+    {
+        return actors_table;
+    }
+}
+
+public void basic_test ()
+{
+    ZeitgeistDatabase database = new Zeitgeist.SQLite.ZeitgeistDatabase ();
+    unowned Sqlite.Database db = database.database;
+    TableLookup table_lookup = new TableLookup (database, "actor");
+
+    assert_cmpint (table_lookup.get_id ("1st-actor"), OperatorType.EQUAL, 1);
+    assert_cmpint (table_lookup.get_id ("2nd-actor"), OperatorType.EQUAL, 2);
+    assert_cmpint (table_lookup.get_id ("1st-actor"), OperatorType.EQUAL, 1);
+
+    int rc = db.exec ("DELETE FROM actor WHERE value='1st-actor'");
+    assert (rc == Sqlite.OK);
+
+    table_lookup.remove (1);
+    assert_cmpint (table_lookup.get_id ("2nd-actor"), OperatorType.EQUAL, 2);
+    assert_cmpint (table_lookup.get_id ("1st-actor"), OperatorType.EQUAL, 3);
+}
+
+public void engine_test ()
+{
+    PublicEngine engine = new PublicEngine ();
+    ZeitgeistDatabase database = engine.database;
+    unowned Sqlite.Database db = database.database;
+    TableLookup table_lookup = engine.get_actors_table_lookup();
+
+    assert_cmpint (table_lookup.get_id ("something"), OperatorType.EQUAL, 1);
+
+    // Since we're running with Engine, this should trigger the deletion
+    // callback, which in turn should fix the cache (LP: #598666).
+    int rc = db.exec ("DELETE FROM actor WHERE value='something'");
+    assert (rc == Sqlite.OK);
+
+    assert_cmpint (
+        table_lookup.get_id ("sqlite-reuses-the-id"), OperatorType.EQUAL, 1);
+    assert_cmpint (table_lookup.get_id ("something"), OperatorType.EQUAL, 2);
+}
+
+// vim:expandtab:ts=4:sw=4