Bug 614439 - Downgrading from a Places branch version leaves user with double triggers.
authorMarco Bonardo <mbonardo@mozilla.com>
Wed, 24 Nov 2010 16:36:05 +0100
changeset 57709 871fb4bfcce054164a5f46344b3b7acd08d47709
parent 57708 9d7cc07690d267f79ea52b59fba47be4a0e3ab31
child 57710 95cca4f726cb182fc9d00c570bda5d3669dde73c
push id48
push usermak77@bonardo.net
push dateWed, 24 Nov 2010 15:36:50 +0000
bugs614439
milestone2.0b8pre
Bug 614439 - Downgrading from a Places branch version leaves user with double triggers. r=dietrich a=blocking
toolkit/components/places/src/nsNavHistory.cpp
toolkit/components/places/src/nsNavHistory.h
toolkit/components/places/src/nsPlacesTriggers.h
--- a/toolkit/components/places/src/nsNavHistory.cpp
+++ b/toolkit/components/places/src/nsNavHistory.cpp
@@ -941,22 +941,16 @@ nsNavHistory::InitDB()
 
     // 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);
 
-    // Visits triggers.
-    rv = mDBConn->ExecuteSimpleSQL(CREATE_HISTORYVISITS_AFTERINSERT_TRIGGER);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = mDBConn->ExecuteSimpleSQL(CREATE_HISTORYVISITS_AFTERDELETE_TRIGGER);
-    NS_ENSURE_SUCCESS(rv, rv);
-
     // This makes a big difference in startup time for large profiles because of
     // finding bookmark redirects using the referring page. 
     rv = mDBConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_HISTORYVISITS_FROMVISIT);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = mDBConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_HISTORYVISITS_VISITDATE);
     NS_ENSURE_SUCCESS(rv, rv);
 
@@ -988,16 +982,19 @@ nsNavHistory::InitDB()
 
 
 nsresult
 nsNavHistory::InitAdditionalDBItems()
 {
   nsresult rv = InitFunctions();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  rv = InitTriggers();
+  NS_ENSURE_SUCCESS(rv, rv);
+
   // These statements are used by frecency calculation.  Since frecency runs in
   // the storage async thread, it needs to access them through a const history
   // object, for thread-safety.  Due to const correctness it's not possible for
   // the statements getter to lazily initialize them on first use, thus they
   // are initialized here.
   (void*)GetStatement(mDBPageInfoForFrecency);
   (void*)GetStatement(mDBAsyncThreadPageInfoForFrecency);
   (void*)GetStatement(mDBVisitsForFrecency);
@@ -1105,16 +1102,27 @@ nsNavHistory::InitFunctions()
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = GenerateGUIDFunction::create(mDBConn);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
+nsresult
+nsNavHistory::InitTriggers()
+{
+  nsresult rv = mDBConn->ExecuteSimpleSQL(CREATE_HISTORYVISITS_AFTERINSERT_TRIGGER);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = mDBConn->ExecuteSimpleSQL(CREATE_HISTORYVISITS_AFTERDELETE_TRIGGER);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
+
 mozIStorageStatement*
 nsNavHistory::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
 {
   // mCanNotify is set to false on shutdown.
   if (!mCanNotify)
     return nsnull;
 
   RETURN_IF_STMT(mDBGetURLPageInfo, NS_LITERAL_CSTRING(
@@ -1788,61 +1796,32 @@ nsNavHistory::MigrateV10Up(mozIStorageCo
 
   return NS_OK;
 }
 
 
 nsresult
 nsNavHistory::MigrateV11Up(mozIStorageConnection *aDBConn)
 {
-  // Temp tables are going away, so we need the visit_count triggers to return.
-
-  // Regardless triggers existance, every time we pass through this migration
+  // Temp tables are going away.
+  // For triggers correctness, every time we pass through this migration
   // step, we must ensure correctness of visit_count values.
   nsresult rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     "UPDATE moz_places SET visit_count = "
       "(SELECT count(*) FROM moz_historyvisits "
        "WHERE place_id = moz_places.id "
         "AND visit_type NOT IN ") +
           nsPrintfCString("(0,%d,%d,%d) ",
                           nsINavHistoryService::TRANSITION_EMBED,
                           nsINavHistoryService::TRANSITION_FRAMED_LINK,
                           nsINavHistoryService::TRANSITION_DOWNLOAD) +
       NS_LITERAL_CSTRING(")")
   );
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Now create triggers if needed.
-  nsCOMPtr<mozIStorageStatement> triggerDetection;
-  rv = aDBConn->CreateStatement(NS_LITERAL_CSTRING(
-      "SELECT name "
-      "FROM sqlite_master "
-      "WHERE type = 'trigger' "
-      "AND name = :trigger_name"),
-    getter_AddRefs(triggerDetection));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Both visits triggers were removed in the past at the same time, so we can
-  // check just one of them.
-  PRBool triggerExists;
-  rv = triggerDetection->BindUTF8StringByName(
-    NS_LITERAL_CSTRING("trigger_name"),
-    NS_LITERAL_CSTRING("moz_historyvisits_afterinsert_v2_trigger")
-  );
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = triggerDetection->ExecuteStep(&triggerExists);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!triggerExists) {
-    rv = mDBConn->ExecuteSimpleSQL(CREATE_HISTORYVISITS_AFTERINSERT_TRIGGER);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = mDBConn->ExecuteSimpleSQL(CREATE_HISTORYVISITS_AFTERDELETE_TRIGGER);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
   return NS_OK;
 }
 
 
 // nsNavHistory::GetUrlIdFor
 //
 //    Called by the bookmarks and annotation services, this function returns the
 //    ID of the row for the given URL, optionally creating one if it doesn't
--- a/toolkit/components/places/src/nsNavHistory.h
+++ b/toolkit/components/places/src/nsNavHistory.h
@@ -712,17 +712,17 @@ protected:
   nsresult InitDB();
 
   /**
    * Initializes additional database items like functions, triggers, and
    * statements.
    */
   nsresult InitAdditionalDBItems();
   nsresult InitFunctions();
-  nsresult InitStatements();
+  nsresult InitTriggers();
   nsresult ForceMigrateBookmarksDB(mozIStorageConnection *aDBConn);
   nsresult MigrateV3Up(mozIStorageConnection *aDBConn);
   nsresult MigrateV6Up(mozIStorageConnection *aDBConn);
   nsresult MigrateV7Up(mozIStorageConnection *aDBConn);
   nsresult MigrateV8Up(mozIStorageConnection *aDBConn);
   nsresult MigrateV9Up(mozIStorageConnection *aDBConn);
   nsresult MigrateV10Up(mozIStorageConnection *aDBConn);
   nsresult MigrateV11Up(mozIStorageConnection *aDBConn);
--- a/toolkit/components/places/src/nsPlacesTriggers.h
+++ b/toolkit/components/places/src/nsPlacesTriggers.h
@@ -72,28 +72,28 @@
   "END" \
 )
 
 /**
  * This triggers update visit_count and last_visit_date based on historyvisits
  * table changes.
  */
 #define CREATE_HISTORYVISITS_AFTERINSERT_TRIGGER NS_LITERAL_CSTRING( \
-  "CREATE TRIGGER moz_historyvisits_afterinsert_v2_trigger " \
+  "CREATE TEMP TRIGGER moz_historyvisits_afterinsert_v2_trigger " \
   "AFTER INSERT ON moz_historyvisits FOR EACH ROW " \
   "BEGIN " \
     "UPDATE moz_places SET " \
       "visit_count = visit_count + (SELECT NEW.visit_type NOT IN (" EXCLUDED_VISIT_TYPES ")), "\
       "last_visit_date = MAX(IFNULL(last_visit_date, 0), NEW.visit_date) " \
     "WHERE id = NEW.place_id;" \
   "END" \
 )
 
 #define CREATE_HISTORYVISITS_AFTERDELETE_TRIGGER NS_LITERAL_CSTRING( \
-  "CREATE TRIGGER moz_historyvisits_afterdelete_v2_trigger " \
+  "CREATE TEMP TRIGGER moz_historyvisits_afterdelete_v2_trigger " \
   "AFTER DELETE ON moz_historyvisits FOR EACH ROW " \
   "BEGIN " \
     "UPDATE moz_places SET " \
       "visit_count = visit_count - (SELECT OLD.visit_type NOT IN (" EXCLUDED_VISIT_TYPES ")), "\
       "last_visit_date = (SELECT visit_date FROM moz_historyvisits " \
                          "WHERE place_id = OLD.place_id " \
                          "ORDER BY visit_date DESC LIMIT 1) " \
     "WHERE id = OLD.place_id;" \