mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 13:21:28 +00:00
Bug 1133763 - Part 3: Wipe out the cache directory when detecting a change in the DB schema; r=bkelly
This commit is contained in:
parent
58b1ce9c4b
commit
d5840b488d
43
dom/cache/DBAction.cpp
vendored
43
dom/cache/DBAction.cpp
vendored
@ -14,6 +14,8 @@
|
||||
#include "nsIFile.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "DBSchema.h"
|
||||
#include "FileUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -75,6 +77,8 @@ DBAction::OpenConnection(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
|
||||
MOZ_ASSERT(aDBDir);
|
||||
MOZ_ASSERT(aConnOut);
|
||||
|
||||
nsCOMPtr<mozIStorageConnection> conn;
|
||||
|
||||
bool exists;
|
||||
nsresult rv = aDBDir->Exists(&exists);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
@ -123,21 +127,48 @@ DBAction::OpenConnection(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
|
||||
do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID);
|
||||
if (NS_WARN_IF(!ss)) { return NS_ERROR_UNEXPECTED; }
|
||||
|
||||
rv = ss->OpenDatabaseWithFileURL(dbFileUrl, aConnOut);
|
||||
rv = ss->OpenDatabaseWithFileURL(dbFileUrl, getter_AddRefs(conn));
|
||||
if (rv == NS_ERROR_FILE_CORRUPTED) {
|
||||
NS_WARNING("Cache database corrupted. Recreating empty database.");
|
||||
|
||||
conn = nullptr;
|
||||
|
||||
// There is nothing else we can do to recover. Also, this data can
|
||||
// be deleted by QuotaManager at any time anyways.
|
||||
rv = dbFile->Remove(false);
|
||||
rv = WipeDatabase(dbFile, aDBDir);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
// TODO: clean up any orphaned body files (bug 1110446)
|
||||
|
||||
rv = ss->OpenDatabaseWithFileURL(dbFileUrl, aConnOut);
|
||||
rv = ss->OpenDatabaseWithFileURL(dbFileUrl, getter_AddRefs(conn));
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
MOZ_ASSERT(*aConnOut);
|
||||
|
||||
// Check the schema to make sure it is not too old.
|
||||
int32_t schemaVersion = 0;
|
||||
rv = conn->GetSchemaVersion(&schemaVersion);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
if (schemaVersion > 0 && schemaVersion < DBSchema::kMaxWipeSchemaVersion) {
|
||||
conn = nullptr;
|
||||
rv = WipeDatabase(dbFile, aDBDir);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = ss->OpenDatabaseWithFileURL(dbFileUrl, getter_AddRefs(conn));
|
||||
}
|
||||
|
||||
conn.forget(aConnOut);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
DBAction::WipeDatabase(nsIFile* aDBFile, nsIFile* aDBDir)
|
||||
{
|
||||
nsresult rv = aDBFile->Remove(false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
// Delete the morgue as well.
|
||||
rv = FileUtils::BodyDeleteDir(aDBDir);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
2
dom/cache/DBAction.h
vendored
2
dom/cache/DBAction.h
vendored
@ -49,6 +49,8 @@ private:
|
||||
nsresult OpenConnection(const QuotaInfo& aQuotaInfo, nsIFile* aQuotaDir,
|
||||
mozIStorageConnection** aConnOut);
|
||||
|
||||
nsresult WipeDatabase(nsIFile* aDBFile, nsIFile* aDBDir);
|
||||
|
||||
const Mode mMode;
|
||||
};
|
||||
|
||||
|
1
dom/cache/DBSchema.cpp
vendored
1
dom/cache/DBSchema.cpp
vendored
@ -20,6 +20,7 @@ namespace dom {
|
||||
namespace cache {
|
||||
|
||||
|
||||
const int32_t DBSchema::kMaxWipeSchemaVersion = 1;
|
||||
const int32_t DBSchema::kLatestSchemaVersion = 1;
|
||||
const int32_t DBSchema::kMaxEntriesPerStatement = 255;
|
||||
|
||||
|
3
dom/cache/DBSchema.h
vendored
3
dom/cache/DBSchema.h
vendored
@ -88,6 +88,9 @@ public:
|
||||
Namespace aNamespace,
|
||||
nsTArray<nsString>& aKeysOut);
|
||||
|
||||
// We will wipe out databases with a schema versions less than this.
|
||||
static const int32_t kMaxWipeSchemaVersion;
|
||||
|
||||
private:
|
||||
typedef int32_t EntryId;
|
||||
|
||||
|
23
dom/cache/FileUtils.cpp
vendored
23
dom/cache/FileUtils.cpp
vendored
@ -47,6 +47,29 @@ FileUtils::BodyCreateDir(nsIFile* aBaseDir)
|
||||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
FileUtils::BodyDeleteDir(nsIFile* aBaseDir)
|
||||
{
|
||||
MOZ_ASSERT(aBaseDir);
|
||||
|
||||
nsCOMPtr<nsIFile> aBodyDir;
|
||||
nsresult rv = aBaseDir->Clone(getter_AddRefs(aBodyDir));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = aBodyDir->Append(NS_LITERAL_STRING("morgue"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = aBodyDir->Remove(/* recursive = */ true);
|
||||
if (rv == NS_ERROR_FILE_NOT_FOUND ||
|
||||
rv == NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
|
||||
rv = NS_OK;
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
FileUtils::BodyGetCacheDir(nsIFile* aBaseDir, const nsID& aId,
|
||||
|
4
dom/cache/FileUtils.h
vendored
4
dom/cache/FileUtils.h
vendored
@ -30,6 +30,10 @@ public:
|
||||
};
|
||||
|
||||
static nsresult BodyCreateDir(nsIFile* aBaseDir);
|
||||
// Note that this function can only be used during the initialization of the
|
||||
// database. We're unlikely to be able to delete the DB successfully past
|
||||
// that point due to the file being in use.
|
||||
static nsresult BodyDeleteDir(nsIFile* aBaseDir);
|
||||
static nsresult BodyGetCacheDir(nsIFile* aBaseDir, const nsID& aId,
|
||||
nsIFile** aCacheDirOut);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user