1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef WEBKIT_BROWSER_APPCACHE_APPCACHE_DATABASE_H_ 6 #define WEBKIT_BROWSER_APPCACHE_APPCACHE_DATABASE_H_ 7 8 #include <map> 9 #include <set> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "base/files/file_path.h" 14 #include "base/gtest_prod_util.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/time/time.h" 17 #include "url/gurl.h" 18 #include "webkit/browser/webkit_storage_browser_export.h" 19 #include "webkit/common/appcache/appcache_interfaces.h" 20 21 namespace sql { 22 class Connection; 23 class MetaTable; 24 class Statement; 25 class StatementID; 26 } 27 28 namespace appcache { 29 30 class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheDatabase { 31 public: 32 struct WEBKIT_STORAGE_BROWSER_EXPORT GroupRecord { 33 GroupRecord(); 34 ~GroupRecord(); 35 36 int64 group_id; 37 GURL origin; 38 GURL manifest_url; 39 base::Time creation_time; 40 base::Time last_access_time; 41 }; 42 43 struct WEBKIT_STORAGE_BROWSER_EXPORT CacheRecord { 44 CacheRecord() 45 : cache_id(0), group_id(0), online_wildcard(false), cache_size(0) {} 46 47 int64 cache_id; 48 int64 group_id; 49 bool online_wildcard; 50 base::Time update_time; 51 int64 cache_size; // the sum of all response sizes in this cache 52 }; 53 54 struct EntryRecord { 55 EntryRecord() : cache_id(0), flags(0), response_id(0), response_size(0) {} 56 57 int64 cache_id; 58 GURL url; 59 int flags; 60 int64 response_id; 61 int64 response_size; 62 }; 63 64 struct WEBKIT_STORAGE_BROWSER_EXPORT NamespaceRecord { 65 NamespaceRecord(); 66 ~NamespaceRecord(); 67 68 int64 cache_id; 69 GURL origin; 70 Namespace namespace_; 71 }; 72 73 typedef std::vector<NamespaceRecord> NamespaceRecordVector; 74 75 struct OnlineWhiteListRecord { 76 OnlineWhiteListRecord() : cache_id(0), is_pattern(false) {} 77 78 int64 cache_id; 79 GURL namespace_url; 80 bool is_pattern; 81 }; 82 83 explicit AppCacheDatabase(const base::FilePath& path); 84 ~AppCacheDatabase(); 85 86 void CloseConnection(); 87 void Disable(); 88 bool is_disabled() const { return is_disabled_; } 89 90 int64 GetOriginUsage(const GURL& origin); 91 bool GetAllOriginUsage(std::map<GURL, int64>* usage_map); 92 93 bool FindOriginsWithGroups(std::set<GURL>* origins); 94 bool FindLastStorageIds( 95 int64* last_group_id, int64* last_cache_id, int64* last_response_id, 96 int64* last_deletable_response_rowid); 97 98 bool FindGroup(int64 group_id, GroupRecord* record); 99 bool FindGroupForManifestUrl(const GURL& manifest_url, GroupRecord* record); 100 bool FindGroupsForOrigin( 101 const GURL& origin, std::vector<GroupRecord>* records); 102 bool FindGroupForCache(int64 cache_id, GroupRecord* record); 103 bool UpdateGroupLastAccessTime( 104 int64 group_id, base::Time last_access_time); 105 bool InsertGroup(const GroupRecord* record); 106 bool DeleteGroup(int64 group_id); 107 108 bool FindCache(int64 cache_id, CacheRecord* record); 109 bool FindCacheForGroup(int64 group_id, CacheRecord* record); 110 bool FindCachesForOrigin( 111 const GURL& origin, std::vector<CacheRecord>* records); 112 bool InsertCache(const CacheRecord* record); 113 bool DeleteCache(int64 cache_id); 114 115 bool FindEntriesForCache( 116 int64 cache_id, std::vector<EntryRecord>* records); 117 bool FindEntriesForUrl( 118 const GURL& url, std::vector<EntryRecord>* records); 119 bool FindEntry(int64 cache_id, const GURL& url, EntryRecord* record); 120 bool InsertEntry(const EntryRecord* record); 121 bool InsertEntryRecords( 122 const std::vector<EntryRecord>& records); 123 bool DeleteEntriesForCache(int64 cache_id); 124 bool AddEntryFlags(const GURL& entry_url, int64 cache_id, 125 int additional_flags); 126 bool FindResponseIdsForCacheAsVector( 127 int64 cache_id, std::vector<int64>* response_ids) { 128 return FindResponseIdsForCacheHelper(cache_id, response_ids, NULL); 129 } 130 bool FindResponseIdsForCacheAsSet( 131 int64 cache_id, std::set<int64>* response_ids) { 132 return FindResponseIdsForCacheHelper(cache_id, NULL, response_ids); 133 } 134 135 bool FindNamespacesForOrigin( 136 const GURL& origin, 137 NamespaceRecordVector* intercepts, 138 NamespaceRecordVector* fallbacks); 139 bool FindNamespacesForCache( 140 int64 cache_id, 141 NamespaceRecordVector* intercepts, 142 std::vector<NamespaceRecord>* fallbacks); 143 bool InsertNamespaceRecords( 144 const NamespaceRecordVector& records); 145 bool InsertNamespace(const NamespaceRecord* record); 146 bool DeleteNamespacesForCache(int64 cache_id); 147 148 bool FindOnlineWhiteListForCache( 149 int64 cache_id, std::vector<OnlineWhiteListRecord>* records); 150 bool InsertOnlineWhiteList(const OnlineWhiteListRecord* record); 151 bool InsertOnlineWhiteListRecords( 152 const std::vector<OnlineWhiteListRecord>& records); 153 bool DeleteOnlineWhiteListForCache(int64 cache_id); 154 155 bool GetDeletableResponseIds(std::vector<int64>* response_ids, 156 int64 max_rowid, int limit); 157 bool InsertDeletableResponseIds(const std::vector<int64>& response_ids); 158 bool DeleteDeletableResponseIds(const std::vector<int64>& response_ids); 159 160 // So our callers can wrap operations in transactions. 161 sql::Connection* db_connection() { 162 LazyOpen(true); 163 return db_.get(); 164 } 165 166 private: 167 bool RunCachedStatementWithIds( 168 const sql::StatementID& statement_id, const char* sql, 169 const std::vector<int64>& ids); 170 bool RunUniqueStatementWithInt64Result(const char* sql, int64* result); 171 172 bool FindResponseIdsForCacheHelper( 173 int64 cache_id, std::vector<int64>* ids_vector, 174 std::set<int64>* ids_set); 175 176 // Record retrieval helpers 177 void ReadGroupRecord(const sql::Statement& statement, GroupRecord* record); 178 void ReadCacheRecord(const sql::Statement& statement, CacheRecord* record); 179 void ReadEntryRecord(const sql::Statement& statement, EntryRecord* record); 180 void ReadNamespaceRecords( 181 sql::Statement* statement, 182 NamespaceRecordVector* intercepts, 183 NamespaceRecordVector* fallbacks); 184 void ReadNamespaceRecord( 185 const sql::Statement* statement, NamespaceRecord* record); 186 void ReadOnlineWhiteListRecord( 187 const sql::Statement& statement, OnlineWhiteListRecord* record); 188 189 // Database creation 190 bool LazyOpen(bool create_if_needed); 191 bool EnsureDatabaseVersion(); 192 bool CreateSchema(); 193 bool UpgradeSchema(); 194 195 void ResetConnectionAndTables(); 196 197 // Deletes the existing database file and the entire directory containing 198 // the database file including the disk cache in which response headers 199 // and bodies are stored, and then creates a new database file. 200 bool DeleteExistingAndCreateNewDatabase(); 201 202 base::FilePath db_file_path_; 203 scoped_ptr<sql::Connection> db_; 204 scoped_ptr<sql::MetaTable> meta_table_; 205 bool is_disabled_; 206 bool is_recreating_; 207 208 FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, CacheRecords); 209 FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, EntryRecords); 210 FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, QuickIntegrityCheck); 211 FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, NamespaceRecords); 212 FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, GroupRecords); 213 FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, LazyOpen); 214 FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, ExperimentalFlags); 215 FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, OnlineWhiteListRecords); 216 FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, ReCreate); 217 FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, DeletableResponseIds); 218 FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, OriginUsage); 219 FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, UpgradeSchema3to5); 220 FRIEND_TEST_ALL_PREFIXES(AppCacheDatabaseTest, UpgradeSchema4to5); 221 222 DISALLOW_COPY_AND_ASSIGN(AppCacheDatabase); 223 }; 224 225 } // namespace appcache 226 227 #endif // WEBKIT_BROWSER_APPCACHE_APPCACHE_DATABASE_H_ 228