// Copyright (c) 2012 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_BROWSER_APPCACHE_APPCACHE_DATABASE_H_
#define WEBKIT_BROWSER_APPCACHE_APPCACHE_DATABASE_H_
#include <map>
#include <set>
#include <vector>
#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "url/gurl.h"
#include "webkit/browser/webkit_storage_browser_export.h"
#include "webkit/common/appcache/appcache_interfaces.h"
namespace sql {
class Connection;
class MetaTable;
class Statement;
class StatementID;
}
namespace appcache {
class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheDatabase {
public:
struct WEBKIT_STORAGE_BROWSER_EXPORT GroupRecord {
GroupRecord();
~GroupRecord();
int64 group_id;
GURL origin;
GURL manifest_url;
base::Time creation_time;
base::Time last_access_time;
};
struct WEBKIT_STORAGE_BROWSER_EXPORT CacheRecord {
CacheRecord()
: cache_id(0), group_id(0), online_wildcard(false), cache_size(0) {}
int64 cache_id;
int64 group_id;
bool online_wildcard;
base::Time update_time;
int64 cache_size; // the sum of all response sizes in this cache
};
struct EntryRecord {
EntryRecord() : cache_id(0), flags(0), response_id(0), response_size(0) {}
int64 cache_id;
GURL url;
int flags;
int64 response_id;
int64 response_size;
};
struct WEBKIT_STORAGE_BROWSER_EXPORT NamespaceRecord {
NamespaceRecord();
~NamespaceRecord();
int64 cache_id;
GURL origin;
Namespace namespace_;
};
typedef std::vector<NamespaceRecord> NamespaceRecordVector;
struct OnlineWhiteListRecord {
OnlineWhiteListRecord() : cache_id(0), is_pattern(false) {}
int64 cache_id;
GURL namespace_url;
bool is_pattern;
};
explicit AppCacheDatabase(const base::FilePath& path);
~AppCacheDatabase();
void CloseConnection();
void Disable();
bool is_disabled() const { return is_disabled_; }
int64 GetOriginUsage(const GURL& origin);
bool GetAllOriginUsage(std::map<GURL, int64>* usage_map);
bool FindOriginsWithGroups(std::set<GURL>* origins);
bool FindLastStorageIds(
int64* last_group_id, int64* last_cache_id, int64* last_response_id,
int64* last_deletable_response_rowid);
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 UpdateGroupLastAccessTime(
int64 group_id, base::Time last_access_time);
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 FindCachesForOrigin(
const GURL& origin, std::vector<CacheRecord>* records);
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 FindResponseIdsForCacheAsVector(
int64 cache_id, std::vector<int64>* response_ids) {
return FindResponseIdsForCacheHelper(cache_id, response_ids, NULL);
}
bool FindResponseIdsForCacheAsSet(
int64 cache_id, std::set<int64>* response_ids) {
return FindResponseIdsForCacheHelper(cache_id, NULL, response_ids);
}
bool FindNamespacesForOrigin(
const GURL& origin,
NamespaceRecordVector* intercepts,
NamespaceRecordVector* fallbacks);
bool FindNamespacesForCache(
int64 cache_id,
NamespaceRecordVector* intercepts,
std::vector<NamespaceRecord>* fallbacks);
bool InsertNamespaceRecords(
const NamespaceRecordVector& records);
bool InsertNamespace(const NamespaceRecord* record);
bool DeleteNamespacesForCache(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);
bool GetDeletableResponseIds(std::vector<int64>* response_ids,
int64 max_rowid, int limit);
bool InsertDeletableResponseIds(const std::vector<int64>& response_ids);
bool DeleteDeletableResponseIds(const std::vector<int64>& response_ids);
// So our callers can wrap operations in transactions.
sql::Connection* db_connection() {
LazyOpen(true);
return db_.get();
}
private:
bool RunCachedStatementWithIds(
const sql::StatementID& statement_id, const char* sql,
const std::vector<int64>& ids);
bool RunUniqueStatementWithInt64Result(const char* sql, int64* result);
bool FindResponseIdsForCacheHelper(
int64 cache_id, std::vector<int64>* ids_vector,
std::set<int64>* ids_set);
// 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 ReadNamespaceRecords(
sql::Statement* statement,
NamespaceRecordVector* intercepts,
NamespaceRecordVector* fallbacks);
void ReadNamespaceRecord(
const sql::Statement* statement, NamespaceRecord* record);
void ReadOnlineWhiteListRecord(
const sql::Statement& statement, OnlineWhiteListRecord* record);
// Database creation
bool LazyOpen(bool create_if_needed);
bool EnsureDatabaseVersion();
bool CreateSchema();
bool UpgradeSchema();
void ResetConnectionAndTables();
// 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();
base::FilePath db_file_path_;
scoped_ptr<sql::Connection> db_;
scoped_ptr<sql::MetaTable> meta_table_;
bool is_disabled_;
bool is_recreating_;
FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, CacheRecords);
FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, EntryRecords);
FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, QuickIntegrityCheck);
FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, NamespaceRecords);
FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, GroupRecords);
FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, LazyOpen);
FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, ExperimentalFlags);
FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, OnlineWhiteListRecords);
FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, ReCreate);
FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, DeletableResponseIds);
FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, OriginUsage);
FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, UpgradeSchema3to5);
FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, UpgradeSchema4to5);
DISALLOW_COPY_AND_ASSIGN(AppCacheDatabase);
};
} // namespace appcache
#endif // WEBKIT_BROWSER_APPCACHE_APPCACHE_DATABASE_H_