Bug 607112 - make GUID a column in moz_places and moz_bookmarks
authorShawn Wilsher <me@shawnwilsher.com>
Thu, 02 Dec 2010 09:43:50 -0800
changeset 59372 fa66a8f0f02acacbeffa8099ed493bd71d756ef4
parent 59371 60e4b26536ff2eaf53073e308dfa9bb95e091890
child 59373 7bfe544f55de05d3335700512333c944a22c3200
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
bugs607112
milestone2.0b8pre
Bug 607112 - make GUID a column in moz_places and moz_bookmarks Part 3 - create a guid column on moz_places and add guids r=mak
toolkit/components/places/src/nsNavHistory.cpp
toolkit/components/places/src/nsPlacesIndexes.h
toolkit/components/places/src/nsPlacesTables.h
toolkit/components/places/tests/migration/test_v11_from_v10.js
--- a/toolkit/components/places/src/nsNavHistory.cpp
+++ b/toolkit/components/places/src/nsNavHistory.cpp
@@ -947,16 +947,19 @@ nsNavHistory::InitDB()
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = mDBConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_PLACES_FRECENCY);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = mDBConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_PLACES_LASTVISITDATE);
     NS_ENSURE_SUCCESS(rv, rv);
 
+    rv = mDBConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_PLACES_GUID);
+    NS_ENSURE_SUCCESS(rv, rv);
+
     // CREATE TABLE moz_historyvisits.
     rv = mDBConn->ExecuteSimpleSQL(CREATE_MOZ_HISTORYVISITS);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = mDBConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_HISTORYVISITS_PLACEDATE);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // This makes a big difference in startup time for large profiles because of
@@ -1089,16 +1092,28 @@ nsNavHistory::CheckAndUpdateGUIDs()
     "SET guid = GENERATE_GUID() "
     "WHERE guid IS NULL "
   ), getter_AddRefs(stmt));
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = stmt->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // Finally, we need to generate guids for any places that do not already have
+  // one.
+  rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
+    "UPDATE moz_places "
+    "SET guid = GENERATE_GUID() "
+    "WHERE guid IS NULL "
+  ), getter_AddRefs(stmt));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = stmt->Execute();
+  NS_ENSURE_SUCCESS(rv, rv);
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNavHistory::GetDatabaseStatus(PRUint16 *aDatabaseStatus)
 {
   NS_ENSURE_ARG_POINTER(aDatabaseStatus);
   *aDatabaseStatus = mDatabaseStatus;
@@ -1922,16 +1937,27 @@ nsNavHistory::MigrateV11Up(mozIStorageCo
     rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
       "ALTER TABLE moz_bookmarks "
       "ADD COLUMN guid TEXT"
     ));
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = aDBConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_BOOKMARKS_GUID);
     NS_ENSURE_SUCCESS(rv, rv);
+
+    // moz_placess grew a guid column.  Add the column, but do not populate it
+    // with anything just yet.  We will do that soon.
+    rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
+      "ALTER TABLE moz_places "
+      "ADD COLUMN guid TEXT"
+    ));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = aDBConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_PLACES_GUID);
+    NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // We need to update our guids before we do any real database work.
   rv = CheckAndUpdateGUIDs();
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
--- a/toolkit/components/places/src/nsPlacesIndexes.h
+++ b/toolkit/components/places/src/nsPlacesIndexes.h
@@ -74,16 +74,21 @@
     "frecencyindex", "moz_places", "frecency", "" \
   )
 
 #define CREATE_IDX_MOZ_PLACES_LASTVISITDATE \
   CREATE_PLACES_IDX( \
     "lastvisitdateindex", "moz_places", "last_visit_date", "" \
   )
 
+#define CREATE_IDX_MOZ_PLACES_GUID \
+  CREATE_PLACES_IDX( \
+    "guid_uniqueindex", "moz_places", "guid", "UNIQUE" \
+  )
+
 /**
  * moz_historyvisits
  */
 
 #define CREATE_IDX_MOZ_HISTORYVISITS_PLACEDATE \
   CREATE_PLACES_IDX( \
     "placedateindex", "moz_historyvisits", "place_id, visit_date", "" \
   )
--- a/toolkit/components/places/src/nsPlacesTables.h
+++ b/toolkit/components/places/src/nsPlacesTables.h
@@ -48,16 +48,17 @@
     ", title LONGVARCHAR" \
     ", rev_host LONGVARCHAR" \
     ", visit_count INTEGER DEFAULT 0" \
     ", hidden INTEGER DEFAULT 0 NOT NULL" \
     ", typed INTEGER DEFAULT 0 NOT NULL" \
     ", favicon_id INTEGER" \
     ", frecency INTEGER DEFAULT -1 NOT NULL" \
     ", last_visit_date INTEGER " \
+    ", guid TEXT" \
   ")" \
 )
 #define MOZ_PLACES_COLUMNS \
   "id, url, title, rev_host, visit_count, hidden, typed, favicon_id, " \
   "frecency, last_visit_date"
 
 #define CREATE_MOZ_HISTORYVISITS NS_LITERAL_CSTRING( \
   "CREATE TABLE moz_historyvisits (" \
--- a/toolkit/components/places/tests/migration/test_v11_from_v10.js
+++ b/toolkit/components/places/tests/migration/test_v11_from_v10.js
@@ -46,16 +46,17 @@ function test_initial_state()
 
   let stmt = db.createStatement("PRAGMA journal_mode");
   do_check_true(stmt.executeStep());
   // WAL journal mode should not be set on this database.
   do_check_neq(stmt.getString(0).toLowerCase(), "wal");
   stmt.finalize();
 
   do_check_false(db.indexExists("moz_bookmarks_guid_uniqueindex"));
+  do_check_false(db.indexExists("moz_places_guid_uniqueindex"));
 
   // There should be five item annotations for a bookmark guid.
   stmt = db.createStatement(
     "SELECT content AS guid, item_id "
   + "FROM moz_items_annos "
   + "WHERE anno_attribute_id = ( "
   +   "SELECT id "
   +   "FROM moz_anno_attributes "
@@ -162,48 +163,85 @@ function test_bookmark_guid_annotation_r
   stmt.params.attr_name = kGuidAnnotationName;
   do_check_true(stmt.executeStep());
   do_check_eq(stmt.getInt32(0), 0);
   stmt.finalize();
 
   run_next_test();
 }
 
+function test_moz_places_guid_exists()
+{
+  // This will throw if the column does not exist
+  let stmt = DBConn().createStatement(
+    "SELECT guid "
+  + "FROM moz_places "
+  );
+  stmt.finalize();
+
+  run_next_test();
+}
+
+function test_place_guids_non_null()
+{
+  // First, sanity check that we have a non-zero amount of places.
+  let stmt = DBConn().createStatement(
+    "SELECT COUNT(1) "
+  + "FROM moz_places "
+  );
+  do_check_true(stmt.executeStep());
+  do_check_neq(stmt.getInt32(0), 0);
+  stmt.finalize();
+
+  // Now, make sure we have no NULL guid entry.
+  stmt = DBConn().createStatement(
+    "SELECT guid "
+  + "FROM moz_places "
+  + "WHERE guid IS NULL "
+  );
+  do_check_false(stmt.executeStep());
+  stmt.finalize();
+  run_next_test();
+}
+
 function test_final_state()
 {
   // We open a new database mostly so that we can check that the settings were
   // actually saved.
   let dbFile = gProfD.clone();
   dbFile.append(kDBName);
   let db = Services.storage.openUnsharedDatabase(dbFile);
 
   let (stmt = db.createStatement("PRAGMA journal_mode")) {
     do_check_true(stmt.executeStep());
     // WAL journal mode should be set on this database.
     do_check_eq(stmt.getString(0).toLowerCase(), "wal");
     stmt.finalize();
   }
 
   do_check_true(db.indexExists("moz_bookmarks_guid_uniqueindex"));
+  do_check_true(db.indexExists("moz_places_guid_uniqueindex"));
 
   do_check_eq(db.schemaVersion, 11);
 
   db.close();
   run_next_test();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Test Runner
 
 let tests = [
   test_initial_state,
   test_moz_bookmarks_guid_exists,
   test_bookmark_guids_non_null,
   test_bookmark_guid_annotation_imported,
   test_bookmark_guid_annotation_removed,
+  test_moz_places_guid_exists,
+  test_place_guids_non_null,
   test_final_state,
 ];
 let index = 0;
 
 function run_next_test()
 {
   function _run_next_test() {
     if (index < tests.length) {