summaryrefslogtreecommitdiffstats
path: root/webkit/appcache
diff options
context:
space:
mode:
Diffstat (limited to 'webkit/appcache')
-rw-r--r--webkit/appcache/appcache.cc78
-rw-r--r--webkit/appcache/appcache.h18
-rw-r--r--webkit/appcache/appcache_database.cc879
-rw-r--r--webkit/appcache/appcache_database.h159
-rw-r--r--webkit/appcache/appcache_database_unittest.cc439
-rw-r--r--webkit/appcache/appcache_group_unittest.cc5
-rw-r--r--webkit/appcache/appcache_host.cc2
-rw-r--r--webkit/appcache/appcache_host.h5
-rw-r--r--webkit/appcache/appcache_storage_impl.cc856
-rw-r--r--webkit/appcache/appcache_storage_impl.h92
-rw-r--r--webkit/appcache/appcache_storage_impl_unittest.cc1007
-rw-r--r--webkit/appcache/appcache_thread.h10
-rw-r--r--webkit/appcache/appcache_working_set.cc13
-rw-r--r--webkit/appcache/appcache_working_set.h15
-rw-r--r--webkit/appcache/mock_appcache_storage.cc12
15 files changed, 25 insertions, 3565 deletions
diff --git a/webkit/appcache/appcache.cc b/webkit/appcache/appcache.cc
index ec00cc4..38d3228 100644
--- a/webkit/appcache/appcache.cc
+++ b/webkit/appcache/appcache.cc
@@ -79,84 +79,6 @@ void AppCache::InitializeWithManifest(Manifest* manifest) {
SortByLength);
}
-void AppCache::InitializeWithDatabaseRecords(
- const AppCacheDatabase::CacheRecord& cache_record,
- const std::vector<AppCacheDatabase::EntryRecord>& entries,
- const std::vector<AppCacheDatabase::FallbackNameSpaceRecord>& fallbacks,
- const std::vector<AppCacheDatabase::OnlineWhiteListRecord>& whitelists) {
- DCHECK(cache_id_ == cache_record.cache_id);
- online_whitelist_all_ = cache_record.online_wildcard;
- update_time_ = cache_record.update_time;
-
- for (size_t i = 0; i < entries.size(); ++i) {
- const AppCacheDatabase::EntryRecord& entry = entries.at(i);
- AddEntry(entry.url, AppCacheEntry(entry.flags, entry.response_id));
- }
-
- for (size_t i = 0; i < fallbacks.size(); ++i) {
- const AppCacheDatabase::FallbackNameSpaceRecord& fallback = fallbacks.at(i);
- fallback_namespaces_.push_back(
- FallbackNamespace(fallback.namespace_url, fallback.fallback_entry_url));
- }
-
- // Sort the fallback namespaces by url string length, longest to shortest,
- // since longer matches trump when matching a url to a namespace.
- std::sort(fallback_namespaces_.begin(), fallback_namespaces_.end(),
- SortByLength);
-
- if (!online_whitelist_all_) {
- for (size_t i = 0; i < whitelists.size(); ++i) {
- online_whitelist_namespaces_.push_back(whitelists.at(i).namespace_url);
- }
- }
-}
-
-void AppCache::ToDatabaseRecords(
- const AppCacheGroup* group,
- AppCacheDatabase::CacheRecord* cache_record,
- std::vector<AppCacheDatabase::EntryRecord>* entries,
- std::vector<AppCacheDatabase::FallbackNameSpaceRecord>* fallbacks,
- std::vector<AppCacheDatabase::OnlineWhiteListRecord>* whitelists) {
- DCHECK(group && cache_record && entries && fallbacks && whitelists);
- DCHECK(entries->empty() && fallbacks->empty() && whitelists->empty());
-
- cache_record->cache_id = cache_id_;
- cache_record->group_id = group->group_id();
- cache_record->online_wildcard = online_whitelist_all_;
- cache_record->update_time = update_time_;
-
- for (EntryMap::const_iterator iter = entries_.begin();
- iter != entries_.end(); ++iter) {
- entries->push_back(AppCacheDatabase::EntryRecord());
- AppCacheDatabase::EntryRecord& record = entries->back();
- record.url = iter->first;
- record.cache_id = cache_id_;
- record.flags = iter->second.types();
- record.response_id = iter->second.response_id();
- }
-
- GURL origin = group->manifest_url().GetOrigin();
-
- for (size_t i = 0; i < fallback_namespaces_.size(); ++i) {
- fallbacks->push_back(AppCacheDatabase::FallbackNameSpaceRecord());
- AppCacheDatabase::FallbackNameSpaceRecord& record = fallbacks->back();
- record.cache_id = cache_id_;
- record.origin = origin;
- record.namespace_url = fallback_namespaces_[i].first;
- record.fallback_entry_url = fallback_namespaces_[i].second;
- }
-
- if (!online_whitelist_all_) {
- for (size_t i = 0; i < online_whitelist_namespaces_.size(); ++i) {
- whitelists->push_back(AppCacheDatabase::OnlineWhiteListRecord());
- AppCacheDatabase::OnlineWhiteListRecord& record = whitelists->back();
- record.cache_id = cache_id_;
- record.namespace_url = online_whitelist_namespaces_[i];
- }
- }
-}
-
-
bool AppCache::FindResponseForRequest(const GURL& url,
AppCacheEntry* found_entry, AppCacheEntry* found_fallback_entry,
GURL* found_fallback_namespace, bool* found_network_namespace) {
diff --git a/webkit/appcache/appcache.h b/webkit/appcache/appcache.h
index c4446f9..6e43a85 100644
--- a/webkit/appcache/appcache.h
+++ b/webkit/appcache/appcache.h
@@ -14,7 +14,6 @@
#include "base/time.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
-#include "webkit/appcache/appcache_database.h"
#include "webkit/appcache/appcache_entry.h"
#include "webkit/appcache/manifest_parser.h"
@@ -76,22 +75,6 @@ class AppCache : public base::RefCounted<AppCache> {
// Do not use the manifest after this call.
void InitializeWithManifest(Manifest* manifest);
- // Initializes the cache with the information in the database records.
- void InitializeWithDatabaseRecords(
- const AppCacheDatabase::CacheRecord& cache_record,
- const std::vector<AppCacheDatabase::EntryRecord>& entries,
- const std::vector<AppCacheDatabase::FallbackNameSpaceRecord>& fallbacks,
- const std::vector<AppCacheDatabase::OnlineWhiteListRecord>& whitelists);
-
- // Returns the database records to be stored in the AppCacheDatabase
- // to represent this cache.
- void ToDatabaseRecords(
- const AppCacheGroup* group,
- AppCacheDatabase::CacheRecord* cache_record,
- std::vector<AppCacheDatabase::EntryRecord>* entries,
- std::vector<AppCacheDatabase::FallbackNameSpaceRecord>* fallbacks,
- std::vector<AppCacheDatabase::OnlineWhiteListRecord>* whitelists);
-
bool FindResponseForRequest(const GURL& url,
AppCacheEntry* found_entry, AppCacheEntry* found_fallback_entry,
GURL* found_fallback_namespace, bool* found_network_namespace);
@@ -99,7 +82,6 @@ class AppCache : public base::RefCounted<AppCache> {
private:
friend class AppCacheGroup;
friend class AppCacheHost;
- friend class AppCacheStorageImplTest;
friend class AppCacheUpdateJobTest;
friend class base::RefCounted<AppCache>;
diff --git a/webkit/appcache/appcache_database.cc b/webkit/appcache/appcache_database.cc
deleted file mode 100644
index 256def1..0000000
--- a/webkit/appcache/appcache_database.cc
+++ /dev/null
@@ -1,879 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "webkit/appcache/appcache_database.h"
-
-#include "app/sql/connection.h"
-#include "app/sql/meta_table.h"
-#include "app/sql/statement.h"
-#include "app/sql/transaction.h"
-#include "base/auto_reset.h"
-#include "base/file_util.h"
-#include "base/logging.h"
-#include "webkit/appcache/appcache_entry.h"
-
-// Schema -------------------------------------------------------------------
-namespace {
-
-const int kCurrentVersion = 0;
-const int kCompatibleVersion = 0;
-
-const char* kGroupsTable = "Groups";
-const char* kCachesTable = "Caches";
-const char* kEntriesTable = "Entries";
-const char* kFallbackNameSpacesTable = "FallbackNameSpaces";
-const char* kOnlineWhiteListsTable = "OnlineWhiteLists";
-
-const struct {
- const char* table_name;
- const char* columns;
-} kTables[] = {
- { kGroupsTable,
- "(group_id INTEGER PRIMARY KEY,"
- " origin TEXT,"
- " manifest_url TEXT)" },
-
- { kCachesTable,
- "(cache_id INTEGER PRIMARY KEY,"
- " group_id INTEGER,"
- " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1)),"
- " update_time INTEGER)" },
-
- { kEntriesTable,
- "(cache_id INTEGER,"
- " url TEXT,"
- " flags INTEGER,"
- " response_id INTEGER)" },
-
- { kFallbackNameSpacesTable,
- "(cache_id INTEGER,"
- " origin TEXT," // intentionally not normalized
- " namespace_url TEXT,"
- " fallback_entry_url TEXT)" },
-
- { kOnlineWhiteListsTable,
- "(cache_id INTEGER,"
- " namespace_url TEXT)" },
-};
-
-const struct {
- const char* index_name;
- const char* table_name;
- const char* columns;
- bool unique;
-} kIndexes[] = {
- { "GroupsOriginIndex",
- kGroupsTable,
- "(origin)",
- false },
-
- { "GroupsManifestIndex",
- kGroupsTable,
- "(manifest_url)",
- true },
-
- { "CachesGroupIndex",
- kCachesTable,
- "(group_id)",
- false },
-
- { "EntriesCacheIndex",
- kEntriesTable,
- "(cache_id)",
- false },
-
- { "EntriesCacheAndUrlIndex",
- kEntriesTable,
- "(cache_id, url)",
- true },
-
- { "FallbackNameSpacesCacheIndex",
- kFallbackNameSpacesTable,
- "(cache_id)",
- false },
-
- { "FallbackNameSpacesOriginIndex",
- kFallbackNameSpacesTable,
- "(origin)",
- false },
-
- { "FallbackNameSpacesCacheAndUrlIndex",
- kFallbackNameSpacesTable,
- "(cache_id, namespace_url)",
- true },
-
- { "OnlineWhiteListCacheIndex",
- kOnlineWhiteListsTable,
- "(cache_id)",
- false },
-};
-
-const int kTableCount = ARRAYSIZE_UNSAFE(kTables);
-const int kIndexCount = ARRAYSIZE_UNSAFE(kIndexes);
-
-} // anon namespace
-
-
-// AppCacheDatabase ----------------------------------------------------------
-namespace appcache {
-
-AppCacheDatabase::AppCacheDatabase(const FilePath& path)
- : db_file_path_(path), has_open_error_(false), is_recreating_(false) {
-}
-
-AppCacheDatabase::~AppCacheDatabase() {
-}
-
-void AppCacheDatabase::CloseConnection() {
- // We can't close the connection for an in-memory database w/o
- // losing all of the data, so we don't do that.
- if (!db_file_path_.empty()) {
- meta_table_.reset();
- db_.reset();
- }
-}
-
-bool AppCacheDatabase::FindOriginsWithGroups(std::set<GURL>* origins) {
- DCHECK(origins && origins->empty());
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "SELECT DISTINCT(origin) FROM Groups";
-
- sql::Statement statement;
- if (!PrepareUniqueStatement(kSql, &statement))
- return false;
-
- while (statement.Step())
- origins->insert(GURL(statement.ColumnString(0)));
-
- return statement.Succeeded();
-}
-
-bool AppCacheDatabase::FindLastStorageIds(
- int64* last_group_id, int64* last_cache_id, int64* last_response_id) {
- DCHECK(last_group_id && last_cache_id && last_response_id);
-
- *last_group_id = 0;
- *last_cache_id = 0;
- *last_response_id = 0;
-
- if (!LazyOpen(false))
- return false;
-
- sql::Statement statement;
-
- const char* kSql1 = "SELECT MAX(group_id) FROM Groups";
- if (!PrepareUniqueStatement(kSql1, &statement) ||
- !statement.Step()) {
- return false;
- }
- int64 group_id = statement.ColumnInt64(0);
-
- const char* kSql2 = "SELECT MAX(cache_id) FROM Caches";
- if (!PrepareUniqueStatement(kSql2, &statement) ||
- !statement.Step()) {
- return false;
- }
- int64 cache_id = statement.ColumnInt64(0);
-
- // TODO(michaeln): SELECT MAX(responseId) FROM Where/How ?
- int64 response_id = 0;
-
- *last_group_id = group_id;
- *last_cache_id = cache_id;
- *last_response_id = response_id;
- return true;
-}
-
-bool AppCacheDatabase::FindGroup(int64 group_id, GroupRecord* record) {
- DCHECK(record);
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "SELECT group_id, origin, manifest_url FROM Groups WHERE group_id = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, group_id);
- if (!statement.Step() || !statement.Succeeded())
- return false;
-
- ReadGroupRecord(statement, record);
- DCHECK(record->group_id == group_id);
- return true;
-}
-
-bool AppCacheDatabase::FindGroupForManifestUrl(
- const GURL& manifest_url, GroupRecord* record) {
- DCHECK(record);
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "SELECT group_id, origin, manifest_url FROM Groups"
- " WHERE manifest_url = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindString(0, manifest_url.spec());
- if (!statement.Step() || !statement.Succeeded())
- return false;
-
- ReadGroupRecord(statement, record);
- DCHECK(record->manifest_url == manifest_url);
- return true;
-}
-
-bool AppCacheDatabase::FindGroupsForOrigin(
- const GURL& origin, std::vector<GroupRecord>* records) {
- DCHECK(records && records->empty());
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "SELECT group_id, origin, manifest_url FROM Groups WHERE origin = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindString(0, origin.spec());
- while (statement.Step()) {
- records->push_back(GroupRecord());
- ReadGroupRecord(statement, &records->back());
- DCHECK(records->back().origin == origin);
- }
-
- return statement.Succeeded();
-}
-
-bool AppCacheDatabase::FindGroupForCache(int64 cache_id, GroupRecord* record) {
- DCHECK(record);
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "SELECT g.group_id, g.origin, g.manifest_url FROM Groups g, Caches c"
- " WHERE c.cache_id = ? AND c.group_id = g.group_id";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, cache_id);
- if (!statement.Step() || !statement.Succeeded())
- return false;
-
- ReadGroupRecord(statement, record);
- return true;
-}
-
-bool AppCacheDatabase::InsertGroup(const GroupRecord* record) {
- if (!LazyOpen(true))
- return false;
-
- const char* kSql =
- "INSERT INTO Groups (group_id, origin, manifest_url)"
- " VALUES(?, ?, ?)";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, record->group_id);
- statement.BindString(1, record->origin.spec());
- statement.BindString(2, record->manifest_url.spec());
- return statement.Run();
-}
-
-bool AppCacheDatabase::DeleteGroup(int64 group_id) {
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "DELETE FROM Groups WHERE group_id = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, group_id);
- return statement.Run();
-}
-
-bool AppCacheDatabase::FindCache(int64 cache_id, CacheRecord* record) {
- DCHECK(record);
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "SELECT cache_id, group_id, online_wildcard, update_time"
- " FROM Caches WHERE cache_id = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, cache_id);
- if (!statement.Step() || !statement.Succeeded())
- return false;
-
- ReadCacheRecord(statement, record);
- return true;
-}
-
-bool AppCacheDatabase::FindCacheForGroup(int64 group_id, CacheRecord* record) {
- DCHECK(record);
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "SELECT cache_id, group_id, online_wildcard, update_time"
- " FROM Caches WHERE group_id = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, group_id);
- if (!statement.Step() || !statement.Succeeded())
- return false;
-
- ReadCacheRecord(statement, record);
- return true;
-}
-
-bool AppCacheDatabase::InsertCache(const CacheRecord* record) {
- if (!LazyOpen(true))
- return false;
-
- const char* kSql =
- "INSERT INTO Caches (cache_id, group_id, online_wildcard,"
- " update_time)"
- " VALUES(?, ?, ?, ?)";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, record->cache_id);
- statement.BindInt64(1, record->group_id);
- statement.BindBool(2, record->online_wildcard);
-
- // There are no convinient methods to convert TimeTicks to or
- // from microseconds directly, so we compute TimeDelta's
- // as an intermediary step.
- statement.BindInt64(3,
- (record->update_time - base::TimeTicks()).InMicroseconds());
-
- return statement.Run();
-}
-
-bool AppCacheDatabase::DeleteCache(int64 cache_id) {
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "DELETE FROM Caches WHERE cache_id = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, cache_id);
- return statement.Run();
-}
-
-bool AppCacheDatabase::FindEntriesForCache(
- int64 cache_id, std::vector<EntryRecord>* records) {
- DCHECK(records && records->empty());
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "SELECT cache_id, url, flags, response_id FROM Entries"
- " WHERE cache_id = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, cache_id);
- while (statement.Step()) {
- records->push_back(EntryRecord());
- ReadEntryRecord(statement, &records->back());
- DCHECK(records->back().cache_id == cache_id);
- }
-
- return statement.Succeeded();
-}
-
-bool AppCacheDatabase::FindEntriesForUrl(
- const GURL& url, std::vector<EntryRecord>* records) {
- DCHECK(records && records->empty());
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "SELECT cache_id, url, flags, response_id FROM Entries"
- " WHERE url = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindString(0, url.spec());
- while (statement.Step()) {
- records->push_back(EntryRecord());
- ReadEntryRecord(statement, &records->back());
- DCHECK(records->back().url == url);
- }
-
- return statement.Succeeded();
-}
-
-
-bool AppCacheDatabase::FindEntry(
- int64 cache_id, const GURL& url, EntryRecord* record) {
- DCHECK(record);
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "SELECT cache_id, url, flags, response_id FROM Entries"
- " WHERE cache_id = ? AND url = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, cache_id);
- statement.BindString(1, url.spec());
- if (!statement.Step() || !statement.Succeeded())
- return false;
-
- ReadEntryRecord(statement, record);
- DCHECK(record->cache_id == cache_id);
- DCHECK(record->url == url);
- return true;
-}
-
-bool AppCacheDatabase::InsertEntry(const EntryRecord* record) {
- if (!LazyOpen(true))
- return false;
-
- const char* kSql =
- "INSERT INTO Entries (cache_id, url, flags, response_id)"
- " VALUES(?, ?, ?, ?)";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, record->cache_id);
- statement.BindString(1, record->url.spec());
- statement.BindInt(2, record->flags);
- statement.BindInt64(3, record->response_id);
- return statement.Run();
-}
-
-bool AppCacheDatabase::InsertEntryRecords(
- const std::vector<EntryRecord>& records) {
- std::vector<EntryRecord>::const_iterator iter = records.begin();
- while (iter != records.end()) {
- if (!InsertEntry(&(*iter)))
- return false;
- ++iter;
- }
- return true;
-}
-
-bool AppCacheDatabase::DeleteEntriesForCache(int64 cache_id) {
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "DELETE FROM Entries WHERE cache_id = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, cache_id);
- return statement.Run();
-}
-
-bool AppCacheDatabase::AddEntryFlags(
- const GURL& entry_url, int64 cache_id, int additional_flags) {
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "UPDATE Entries SET flags = flags | ? WHERE cache_id = ? AND url = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt(0, additional_flags);
- statement.BindInt64(1, cache_id);
- statement.BindString(2, entry_url.spec());
- return statement.Run() && db_->GetLastChangeCount();
-}
-
-bool AppCacheDatabase::FindFallbackNameSpacesForOrigin(
- const GURL& origin, std::vector<FallbackNameSpaceRecord>* records) {
- DCHECK(records && records->empty());
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "SELECT cache_id, origin, namespace_url, fallback_entry_url"
- " FROM FallbackNameSpaces WHERE origin = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindString(0, origin.spec());
- while (statement.Step()) {
- records->push_back(FallbackNameSpaceRecord());
- ReadFallbackNameSpaceRecord(statement, &records->back());
- DCHECK(records->back().origin == origin);
- }
- return statement.Succeeded();
-}
-
-bool AppCacheDatabase::FindFallbackNameSpacesForCache(
- int64 cache_id, std::vector<FallbackNameSpaceRecord>* records) {
- DCHECK(records && records->empty());
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "SELECT cache_id, origin, namespace_url, fallback_entry_url"
- " FROM FallbackNameSpaces WHERE cache_id = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, cache_id);
- while (statement.Step()) {
- records->push_back(FallbackNameSpaceRecord());
- ReadFallbackNameSpaceRecord(statement, &records->back());
- DCHECK(records->back().cache_id == cache_id);
- }
- return statement.Succeeded();
-}
-
-bool AppCacheDatabase::InsertFallbackNameSpace(
- const FallbackNameSpaceRecord* record) {
- if (!LazyOpen(true))
- return false;
-
- const char* kSql =
- "INSERT INTO FallbackNameSpaces"
- " (cache_id, origin, namespace_url, fallback_entry_url)"
- " VALUES (?, ?, ?, ?)";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, record->cache_id);
- statement.BindString(1, record->origin.spec());
- statement.BindString(2, record->namespace_url.spec());
- statement.BindString(3, record->fallback_entry_url.spec());
- return statement.Run();
-}
-
-bool AppCacheDatabase::InsertFallbackNameSpaceRecords(
- const std::vector<FallbackNameSpaceRecord>& records) {
- std::vector<FallbackNameSpaceRecord>::const_iterator iter = records.begin();
- while (iter != records.end()) {
- if (!InsertFallbackNameSpace(&(*iter)))
- return false;
- ++iter;
- }
- return true;
-}
-
-bool AppCacheDatabase::DeleteFallbackNameSpacesForCache(int64 cache_id) {
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "DELETE FROM FallbackNameSpaces WHERE cache_id = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, cache_id);
- return statement.Run();
-}
-
-bool AppCacheDatabase::FindOnlineWhiteListForCache(
- int64 cache_id, std::vector<OnlineWhiteListRecord>* records) {
- DCHECK(records && records->empty());
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "SELECT cache_id, namespace_url FROM OnlineWhiteLists"
- " WHERE cache_id = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, cache_id);
- while (statement.Step()) {
- records->push_back(OnlineWhiteListRecord());
- this->ReadOnlineWhiteListRecord(statement, &records->back());
- DCHECK(records->back().cache_id == cache_id);
- }
- return statement.Succeeded();
-}
-
-bool AppCacheDatabase::InsertOnlineWhiteList(
- const OnlineWhiteListRecord* record) {
- if (!LazyOpen(true))
- return false;
-
- const char* kSql =
- "INSERT INTO OnlineWhiteLists (cache_id, namespace_url) VALUES (?, ?)";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, record->cache_id);
- statement.BindString(1, record->namespace_url.spec());
- return statement.Run();
-}
-
-bool AppCacheDatabase::InsertOnlineWhiteListRecords(
- const std::vector<OnlineWhiteListRecord>& records) {
- std::vector<OnlineWhiteListRecord>::const_iterator iter = records.begin();
- while (iter != records.end()) {
- if (!InsertOnlineWhiteList(&(*iter)))
- return false;
- ++iter;
- }
- return true;
-}
-
-bool AppCacheDatabase::DeleteOnlineWhiteListForCache(int64 cache_id) {
- if (!LazyOpen(false))
- return false;
-
- const char* kSql =
- "DELETE FROM OnlineWhiteLists WHERE cache_id = ?";
-
- sql::Statement statement;
- if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement))
- return false;
-
- statement.BindInt64(0, cache_id);
- return statement.Run();
-}
-
-bool AppCacheDatabase::PrepareUniqueStatement(
- const char* sql, sql::Statement* statement) {
- DCHECK(sql && statement);
- statement->Assign(db_->GetUniqueStatement(sql));
- if (!statement->is_valid()) {
- NOTREACHED() << db_->GetErrorMessage();
- return false;
- }
- return true;
-}
-
-bool AppCacheDatabase::PrepareCachedStatement(
- const sql::StatementID& id, const char* sql, sql::Statement* statement) {
- DCHECK(sql && statement);
- statement->Assign(db_->GetCachedStatement(id, sql));
- if (!statement->is_valid()) {
- NOTREACHED() << db_->GetErrorMessage();
- return false;
- }
- return true;
-}
-
-void AppCacheDatabase::ReadGroupRecord(
- const sql::Statement& statement, GroupRecord* record) {
- record->group_id = statement.ColumnInt64(0);
- record->origin = GURL(statement.ColumnString(1));
- record->manifest_url = GURL(statement.ColumnString(2));
-}
-
-void AppCacheDatabase::ReadCacheRecord(
- const sql::Statement& statement, CacheRecord* record) {
- record->cache_id = statement.ColumnInt64(0);
- record->group_id = statement.ColumnInt64(1);
- record->online_wildcard = statement.ColumnBool(2);
-
- // There are no convinient methods to convert TimeTicks to or
- // from microseconds directly, so we compute TimeDelta's
- // as an intermediary step.
- record->update_time = base::TimeTicks() +
- base::TimeDelta::FromMicroseconds(statement.ColumnInt64(3));
-}
-
-void AppCacheDatabase::ReadEntryRecord(
- const sql::Statement& statement, EntryRecord* record) {
- record->cache_id = statement.ColumnInt64(0);
- record->url = GURL(statement.ColumnString(1));
- record->flags = statement.ColumnInt(2);
- record->response_id = statement.ColumnInt64(3);
-}
-
-void AppCacheDatabase::ReadFallbackNameSpaceRecord(
- const sql::Statement& statement, FallbackNameSpaceRecord* record) {
- record->cache_id = statement.ColumnInt64(0);
- record->origin = GURL(statement.ColumnString(1));
- record->namespace_url = GURL(statement.ColumnString(2));
- record->fallback_entry_url = GURL(statement.ColumnString(3));
-}
-
-void AppCacheDatabase::ReadOnlineWhiteListRecord(
- const sql::Statement& statement, OnlineWhiteListRecord* record) {
- record->cache_id = statement.ColumnInt64(0);
- record->namespace_url = GURL(statement.ColumnString(1));
-}
-
-bool AppCacheDatabase::LazyOpen(bool create_if_needed) {
- if (db_.get())
- return true;
-
- // If we tried and failed once, don't try again in the same session
- // to avoid creating an incoherent mess on disk.
- if (has_open_error_)
- return false;
-
- // Avoid creating a database at all if we can.
- bool use_in_memory_db = db_file_path_.empty();
- if (!create_if_needed &&
- (use_in_memory_db || !file_util::PathExists(db_file_path_))) {
- return false;
- }
-
- db_.reset(new sql::Connection);
- bool opened = use_in_memory_db ? db_->OpenInMemory()
- : db_->Open(db_file_path_);
- if (opened)
- db_->Preload();
- if (!opened || !EnsureDatabaseVersion()) {
- has_open_error_ = true;
- meta_table_.reset();
- db_.reset();
- return false;
- }
-
- return true;
-}
-
-bool AppCacheDatabase::EnsureDatabaseVersion() {
- bool did_create_meta_table = !sql::MetaTable::DoesTableExist(db_.get());
-
- meta_table_.reset(new sql::MetaTable);
- if (!meta_table_->Init(db_.get(), kCurrentVersion, kCompatibleVersion))
- return false;
-
- if (did_create_meta_table)
- return CreateSchema();
-
- if (meta_table_->GetCompatibleVersionNumber() > kCurrentVersion) {
- DCHECK(!did_create_meta_table);
- LOG(WARNING) << "AppCache database is too new.";
- return false;
- }
-
- if (meta_table_->GetVersionNumber() < kCurrentVersion)
- return UpgradeSchema();
-
-#ifndef NDEBUG
- for (int i = 0; i < kTableCount; ++i) {
- DCHECK(db_->DoesTableExist(kTables[i].table_name));
- }
-#endif
-
- return true;
-}
-
-bool AppCacheDatabase::CreateSchema() {
- sql::Transaction transaction(db_.get());
- if (!transaction.Begin())
- return false;
-
- for (int i = 0; i < kTableCount; ++i) {
- std::string sql("CREATE TABLE ");
- sql += kTables[i].table_name;
- sql += kTables[i].columns;
- if (!db_->Execute(sql.c_str()))
- return false;
- }
-
- for (int i = 0; i < kIndexCount; ++i) {
- std::string sql;
- if (kIndexes[i].unique)
- sql += "CREATE UNIQUE INDEX ";
- else
- sql += "CREATE INDEX ";
- sql += kIndexes[i].index_name;
- sql += " ON ";
- sql += kIndexes[i].table_name;
- sql += kIndexes[i].columns;
- if (!db_->Execute(sql.c_str()))
- return false;
- }
-
- return transaction.Commit();
-}
-
-bool AppCacheDatabase::UpgradeSchema() {
- DCHECK(false); // We don't have any upgrades yet since we're at version 0
-
- // Upgrade logic goes here
-
- // If there is no upgrade path for the version on disk to the current
- // version, nuke everything and start over.
- return DeleteExistingAndCreateNewDatabase();
-}
-
-bool AppCacheDatabase::DeleteExistingAndCreateNewDatabase() {
- DCHECK(!db_file_path_.empty());
- DCHECK(file_util::PathExists(db_file_path_));
-
- meta_table_.reset();
- db_.reset();
-
- FilePath directory = db_file_path_.DirName();
- if (!file_util::Delete(directory, true) ||
- !file_util::CreateDirectory(directory)) {
- return false;
- }
-
- // Make sure the steps above actually deleted things.
- if (file_util::PathExists(db_file_path_))
- return false;
-
- // So we can't go recursive.
- if (is_recreating_)
- return false;
-
- AutoReset auto_reset(&is_recreating_, true);
- return LazyOpen(true);
-}
-
-} // namespace appcache
diff --git a/webkit/appcache/appcache_database.h b/webkit/appcache/appcache_database.h
deleted file mode 100644
index 89ff701..0000000
--- a/webkit/appcache/appcache_database.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef WEBKIT_APPCACHE_APPCACHE_DATABASE_H_
-#define WEBKIT_APPCACHE_APPCACHE_DATABASE_H_
-
-#include <set>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/file_path.h"
-#include "base/scoped_ptr.h"
-#include "base/time.h"
-#include "googleurl/src/gurl.h"
-#include "testing/gtest/include/gtest/gtest_prod.h"
-
-namespace sql {
-class Connection;
-class MetaTable;
-class Statement;
-class StatementID;
-}
-
-namespace appcache {
-
-class AppCacheDatabase {
- public:
- struct GroupRecord {
- int64 group_id;
- GURL origin;
- GURL manifest_url;
- };
-
- struct CacheRecord {
- int64 cache_id;
- int64 group_id;
- bool online_wildcard;
- base::TimeTicks update_time;
- };
-
- struct EntryRecord {
- int64 cache_id;
- GURL url;
- int flags;
- int64 response_id;
- };
-
- struct FallbackNameSpaceRecord {
- int64 cache_id;
- GURL origin; // intentionally not normalized
- GURL namespace_url;
- GURL fallback_entry_url;
- };
-
- struct OnlineWhiteListRecord {
- int64 cache_id;
- GURL namespace_url;
- };
-
- explicit AppCacheDatabase(const FilePath& path);
- ~AppCacheDatabase();
-
- void CloseConnection();
- bool FindOriginsWithGroups(std::set<GURL>* origins);
- bool FindLastStorageIds(
- int64* last_group_id, int64* last_cache_id, int64* last_response_id);
-
- bool FindGroup(int64 group_id, GroupRecord* record);
- bool FindGroupForManifestUrl(const GURL& manifest_url, GroupRecord* record);
- bool FindGroupsForOrigin(
- const GURL& origin, std::vector<GroupRecord>* records);
- bool FindGroupForCache(int64 cache_id, GroupRecord* record);
- bool InsertGroup(const GroupRecord* record);
- bool DeleteGroup(int64 group_id);
-
- bool FindCache(int64 cache_id, CacheRecord* record);
- bool FindCacheForGroup(int64 group_id, CacheRecord* record);
- bool InsertCache(const CacheRecord* record);
- bool DeleteCache(int64 cache_id);
-
- bool FindEntriesForCache(
- int64 cache_id, std::vector<EntryRecord>* records);
- bool FindEntriesForUrl(
- const GURL& url, std::vector<EntryRecord>* records);
- bool FindEntry(int64 cache_id, const GURL& url, EntryRecord* record);
- bool InsertEntry(const EntryRecord* record);
- bool InsertEntryRecords(
- const std::vector<EntryRecord>& records);
- bool DeleteEntriesForCache(int64 cache_id);
- bool AddEntryFlags(const GURL& entry_url, int64 cache_id,
- int additional_flags);
-
- bool FindFallbackNameSpacesForOrigin(
- const GURL& origin, std::vector<FallbackNameSpaceRecord>* records);
- bool FindFallbackNameSpacesForCache(
- int64 cache_id, std::vector<FallbackNameSpaceRecord>* records);
- bool InsertFallbackNameSpace(const FallbackNameSpaceRecord* record);
- bool InsertFallbackNameSpaceRecords(
- const std::vector<FallbackNameSpaceRecord>& records);
- bool DeleteFallbackNameSpacesForCache(int64 cache_id);
-
- bool FindOnlineWhiteListForCache(
- int64 cache_id, std::vector<OnlineWhiteListRecord>* records);
- bool InsertOnlineWhiteList(const OnlineWhiteListRecord* record);
- bool InsertOnlineWhiteListRecords(
- const std::vector<OnlineWhiteListRecord>& records);
- bool DeleteOnlineWhiteListForCache(int64 cache_id);
-
- // So our callers can wrap operations in transactions.
- sql::Connection* db_connection() {
- LazyOpen(true);
- return db_.get();
- }
-
- private:
- bool PrepareUniqueStatement(const char* sql, sql::Statement* statement);
- bool PrepareCachedStatement(
- const sql::StatementID& id, const char* sql, sql::Statement* statement);
-
- // Record retrieval helpers
- void ReadGroupRecord(const sql::Statement& statement, GroupRecord* record);
- void ReadCacheRecord(const sql::Statement& statement, CacheRecord* record);
- void ReadEntryRecord(const sql::Statement& statement, EntryRecord* record);
- void ReadFallbackNameSpaceRecord(
- const sql::Statement& statement, FallbackNameSpaceRecord* record);
- void ReadOnlineWhiteListRecord(
- const sql::Statement& statement, OnlineWhiteListRecord* record);
-
- // Database creation
- bool LazyOpen(bool create_if_needed);
- bool EnsureDatabaseVersion();
- bool CreateSchema();
- bool UpgradeSchema();
-
- // Deletes the existing database file and the entire directory containing
- // the database file including the disk cache in which response headers
- // and bodies are stored, and then creates a new database file.
- bool DeleteExistingAndCreateNewDatabase();
-
- FilePath db_file_path_;
- scoped_ptr<sql::Connection> db_;
- scoped_ptr<sql::MetaTable> meta_table_;
- bool has_open_error_;
- bool is_recreating_;
-
- FRIEND_TEST(AppCacheDatabaseTest, CacheRecords);
- FRIEND_TEST(AppCacheDatabaseTest, EntryRecords);
- FRIEND_TEST(AppCacheDatabaseTest, FallbackNameSpaceRecords);
- FRIEND_TEST(AppCacheDatabaseTest, GroupRecords);
- FRIEND_TEST(AppCacheDatabaseTest, LazyOpen);
- FRIEND_TEST(AppCacheDatabaseTest, OnlineWhiteListRecords);
- FRIEND_TEST(AppCacheDatabaseTest, ReCreate);
- DISALLOW_COPY_AND_ASSIGN(AppCacheDatabase);
-};
-
-} // namespace appcache
-
-#endif // WEBKIT_APPCACHE_APPCACHE_DATABASE_H_
diff --git a/webkit/appcache/appcache_database_unittest.cc b/webkit/appcache/appcache_database_unittest.cc
deleted file mode 100644
index 62ff4ca..0000000
--- a/webkit/appcache/appcache_database_unittest.cc
+++ /dev/null
@@ -1,439 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-#include "app/sql/connection.h"
-#include "base/file_util.h"
-#include "base/scoped_temp_dir.h"
-#include "webkit/appcache/appcache_database.h"
-#include "webkit/appcache/appcache_entry.h"
-
-namespace {
-
-const base::TimeTicks kZeroTimeTicks;
-
-class TestErrorDelegate : public sql::ErrorDelegate {
- public:
- virtual ~TestErrorDelegate() { }
- virtual int OnError(
- int error, sql::Connection* connection, sql::Statement* stmt) {
- return error;
- }
-};
-
-} // namespace
-
-namespace appcache {
-
-class AppCacheDatabaseTest {};
-
-TEST(AppCacheDatabaseTest, LazyOpen) {
- // Use an empty file path to use an in-memory sqlite database.
- const FilePath kEmptyPath;
- AppCacheDatabase db(kEmptyPath);
-
- EXPECT_FALSE(db.LazyOpen(false));
- EXPECT_TRUE(db.LazyOpen(true));
-
- int64 group_id, cache_id, response_id;
- group_id = cache_id = response_id = 0;
- EXPECT_TRUE(db.FindLastStorageIds(&group_id, &cache_id, &response_id));
- EXPECT_EQ(0, group_id);
- EXPECT_EQ(0, cache_id);
- EXPECT_EQ(0, response_id);
-
- std::set<GURL> origins;
- EXPECT_TRUE(db.FindOriginsWithGroups(&origins));
- EXPECT_TRUE(origins.empty());
-}
-
-TEST(AppCacheDatabaseTest, ReCreate) {
- // Real files on disk for this test.
- ScopedTempDir temp_dir;
- EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
- const FilePath kDbFile = temp_dir.path().AppendASCII("appcache.db");
- const FilePath kNestedDir = temp_dir.path().AppendASCII("nested");
- const FilePath kOtherFile = kNestedDir.AppendASCII("other_file");
- EXPECT_TRUE(file_util::CreateDirectory(kNestedDir));
- EXPECT_EQ(3, file_util::WriteFile(kOtherFile, "foo", 3));
-
- AppCacheDatabase db(kDbFile);
- EXPECT_FALSE(db.LazyOpen(false));
- EXPECT_TRUE(db.LazyOpen(true));
-
- EXPECT_TRUE(file_util::PathExists(kDbFile));
- EXPECT_TRUE(file_util::DirectoryExists(kNestedDir));
- EXPECT_TRUE(file_util::PathExists(kOtherFile));
-
- EXPECT_TRUE(db.DeleteExistingAndCreateNewDatabase());
-
- EXPECT_TRUE(file_util::PathExists(kDbFile));
- EXPECT_FALSE(file_util::DirectoryExists(kNestedDir));
- EXPECT_FALSE(file_util::PathExists(kOtherFile));
-}
-
-TEST(AppCacheDatabaseTest, EntryRecords) {
- const FilePath kEmptyPath;
- AppCacheDatabase db(kEmptyPath);
- EXPECT_TRUE(db.LazyOpen(true));
-
- // Set an error delegate that will make all operations return false on error.
- scoped_refptr<TestErrorDelegate> error_delegate(new TestErrorDelegate);
- db.db_->set_error_delegate(error_delegate);
-
- AppCacheDatabase::EntryRecord entry;
-
- entry.cache_id = 1;
- entry.url = GURL("http://blah/1");
- entry.flags = AppCacheEntry::MASTER;
- entry.response_id = 1;
- EXPECT_TRUE(db.InsertEntry(&entry));
- EXPECT_FALSE(db.InsertEntry(&entry));
-
- entry.cache_id = 2;
- entry.url = GURL("http://blah/2");
- entry.flags = AppCacheEntry::EXPLICIT;
- entry.response_id = 2;
- EXPECT_TRUE(db.InsertEntry(&entry));
-
- entry.cache_id = 2;
- entry.url = GURL("http://blah/3");
- entry.flags = AppCacheEntry::MANIFEST;
- entry.response_id = 3;
- EXPECT_TRUE(db.InsertEntry(&entry));
-
- std::vector<AppCacheDatabase::EntryRecord> found;
-
- EXPECT_TRUE(db.FindEntriesForCache(1, &found));
- EXPECT_EQ(1U, found.size());
- EXPECT_EQ(1, found[0].cache_id);
- EXPECT_EQ(GURL("http://blah/1"), found[0].url);
- EXPECT_EQ(AppCacheEntry::MASTER, found[0].flags);
- EXPECT_EQ(1, found[0].response_id);
- found.clear();
-
- EXPECT_TRUE(db.AddEntryFlags(GURL("http://blah/1"), 1,
- AppCacheEntry::FOREIGN));
- EXPECT_TRUE(db.FindEntriesForCache(1, &found));
- EXPECT_EQ(1U, found.size());
- EXPECT_EQ(AppCacheEntry::MASTER | AppCacheEntry::FOREIGN, found[0].flags);
- found.clear();
-
- EXPECT_TRUE(db.FindEntriesForCache(2, &found));
- EXPECT_EQ(2U, found.size());
- EXPECT_EQ(2, found[0].cache_id);
- EXPECT_EQ(GURL("http://blah/2"), found[0].url);
- EXPECT_EQ(AppCacheEntry::EXPLICIT, found[0].flags);
- EXPECT_EQ(2, found[0].response_id);
- EXPECT_EQ(2, found[1].cache_id);
- EXPECT_EQ(GURL("http://blah/3"), found[1].url);
- EXPECT_EQ(AppCacheEntry::MANIFEST, found[1].flags);
- EXPECT_EQ(3, found[1].response_id);
- found.clear();
-
- EXPECT_TRUE(db.DeleteEntriesForCache(2));
- EXPECT_TRUE(db.FindEntriesForCache(2, &found));
- EXPECT_TRUE(found.empty());
- found.clear();
-
- EXPECT_TRUE(db.DeleteEntriesForCache(1));
- EXPECT_FALSE(db.AddEntryFlags(GURL("http://blah/1"), 1,
- AppCacheEntry::FOREIGN));
-}
-
-TEST(AppCacheDatabaseTest, CacheRecords) {
- const FilePath kEmptyPath;
- AppCacheDatabase db(kEmptyPath);
- EXPECT_TRUE(db.LazyOpen(true));
-
- scoped_refptr<TestErrorDelegate> error_delegate(new TestErrorDelegate);
- db.db_->set_error_delegate(error_delegate);
-
- const AppCacheDatabase::CacheRecord kZeroRecord = {0};
- AppCacheDatabase::CacheRecord record = kZeroRecord;
- EXPECT_FALSE(db.FindCache(1, &record));
-
- record.cache_id = 1;
- record.group_id = 1;
- record.online_wildcard = true;
- record.update_time = kZeroTimeTicks;
- EXPECT_TRUE(db.InsertCache(&record));
- EXPECT_FALSE(db.InsertCache(&record));
-
- record = kZeroRecord;
- EXPECT_TRUE(db.FindCache(1, &record));
- EXPECT_EQ(1, record.cache_id);
- EXPECT_EQ(1, record.group_id);
- EXPECT_TRUE(record.online_wildcard);
- EXPECT_TRUE(kZeroTimeTicks == record.update_time);
-
- record = kZeroRecord;
- EXPECT_TRUE(db.FindCacheForGroup(1, &record));
- EXPECT_EQ(1, record.cache_id);
- EXPECT_EQ(1, record.group_id);
- EXPECT_TRUE(record.online_wildcard);
- EXPECT_TRUE(kZeroTimeTicks == record.update_time);
-
- EXPECT_TRUE(db.DeleteCache(1));
- EXPECT_FALSE(db.FindCache(1, &record));
- EXPECT_FALSE(db.FindCacheForGroup(1, &record));
-
- EXPECT_TRUE(db.DeleteCache(1));
-}
-
-TEST(AppCacheDatabaseTest, GroupRecords) {
- const FilePath kEmptyPath;
- AppCacheDatabase db(kEmptyPath);
- EXPECT_TRUE(db.LazyOpen(true));
-
- scoped_refptr<TestErrorDelegate> error_delegate(new TestErrorDelegate);
- db.db_->set_error_delegate(error_delegate);
-
- const GURL kManifestUrl("http://blah/manifest");
- const GURL kOrigin(kManifestUrl.GetOrigin());
-
- const AppCacheDatabase::GroupRecord kZeroRecord = {0, GURL(), GURL()};
- AppCacheDatabase::GroupRecord record = kZeroRecord;
- std::vector<AppCacheDatabase::GroupRecord> records;
-
- // Behavior with an empty table
- EXPECT_FALSE(db.FindGroup(1, &record));
- EXPECT_FALSE(db.FindGroupForManifestUrl(kManifestUrl, &record));
- EXPECT_TRUE(db.DeleteGroup(1));
- EXPECT_TRUE(db.FindGroupsForOrigin(kOrigin, &records));
- EXPECT_TRUE(records.empty());
- EXPECT_FALSE(db.FindGroupForCache(1, &record));
-
- record.group_id = 1;
- record.manifest_url = kManifestUrl;
- record.origin = kOrigin;
- EXPECT_TRUE(db.InsertGroup(&record));
- EXPECT_FALSE(db.InsertGroup(&record));
-
- record.group_id = 2;
- EXPECT_FALSE(db.InsertGroup(&record));
-
- record = kZeroRecord;
- EXPECT_TRUE(db.FindGroup(1, &record));
- EXPECT_EQ(1, record.group_id);
- EXPECT_EQ(kManifestUrl, record.manifest_url);
- EXPECT_EQ(kOrigin, record.origin);
-
- record = kZeroRecord;
- EXPECT_TRUE(db.FindGroupForManifestUrl(kManifestUrl, &record));
- EXPECT_EQ(1, record.group_id);
- EXPECT_EQ(kManifestUrl, record.manifest_url);
- EXPECT_EQ(kOrigin, record.origin);
-
- record.group_id = 2;
- record.manifest_url = kOrigin;
- record.origin = kOrigin;
- EXPECT_TRUE(db.InsertGroup(&record));
-
- record = kZeroRecord;
- EXPECT_TRUE(db.FindGroupForManifestUrl(kOrigin, &record));
- EXPECT_EQ(2, record.group_id);
- EXPECT_EQ(kOrigin, record.manifest_url);
- EXPECT_EQ(kOrigin, record.origin);
-
- EXPECT_TRUE(db.FindGroupsForOrigin(kOrigin, &records));
- EXPECT_EQ(2U, records.size());
- EXPECT_EQ(1, records[0].group_id);
- EXPECT_EQ(kManifestUrl, records[0].manifest_url);
- EXPECT_EQ(kOrigin, records[0].origin);
- EXPECT_EQ(2, records[1].group_id);
- EXPECT_EQ(kOrigin, records[1].manifest_url);
- EXPECT_EQ(kOrigin, records[1].origin);
-
- EXPECT_TRUE(db.DeleteGroup(1));
-
- records.clear();
- EXPECT_TRUE(db.FindGroupsForOrigin(kOrigin, &records));
- EXPECT_EQ(1U, records.size());
- EXPECT_EQ(2, records[0].group_id);
- EXPECT_EQ(kOrigin, records[0].manifest_url);
- EXPECT_EQ(kOrigin, records[0].origin);
-
- std::set<GURL> origins;
- EXPECT_TRUE(db.FindOriginsWithGroups(&origins));
- EXPECT_EQ(1U, origins.size());
- EXPECT_EQ(kOrigin, *(origins.begin()));
-
- const GURL kManifest2("http://blah2/manifest");
- const GURL kOrigin2(kManifest2.GetOrigin());
- record.group_id = 1;
- record.manifest_url = kManifest2;
- record.origin = kOrigin2;
- EXPECT_TRUE(db.InsertGroup(&record));
-
- origins.clear();
- EXPECT_TRUE(db.FindOriginsWithGroups(&origins));
- EXPECT_EQ(2U, origins.size());
- EXPECT_TRUE(origins.end() != origins.find(kOrigin));
- EXPECT_TRUE(origins.end() != origins.find(kOrigin2));
-
- AppCacheDatabase::CacheRecord cache_record;
- cache_record.cache_id = 1;
- cache_record.group_id = 1;
- cache_record.online_wildcard = true;
- cache_record.update_time = kZeroTimeTicks;
- EXPECT_TRUE(db.InsertCache(&cache_record));
-
- record = kZeroRecord;
- EXPECT_TRUE(db.FindGroupForCache(1, &record));
- EXPECT_EQ(1, record.group_id);
- EXPECT_EQ(kManifest2, record.manifest_url);
- EXPECT_EQ(kOrigin2, record.origin);
-}
-
-TEST(AppCacheDatabaseTest, FallbackNameSpaceRecords) {
- const FilePath kEmptyPath;
- AppCacheDatabase db(kEmptyPath);
- EXPECT_TRUE(db.LazyOpen(true));
-
- scoped_refptr<TestErrorDelegate> error_delegate(new TestErrorDelegate);
- db.db_->set_error_delegate(error_delegate);
-
- const GURL kFooNameSpace1("http://foo/namespace1");
- const GURL kFooNameSpace2("http://foo/namespace2");
- const GURL kFooFallbackEntry("http://foo/entry");
- const GURL kFooOrigin(kFooNameSpace1.GetOrigin());
- const GURL kBarNameSpace1("http://bar/namespace1");
- const GURL kBarNameSpace2("http://bar/namespace2");
- const GURL kBarFallbackEntry("http://bar/entry");
- const GURL kBarOrigin(kBarNameSpace1.GetOrigin());
-
- const AppCacheDatabase::FallbackNameSpaceRecord kZeroRecord =
- { 0, GURL(), GURL(), GURL() };
- AppCacheDatabase::FallbackNameSpaceRecord record = kZeroRecord;
- std::vector<AppCacheDatabase::FallbackNameSpaceRecord> records;
-
- // Behavior with an empty table
- EXPECT_TRUE(db.FindFallbackNameSpacesForCache(1, &records));
- EXPECT_TRUE(records.empty());
- EXPECT_TRUE(db.FindFallbackNameSpacesForOrigin(kFooOrigin, &records));
- EXPECT_TRUE(records.empty());
- EXPECT_TRUE(db.DeleteFallbackNameSpacesForCache(1));
-
- // Two records for two differenent caches in the Foo origin.
- record.cache_id = 1;
- record.origin = kFooOrigin;
- record.namespace_url = kFooNameSpace1;
- record.fallback_entry_url = kFooFallbackEntry;
- EXPECT_TRUE(db.InsertFallbackNameSpace(&record));
- EXPECT_FALSE(db.InsertFallbackNameSpace(&record));
-
- record.cache_id = 2;
- record.origin = kFooOrigin;
- record.namespace_url = kFooNameSpace2;
- record.fallback_entry_url = kFooFallbackEntry;
- EXPECT_TRUE(db.InsertFallbackNameSpace(&record));
-
- records.clear();
- EXPECT_TRUE(db.FindFallbackNameSpacesForCache(1, &records));
- EXPECT_EQ(1U, records.size());
- EXPECT_EQ(1, records[0].cache_id);
- EXPECT_EQ(kFooOrigin, records[0].origin);
- EXPECT_EQ(kFooNameSpace1, records[0].namespace_url);
- EXPECT_EQ(kFooFallbackEntry, records[0].fallback_entry_url);
-
- records.clear();
- EXPECT_TRUE(db.FindFallbackNameSpacesForCache(2, &records));
- EXPECT_EQ(1U, records.size());
- EXPECT_EQ(2, records[0].cache_id);
- EXPECT_EQ(kFooOrigin, records[0].origin);
- EXPECT_EQ(kFooNameSpace2, records[0].namespace_url);
- EXPECT_EQ(kFooFallbackEntry, records[0].fallback_entry_url);
-
- records.clear();
- EXPECT_TRUE(db.FindFallbackNameSpacesForOrigin(kFooOrigin, &records));
- EXPECT_EQ(2U, records.size());
- EXPECT_EQ(1, records[0].cache_id);
- EXPECT_EQ(kFooOrigin, records[0].origin);
- EXPECT_EQ(kFooNameSpace1, records[0].namespace_url);
- EXPECT_EQ(kFooFallbackEntry, records[0].fallback_entry_url);
- EXPECT_EQ(2, records[1].cache_id);
- EXPECT_EQ(kFooOrigin, records[1].origin);
- EXPECT_EQ(kFooNameSpace2, records[1].namespace_url);
- EXPECT_EQ(kFooFallbackEntry, records[1].fallback_entry_url);
-
- EXPECT_TRUE(db.DeleteFallbackNameSpacesForCache(1));
- records.clear();
- EXPECT_TRUE(db.FindFallbackNameSpacesForOrigin(kFooOrigin, &records));
- EXPECT_EQ(1U, records.size());
- EXPECT_EQ(2, records[0].cache_id);
- EXPECT_EQ(kFooOrigin, records[0].origin);
- EXPECT_EQ(kFooNameSpace2, records[0].namespace_url);
- EXPECT_EQ(kFooFallbackEntry, records[0].fallback_entry_url);
-
- // Two more records for the same cache in the Bar origin.
- record.cache_id = 3;
- record.origin = kBarOrigin;
- record.namespace_url = kBarNameSpace1;
- record.fallback_entry_url = kBarFallbackEntry;
- EXPECT_TRUE(db.InsertFallbackNameSpace(&record));
-
- record.cache_id = 3;
- record.origin = kBarOrigin;
- record.namespace_url = kBarNameSpace2;
- record.fallback_entry_url = kBarFallbackEntry;
- EXPECT_TRUE(db.InsertFallbackNameSpace(&record));
-
- records.clear();
- EXPECT_TRUE(db.FindFallbackNameSpacesForCache(3, &records));
- EXPECT_EQ(2U, records.size());
- records.clear();
- EXPECT_TRUE(db.FindFallbackNameSpacesForOrigin(kBarOrigin, &records));
- EXPECT_EQ(2U, records.size());
-}
-
-TEST(AppCacheDatabaseTest, OnlineWhiteListRecords) {
- const FilePath kEmptyPath;
- AppCacheDatabase db(kEmptyPath);
- EXPECT_TRUE(db.LazyOpen(true));
-
- scoped_refptr<TestErrorDelegate> error_delegate(new TestErrorDelegate);
- db.db_->set_error_delegate(error_delegate);
-
- const GURL kFooNameSpace1("http://foo/namespace1");
- const GURL kFooNameSpace2("http://foo/namespace2");
- const GURL kBarNameSpace1("http://bar/namespace1");
-
- const AppCacheDatabase::OnlineWhiteListRecord kZeroRecord = { 0, GURL() };
- AppCacheDatabase::OnlineWhiteListRecord record = kZeroRecord;
- std::vector<AppCacheDatabase::OnlineWhiteListRecord> records;
-
- // Behavior with an empty table
- EXPECT_TRUE(db.FindOnlineWhiteListForCache(1, &records));
- EXPECT_TRUE(records.empty());
- EXPECT_TRUE(db.DeleteOnlineWhiteListForCache(1));
-
- record.cache_id = 1;
- record.namespace_url = kFooNameSpace1;
- EXPECT_TRUE(db.InsertOnlineWhiteList(&record));
- record.namespace_url = kFooNameSpace2;
- EXPECT_TRUE(db.InsertOnlineWhiteList(&record));
- records.clear();
- EXPECT_TRUE(db.FindOnlineWhiteListForCache(1, &records));
- EXPECT_EQ(2U, records.size());
- EXPECT_EQ(1, records[0].cache_id);
- EXPECT_EQ(kFooNameSpace1, records[0].namespace_url);
- EXPECT_EQ(1, records[1].cache_id);
- EXPECT_EQ(kFooNameSpace2, records[1].namespace_url);
-
- record.cache_id = 2;
- record.namespace_url = kBarNameSpace1;
- EXPECT_TRUE(db.InsertOnlineWhiteList(&record));
- records.clear();
- EXPECT_TRUE(db.FindOnlineWhiteListForCache(2, &records));
- EXPECT_EQ(1U, records.size());
-
- EXPECT_TRUE(db.DeleteOnlineWhiteListForCache(1));
- records.clear();
- EXPECT_TRUE(db.FindOnlineWhiteListForCache(1, &records));
- EXPECT_TRUE(records.empty());
-}
-
-} // namespace appcache
diff --git a/webkit/appcache/appcache_group_unittest.cc b/webkit/appcache/appcache_group_unittest.cc
index 180cc3a..5986021 100644
--- a/webkit/appcache/appcache_group_unittest.cc
+++ b/webkit/appcache/appcache_group_unittest.cc
@@ -77,7 +77,7 @@ class AppCacheGroupTest : public testing::Test {
TEST(AppCacheGroupTest, AddRemoveCache) {
MockAppCacheService service;
scoped_refptr<AppCacheGroup> group =
- new AppCacheGroup(&service, GURL("http://foo.com"), 111);
+ new AppCacheGroup(&service, GURL::EmptyGURL(), 111);
base::TimeTicks ticks = base::TimeTicks::Now();
@@ -146,8 +146,7 @@ TEST(AppCacheGroupTest, AddRemoveCache) {
TEST(AppCacheGroupTest, CleanupUnusedGroup) {
MockAppCacheService service;
TestAppCacheFrontend frontend;
- AppCacheGroup* group =
- new AppCacheGroup(&service, GURL("http://foo.com"), 111);
+ AppCacheGroup* group = new AppCacheGroup(&service, GURL::EmptyGURL(), 111);
AppCacheHost host1(1, &frontend, &service);
AppCacheHost host2(2, &frontend, &service);
diff --git a/webkit/appcache/appcache_host.cc b/webkit/appcache/appcache_host.cc
index 489d062..6a62a44 100644
--- a/webkit/appcache/appcache_host.cc
+++ b/webkit/appcache/appcache_host.cc
@@ -300,7 +300,6 @@ void AppCacheHost::FinishCacheSelection(
void AppCacheHost::ObserveGroupBeingUpdated(AppCacheGroup* group) {
DCHECK(!group_being_updated_);
group_being_updated_ = group;
- newest_cache_of_group_being_updated_ = group->newest_complete_cache();
group->AddUpdateObserver(this);
}
@@ -312,7 +311,6 @@ void AppCacheHost::OnUpdateComplete(AppCacheGroup* group) {
SetSwappableCache(group);
group_being_updated_ = NULL;
- newest_cache_of_group_being_updated_ = NULL;
}
void AppCacheHost::SetSwappableCache(AppCacheGroup* group) {
diff --git a/webkit/appcache/appcache_host.h b/webkit/appcache/appcache_host.h
index 3029cd3..13acdb0 100644
--- a/webkit/appcache/appcache_host.h
+++ b/webkit/appcache/appcache_host.h
@@ -135,11 +135,6 @@ class AppCacheHost : public AppCacheStorage::Delegate,
// Keep a reference to the group being updated until the update completes.
scoped_refptr<AppCacheGroup> group_being_updated_;
- // Similarly, keep a reference to the newest cache of the group until the
- // update completes. When adding a new master entry to a cache that is not
- // in use in any other host, this reference keeps the cache in memory.
- scoped_refptr<AppCache> newest_cache_of_group_being_updated_;
-
// Keep a reference to the cache of the main resource so it survives frame
// navigations.
scoped_refptr<AppCache> main_resource_cache_;
diff --git a/webkit/appcache/appcache_storage_impl.cc b/webkit/appcache/appcache_storage_impl.cc
index 04809eb..3fb8280 100644
--- a/webkit/appcache/appcache_storage_impl.cc
+++ b/webkit/appcache/appcache_storage_impl.cc
@@ -4,862 +4,12 @@
#include "webkit/appcache/appcache_storage_impl.h"
-#include "app/sql/connection.h"
-#include "app/sql/transaction.h"
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "base/stl_util-inl.h"
-#include "base/string_util.h"
-#include "webkit/appcache/appcache.h"
-#include "webkit/appcache/appcache_database.h"
-#include "webkit/appcache/appcache_entry.h"
-#include "webkit/appcache/appcache_group.h"
-#include "webkit/appcache/appcache_response.h"
-#include "webkit/appcache/appcache_thread.h"
-
namespace appcache {
-static const char kAppCacheDatabaseName[] = "Index";
-static const char kDiskCacheDirectoryName[] = "Cache";
-static const int kMaxDiskCacheSize = 10 * 1024 * 1024;
-
-// DatabaseTask -----------------------------------------
-
-class AppCacheStorageImpl::DatabaseTask
- : public base::RefCountedThreadSafe<DatabaseTask> {
- public:
- explicit DatabaseTask(AppCacheStorageImpl* storage)
- : storage_(storage), database_(storage->database_) {}
-
- void AddDelegate(DelegateReference* delegate_reference) {
- delegates_.push_back(delegate_reference);
- }
-
- // Schedules a task to be Run() on the DB thread. Tasks
- // are run in the order in which they are scheduled.
- void Schedule();
-
- // Called on the DB thread.
- virtual void Run() = 0;
-
- // Called on the IO thread after Run() has completed.
- virtual void RunCompleted() {}
-
- // Once scheduled a task cannot be cancelled, but the
- // call to RunCompleted may be. This method should only be
- // called on the IO thread. This is used by AppCacheStorageImpl
- // to cancel the completion calls when AppCacheStorageImpl is
- // destructed. This method may be overriden to release or delete
- // additional data associated with the task that is not DB thread
- // safe. If overriden, this base class method must be called from
- // within the override.
- virtual void CancelCompletion();
-
- protected:
- AppCacheStorageImpl* storage_;
- AppCacheDatabase* database_;
- DelegateReferenceVector delegates_;
-
- private:
- void CallRun();
- void CallRunCompleted();
-};
-
-void AppCacheStorageImpl::DatabaseTask::Schedule() {
- DCHECK(storage_);
- DCHECK(AppCacheThread::CurrentlyOn(AppCacheThread::io()));
- storage_->scheduled_database_tasks_.push_back(this);
- AppCacheThread::PostTask(AppCacheThread::db(), FROM_HERE,
- NewRunnableMethod(this, &DatabaseTask::CallRun));
-}
-
-void AppCacheStorageImpl::DatabaseTask::CancelCompletion() {
- DCHECK(AppCacheThread::CurrentlyOn(AppCacheThread::io()));
- delegates_.clear();
- storage_ = NULL;
-}
-
-void AppCacheStorageImpl::DatabaseTask::CallRun() {
- DCHECK(AppCacheThread::CurrentlyOn(AppCacheThread::db()));
- Run();
- AppCacheThread::PostTask(AppCacheThread::io(), FROM_HERE,
- NewRunnableMethod(this, &DatabaseTask::CallRunCompleted));
-}
-
-void AppCacheStorageImpl::DatabaseTask::CallRunCompleted() {
- if (storage_) {
- DCHECK(AppCacheThread::CurrentlyOn(AppCacheThread::io()));
- DCHECK(storage_->scheduled_database_tasks_.front() == this);
- storage_->scheduled_database_tasks_.pop_front();
- RunCompleted();
- }
-}
-
-// InitTask -------
-
-class AppCacheStorageImpl::InitTask : public DatabaseTask {
- public:
- explicit InitTask(AppCacheStorageImpl* storage)
- : DatabaseTask(storage), last_group_id_(0),
- last_cache_id_(0), last_response_id_(0) {}
-
- virtual void Run();
- virtual void RunCompleted();
-
- int64 last_group_id_;
- int64 last_cache_id_;
- int64 last_response_id_;
- std::set<GURL> origins_with_groups_;
-};
-
-void AppCacheStorageImpl::InitTask::Run() {
- database_->FindLastStorageIds(
- &last_group_id_, &last_cache_id_, &last_response_id_);
- database_->FindOriginsWithGroups(&origins_with_groups_);
-}
-
-void AppCacheStorageImpl::InitTask::RunCompleted() {
- storage_->last_group_id_ = last_group_id_;
- storage_->last_cache_id_ = last_cache_id_;
- storage_->last_response_id_ = last_response_id_;
- storage_->origins_with_groups_.swap(origins_with_groups_);
-}
-
-// CloseConnectionTask -------
-
-class AppCacheStorageImpl::CloseConnectionTask : public DatabaseTask {
- public:
- explicit CloseConnectionTask(AppCacheStorageImpl* storage)
- : DatabaseTask(storage) {}
-
- virtual void Run() { database_->CloseConnection(); }
-};
-
-// StoreOrLoadTask -------
-
-class AppCacheStorageImpl::StoreOrLoadTask : public DatabaseTask {
- protected:
- explicit StoreOrLoadTask(AppCacheStorageImpl* storage)
- : DatabaseTask(storage) {}
-
- bool FindRelatedCacheRecords(int64 cache_id);
- void CreateCacheAndGroupFromRecords(
- scoped_refptr<AppCache>* cache, scoped_refptr<AppCacheGroup>* group);
-
- AppCacheDatabase::GroupRecord group_record_;
- AppCacheDatabase::CacheRecord cache_record_;
- std::vector<AppCacheDatabase::EntryRecord> entry_records_;
- std::vector<AppCacheDatabase::FallbackNameSpaceRecord>
- fallback_namespace_records_;
- std::vector<AppCacheDatabase::OnlineWhiteListRecord>
- online_whitelist_records_;
-};
-
-bool AppCacheStorageImpl::StoreOrLoadTask::FindRelatedCacheRecords(
- int64 cache_id) {
- return database_->FindEntriesForCache(cache_id, &entry_records_) &&
- database_->FindFallbackNameSpacesForCache(
- cache_id, &fallback_namespace_records_) &&
- database_->FindOnlineWhiteListForCache(
- cache_id, &online_whitelist_records_);
-}
-
-void AppCacheStorageImpl::StoreOrLoadTask::CreateCacheAndGroupFromRecords(
- scoped_refptr<AppCache>* cache, scoped_refptr<AppCacheGroup>* group) {
- DCHECK(storage_ && cache && group);
-
- (*cache) = new AppCache(storage_->service_, cache_record_.cache_id);
- cache->get()->InitializeWithDatabaseRecords(
- cache_record_, entry_records_, fallback_namespace_records_,
- online_whitelist_records_);
- cache->get()->set_complete(true);
-
- (*group) = storage_->working_set_.GetGroup(group_record_.manifest_url);
- if (group->get()) {
- DCHECK(group_record_.group_id == group->get()->group_id());
- group->get()->AddCache(cache->get());
- } else {
- (*group) = new AppCacheGroup(
- storage_->service_, group_record_.manifest_url,
- group_record_.group_id);
- group->get()->AddCache(cache->get());
- }
- DCHECK(group->get()->newest_complete_cache() == cache->get());
-
- // We have to update foriegn entries if MarkEntryAsForeignTasks
- // are in flight.
- std::vector<GURL> urls;
- storage_->GetPendingForeignMarkingsForCache(cache->get()->cache_id(), &urls);
- for (std::vector<GURL>::iterator iter = urls.begin();
- iter != urls.end(); ++iter) {
- DCHECK(cache->get()->GetEntry(*iter));
- cache->get()->GetEntry(*iter)->add_types(AppCacheEntry::FOREIGN);
- }
-}
-
-// CacheLoadTask -------
-
-class AppCacheStorageImpl::CacheLoadTask : public StoreOrLoadTask {
- public:
- CacheLoadTask(int64 cache_id, AppCacheStorageImpl* storage)
- : StoreOrLoadTask(storage), cache_id_(cache_id),
- success_(false) {}
-
- virtual void Run();
- virtual void RunCompleted();
-
- int64 cache_id_;
- bool success_;
-};
-
-void AppCacheStorageImpl::CacheLoadTask::Run() {
- success_ =
- database_->FindCache(cache_id_, &cache_record_) &&
- database_->FindGroup(cache_record_.group_id, &group_record_) &&
- FindRelatedCacheRecords(cache_id_);
-}
-
-void AppCacheStorageImpl::CacheLoadTask::RunCompleted() {
- storage_->pending_cache_loads_.erase(cache_id_);
- scoped_refptr<AppCache> cache;
- scoped_refptr<AppCacheGroup> group;
- if (success_) {
- DCHECK(cache_record_.cache_id == cache_id_);
- DCHECK(!storage_->working_set_.GetCache(cache_record_.cache_id));
- CreateCacheAndGroupFromRecords(&cache, &group);
- }
- FOR_EACH_DELEGATE(delegates_, OnCacheLoaded(cache, cache_id_));
-}
-
-// GroupLoadTask -------
-
-class AppCacheStorageImpl::GroupLoadTask : public StoreOrLoadTask {
- public:
- GroupLoadTask(GURL manifest_url, AppCacheStorageImpl* storage)
- : StoreOrLoadTask(storage), manifest_url_(manifest_url),
- success_(false) {}
-
- virtual void Run();
- virtual void RunCompleted();
-
- GURL manifest_url_;
- bool success_;
-};
-
-void AppCacheStorageImpl::GroupLoadTask::Run() {
- success_ =
- database_->FindGroupForManifestUrl(manifest_url_, &group_record_) &&
- database_->FindCacheForGroup(group_record_.group_id, &cache_record_) &&
- FindRelatedCacheRecords(cache_record_.cache_id);
-}
-
-void AppCacheStorageImpl::GroupLoadTask::RunCompleted() {
- storage_->pending_group_loads_.erase(manifest_url_);
- scoped_refptr<AppCacheGroup> group;
- scoped_refptr<AppCache> cache;
- if (success_) {
- DCHECK(group_record_.manifest_url == manifest_url_);
- DCHECK(!storage_->working_set_.GetGroup(manifest_url_));
- DCHECK(!storage_->working_set_.GetCache(cache_record_.cache_id));
- CreateCacheAndGroupFromRecords(&cache, &group);
- } else {
- group = new AppCacheGroup(
- storage_->service_, manifest_url_,
- storage_->NewGroupId());
- }
- FOR_EACH_DELEGATE(delegates_, OnGroupLoaded(group, manifest_url_));
-}
-
-// StoreGroupAndCacheTask -------
-
-class AppCacheStorageImpl::StoreGroupAndCacheTask : public StoreOrLoadTask {
- public:
- StoreGroupAndCacheTask(AppCacheStorageImpl* storage, AppCacheGroup* group,
- AppCache* newest_cache);
-
- virtual void Run();
- virtual void RunCompleted();
- virtual void CancelCompletion();
-
- scoped_refptr<AppCacheGroup> group_;
- scoped_refptr<AppCache> cache_;
- bool success_;
-};
-
-AppCacheStorageImpl::StoreGroupAndCacheTask::StoreGroupAndCacheTask(
- AppCacheStorageImpl* storage, AppCacheGroup* group, AppCache* newest_cache)
- : StoreOrLoadTask(storage), group_(group), cache_(newest_cache),
- success_(false) {
- group_record_.group_id = group->group_id();
- group_record_.manifest_url = group->manifest_url();
- group_record_.origin = group_record_.manifest_url.GetOrigin();
- newest_cache->ToDatabaseRecords(
- group,
- &cache_record_, &entry_records_, &fallback_namespace_records_,
- &online_whitelist_records_);
-}
-
-void AppCacheStorageImpl::StoreGroupAndCacheTask::Run() {
- DCHECK(!success_);
- sql::Connection* connection = database_->db_connection();
- if (!connection)
- return;
-
- sql::Transaction transaction(connection);
- if (!transaction.Begin())
- return;
-
- AppCacheDatabase::GroupRecord existing_group;
- success_ = database_->FindGroup(group_record_.group_id, &existing_group);
- if (!success_) {
- success_ = database_->InsertGroup(&group_record_);
- } else {
- DCHECK(group_record_.group_id == existing_group.group_id);
- DCHECK(group_record_.manifest_url == existing_group.manifest_url);
- DCHECK(group_record_.origin == existing_group.origin);
-
- AppCacheDatabase::CacheRecord cache;
- if (database_->FindCacheForGroup(group_record_.group_id, &cache)) {
- success_ =
- database_->DeleteCache(cache.cache_id) &&
- database_->DeleteEntriesForCache(cache.cache_id) &&
- database_->DeleteFallbackNameSpacesForCache(cache.cache_id) &&
- database_->DeleteOnlineWhiteListForCache(cache.cache_id);
- // TODO(michaeln): schedule to purge unused responses from the disk cache
- } else {
- NOTREACHED() << "A existing group without a cache is unexpected";
- }
- }
-
- success_ =
- success_ &&
- database_->InsertCache(&cache_record_) &&
- database_->InsertEntryRecords(entry_records_) &&
- database_->InsertFallbackNameSpaceRecords(fallback_namespace_records_)&&
- database_->InsertOnlineWhiteListRecords(online_whitelist_records_) &&
- transaction.Commit();
-}
-
-void AppCacheStorageImpl::StoreGroupAndCacheTask::RunCompleted() {
- if (success_) {
- storage_->origins_with_groups_.insert(group_->manifest_url().GetOrigin());
- if (cache_ != group_->newest_complete_cache())
- group_->AddCache(cache_);
- }
- FOR_EACH_DELEGATE(delegates_, OnGroupAndNewestCacheStored(group_, success_));
- group_ = NULL;
- cache_ = NULL;
-}
-
-void AppCacheStorageImpl::StoreGroupAndCacheTask::CancelCompletion() {
- // Overriden to safely drop our reference to the group and cache
- // which are not thread safe refcounted.
- DatabaseTask::CancelCompletion();
- group_ = NULL;
- cache_ = NULL;
-}
-
-// FindMainResponseTask -------
-
-class AppCacheStorageImpl::FindMainResponseTask : public DatabaseTask {
- public:
- FindMainResponseTask(AppCacheStorageImpl* storage, const GURL& url,
- const AppCacheWorkingSet::GroupMap* groups_in_use)
- : DatabaseTask(storage), url_(url), cache_id_(kNoCacheId) {
- if (groups_in_use) {
- for (AppCacheWorkingSet::GroupMap::const_iterator it =
- groups_in_use->begin();
- it != groups_in_use->end(); ++it) {
- AppCacheGroup* group = it->second;
- AppCache* cache = group->newest_complete_cache();
- if (group->is_obsolete() || !cache)
- continue;
- cache_ids_in_use_.insert(cache->cache_id());
- }
- }
- }
-
- virtual void Run();
- virtual void RunCompleted();
-
- GURL url_;
- std::set<int64> cache_ids_in_use_;
- AppCacheEntry entry_;
- AppCacheEntry fallback_entry_;
- int64 cache_id_;
- GURL manifest_url_;
-};
-
-namespace {
-
-bool SortByLength(
- const AppCacheDatabase::FallbackNameSpaceRecord& lhs,
- const AppCacheDatabase::FallbackNameSpaceRecord& rhs) {
- return lhs.namespace_url.spec().length() > rhs.namespace_url.spec().length();
-}
-
-}
-
-void AppCacheStorageImpl::FindMainResponseTask::Run() {
- // We have a bias for hits from caches that are in use.
-
- // TODO(michaeln): The heuristics around choosing amoungst
- // multiple candidates is under specified, and just plain
- // not fully understood. Refine these over time. In particular,
- // * prefer candidates from newer caches
- // * take into account the cache associated with the document
- // that initiated the navigation
- // * take into account the cache associated with the document
- // currently residing in the frame being navigated
-
- // First look for an exact match. We don't worry about whether
- // the containing cache is in-use in this loop because the
- // storage class's FindResponseForMainRequest method does that
- // as a pre-optimization.
- std::vector<AppCacheDatabase::EntryRecord> entries;
- if (database_->FindEntriesForUrl(url_, &entries) && !entries.empty()) {
- std::vector<AppCacheDatabase::EntryRecord>::iterator iter;
- for (iter = entries.begin(); iter < entries.end(); ++iter) {
- if (iter->flags & AppCacheEntry::FOREIGN)
- continue;
-
- AppCacheDatabase::GroupRecord group_record;
- if (!database_->FindGroupForCache(iter->cache_id, &group_record)) {
- NOTREACHED() << "A cache without a group is not expected.";
- continue;
- }
- entry_ = AppCacheEntry(iter->flags, iter->response_id);
- cache_id_ = iter->cache_id;
- manifest_url_ = group_record.manifest_url;
- return;
- }
- }
-
- // No exact matches, look at the fallback namespaces for this origin.
- std::vector<AppCacheDatabase::FallbackNameSpaceRecord> fallbacks;
- if (!database_->FindFallbackNameSpacesForOrigin(url_.GetOrigin(), &fallbacks)
- || fallbacks.empty()) {
- return;
- }
-
- // Sort by namespace url string length, longest to shortest,
- // since longer matches trump when matching a url to a namespace.
- std::sort(fallbacks.begin(), fallbacks.end(), SortByLength);
-
- bool has_candidate = false;
- GURL candidate_fallback_namespace;
- std::vector<AppCacheDatabase::FallbackNameSpaceRecord>::iterator iter;
- for (iter = fallbacks.begin(); iter < fallbacks.end(); ++iter) {
- if (has_candidate &&
- (candidate_fallback_namespace.spec().length() >
- iter->namespace_url.spec().length())) {
- break; // Stop iterating since longer namespace prefix matches win.
- }
-
- if (StartsWithASCII(url_.spec(), iter->namespace_url.spec(), true)) {
- bool is_cache_in_use = cache_ids_in_use_.find(iter->cache_id) !=
- cache_ids_in_use_.end();
-
- bool take_new_candidate = !has_candidate || is_cache_in_use;
-
- AppCacheDatabase::EntryRecord entry_record;
- if (take_new_candidate &&
- database_->FindEntry(iter->cache_id, iter->fallback_entry_url,
- &entry_record)) {
- AppCacheDatabase::GroupRecord group_record;
- if (!database_->FindGroupForCache(iter->cache_id, &group_record)) {
- NOTREACHED() << "A cache without a group is not expected.";
- continue;
- }
- cache_id_ = iter->cache_id;
- manifest_url_ = group_record.manifest_url;
- fallback_entry_ = AppCacheEntry(
- entry_record.flags, entry_record.response_id);
- if (is_cache_in_use)
- break; // Stop iterating since we favor hits from in-use caches.
- candidate_fallback_namespace = iter->namespace_url;
- has_candidate = true;
- }
- }
- }
-}
-
-void AppCacheStorageImpl::FindMainResponseTask::RunCompleted() {
- FOR_EACH_DELEGATE(delegates_,
- OnMainResponseFound(url_, entry_, fallback_entry_,
- cache_id_, manifest_url_));
-}
-
-// MarkEntryAsForeignTask -------
-
-class AppCacheStorageImpl::MarkEntryAsForeignTask : public DatabaseTask {
- public:
- MarkEntryAsForeignTask(
- AppCacheStorageImpl* storage, const GURL& url, int64 cache_id)
- : DatabaseTask(storage), cache_id_(cache_id), entry_url_(url) {}
-
- virtual void Run();
- virtual void RunCompleted();
-
- int64 cache_id_;
- GURL entry_url_;
-};
-
-void AppCacheStorageImpl::MarkEntryAsForeignTask::Run() {
- database_->AddEntryFlags(entry_url_, cache_id_, AppCacheEntry::FOREIGN);
-}
-
-void AppCacheStorageImpl::MarkEntryAsForeignTask::RunCompleted() {
- DCHECK(storage_->pending_foreign_markings_.front().first == entry_url_ &&
- storage_->pending_foreign_markings_.front().second == cache_id_);
- storage_->pending_foreign_markings_.pop_front();
-}
-
-// MakeGroupObsoleteTask -------
-
-class AppCacheStorageImpl::MakeGroupObsoleteTask : public DatabaseTask {
- public:
- MakeGroupObsoleteTask(AppCacheStorageImpl* storage, AppCacheGroup* group);
-
- virtual void Run();
- virtual void RunCompleted();
- virtual void CancelCompletion();
-
- scoped_refptr<AppCacheGroup> group_;
- int64 group_id_;
- bool success_;
- std::set<GURL> origins_with_groups_;
-};
-
-AppCacheStorageImpl::MakeGroupObsoleteTask::MakeGroupObsoleteTask(
- AppCacheStorageImpl* storage, AppCacheGroup* group)
- : DatabaseTask(storage), group_(group), group_id_(group->group_id()),
- success_(false) {
-}
-
-void AppCacheStorageImpl::MakeGroupObsoleteTask::Run() {
- DCHECK(!success_);
- sql::Connection* connection = database_->db_connection();
- if (!connection)
- return;
-
- sql::Transaction transaction(connection);
- if (!transaction.Begin())
- return;
-
- AppCacheDatabase::GroupRecord group_record;
- if (!database_->FindGroup(group_id_, &group_record)) {
- // This group doesn't exists in the database, nothing todo here.
- success_ = true;
- return;
- }
-
- AppCacheDatabase::CacheRecord cache_record;
- if (database_->FindCacheForGroup(group_id_, &cache_record)) {
- success_ =
- database_->DeleteGroup(group_id_) &&
- database_->DeleteCache(cache_record.cache_id) &&
- database_->DeleteEntriesForCache(cache_record.cache_id) &&
- database_->DeleteFallbackNameSpacesForCache(cache_record.cache_id) &&
- database_->DeleteOnlineWhiteListForCache(cache_record.cache_id);
- } else {
- NOTREACHED() << "A existing group without a cache is unexpected";
- success_ = database_->DeleteGroup(group_id_);
- }
-
- success_ = success_ &&
- database_->FindOriginsWithGroups(&origins_with_groups_) &&
- transaction.Commit();
-
- // TODO(michaeln): schedule to purge unused responses from the disk cache
-}
-
-void AppCacheStorageImpl::MakeGroupObsoleteTask::RunCompleted() {
- if (success_) {
- storage_->origins_with_groups_.swap(origins_with_groups_);
- group_->set_obsolete(true);
- }
- FOR_EACH_DELEGATE(delegates_, OnGroupMadeObsolete(group_, success_));
- group_ = NULL;
-}
-
-void AppCacheStorageImpl::MakeGroupObsoleteTask::CancelCompletion() {
- // Overriden to safely drop our reference to the group
- // which is not thread safe refcounted.
- DatabaseTask::CancelCompletion();
- group_ = NULL;
-}
-
-
-// AppCacheStorageImpl ---------------------------------------------------
-
-AppCacheStorageImpl::AppCacheStorageImpl(AppCacheService* service)
- : AppCacheStorage(service), is_incognito_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
-}
-
-AppCacheStorageImpl::~AppCacheStorageImpl() {
- STLDeleteElements(&pending_simple_tasks_);
-
- std::for_each(scheduled_database_tasks_.begin(),
- scheduled_database_tasks_.end(),
- std::mem_fun(&DatabaseTask::CancelCompletion));
-
- if (database_)
- AppCacheThread::DeleteSoon(AppCacheThread::db(), FROM_HERE, database_);
-}
-
void AppCacheStorageImpl::Initialize(const FilePath& cache_directory) {
- // TODO(michaeln): until purging of responses is addressed in some way,
- // always use incognito mode which doesn't put anything to disk.
- // Uncomment the following line when responses are dealt with.
- // cache_directory_ = cache_directory;
- is_incognito_ = cache_directory_.empty();
-
- FilePath db_file_path;
- if (!is_incognito_)
- db_file_path = cache_directory.AppendASCII(kAppCacheDatabaseName);
- database_ = new AppCacheDatabase(db_file_path);
-
- scoped_refptr<InitTask> task = new InitTask(this);
- task->Schedule();
-}
-
-void AppCacheStorageImpl::LoadCache(int64 id, Delegate* delegate) {
- DCHECK(delegate);
- AppCache* cache = working_set_.GetCache(id);
- if (cache) {
- delegate->OnCacheLoaded(cache, id);
- return;
- }
- scoped_refptr<CacheLoadTask> task = GetPendingCacheLoadTask(id);
- if (task) {
- task->AddDelegate(GetOrCreateDelegateReference(delegate));
- return;
- }
- task = new CacheLoadTask(id, this);
- task->AddDelegate(GetOrCreateDelegateReference(delegate));
- task->Schedule();
- pending_cache_loads_[id] = task;
-}
-
-void AppCacheStorageImpl::LoadOrCreateGroup(
- const GURL& manifest_url, Delegate* delegate) {
- DCHECK(delegate);
- AppCacheGroup* group = working_set_.GetGroup(manifest_url);
- if (group) {
- delegate->OnGroupLoaded(group, manifest_url);
- return;
- }
-
- scoped_refptr<GroupLoadTask> task = GetPendingGroupLoadTask(manifest_url);
- if (task) {
- task->AddDelegate(GetOrCreateDelegateReference(delegate));
- return;
- }
-
- if (origins_with_groups_.find(manifest_url.GetOrigin()) ==
- origins_with_groups_.end()) {
- // No need to query the database, return NULL immediately.
- scoped_refptr<AppCacheGroup> group = new AppCacheGroup(
- service_, manifest_url, NewGroupId());
- delegate->OnGroupLoaded(group, manifest_url);
- return;
- }
-
- task = new GroupLoadTask(manifest_url, this);
- task->AddDelegate(GetOrCreateDelegateReference(delegate));
- task->Schedule();
- pending_group_loads_[manifest_url] = task.get();
-}
-
-void AppCacheStorageImpl::StoreGroupAndNewestCache(
- AppCacheGroup* group, AppCache* newest_cache, Delegate* delegate) {
- // TODO(michaeln): distinguish between a simple update of an existing
- // cache that just adds new master entry(s), and the insertion of a
- // whole new cache. The StoreGroupAndCacheTask as written will handle
- // the simple update case in a very heavy weight way (delete all and
- // the reinsert all over again).
- DCHECK(group && delegate);
- DCHECK(newest_cache && newest_cache->is_complete());
- scoped_refptr<StoreGroupAndCacheTask> task =
- new StoreGroupAndCacheTask(this, group, newest_cache);
- task->AddDelegate(GetOrCreateDelegateReference(delegate));
- task->Schedule();
-}
-
-void AppCacheStorageImpl::FindResponseForMainRequest(
- const GURL& url, Delegate* delegate) {
- DCHECK(delegate);
-
- const GURL* url_ptr = &url;
- GURL url_no_ref;
- if (url.has_ref()) {
- GURL::Replacements replacements;
- replacements.ClearRef();
- url_no_ref = url.ReplaceComponents(replacements);
- url_ptr = &url_no_ref;
- }
-
- // First look in our working set for a direct hit without having to query
- // the database.
- const AppCacheWorkingSet::GroupMap* groups_in_use =
- working_set()->GetGroupsInOrigin(url_ptr->GetOrigin());
- if (groups_in_use) {
- for (AppCacheWorkingSet::GroupMap::const_iterator it =
- groups_in_use->begin();
- it != groups_in_use->end(); ++it) {
- AppCacheGroup* group = it->second;
- AppCache* cache = group->newest_complete_cache();
- if (group->is_obsolete() || !cache)
- continue;
-
- AppCacheEntry* entry = cache->GetEntry(*url_ptr);
- if (entry && !entry->IsForeign()) {
- ScheduleSimpleTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse,
- url, *entry, make_scoped_refptr(group), make_scoped_refptr(cache),
- make_scoped_refptr(GetOrCreateDelegateReference(delegate))));
- return;
- }
- }
- }
-
- if (origins_with_groups_.find(url.GetOrigin()) ==
- origins_with_groups_.end()) {
- // No need to query the database, return async'ly but without going thru
- // the DB thread.
- scoped_refptr<AppCacheGroup> no_group;
- scoped_refptr<AppCache> no_cache;
- ScheduleSimpleTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse,
- url, AppCacheEntry(), no_group, no_cache,
- make_scoped_refptr(GetOrCreateDelegateReference(delegate))));
- return;
- }
-
- // We have to query the database, schedule a database task to do so.
- scoped_refptr<FindMainResponseTask> task =
- new FindMainResponseTask(this, *url_ptr, groups_in_use);
- task->AddDelegate(GetOrCreateDelegateReference(delegate));
- task->Schedule();
-}
-
-void AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse(
- const GURL& url, AppCacheEntry found_entry,
- scoped_refptr<AppCacheGroup> group, scoped_refptr<AppCache> cache,
- scoped_refptr<DelegateReference> delegate_ref) {
- if (delegate_ref->delegate) {
- delegate_ref->delegate->OnMainResponseFound(
- url, found_entry, AppCacheEntry(),
- cache.get() ? cache->cache_id() : kNoCacheId,
- group.get() ? group->manifest_url() : GURL::EmptyGURL());
- }
-}
-
-void AppCacheStorageImpl::FindResponseForSubRequest(
- AppCache* cache, const GURL& url,
- AppCacheEntry* found_entry, AppCacheEntry* found_fallback_entry,
- bool* found_network_namespace) {
- DCHECK(cache && cache->is_complete());
- GURL fallback_namespace_not_used;
- cache->FindResponseForRequest(
- url, found_entry, found_fallback_entry,
- &fallback_namespace_not_used, found_network_namespace);
-}
-
-void AppCacheStorageImpl::MarkEntryAsForeign(
- const GURL& entry_url, int64 cache_id) {
- AppCache* cache = working_set_.GetCache(cache_id);
- if (cache) {
- AppCacheEntry* entry = cache->GetEntry(entry_url);
- DCHECK(entry);
- if (entry)
- entry->add_types(AppCacheEntry::FOREIGN);
- }
- scoped_refptr<MarkEntryAsForeignTask> task =
- new MarkEntryAsForeignTask(this, entry_url, cache_id);
- task->Schedule();
- pending_foreign_markings_.push_back(std::make_pair(entry_url, cache_id));
-}
-
-void AppCacheStorageImpl::MakeGroupObsolete(
- AppCacheGroup* group, Delegate* delegate) {
- DCHECK(group && delegate);
- scoped_refptr<MakeGroupObsoleteTask> task =
- new MakeGroupObsoleteTask(this, group);
- task->AddDelegate(GetOrCreateDelegateReference(delegate));
- task->Schedule();
-}
-
-AppCacheResponseReader* AppCacheStorageImpl::CreateResponseReader(
- const GURL& manifest_url, int64 response_id) {
- return new AppCacheResponseReader(response_id, disk_cache());
-}
-
-AppCacheResponseWriter* AppCacheStorageImpl::CreateResponseWriter(
- const GURL& manifest_url) {
- return new AppCacheResponseWriter(NewResponseId(), disk_cache());
-}
-
-void AppCacheStorageImpl::DoomResponses(
- const GURL& manifest_url, const std::vector<int64>& response_ids) {
- // TODO(michaeln): do something here when deleting responses
-}
-
-AppCacheStorageImpl::CacheLoadTask*
-AppCacheStorageImpl::GetPendingCacheLoadTask(int64 cache_id) {
- PendingCacheLoads::iterator found = pending_cache_loads_.find(cache_id);
- if (found != pending_cache_loads_.end())
- return found->second;
- return NULL;
-}
-
-AppCacheStorageImpl::GroupLoadTask*
-AppCacheStorageImpl::GetPendingGroupLoadTask(const GURL& manifest_url) {
- PendingGroupLoads::iterator found = pending_group_loads_.find(manifest_url);
- if (found != pending_group_loads_.end())
- return found->second;
- return NULL;
-}
-
-void AppCacheStorageImpl::GetPendingForeignMarkingsForCache(
- int64 cache_id, std::vector<GURL>* urls) {
- PendingForeignMarkings::iterator iter = pending_foreign_markings_.begin();
- while (iter != pending_foreign_markings_.end()) {
- if (iter->second == cache_id)
- urls->push_back(iter->first);
- ++iter;
- }
-}
-
-void AppCacheStorageImpl::ScheduleSimpleTask(Task* task) {
- pending_simple_tasks_.push_back(task);
- MessageLoop::current()->PostTask(FROM_HERE,
- method_factory_.NewRunnableMethod(
- &AppCacheStorageImpl::RunOnePendingSimpleTask));
-}
-
-void AppCacheStorageImpl::RunOnePendingSimpleTask() {
- DCHECK(!pending_simple_tasks_.empty());
- Task* task = pending_simple_tasks_.front();
- pending_simple_tasks_.pop_front();
- task->Run();
- delete task;
-}
-
-disk_cache::Backend* AppCacheStorageImpl::disk_cache() {
- if (!disk_cache_.get()) {
- if (is_incognito_) {
- disk_cache_.reset(
- disk_cache::CreateInMemoryCacheBackend(kMaxDiskCacheSize));
- } else {
- // TODO(michaeln): create a disk backed backend
- disk_cache_.reset(
- disk_cache::CreateInMemoryCacheBackend(kMaxDiskCacheSize));
- }
- }
- return disk_cache_.get();
+ is_incognito_ = cache_directory.empty();
+ cache_directory_ = cache_directory;
+ // TODO(michaeln): retrieve last_ids from storage
}
} // namespace appcache
diff --git a/webkit/appcache/appcache_storage_impl.h b/webkit/appcache/appcache_storage_impl.h
index 9debc1c..ef75d1e 100644
--- a/webkit/appcache/appcache_storage_impl.h
+++ b/webkit/appcache/appcache_storage_impl.h
@@ -5,102 +5,22 @@
#ifndef WEBKIT_APPCACHE_APPCACHE_STORAGE_IMPL_H_
#define WEBKIT_APPCACHE_APPCACHE_STORAGE_IMPL_H_
-#include <deque>
-#include <map>
-#include <set>
-#include <vector>
-
#include "base/file_path.h"
-#include "net/disk_cache/disk_cache.h"
-#include "webkit/appcache/appcache_database.h"
-#include "webkit/appcache/appcache_storage.h"
+#include "webkit/appcache/mock_appcache_storage.h"
namespace appcache {
-class AppCacheStorageImpl : public AppCacheStorage {
+// TODO(michaeln): write me, for now we derive from 'mock' storage.
+class AppCacheStorageImpl : public MockAppCacheStorage {
public:
- explicit AppCacheStorageImpl(AppCacheService* service);
- virtual ~AppCacheStorageImpl();
+ explicit AppCacheStorageImpl(AppCacheService* service)
+ : MockAppCacheStorage(service), is_incognito_(false) {}
void Initialize(const FilePath& cache_directory);
- // AppCacheStorage methods
- virtual void LoadCache(int64 id, Delegate* delegate);
- virtual void LoadOrCreateGroup(const GURL& manifest_url, Delegate* delegate);
- virtual void StoreGroupAndNewestCache(
- AppCacheGroup* group, AppCache* newest_cache, Delegate* delegate);
- virtual void FindResponseForMainRequest(const GURL& url, Delegate* delegate);
- virtual void FindResponseForSubRequest(
- AppCache* cache, const GURL& url,
- AppCacheEntry* found_entry, AppCacheEntry* found_fallback_entry,
- bool* found_network_namespace);
- virtual void MarkEntryAsForeign(const GURL& entry_url, int64 cache_id);
- virtual void MakeGroupObsolete(AppCacheGroup* group, Delegate* delegate);
- virtual AppCacheResponseReader* CreateResponseReader(
- const GURL& manifest_url, int64 response_id);
- virtual AppCacheResponseWriter* CreateResponseWriter(
- const GURL& manifest_url);
- virtual void DoomResponses(
- const GURL& manifest_url, const std::vector<int64>& response_ids);
-
private:
- friend class AppCacheStorageImplTest;
-
- // A handful of tasks used to perform database operations on the
- // background database thread.
- class DatabaseTask;
- class InitTask;
- class CloseConnectionTask;
- class StoreOrLoadTask;
- class CacheLoadTask;
- class GroupLoadTask;
- class StoreGroupAndCacheTask;
- class FindMainResponseTask;
- class MarkEntryAsForeignTask;
- class MakeGroupObsoleteTask;
-
- typedef std::deque<DatabaseTask*> DatabaseTaskQueue;
- typedef std::map<int64, CacheLoadTask*> PendingCacheLoads;
- typedef std::map<GURL, GroupLoadTask*> PendingGroupLoads;
- typedef std::deque<std::pair<GURL, int64> > PendingForeignMarkings;
-
- CacheLoadTask* GetPendingCacheLoadTask(int64 cache_id);
- GroupLoadTask* GetPendingGroupLoadTask(const GURL& manifest_url);
- void GetPendingForeignMarkingsForCache(
- int64 cache_id, std::vector<GURL>* urls);
-
- void ScheduleSimpleTask(Task* task);
- void RunOnePendingSimpleTask();
-
- // Sometimes we can respond without having to query the database.
- void DeliverShortCircuitedFindMainResponse(
- const GURL& url, AppCacheEntry found_entry,
- scoped_refptr<AppCacheGroup> group, scoped_refptr<AppCache> newest_cache,
- scoped_refptr<DelegateReference> delegate_ref);
-
- disk_cache::Backend* disk_cache();
-
- // The directory in which we place files in the file system.
- FilePath cache_directory_;
bool is_incognito_;
-
- // Structures to keep track of DatabaseTasks that are in-flight.
- DatabaseTaskQueue scheduled_database_tasks_;
- PendingCacheLoads pending_cache_loads_;
- PendingGroupLoads pending_group_loads_;
- PendingForeignMarkings pending_foreign_markings_;
-
- // Created on the IO thread, but only used on the DB thread.
- AppCacheDatabase* database_;
-
- // TODO(michaeln): use a disk_cache per group (manifest or group_id).
- scoped_ptr<disk_cache::Backend> disk_cache_;
-
- // Used to short-circuit certain operations without having to schedule
- // any tasks on the background database thread.
- std::set<GURL> origins_with_groups_;
- std::deque<Task*> pending_simple_tasks_;
- ScopedRunnableMethodFactory<AppCacheStorageImpl> method_factory_;
+ FilePath cache_directory_;
};
} // namespace appcache
diff --git a/webkit/appcache/appcache_storage_impl_unittest.cc b/webkit/appcache/appcache_storage_impl_unittest.cc
deleted file mode 100644
index 1db4aa8..0000000
--- a/webkit/appcache/appcache_storage_impl_unittest.cc
+++ /dev/null
@@ -1,1007 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/message_loop.h"
-#include "base/thread.h"
-#include "base/waitable_event.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "webkit/appcache/appcache.h"
-#include "webkit/appcache/appcache_database.h"
-#include "webkit/appcache/appcache_entry.h"
-#include "webkit/appcache/appcache_group.h"
-#include "webkit/appcache/appcache_service.h"
-#include "webkit/appcache/appcache_storage_impl.h"
-#include "webkit/tools/test_shell/simple_appcache_system.h"
-
-namespace appcache {
-
-namespace {
-
-const base::TimeTicks kZeroTimeTicks;
-const GURL kManifestUrl("http://blah/manifest");
-const GURL kManifestUrl2("http://blah/manifest2");
-const GURL kEntryUrl("http://blah/entry");
-const GURL kEntryUrl2("http://blah/entry2");
-const GURL kFallbackNamespace("http://blah/fallback_namespace/");
-const GURL kFallbackNamespace2("http://blah/fallback_namespace/longer");
-const GURL kFallbackTestUrl("http://blah/fallback_namespace/longer/test");
-const GURL kOnlineNamespace("http://blah/online_namespace");
-
-// For the duration of this test case, we hijack the AppCacheThread API
-// calls and implement them in terms of the io and db threads created here.
-
-scoped_ptr<base::Thread> io_thread;
-scoped_ptr<base::Thread> db_thread;
-
-class TestThreadProvider : public SimpleAppCacheSystem::ThreadProvider {
- public:
- virtual bool PostTask(
- int id,
- const tracked_objects::Location& from_here,
- Task* task) {
- GetMessageLoop(id)->PostTask(from_here, task);
- return true;
- }
-
- virtual bool CurrentlyOn(int id) {
- return MessageLoop::current() == GetMessageLoop(id);
- }
-
- MessageLoop* GetMessageLoop(int id) {
- DCHECK(io_thread.get() && db_thread.get());
- if (id == SimpleAppCacheSystem::IO_THREAD_ID)
- return io_thread->message_loop();
- if (id == SimpleAppCacheSystem::DB_THREAD_ID)
- return db_thread->message_loop();
- NOTREACHED() << "Invalid AppCacheThreadID value";
- return NULL;
- }
-};
-
-TestThreadProvider thread_provider;
-
-} // namespace
-
-class AppCacheStorageImplTest : public testing::Test {
- public:
- class MockStorageDelegate : public AppCacheStorage::Delegate {
- public:
- explicit MockStorageDelegate(AppCacheStorageImplTest* test)
- : loaded_cache_id_(0), stored_group_success_(false),
- obsoleted_success_(false), found_cache_id_(kNoCacheId),
- test_(test) {
- }
-
- void OnCacheLoaded(AppCache* cache, int64 cache_id) {
- loaded_cache_ = cache;
- loaded_cache_id_ = cache_id;
- test_->ScheduleNextTask();
- }
-
- void OnGroupLoaded(AppCacheGroup* group, const GURL& manifest_url) {
- loaded_group_ = group;
- loaded_manifest_url_ = manifest_url;
- loaded_groups_newest_cache_ = group ? group->newest_complete_cache()
- : NULL;
- test_->ScheduleNextTask();
- }
-
- void OnGroupAndNewestCacheStored(AppCacheGroup* group, bool success) {
- stored_group_ = group;
- stored_group_success_ = success;
- test_->ScheduleNextTask();
- }
-
- void OnGroupMadeObsolete(AppCacheGroup* group, bool success) {
- obsoleted_group_ = group;
- obsoleted_success_ = success;
- test_->ScheduleNextTask();
- }
-
- void OnMainResponseFound(const GURL& url, const AppCacheEntry& entry,
- const AppCacheEntry& fallback_entry,
- int64 cache_id, const GURL& manifest_url) {
- found_url_ = url;
- found_entry_ = entry;
- found_fallback_entry_ = fallback_entry;
- found_cache_id_ = cache_id;
- found_manifest_url_ = manifest_url;
- test_->ScheduleNextTask();
- }
-
- scoped_refptr<AppCache> loaded_cache_;
- int64 loaded_cache_id_;
- scoped_refptr<AppCacheGroup> loaded_group_;
- GURL loaded_manifest_url_;
- scoped_refptr<AppCache> loaded_groups_newest_cache_;
- scoped_refptr<AppCacheGroup> stored_group_;
- bool stored_group_success_;
- scoped_refptr<AppCacheGroup> obsoleted_group_;
- bool obsoleted_success_;
- GURL found_url_;
- AppCacheEntry found_entry_;
- AppCacheEntry found_fallback_entry_;
- int64 found_cache_id_;
- GURL found_manifest_url_;
- AppCacheStorageImplTest* test_;
- };
-
- // Helper class run a test on our io_thread. The io_thread
- // is spun up once and reused for all tests.
- template <class Method>
- class WrapperTask : public Task {
- public:
- WrapperTask(AppCacheStorageImplTest* test, Method method)
- : test_(test), method_(method) {
- }
-
- virtual void Run() {
- test_->SetUpTest();
-
- // Ensure InitTask execution prior to conducting a test.
- test_->FlushDbThreadTasks();
-
- // We also have to wait for InitTask completion call to be performed
- // on the IO thread prior to running the test. Its guaranteed to be
- // queued by this time.
- MessageLoop::current()->PostTask(FROM_HERE,
- NewRunnableFunction(&RunMethod, test_, method_));
- }
-
- static void RunMethod(AppCacheStorageImplTest* test, Method method) {
- (test->*method)();
- }
-
- private:
- AppCacheStorageImplTest* test_;
- Method method_;
- };
-
-
- static void SetUpTestCase() {
- io_thread.reset(new base::Thread("AppCacheTest.IOThread"));
- base::Thread::Options options(MessageLoop::TYPE_IO, 0);
- ASSERT_TRUE(io_thread->StartWithOptions(options));
-
- db_thread.reset(new base::Thread("AppCacheTest::DBThread"));
- ASSERT_TRUE(db_thread->Start());
-
- SimpleAppCacheSystem::set_thread_provider(&thread_provider);
- }
-
- static void TearDownTestCase() {
- SimpleAppCacheSystem::set_thread_provider(NULL);
- io_thread.reset(NULL);
- db_thread.reset(NULL);
- }
-
- // Test harness --------------------------------------------------
-
- AppCacheStorageImplTest()
- : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
- }
-
- template <class Method>
- void RunTestOnIOThread(Method method) {
- test_finished_event_ .reset(new base::WaitableEvent(false, false));
- io_thread->message_loop()->PostTask(
- FROM_HERE, new WrapperTask<Method>(this, method));
- test_finished_event_->Wait();
- }
-
- void SetUpTest() {
- DCHECK(MessageLoop::current() == io_thread->message_loop());
- service_.reset(new AppCacheService);
- service_->Initialize(FilePath());
- delegate_.reset(new MockStorageDelegate(this));
- }
-
- void TearDownTest() {
- DCHECK(MessageLoop::current() == io_thread->message_loop());
- storage()->CancelDelegateCallbacks(delegate());
- group_ = NULL;
- cache_ = NULL;
- cache2_ = NULL;
- delegate_.reset();
- service_.reset();
- FlushDbThreadTasks();
- }
-
- void TestFinished() {
- // We unwind the stack prior to finishing up to let stack
- // based objects get deleted.
- DCHECK(MessageLoop::current() == io_thread->message_loop());
- MessageLoop::current()->PostTask(FROM_HERE,
- method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::TestFinishedUnwound));
- }
-
- void TestFinishedUnwound() {
- TearDownTest();
- test_finished_event_->Signal();
- }
-
- void PushNextTask(Task* task) {
- task_stack_.push(task);
- }
-
- void ScheduleNextTask() {
- DCHECK(MessageLoop::current() == io_thread->message_loop());
- if (task_stack_.empty()) {
- return;
- }
- MessageLoop::current()->PostTask(FROM_HERE, task_stack_.top());
- task_stack_.pop();
- }
-
- static void SignalEvent(base::WaitableEvent* event) {
- event->Signal();
- }
-
- void FlushDbThreadTasks() {
- // We pump a task thru the db thread to ensure any tasks previously
- // scheduled on that thread have been performed prior to return.
- base::WaitableEvent event(false, false);
- db_thread->message_loop()->PostTask(FROM_HERE,
- NewRunnableFunction(&AppCacheStorageImplTest::SignalEvent,
- &event));
- event.Wait();
- }
-
- // LoadCache_Miss ----------------------------------------------------
-
- void LoadCache_Miss() {
- // Attempt to load a cache that doesn't exist. Should
- // complete asyncly.
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_LoadCache_Miss));
-
- storage()->LoadCache(111, delegate());
- EXPECT_NE(111, delegate()->loaded_cache_id_);
- }
-
- void Verify_LoadCache_Miss() {
- EXPECT_EQ(111, delegate()->loaded_cache_id_);
- EXPECT_FALSE(delegate()->loaded_cache_);
- TestFinished();
- }
-
- // LoadCache_NearHit -------------------------------------------------
-
- void LoadCache_NearHit() {
- // Attempt to load a cache that is currently in use
- // and does not require loading from storage. This
- // load should complete syncly.
-
- // Setup some preconditions. Make an 'unstored' cache for
- // us to load. The ctor should put it in the working set.
- int64 cache_id = storage()->NewCacheId();
- scoped_refptr<AppCache> cache = new AppCache(service(), cache_id);
-
- // Conduct the test.
- storage()->LoadCache(cache_id, delegate());
- EXPECT_EQ(cache_id, delegate()->loaded_cache_id_);
- EXPECT_EQ(cache.get(), delegate()->loaded_cache_.get());
- TestFinished();
- }
-
- // CreateGroup --------------------------------------------
-
- void CreateGroupInEmptyOrigin() {
- // Attempt to load a group that doesn't exist, one should
- // be created for us, but not stored.
-
- // Since the origin has no groups, the storage class will respond
- // syncly.
- storage()->LoadOrCreateGroup(kManifestUrl, delegate());
- Verify_CreateGroup();
- }
-
- void CreateGroupInPopulatedOrigin() {
- // Attempt to load a group that doesn't exist, one should
- // be created for us, but not stored.
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_CreateGroup));
-
- // Since the origin has groups, storage class will have to
- // consult the database and completion will be async.
- storage()->origins_with_groups_.insert(kManifestUrl.GetOrigin());
-
- storage()->LoadOrCreateGroup(kManifestUrl, delegate());
- EXPECT_FALSE(delegate()->loaded_group_.get());
- }
-
- void Verify_CreateGroup() {
- EXPECT_EQ(kManifestUrl, delegate()->loaded_manifest_url_);
- EXPECT_TRUE(delegate()->loaded_group_.get());
- EXPECT_TRUE(delegate()->loaded_group_->HasOneRef());
- EXPECT_FALSE(delegate()->loaded_group_->newest_complete_cache());
-
- // Should not have been stored in the database.
- AppCacheDatabase::GroupRecord record;
- EXPECT_FALSE(database()->FindGroup(
- delegate()->loaded_group_->group_id(), &record));
-
- TestFinished();
- }
-
- // LoadGroupAndCache_FarHit --------------------------------------
-
- void LoadGroupAndCache_FarHit() {
- // Attempt to load a cache that is not currently in use
- // and does require loading from disk. This
- // load should complete asyncly.
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_LoadCache_Far_Hit));
-
- // Setup some preconditions. Create a group and newest cache that
- // appear to be "stored" and "not currently in use".
- MakeCacheAndGroup(kManifestUrl, 1, 1, true);
- group_ = NULL;
- cache_ = NULL;
-
- // Conduct the cache load test, completes async
- storage()->LoadCache(1, delegate());
- }
-
- void Verify_LoadCache_Far_Hit() {
- EXPECT_TRUE(delegate()->loaded_cache_);
- EXPECT_TRUE(delegate()->loaded_cache_->HasOneRef());
- EXPECT_EQ(1, delegate()->loaded_cache_id_);
-
- // The group should also have been loaded.
- EXPECT_TRUE(delegate()->loaded_cache_->owning_group());
- EXPECT_TRUE(delegate()->loaded_cache_->owning_group()->HasOneRef());
- EXPECT_EQ(1, delegate()->loaded_cache_->owning_group()->group_id());
-
- // Drop things from the working set.
- delegate()->loaded_cache_ = NULL;
- EXPECT_FALSE(delegate()->loaded_group_);
-
- // Conduct the group load test, also complete asyncly.
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_LoadGroup_Far_Hit));
-
- storage()->LoadOrCreateGroup(kManifestUrl, delegate());
- }
-
- void Verify_LoadGroup_Far_Hit() {
- EXPECT_TRUE(delegate()->loaded_group_);
- EXPECT_EQ(kManifestUrl, delegate()->loaded_manifest_url_);
- EXPECT_TRUE(delegate()->loaded_group_->newest_complete_cache());
- delegate()->loaded_groups_newest_cache_ = NULL;
- EXPECT_TRUE(delegate()->loaded_group_->HasOneRef());
- TestFinished();
- }
-
- // StoreNewGroup --------------------------------------
-
- void StoreNewGroup() {
- // Store a group and its newest cache. Should complete asyncly.
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_StoreNewGroup));
-
- // Setup some preconditions. Create a group and newest cache that
- // appear to be "unstored".
- group_ = new AppCacheGroup(
- service(), kManifestUrl, storage()->NewGroupId());
- cache_ = new AppCache(service(), storage()->NewCacheId());
- cache_->set_complete(true);
- // Hold a ref to the cache simulate the UpdateJob holding that ref,
- // and hold a ref to the group to simulate the CacheHost holding that ref.
-
- // Conduct the store test.
- storage()->StoreGroupAndNewestCache(group_, cache_, delegate());
- EXPECT_FALSE(delegate()->stored_group_success_);
- }
-
- void Verify_StoreNewGroup() {
- EXPECT_TRUE(delegate()->stored_group_success_);
- EXPECT_EQ(group_.get(), delegate()->stored_group_.get());
- EXPECT_EQ(cache_.get(), group_->newest_complete_cache());
-
- // Should have been stored in the database.
- AppCacheDatabase::GroupRecord group_record;
- AppCacheDatabase::CacheRecord cache_record;
- EXPECT_TRUE(database()->FindGroup(group_->group_id(), &group_record));
- EXPECT_TRUE(database()->FindCache(cache_->cache_id(), &cache_record));
- TestFinished();
- }
-
- // StoreExistingGroup --------------------------------------
-
- void StoreExistingGroup() {
- // Store a group and its newest cache. Should complete asyncly.
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_StoreExistingGroup));
-
- // Setup some preconditions. Create a group and old complete cache
- // that appear to be "stored"
- MakeCacheAndGroup(kManifestUrl, 1, 1, true);
-
- // And a newest unstored complete cache.
- cache2_ = new AppCache(service(), 2);
- cache2_->set_complete(true);
-
- // Conduct the test.
- storage()->StoreGroupAndNewestCache(group_, cache2_, delegate());
- EXPECT_FALSE(delegate()->stored_group_success_);
- }
-
- void Verify_StoreExistingGroup() {
- EXPECT_TRUE(delegate()->stored_group_success_);
- EXPECT_EQ(group_.get(), delegate()->stored_group_.get());
- EXPECT_EQ(cache2_.get(), group_->newest_complete_cache());
-
- // The new cache should have been stored in the database.
- AppCacheDatabase::GroupRecord group_record;
- AppCacheDatabase::CacheRecord cache_record;
- EXPECT_TRUE(database()->FindGroup(1, &group_record));
- EXPECT_TRUE(database()->FindCache(2, &cache_record));
-
- // The old cache should have been deleted
- EXPECT_FALSE(database()->FindCache(1, &cache_record));
- TestFinished();
- }
-
- // StoreExistingGroupExistingCache -------------------------------
-
- void StoreExistingGroupExistingCache() {
- // Store a group with updates to its existing newest complete cache.
- // Setup some preconditions. Create a group and a complete cache that
- // appear to be "stored".
-
- // Setup some preconditions. Create a group and old complete cache
- // that appear to be "stored"
- MakeCacheAndGroup(kManifestUrl, 1, 1, true);
-
- // Change the cache.
- base::TimeTicks now = base::TimeTicks::Now();
- cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::MASTER));
- cache_->set_update_time(now);
-
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_StoreExistingGroupExistingCache,
- now));
-
- // Conduct the test.
- EXPECT_EQ(cache_, group_->newest_complete_cache());
- storage()->StoreGroupAndNewestCache(group_, cache_, delegate());
- EXPECT_FALSE(delegate()->stored_group_success_);
- }
-
- void Verify_StoreExistingGroupExistingCache(
- base::TimeTicks expected_update_time) {
- EXPECT_TRUE(delegate()->stored_group_success_);
- EXPECT_EQ(cache_, group_->newest_complete_cache());
-
- AppCacheDatabase::CacheRecord cache_record;
- EXPECT_TRUE(database()->FindCache(1, &cache_record));
- EXPECT_EQ(1, cache_record.cache_id);
- EXPECT_EQ(1, cache_record.group_id);
- EXPECT_FALSE(cache_record.online_wildcard);
- EXPECT_TRUE(expected_update_time == cache_record.update_time);
-
- std::vector<AppCacheDatabase::EntryRecord> entry_records;
- EXPECT_TRUE(database()->FindEntriesForCache(1, &entry_records));
- EXPECT_EQ(1U, entry_records.size());
- EXPECT_EQ(1 , entry_records[0].cache_id);
- EXPECT_EQ(kEntryUrl, entry_records[0].url);
- EXPECT_EQ(AppCacheEntry::MASTER, entry_records[0].flags);
- EXPECT_EQ(0, entry_records[0].response_id);
-
- TestFinished();
- }
-
- // MakeGroupObsolete -------------------------------
-
- void MakeGroupObsolete() {
- // Make a group obsolete, should complete asyncly.
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_MakeGroupObsolete));
-
- // Setup some preconditions. Create a group and newest cache that
- // appears to be "stored" and "currently in use".
- MakeCacheAndGroup(kManifestUrl, 1, 1, true);
- EXPECT_FALSE(storage()->origins_with_groups_.empty());
-
- // Also insert some related records.
- AppCacheDatabase::EntryRecord entry_record;
- entry_record.cache_id = 1;
- entry_record.flags = AppCacheEntry::FALLBACK;
- entry_record.response_id = 1;
- entry_record.url = kEntryUrl;
- EXPECT_TRUE(database()->InsertEntry(&entry_record));
-
- AppCacheDatabase::FallbackNameSpaceRecord fallback_namespace_record;
- fallback_namespace_record.cache_id = 1;
- fallback_namespace_record.fallback_entry_url = kEntryUrl;
- fallback_namespace_record.namespace_url = kFallbackNamespace;
- fallback_namespace_record.origin = kManifestUrl.GetOrigin();
- EXPECT_TRUE(
- database()->InsertFallbackNameSpace(&fallback_namespace_record));
-
- AppCacheDatabase::OnlineWhiteListRecord online_whitelist_record;
- online_whitelist_record.cache_id = 1;
- online_whitelist_record.namespace_url = kOnlineNamespace;
- EXPECT_TRUE(database()->InsertOnlineWhiteList(&online_whitelist_record));
-
- // Conduct the test.
- storage()->MakeGroupObsolete(group_, delegate());
- EXPECT_FALSE(group_->is_obsolete());
- }
-
- void Verify_MakeGroupObsolete() {
- EXPECT_TRUE(delegate()->obsoleted_success_);
- EXPECT_EQ(group_.get(), delegate()->obsoleted_group_.get());
- EXPECT_TRUE(group_->is_obsolete());
- EXPECT_TRUE(storage()->origins_with_groups_.empty());
-
- // The cache and group have been deleted from the database.
- AppCacheDatabase::GroupRecord group_record;
- AppCacheDatabase::CacheRecord cache_record;
- EXPECT_FALSE(database()->FindGroup(1, &group_record));
- EXPECT_FALSE(database()->FindCache(1, &cache_record));
-
- // The related records should have been deleted too.
- std::vector<AppCacheDatabase::EntryRecord> entry_records;
- database()->FindEntriesForCache(1, &entry_records);
- EXPECT_TRUE(entry_records.empty());
- std::vector<AppCacheDatabase::FallbackNameSpaceRecord> fallback_records;
- database()->FindFallbackNameSpacesForCache(1, &fallback_records);
- EXPECT_TRUE(fallback_records.empty());
- std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelist_records;
- database()->FindOnlineWhiteListForCache(1, &whitelist_records);
- EXPECT_TRUE(whitelist_records.empty());
-
- TestFinished();
- }
-
- // MarkEntryAsForeign -------------------------------
-
- void MarkEntryAsForeign() {
- // Setup some preconditions. Create a cache with an entry
- // in storage and in the working set.
- MakeCacheAndGroup(kManifestUrl, 1, 1, true);
- cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT));
- AppCacheDatabase::EntryRecord entry_record;
- entry_record.cache_id = 1;
- entry_record.url = kEntryUrl;
- entry_record.flags = AppCacheEntry::EXPLICIT;
- entry_record.response_id = 0;
- EXPECT_TRUE(database()->InsertEntry(&entry_record));
- EXPECT_FALSE(cache_->GetEntry(kEntryUrl)->IsForeign());
-
- // Conduct the test.
- storage()->MarkEntryAsForeign(kEntryUrl, 1);
-
- // The entry in the working set should have been updated syncly.
- EXPECT_TRUE(cache_->GetEntry(kEntryUrl)->IsForeign());
- EXPECT_TRUE(cache_->GetEntry(kEntryUrl)->IsExplicit());
-
- // And the entry in storage should also be updated, but that
- // happens asyncly on the db thread.
- FlushDbThreadTasks();
- AppCacheDatabase::EntryRecord entry_record2;
- EXPECT_TRUE(database()->FindEntry(1, kEntryUrl, &entry_record2));
- EXPECT_EQ(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN,
- entry_record2.flags);
- TestFinished();
- }
-
- // MarkEntryAsForeignWithLoadInProgress -------------------------------
-
- void MarkEntryAsForeignWithLoadInProgress() {
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_MarkEntryAsForeignWithLoadInProgress));
-
- // Setup some preconditions. Create a cache with an entry
- // in storage, but not in the working set.
- MakeCacheAndGroup(kManifestUrl, 1, 1, true);
- cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT));
- AppCacheDatabase::EntryRecord entry_record;
- entry_record.cache_id = 1;
- entry_record.url = kEntryUrl;
- entry_record.flags = AppCacheEntry::EXPLICIT;
- entry_record.response_id = 0;
- EXPECT_TRUE(database()->InsertEntry(&entry_record));
- EXPECT_FALSE(cache_->GetEntry(kEntryUrl)->IsForeign());
- EXPECT_TRUE(cache_->HasOneRef());
- cache_ = NULL;
- group_ = NULL;
-
- // Conduct the test, start a cache load, and prior to completion
- // of that load, mark the entry as foreign.
- storage()->LoadCache(1, delegate());
- storage()->MarkEntryAsForeign(kEntryUrl, 1);
- }
-
- void Verify_MarkEntryAsForeignWithLoadInProgress() {
- EXPECT_EQ(1, delegate()->loaded_cache_id_);
- EXPECT_TRUE(delegate()->loaded_cache_.get());
-
- // The entry in the working set should have been updated upon load.
- EXPECT_TRUE(delegate()->loaded_cache_->GetEntry(kEntryUrl)->IsForeign());
- EXPECT_TRUE(delegate()->loaded_cache_->GetEntry(kEntryUrl)->IsExplicit());
-
- // And the entry in storage should also be updated.
- FlushDbThreadTasks();
- AppCacheDatabase::EntryRecord entry_record;
- EXPECT_TRUE(database()->FindEntry(1, kEntryUrl, &entry_record));
- EXPECT_EQ(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN,
- entry_record.flags);
- TestFinished();
- }
-
- // FindNoMainResponse -------------------------------
-
- void FindNoMainResponse() {
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_FindNoMainResponse));
-
- // Conduct the test.
- storage()->FindResponseForMainRequest(kEntryUrl, delegate());
- EXPECT_NE(kEntryUrl, delegate()->found_url_);
- }
-
- void Verify_FindNoMainResponse() {
- EXPECT_EQ(kEntryUrl, delegate()->found_url_);
- EXPECT_TRUE(delegate()->found_manifest_url_.is_empty());
- EXPECT_EQ(kNoCacheId, delegate()->found_cache_id_);
- EXPECT_EQ(kNoResponseId, delegate()->found_entry_.response_id());
- EXPECT_EQ(kNoResponseId, delegate()->found_fallback_entry_.response_id());
- EXPECT_EQ(0, delegate()->found_entry_.types());
- EXPECT_EQ(0, delegate()->found_fallback_entry_.types());
- TestFinished();
- }
-
- // BasicFindMainResponse -------------------------------
-
- void BasicFindMainResponseInDatabase() {
- BasicFindMainResponse(true);
- }
-
- void BasicFindMainResponseInWorkingSet() {
- BasicFindMainResponse(false);
- }
-
- void BasicFindMainResponse(bool drop_from_working_set) {
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_BasicFindMainResponse));
-
- // Setup some preconditions. Create a complete cache with an entry
- // in storage.
- MakeCacheAndGroup(kManifestUrl, 1, 1, true);
- cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, 1));
- AppCacheDatabase::EntryRecord entry_record;
- entry_record.cache_id = 1;
- entry_record.url = kEntryUrl;
- entry_record.flags = AppCacheEntry::EXPLICIT;
- entry_record.response_id = 1;
- EXPECT_TRUE(database()->InsertEntry(&entry_record));
-
- // Optionally drop the cache/group pair from the working set.
- if (drop_from_working_set) {
- EXPECT_TRUE(cache_->HasOneRef());
- cache_ = NULL;
- EXPECT_TRUE(group_->HasOneRef());
- group_ = NULL;
- }
-
- // Conduct the test.
- storage()->FindResponseForMainRequest(kEntryUrl, delegate());
- EXPECT_NE(kEntryUrl, delegate()->found_url_);
- }
-
- void Verify_BasicFindMainResponse() {
- EXPECT_EQ(kEntryUrl, delegate()->found_url_);
- EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_);
- EXPECT_EQ(1, delegate()->found_cache_id_);
- EXPECT_EQ(1, delegate()->found_entry_.response_id());
- EXPECT_TRUE(delegate()->found_entry_.IsExplicit());
- EXPECT_FALSE(delegate()->found_fallback_entry_.has_response_id());
- TestFinished();
- }
-
- // BasicFindMainFallbackResponse -------------------------------
-
- void BasicFindMainFallbackResponseInDatabase() {
- BasicFindMainFallbackResponse(true);
- }
-
- void BasicFindMainFallbackResponseInWorkingSet() {
- BasicFindMainFallbackResponse(false);
- }
-
- void BasicFindMainFallbackResponse(bool drop_from_working_set) {
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_BasicFindMainFallbackResponse));
-
- // Setup some preconditions. Create a complete cache with a
- // fallback namespace and entry.
- MakeCacheAndGroup(kManifestUrl, 1, 1, true);
- cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::FALLBACK, 1));
- cache_->AddEntry(kEntryUrl2, AppCacheEntry(AppCacheEntry::FALLBACK, 2));
- cache_->fallback_namespaces_.push_back(
- FallbackNamespace(kFallbackNamespace2, kEntryUrl2));
- cache_->fallback_namespaces_.push_back(
- FallbackNamespace(kFallbackNamespace, kEntryUrl));
- AppCacheDatabase::CacheRecord cache_record;
- std::vector<AppCacheDatabase::EntryRecord> entries;
- std::vector<AppCacheDatabase::FallbackNameSpaceRecord> fallbacks;
- std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelists;
- cache_->ToDatabaseRecords(group_,
- &cache_record, &entries, &fallbacks, &whitelists);
- EXPECT_TRUE(database()->InsertEntryRecords(entries));
- EXPECT_TRUE(database()->InsertFallbackNameSpaceRecords(fallbacks));
- EXPECT_TRUE(database()->InsertOnlineWhiteListRecords(whitelists));
- if (drop_from_working_set) {
- EXPECT_TRUE(cache_->HasOneRef());
- cache_ = NULL;
- EXPECT_TRUE(group_->HasOneRef());
- group_ = NULL;
- }
-
- // Conduct the test. The test url is in both fallback namespace urls,
- // but should match the longer of the two.
- storage()->FindResponseForMainRequest(kFallbackTestUrl, delegate());
- EXPECT_NE(kFallbackTestUrl, delegate()->found_url_);
- }
-
- void Verify_BasicFindMainFallbackResponse() {
- EXPECT_EQ(kFallbackTestUrl, delegate()->found_url_);
- EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_);
- EXPECT_EQ(1, delegate()->found_cache_id_);
- EXPECT_FALSE(delegate()->found_entry_.has_response_id());
- EXPECT_EQ(2, delegate()->found_fallback_entry_.response_id());
- EXPECT_TRUE(delegate()->found_fallback_entry_.IsFallback());
- TestFinished();
- }
-
- // FindMainResponseWithMultipleHits -------------------------------
-
- void FindMainResponseWithMultipleHits() {
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_FindMainResponseWithMultipleHits));
-
- // Setup some preconditions. Create 2 complete caches with an entry
- // for the same url.
-
- // The first cache, in the database but not in the working set.
- MakeCacheAndGroup(kManifestUrl, 1, 1, true);
- cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, 1));
- AppCacheDatabase::EntryRecord entry_record;
- entry_record.cache_id = 1;
- entry_record.url = kEntryUrl;
- entry_record.flags = AppCacheEntry::EXPLICIT;
- entry_record.response_id = 1;
- EXPECT_TRUE(database()->InsertEntry(&entry_record));
- cache_ = NULL;
- group_ = NULL;
-
- // The second cache, in the database and working set.
- MakeCacheAndGroup(kManifestUrl2, 2, 2, true);
- cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, 2));
- entry_record.cache_id = 2;
- entry_record.url = kEntryUrl;
- entry_record.flags = AppCacheEntry::EXPLICIT;
- entry_record.response_id = 2;
- EXPECT_TRUE(database()->InsertEntry(&entry_record));
-
- // Conduct the test, we should find the response from the second cache
- // since it's "in use".
- storage()->FindResponseForMainRequest(kEntryUrl, delegate());
- EXPECT_NE(kEntryUrl, delegate()->found_url_);
- }
-
- void Verify_FindMainResponseWithMultipleHits() {
- EXPECT_EQ(kEntryUrl, delegate()->found_url_);
- EXPECT_EQ(kManifestUrl2, delegate()->found_manifest_url_);
- EXPECT_EQ(2, delegate()->found_cache_id_);
- EXPECT_EQ(2, delegate()->found_entry_.response_id());
- EXPECT_TRUE(delegate()->found_entry_.IsExplicit());
- EXPECT_FALSE(delegate()->found_fallback_entry_.has_response_id());
- TestFinished();
- }
-
- // FindMainResponseExclusions -------------------------------
-
- void FindMainResponseExclusionsInDatabase() {
- FindMainResponseExclusions(true);
- }
-
- void FindMainResponseExclusionsInWorkingSet() {
- FindMainResponseExclusions(false);
- }
-
- void FindMainResponseExclusions(bool drop_from_working_set) {
- // Setup some preconditions. Create a complete cache with a
- // foreign entry and an online namespace.
- MakeCacheAndGroup(kManifestUrl, 1, 1, true);
- cache_->AddEntry(kEntryUrl,
- AppCacheEntry(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN, 1));
- cache_->online_whitelist_namespaces_.push_back(kOnlineNamespace);
- AppCacheDatabase::EntryRecord entry_record;
- entry_record.cache_id = 1;
- entry_record.url = kEntryUrl;
- entry_record.flags = AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN;
- entry_record.response_id = 1;
- EXPECT_TRUE(database()->InsertEntry(&entry_record));
- AppCacheDatabase::OnlineWhiteListRecord whitelist_record;
- whitelist_record.cache_id = 1;
- whitelist_record.namespace_url = kOnlineNamespace;
- EXPECT_TRUE(database()->InsertOnlineWhiteList(&whitelist_record));
- if (drop_from_working_set) {
- cache_ = NULL;
- group_ = NULL;
- }
-
- // We should not find anything for the foreign entry.
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_NotFound, kEntryUrl, false));
- storage()->FindResponseForMainRequest(kEntryUrl, delegate());
- }
-
- void Verify_NotFound(GURL expected_url, bool test_finished) {
- EXPECT_EQ(expected_url, delegate()->found_url_);
- EXPECT_TRUE(delegate()->found_manifest_url_.is_empty());
- EXPECT_EQ(kNoCacheId, delegate()->found_cache_id_);
- EXPECT_EQ(kNoResponseId, delegate()->found_entry_.response_id());
- EXPECT_EQ(kNoResponseId, delegate()->found_fallback_entry_.response_id());
- EXPECT_EQ(0, delegate()->found_entry_.types());
- EXPECT_EQ(0, delegate()->found_fallback_entry_.types());
-
- if (!test_finished) {
- // We should not find anything for the online namespace.
- PushNextTask(method_factory_.NewRunnableMethod(
- &AppCacheStorageImplTest::Verify_NotFound, kOnlineNamespace, true));
- storage()->FindResponseForMainRequest(kOnlineNamespace, delegate());
- return;
- }
-
- TestFinished();
- }
-
- // Test case helpers --------------------------------------------------
-
- AppCacheService* service() {
- return service_.get();
- }
-
- AppCacheStorageImpl* storage() {
- return static_cast<AppCacheStorageImpl*>(service()->storage());
- }
-
- AppCacheDatabase* database() {
- return storage()->database_;
- }
-
- MockStorageDelegate* delegate() {
- return delegate_.get();
- }
-
- void MakeCacheAndGroup(
- const GURL& manifest_url, int64 group_id, int64 cache_id,
- bool add_to_database) {
- group_ = new AppCacheGroup(service(), manifest_url, group_id);
- cache_ = new AppCache(service(), cache_id);
- cache_->set_complete(true);
- group_->AddCache(cache_);
- if (add_to_database) {
- AppCacheDatabase::GroupRecord group_record;
- group_record.group_id = group_id;
- group_record.manifest_url = manifest_url;
- group_record.origin = manifest_url.GetOrigin();
- EXPECT_TRUE(database()->InsertGroup(&group_record));
- AppCacheDatabase::CacheRecord cache_record;
- cache_record.cache_id = cache_id;
- cache_record.group_id = group_id;
- cache_record.online_wildcard = false;
- cache_record.update_time = kZeroTimeTicks;
- EXPECT_TRUE(database()->InsertCache(&cache_record));
- storage()->origins_with_groups_.insert(manifest_url.GetOrigin());
- }
- }
-
- // Data members --------------------------------------------------
-
- ScopedRunnableMethodFactory<AppCacheStorageImplTest> method_factory_;
- scoped_ptr<base::WaitableEvent> test_finished_event_;
- std::stack<Task*> task_stack_;
- scoped_ptr<AppCacheService> service_;
- scoped_ptr<MockStorageDelegate> delegate_;
- scoped_refptr<AppCacheGroup> group_;
- scoped_refptr<AppCache> cache_;
- scoped_refptr<AppCache> cache2_;
-};
-
-
-TEST_F(AppCacheStorageImplTest, LoadCache_Miss) {
- RunTestOnIOThread(&AppCacheStorageImplTest::LoadCache_Miss);
-}
-
-TEST_F(AppCacheStorageImplTest, LoadCache_NearHit) {
- RunTestOnIOThread(&AppCacheStorageImplTest::LoadCache_NearHit);
-}
-
-TEST_F(AppCacheStorageImplTest, CreateGroupInEmptyOrigin) {
- RunTestOnIOThread(&AppCacheStorageImplTest::CreateGroupInEmptyOrigin);
-}
-
-TEST_F(AppCacheStorageImplTest, CreateGroupInPopulatedOrigin) {
- RunTestOnIOThread(&AppCacheStorageImplTest::CreateGroupInPopulatedOrigin);
-}
-
-TEST_F(AppCacheStorageImplTest, LoadGroupAndCache_FarHit) {
- RunTestOnIOThread(&AppCacheStorageImplTest::LoadGroupAndCache_FarHit);
-}
-
-TEST_F(AppCacheStorageImplTest, StoreNewGroup) {
- RunTestOnIOThread(&AppCacheStorageImplTest::StoreNewGroup);
-}
-
-TEST_F(AppCacheStorageImplTest, StoreExistingGroup) {
- RunTestOnIOThread(&AppCacheStorageImplTest::StoreExistingGroup);
-}
-
-TEST_F(AppCacheStorageImplTest, StoreExistingGroupExistingCache) {
- RunTestOnIOThread(&AppCacheStorageImplTest::StoreExistingGroupExistingCache);
-}
-
-TEST_F(AppCacheStorageImplTest, MakeGroupObsolete) {
- RunTestOnIOThread(&AppCacheStorageImplTest::MakeGroupObsolete);
-}
-
-TEST_F(AppCacheStorageImplTest, MarkEntryAsForeign) {
- RunTestOnIOThread(&AppCacheStorageImplTest::MarkEntryAsForeign);
-}
-
-TEST_F(AppCacheStorageImplTest, MarkEntryAsForeignWithLoadInProgress) {
- RunTestOnIOThread(
- &AppCacheStorageImplTest::MarkEntryAsForeignWithLoadInProgress);
-}
-
-TEST_F(AppCacheStorageImplTest, FindNoMainResponse) {
- RunTestOnIOThread(&AppCacheStorageImplTest::FindNoMainResponse);
-}
-
-TEST_F(AppCacheStorageImplTest, BasicFindMainResponseInDatabase) {
- RunTestOnIOThread(
- &AppCacheStorageImplTest::BasicFindMainResponseInDatabase);
-}
-
-TEST_F(AppCacheStorageImplTest, BasicFindMainResponseInWorkingSet) {
- RunTestOnIOThread(
- &AppCacheStorageImplTest::BasicFindMainResponseInWorkingSet);
-}
-
-TEST_F(AppCacheStorageImplTest, BasicFindMainFallbackResponseInDatabase) {
- RunTestOnIOThread(
- &AppCacheStorageImplTest::BasicFindMainFallbackResponseInDatabase);
-}
-
-TEST_F(AppCacheStorageImplTest, BasicFindMainFallbackResponseInWorkingSet) {
- RunTestOnIOThread(
- &AppCacheStorageImplTest::BasicFindMainFallbackResponseInWorkingSet);
-}
-
-TEST_F(AppCacheStorageImplTest, FindMainResponseWithMultipleHits) {
- RunTestOnIOThread(
- &AppCacheStorageImplTest::FindMainResponseWithMultipleHits);
-}
-
-TEST_F(AppCacheStorageImplTest, FindMainResponseExclusionsInDatabase) {
- RunTestOnIOThread(
- &AppCacheStorageImplTest::FindMainResponseExclusionsInDatabase);
-}
-
-TEST_F(AppCacheStorageImplTest, FindMainResponseExclusionsInWorkingSet) {
- RunTestOnIOThread(
- &AppCacheStorageImplTest::FindMainResponseExclusionsInWorkingSet);
-}
-
-// That's all folks!
-
-} // namespace appcache
-
diff --git a/webkit/appcache/appcache_thread.h b/webkit/appcache/appcache_thread.h
index 7224d23..9f14b1c 100644
--- a/webkit/appcache/appcache_thread.h
+++ b/webkit/appcache/appcache_thread.h
@@ -5,11 +5,10 @@
#ifndef WEBKIT_APPCACHE_APPCACHE_THREAD_H_
#define WEBKIT_APPCACHE_APPCACHE_THREAD_H_
-#include "base/task.h"
-
namespace tracked_objects {
class Location;
}
+class Task;
namespace appcache {
@@ -32,13 +31,6 @@ class AppCacheThread {
Task* task);
static bool CurrentlyOn(int id);
- template <class T>
- static bool DeleteSoon(int id,
- const tracked_objects::Location& from_here,
- T* object) {
- return PostTask(id, from_here, new DeleteTask<T>(object));
- }
-
private:
AppCacheThread();
~AppCacheThread();
diff --git a/webkit/appcache/appcache_working_set.cc b/webkit/appcache/appcache_working_set.cc
index 652116c..2b61ea3 100644
--- a/webkit/appcache/appcache_working_set.cc
+++ b/webkit/appcache/appcache_working_set.cc
@@ -14,7 +14,6 @@ namespace appcache {
AppCacheWorkingSet::~AppCacheWorkingSet() {
DCHECK(caches_.empty());
DCHECK(groups_.empty());
- DCHECK(groups_by_origin_.empty());
}
void AppCacheWorkingSet::AddCache(AppCache* cache) {
@@ -32,20 +31,10 @@ void AppCacheWorkingSet::AddGroup(AppCacheGroup* group) {
const GURL& url = group->manifest_url();
DCHECK(groups_.find(url) == groups_.end());
groups_.insert(GroupMap::value_type(url, group));
- groups_by_origin_[url.GetOrigin()].insert(GroupMap::value_type(url, group));
}
void AppCacheWorkingSet::RemoveGroup(AppCacheGroup* group) {
- const GURL& url = group->manifest_url();
- groups_.erase(url);
-
- GURL origin_url = url.GetOrigin();
- GroupMap* groups_in_origin = GetMutableGroupsInOrigin(origin_url);
- if (groups_in_origin) {
- groups_in_origin->erase(url);
- if (groups_in_origin->empty())
- groups_by_origin_.erase(origin_url);
- }
+ groups_.erase(group->manifest_url());
}
void AppCacheWorkingSet::AddResponseInfo(AppCacheResponseInfo* info) {
diff --git a/webkit/appcache/appcache_working_set.h b/webkit/appcache/appcache_working_set.h
index 479e74d..6785d50 100644
--- a/webkit/appcache/appcache_working_set.h
+++ b/webkit/appcache/appcache_working_set.h
@@ -20,8 +20,6 @@ class AppCacheResponseInfo;
// currently in memory.
class AppCacheWorkingSet {
public:
- typedef std::map<GURL, AppCacheGroup*> GroupMap;
-
~AppCacheWorkingSet();
void AddCache(AppCache* cache);
@@ -38,10 +36,6 @@ class AppCacheWorkingSet {
return (it != groups_.end()) ? it->second : NULL;
}
- const GroupMap* GetGroupsInOrigin(const GURL& origin_url) {
- return GetMutableGroupsInOrigin(origin_url);
- }
-
void AddResponseInfo(AppCacheResponseInfo* response_info);
void RemoveResponseInfo(AppCacheResponseInfo* response_info);
AppCacheResponseInfo* GetResponseInfo(int64 id) {
@@ -51,17 +45,10 @@ class AppCacheWorkingSet {
private:
typedef base::hash_map<int64, AppCache*> CacheMap;
- typedef std::map<GURL, GroupMap> GroupsByOriginMap;
+ typedef std::map<GURL, AppCacheGroup*> GroupMap;
typedef base::hash_map<int64, AppCacheResponseInfo*> ResponseInfoMap;
-
- GroupMap* GetMutableGroupsInOrigin(const GURL& origin_url) {
- GroupsByOriginMap::iterator it = groups_by_origin_.find(origin_url);
- return (it != groups_by_origin_.end()) ? &it->second : NULL;
- }
-
CacheMap caches_;
GroupMap groups_;
- GroupsByOriginMap groups_by_origin_; // origin -> (manifest -> group)
ResponseInfoMap response_infos_;
};
diff --git a/webkit/appcache/mock_appcache_storage.cc b/webkit/appcache/mock_appcache_storage.cc
index 44bcd12..214be249 100644
--- a/webkit/appcache/mock_appcache_storage.cc
+++ b/webkit/appcache/mock_appcache_storage.cc
@@ -124,6 +124,8 @@ void MockAppCacheStorage::MarkEntryAsForeign(
if (entry)
entry->add_types(AppCacheEntry::FOREIGN);
}
+ // TODO(michaeln): in real storage update in storage, and if this cache is
+ // being loaded be sure to update the memory cache upon load completion.
}
void MockAppCacheStorage::MakeGroupObsolete(
@@ -138,7 +140,7 @@ void MockAppCacheStorage::MakeGroupObsolete(
}
AppCacheResponseReader* MockAppCacheStorage::CreateResponseReader(
- const GURL& manifest_url, int64 response_id) {
+ const GURL& origin, int64 response_id) {
return new AppCacheResponseReader(response_id, disk_cache());
}
@@ -201,6 +203,14 @@ void MockAppCacheStorage::ProcessStoreGroupAndNewestCache(
if (delegate_ref->delegate)
delegate_ref->delegate->OnGroupAndNewestCacheStored(group, true);
+
+ // We don't bother with removing responses from 'mock' storage
+ // TODO(michaeln): for 'real' storage...
+ // std::set<int64> doomed_responses_ = responses from old caches
+ // std::set<int64> needed_responses_ = responses from newest cache
+ // foreach(needed_responses_)
+ // doomed_responses_.remove(needed_response_);
+ // DoomResponses(group->manifest_url(), doomed_responses_);
}
namespace {