Bug 1195930 - Part 6: A new schema upgrade for IndexedDB databases; r=asuth
authorJan Varga <jan.varga@gmail.com>
Sun, 05 Jun 2016 21:42:33 +0200
changeset 339565 bc2fd77579c9ca71bd5d4e155ca32597656b3298
parent 339564 e345136f5a86c04232e3bc0548cafd7976f8bd42
child 339566 9d2d9e54215fe294c581873f9081240219af11de
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1195930
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1195930 - Part 6: A new schema upgrade for IndexedDB databases; r=asuth
dom/indexedDB/ActorsParent.cpp
dom/indexedDB/test/unit/schema23upgrade_profile.zip
dom/indexedDB/test/unit/test_schema23upgrade.js
dom/indexedDB/test/unit/xpcshell-parent-process.ini
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -146,17 +146,17 @@ class VersionChangeTransaction;
  ******************************************************************************/
 
 // If JS_STRUCTURED_CLONE_VERSION changes then we need to update our major
 // schema version.
 static_assert(JS_STRUCTURED_CLONE_VERSION == 6,
               "Need to update the major schema version.");
 
 // Major schema version. Bump for almost everything.
-const uint32_t kMajorSchemaVersion = 22;
+const uint32_t kMajorSchemaVersion = 23;
 
 // Minor schema version. Should almost always be 0 (maybe bump on release
 // branches if we have to).
 const uint32_t kMinorSchemaVersion = 0;
 
 // The schema version we store in the SQLite database is a (signed) 32-bit
 // integer. The major version is left-shifted 4 bits so the max value is
 // 0xFFFFFFF. The minor version occupies the lower 4 bits and its max is 0xF.
@@ -1050,16 +1050,23 @@ CreateTables(mozIStorageConnection* aCon
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
 
   PROFILER_LABEL("IndexedDB",
                  "CreateTables",
                  js::ProfileEntry::Category::STORAGE);
 
   // Table `database`
+
+  // There are two reasons for having the origin column.
+  // First, we can ensure that we don't have collisions in the origin hash we
+  // use for the path because when we open the db we can make sure that the
+  // origins exactly match. Second, chrome code crawling through the idb
+  // directory can figure out the origin of every db without having to
+  // reverse-engineer our hash scheme.
   nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     "CREATE TABLE database"
       "( name TEXT PRIMARY KEY"
       ", origin TEXT NOT NULL"
       ", version INTEGER NOT NULL DEFAULT 0"
       ", last_vacuum_time INTEGER NOT NULL DEFAULT 0"
       ", last_analyze_time INTEGER NOT NULL DEFAULT 0"
       ", last_vacuum_size INTEGER NOT NULL DEFAULT 0"
@@ -4049,16 +4056,55 @@ UpgradeSchemaFrom21_0To22_0(mozIStorageC
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult
+UpgradeSchemaFrom22_0To23_0(mozIStorageConnection* aConnection,
+                            const nsACString& aOrigin)
+{
+  AssertIsOnIOThread();
+  MOZ_ASSERT(aConnection);
+  MOZ_ASSERT(!aOrigin.IsEmpty());
+
+  PROFILER_LABEL("IndexedDB",
+                 "UpgradeSchemaFrom22_0To23_0",
+                 js::ProfileEntry::Category::STORAGE);
+
+  nsCOMPtr<mozIStorageStatement> stmt;
+  nsresult rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
+    "UPDATE database "
+      "SET origin = :origin;"
+  ), getter_AddRefs(stmt));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("origin"), aOrigin);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  rv = stmt->Execute();
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  rv = aConnection->SetSchemaVersion(MakeSchemaVersion(23, 0));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  return NS_OK;
+}
+
+nsresult
 GetDatabaseFileURL(nsIFile* aDatabaseFile,
                    PersistenceType aPersistenceType,
                    const nsACString& aGroup,
                    const nsACString& aOrigin,
                    uint32_t aTelemetryId,
                    nsIFileURL** aResult)
 {
   MOZ_ASSERT(aDatabaseFile);
@@ -4540,17 +4586,17 @@ CreateStorageConnection(nsIFile* aDBFile
       }
 
       rv = stmt->Execute();
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     } else  {
       // This logic needs to change next time we change the schema!
-      static_assert(kSQLiteSchemaVersion == int32_t((22 << 4) + 0),
+      static_assert(kSQLiteSchemaVersion == int32_t((23 << 4) + 0),
                     "Upgrade function needed due to schema version increase.");
 
       while (schemaVersion != kSQLiteSchemaVersion) {
         if (schemaVersion == 4) {
           rv = UpgradeSchemaFrom4To5(connection);
         } else if (schemaVersion == 5) {
           rv = UpgradeSchemaFrom5To6(connection);
         } else if (schemaVersion == 6) {
@@ -4582,16 +4628,18 @@ CreateStorageConnection(nsIFile* aDBFile
         } else if (schemaVersion == MakeSchemaVersion(18, 0)) {
           rv = UpgradeSchemaFrom18_0To19_0(connection);
         } else if (schemaVersion == MakeSchemaVersion(19, 0)) {
           rv = UpgradeSchemaFrom19_0To20_0(aFMDirectory, connection);
         } else if (schemaVersion == MakeSchemaVersion(20, 0)) {
           rv = UpgradeSchemaFrom20_0To21_0(connection);
         } else if (schemaVersion == MakeSchemaVersion(21, 0)) {
           rv = UpgradeSchemaFrom21_0To22_0(connection);
+        } else if (schemaVersion == MakeSchemaVersion(22, 0)) {
+          rv = UpgradeSchemaFrom22_0To23_0(connection, aOrigin);
         } else {
           IDB_WARNING("Unable to open IndexedDB database, no upgrade path is "
                       "available!");
           return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
         }
 
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
@@ -20868,17 +20916,17 @@ OpenDatabaseOp::LoadDatabaseInformation(
 {
   AssertIsOnIOThread();
   MOZ_ASSERT(aConnection);
   MOZ_ASSERT(mMetadata);
 
   // Load version information.
   nsCOMPtr<mozIStorageStatement> stmt;
   nsresult rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
-    "SELECT name, version "
+    "SELECT name, origin, version "
     "FROM database"
   ), getter_AddRefs(stmt));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   bool hasResult;
   rv = stmt->ExecuteStep(&hasResult);
@@ -20895,18 +20943,28 @@ OpenDatabaseOp::LoadDatabaseInformation(
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (NS_WARN_IF(mCommonParams.metadata().name() != databaseName)) {
     return NS_ERROR_FILE_CORRUPTED;
   }
 
+  nsCString origin;
+  rv = stmt->GetUTF8String(1, origin);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  if (mOrigin != origin) {
+    NS_WARNING("Origins don't match!");
+  }
+
   int64_t version;
-  rv = stmt->GetInt64(1, &version);
+  rv = stmt->GetInt64(2, &version);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   mMetadata->mCommonMetadata.version() = uint64_t(version);
 
   ObjectStoreTable& objectStores = mMetadata->mObjectStores;
 
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..fec7aa8307525b00956f7e45104c18bc1a2ec858
GIT binary patch
literal 8309
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
DfN1m8
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/unit/test_schema23upgrade.js
@@ -0,0 +1,70 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var testGenerator = testSteps();
+
+function testSteps()
+{
+  const openParams = [
+    // This one lives in storage/default/http+++www.mozilla.org
+    { url: "http://www.mozilla.org", dbName: "dbB", dbVersion: 1 },
+
+    // This one lives in storage/default/1007+f+app+++system.gaiamobile.org
+    { appId: 1007, inIsolatedMozBrowser: false, url: "app://system.gaiamobile.org",
+      dbName: "dbM", dbVersion: 1 },
+
+    // This one lives in storage/default/1007+t+https+++developer.cdn.mozilla.net
+    { appId: 1007, inIsolatedMozBrowser: true, url: "https://developer.cdn.mozilla.net",
+      dbName: "dbN", dbVersion: 1 },
+  ];
+
+  let ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
+                         .getService(SpecialPowers.Ci.nsIIOService);
+
+  let ssm = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
+                         .getService(SpecialPowers.Ci.nsIScriptSecurityManager);
+
+  function openDatabase(params) {
+    let uri = ios.newURI(params.url, null, null);
+    let principal =
+      ssm.createCodebasePrincipal(uri,
+                                  {appId: params.appId || ssm.NO_APPID,
+                                   inIsolatedMozBrowser: params.inIsolatedMozBrowser});
+    let request = indexedDB.openForPrincipal(principal, params.dbName,
+                                             params.dbVersion);
+    return request;
+  }
+
+  clearAllDatabases(continueToNextStepSync);
+  yield undefined;
+
+  installPackagedProfile("schema23upgrade_profile");
+
+  for (let params of openParams) {
+    let request = openDatabase(params);
+    request.onerror = errorHandler;
+    request.onupgradeneeded = unexpectedSuccessHandler;
+    request.onsuccess = grabEventAndContinueHandler;
+    let event = yield undefined;
+
+    is(event.type, "success", "Correct event type");
+  }
+
+  resetAllDatabases(continueToNextStepSync);
+  yield undefined;
+
+  for (let params of openParams) {
+    let request = openDatabase(params);
+    request.onerror = errorHandler;
+    request.onupgradeneeded = unexpectedSuccessHandler;
+    request.onsuccess = grabEventAndContinueHandler;
+    let event = yield undefined;
+
+    is(event.type, "success", "Correct event type");
+  }
+
+  finishTest();
+  yield undefined;
+}
--- a/dom/indexedDB/test/unit/xpcshell-parent-process.ini
+++ b/dom/indexedDB/test/unit/xpcshell-parent-process.ini
@@ -16,16 +16,17 @@ support-files =
   GlobalObjectsChild.js
   GlobalObjectsComponent.js
   GlobalObjectsComponent.manifest
   GlobalObjectsModule.jsm
   GlobalObjectsSandbox.js
   metadataRestore_profile.zip
   schema18upgrade_profile.zip
   schema21upgrade_profile.zip
+  schema23upgrade_profile.zip
   storagePersistentUpgrade_profile.zip
   xpcshell-shared.ini
 
 [include:xpcshell-shared.ini]
 
 [test_blob_file_backed.js]
 [test_bug1056939.js]
 [test_cleanup_transaction.js]
@@ -39,12 +40,13 @@ skip-if = toolkit == 'android'
 skip-if = true
 [test_lowDiskSpace.js]
 [test_metadataRestore.js]
 [test_mutableFileUpgrade.js]
 [test_quotaExceeded_recovery.js]
 [test_readwriteflush_disabled.js]
 [test_schema18upgrade.js]
 [test_schema21upgrade.js]
+[test_schema23upgrade.js]
 [test_storagePersistentUpgrade.js]
 [test_temporary_storage.js]
 # bug 951017: intermittent failure on Android x86 emulator
 skip-if = os == "android" && processor == "x86"