Bug 406865: Clobber pre-recent-bugfixes urlclassifier3.sqlite files that might be in an inconsistent state. r=tony, a=dsicore
authordcamp@mozilla.com
Tue, 04 Dec 2007 19:22:39 -0800
changeset 8732 9e1cc5a693c05d2dd01635a63b9783cdffb24fd1
parent 8731 9bfc46fa736e8643bcf6a9e614b1423ae2f1d878
child 8733 5b0c49b6c0fd0b188a2721fd251e5622a7dccdac
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherdermozilla-central@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstony, dsicore
bugs406865
milestone1.9b2pre
Bug 406865: Clobber pre-recent-bugfixes urlclassifier3.sqlite files that might be in an inconsistent state. r=tony, a=dsicore
toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp
--- a/toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp
+++ b/toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp
@@ -108,19 +108,32 @@
 static const PRLogModuleInfo *gUrlClassifierDbServiceLog = nsnull;
 #define LOG(args) PR_LOG(gUrlClassifierDbServiceLog, PR_LOG_DEBUG, args)
 #define LOG_ENABLED() PR_LOG_TEST(gUrlClassifierDbServiceLog, 4)
 #else
 #define LOG(args)
 #define LOG_ENABLED() (PR_FALSE)
 #endif
 
-// Change filename each time we change the db schema.
+// Schema versioning:  note that we don't bother to migrate between different
+// versions of the schema, we just start fetching the data freshly with each
+// migration.
+
+// The database filename is updated when there is an incompatible
+// schema change and we expect both implementations to continue
+// accessing the same database (such as between stable versions of the
+// platform).
 #define DATABASE_FILENAME "urlclassifier3.sqlite"
 
+// The implementation version is updated during development when we
+// want to change schema, or to recover from updating bugs.  When an
+// implementation version change is detected, the database is scrapped
+// and we start over.
+#define IMPLEMENTATION_VERSION 1
+
 #define MAX_HOST_COMPONENTS 5
 #define MAX_PATH_COMPONENTS 4
 
 // Updates will fail if fed chunks larger than this
 #define MAX_CHUNK_SIZE (1024 * 1024)
 
 #define KEY_LENGTH 16
 
@@ -1989,26 +2002,60 @@ nsUrlClassifierDBServiceWorker::OpenDb()
   LOG(("Opening db\n"));
 
   nsresult rv;
   // open the connection
   nsCOMPtr<mozIStorageService> storageService =
     do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  PRBool exists;
+  rv = mDBFile->Exists(&exists);
+  NS_ENSURE_SUCCESS(rv, rv);
+  PRBool newDB = !exists;
+
   nsCOMPtr<mozIStorageConnection> connection;
   rv = storageService->OpenDatabase(mDBFile, getter_AddRefs(connection));
   if (rv == NS_ERROR_FILE_CORRUPTED) {
     // delete the db and try opening again
     rv = mDBFile->Remove(PR_FALSE);
     NS_ENSURE_SUCCESS(rv, rv);
+
+    newDB = PR_TRUE;
+
     rv = storageService->OpenDatabase(mDBFile, getter_AddRefs(connection));
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
+  if (!newDB) {
+    PRInt32 databaseVersion;
+    rv = connection->GetSchemaVersion(&databaseVersion);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    if (databaseVersion != IMPLEMENTATION_VERSION) {
+      LOG(("Incompatible database, removing."));
+
+      rv = connection->Close();
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = mDBFile->Remove(PR_FALSE);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      newDB = PR_TRUE;
+
+      rv = storageService->OpenDatabase(mDBFile, getter_AddRefs(connection));
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+  }
+
+  if (newDB) {
+    rv = connection->SetSchemaVersion(IMPLEMENTATION_VERSION);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   rv = connection->ExecuteSimpleSQL(NS_LITERAL_CSTRING("PRAGMA synchronous=OFF"));
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = connection->ExecuteSimpleSQL(NS_LITERAL_CSTRING("PRAGMA page_size=4096"));
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = connection->ExecuteSimpleSQL(NS_LITERAL_CSTRING("PRAGMA default_page_size=4096"));
   NS_ENSURE_SUCCESS(rv, rv);