Index: webkit/appcache/appcache_database.cc |
=================================================================== |
--- webkit/appcache/appcache_database.cc (revision 113546) |
+++ webkit/appcache/appcache_database.cc (working copy) |
@@ -19,20 +19,29 @@ |
// Schema ------------------------------------------------------------------- |
namespace { |
-const int kCurrentVersion = 3; |
-const int kCompatibleVersion = 3; |
+const int kCurrentVersion = 4; |
+const int kCompatibleVersion = 4; |
const char kGroupsTable[] = "Groups"; |
const char kCachesTable[] = "Caches"; |
const char kEntriesTable[] = "Entries"; |
-const char kFallbackNameSpacesTable[] = "FallbackNameSpaces"; |
+const char kNamespacesTable[] = "Namespaces"; |
const char kOnlineWhiteListsTable[] = "OnlineWhiteLists"; |
const char kDeletableResponseIdsTable[] = "DeletableResponseIds"; |
-const struct { |
+struct TableInfo { |
const char* table_name; |
const char* columns; |
-} kTables[] = { |
+}; |
+ |
+struct IndexInfo { |
+ const char* index_name; |
+ const char* table_name; |
+ const char* columns; |
+ bool unique; |
+}; |
+ |
+const TableInfo kTables[] = { |
{ kGroupsTable, |
"(group_id INTEGER PRIMARY KEY," |
" origin TEXT," |
@@ -54,11 +63,12 @@ |
" response_id INTEGER," |
" response_size INTEGER)" }, |
- { kFallbackNameSpacesTable, |
+ { kNamespacesTable, |
"(cache_id INTEGER," |
" origin TEXT," // intentionally not normalized |
+ " type INTEGER," |
" namespace_url TEXT," |
- " fallback_entry_url TEXT)" }, |
+ " target_url TEXT)" }, |
{ kOnlineWhiteListsTable, |
"(cache_id INTEGER," |
@@ -68,12 +78,7 @@ |
"(response_id INTEGER NOT NULL)" }, |
}; |
-const struct { |
- const char* index_name; |
- const char* table_name; |
- const char* columns; |
- bool unique; |
-} kIndexes[] = { |
+const IndexInfo kIndexes[] = { |
{ "GroupsOriginIndex", |
kGroupsTable, |
"(origin)", |
@@ -104,18 +109,18 @@ |
"(response_id)", |
true }, |
- { "FallbackNameSpacesCacheIndex", |
- kFallbackNameSpacesTable, |
+ { "NamespacesCacheIndex", |
+ kNamespacesTable, |
"(cache_id)", |
false }, |
- { "FallbackNameSpacesOriginIndex", |
- kFallbackNameSpacesTable, |
+ { "NamespacesOriginIndex", |
+ kNamespacesTable, |
"(origin)", |
false }, |
- { "FallbackNameSpacesCacheAndUrlIndex", |
- kFallbackNameSpacesTable, |
+ { "NamespacesCacheAndUrlIndex", |
+ kNamespacesTable, |
"(cache_id, namespace_url)", |
true }, |
@@ -142,6 +147,26 @@ |
return new sql::DiagnosticErrorDelegate<HistogramUniquifier>(); |
} |
+bool CreateTable(sql::Connection* db, const TableInfo& info) { |
+ std::string sql("CREATE TABLE "); |
+ sql += info.table_name; |
+ sql += info.columns; |
+ return db->Execute(sql.c_str()); |
+} |
+ |
+bool CreateIndex(sql::Connection* db, const IndexInfo& info) { |
+ std::string sql; |
+ if (info.unique) |
+ sql += "CREATE UNIQUE INDEX "; |
+ else |
+ sql += "CREATE INDEX "; |
+ sql += info.index_name; |
+ sql += " ON "; |
+ sql += info.table_name; |
+ sql += info.columns; |
+ return db->Execute(sql.c_str()); |
+} |
+ |
} // anon namespace |
// AppCacheDatabase ---------------------------------------------------------- |
@@ -154,13 +179,14 @@ |
AppCacheDatabase::GroupRecord::~GroupRecord() { |
} |
-AppCacheDatabase::FallbackNameSpaceRecord::FallbackNameSpaceRecord() |
- : cache_id(0) { |
+AppCacheDatabase::NamespaceRecord::NamespaceRecord() |
+ : cache_id(0), type(FALLBACK_NAMESPACE) { |
} |
-AppCacheDatabase::FallbackNameSpaceRecord::~FallbackNameSpaceRecord() { |
+AppCacheDatabase::NamespaceRecord::~NamespaceRecord() { |
} |
+ |
AppCacheDatabase::AppCacheDatabase(const FilePath& path) |
: db_file_path_(path), is_disabled_(false), is_recreating_(false) { |
} |
@@ -655,61 +681,59 @@ |
return statement.Run() && db_->GetLastChangeCount(); |
} |
-bool AppCacheDatabase::FindFallbackNameSpacesForOrigin( |
- const GURL& origin, std::vector<FallbackNameSpaceRecord>* records) { |
- DCHECK(records && records->empty()); |
+bool AppCacheDatabase::FindNamespacesForOrigin( |
+ const GURL& origin, |
+ std::vector<NamespaceRecord>* intercepts, |
+ std::vector<NamespaceRecord>* fallbacks) { |
+ DCHECK(intercepts && intercepts->empty()); |
+ DCHECK(fallbacks && fallbacks->empty()); |
if (!LazyOpen(false)) |
return false; |
const char* kSql = |
- "SELECT cache_id, origin, namespace_url, fallback_entry_url" |
- " FROM FallbackNameSpaces WHERE origin = ?"; |
+ "SELECT cache_id, origin, type, namespace_url, target_url" |
+ " FROM Namespaces 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); |
- } |
+ ReadNamespaceRecords(&statement, intercepts, fallbacks); |
return statement.Succeeded(); |
} |
-bool AppCacheDatabase::FindFallbackNameSpacesForCache( |
- int64 cache_id, std::vector<FallbackNameSpaceRecord>* records) { |
- DCHECK(records && records->empty()); |
+bool AppCacheDatabase::FindNamespacesForCache( |
+ int64 cache_id, |
+ std::vector<NamespaceRecord>* intercepts, |
+ std::vector<NamespaceRecord>* fallbacks) { |
+ DCHECK(intercepts && intercepts->empty()); |
+ DCHECK(fallbacks && fallbacks->empty()); |
if (!LazyOpen(false)) |
return false; |
const char* kSql = |
- "SELECT cache_id, origin, namespace_url, fallback_entry_url" |
- " FROM FallbackNameSpaces WHERE cache_id = ?"; |
+ "SELECT cache_id, origin, type, namespace_url, target_url" |
+ " FROM Namespaces 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); |
- } |
+ ReadNamespaceRecords(&statement, intercepts, fallbacks); |
return statement.Succeeded(); |
} |
-bool AppCacheDatabase::InsertFallbackNameSpace( |
- const FallbackNameSpaceRecord* record) { |
+bool AppCacheDatabase::InsertNamespace( |
+ const NamespaceRecord* record) { |
if (!LazyOpen(true)) |
return false; |
const char* kSql = |
- "INSERT INTO FallbackNameSpaces" |
- " (cache_id, origin, namespace_url, fallback_entry_url)" |
- " VALUES (?, ?, ?, ?)"; |
+ "INSERT INTO Namespaces" |
+ " (cache_id, origin, type, namespace_url, target_url)" |
+ " VALUES (?, ?, ?, ?, ?)"; |
sql::Statement statement; |
if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement)) |
@@ -717,33 +741,34 @@ |
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()); |
+ statement.BindInt(2, record->type); |
+ statement.BindString(3, record->namespace_url.spec()); |
+ statement.BindString(4, record->target_url.spec()); |
return statement.Run(); |
} |
-bool AppCacheDatabase::InsertFallbackNameSpaceRecords( |
- const std::vector<FallbackNameSpaceRecord>& records) { |
+bool AppCacheDatabase::InsertNamespaceRecords( |
+ const std::vector<NamespaceRecord>& records) { |
if (records.empty()) |
return true; |
sql::Transaction transaction(db_.get()); |
if (!transaction.Begin()) |
return false; |
- std::vector<FallbackNameSpaceRecord>::const_iterator iter = records.begin(); |
+ std::vector<NamespaceRecord>::const_iterator iter = records.begin(); |
while (iter != records.end()) { |
- if (!InsertFallbackNameSpace(&(*iter))) |
+ if (!InsertNamespace(&(*iter))) |
return false; |
++iter; |
} |
return transaction.Commit(); |
} |
-bool AppCacheDatabase::DeleteFallbackNameSpacesForCache(int64 cache_id) { |
+bool AppCacheDatabase::DeleteNamespacesForCache(int64 cache_id) { |
if (!LazyOpen(false)) |
return false; |
const char* kSql = |
- "DELETE FROM FallbackNameSpaces WHERE cache_id = ?"; |
+ "DELETE FROM Namespaces WHERE cache_id = ?"; |
sql::Statement statement; |
if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement)) |
@@ -974,14 +999,28 @@ |
record->response_size = statement.ColumnInt64(4); |
} |
-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::ReadNamespaceRecords( |
+ sql::Statement* statement, |
+ NamespaceRecordVector* intercepts, |
+ NamespaceRecordVector* fallbacks) { |
+ while (statement->Step()) { |
+ NamespaceType type = static_cast<NamespaceType>(statement->ColumnInt(2)); |
+ NamespaceRecordVector* records = |
+ (type == FALLBACK_NAMESPACE) ? fallbacks : intercepts; |
+ records->push_back(NamespaceRecord()); |
+ ReadNamespaceRecord(statement, &records->back()); |
+ } |
} |
+void AppCacheDatabase::ReadNamespaceRecord( |
+ const sql::Statement* statement, NamespaceRecord* record) { |
+ record->cache_id = statement->ColumnInt64(0); |
+ record->origin = GURL(statement->ColumnString(1)); |
+ record->type = static_cast<NamespaceType>(statement->ColumnInt(2)); |
+ record->namespace_url = GURL(statement->ColumnString(3)); |
+ record->target_url = GURL(statement->ColumnString(4)); |
+} |
+ |
void AppCacheDatabase::ReadOnlineWhiteListRecord( |
const sql::Statement& statement, OnlineWhiteListRecord* record) { |
record->cache_id = statement.ColumnInt64(0); |
@@ -1060,6 +1099,9 @@ |
for (int i = 0; i < kTableCount; ++i) { |
DCHECK(db_->DoesTableExist(kTables[i].table_name)); |
} |
+ for (int i = 0; i < kIndexCount; ++i) { |
+ DCHECK(db_->DoesIndexExist(kIndexes[i].index_name)); |
+ } |
#endif |
return true; |
@@ -1074,24 +1116,12 @@ |
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())) |
+ if (!CreateTable(db_.get(), kTables[i])) |
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())) |
+ if (!CreateIndex(db_.get(), kIndexes[i])) |
return false; |
} |
@@ -1099,8 +1129,46 @@ |
} |
bool AppCacheDatabase::UpgradeSchema() { |
- // Upgrade logic goes here |
+ if (meta_table_->GetVersionNumber() == 3) { |
+ DCHECK_EQ(strcmp(kNamespacesTable, kTables[3].table_name), 0); |
+ DCHECK_EQ(strcmp(kNamespacesTable, kIndexes[6].table_name), 0); |
+ DCHECK_EQ(strcmp(kNamespacesTable, kIndexes[7].table_name), 0); |
+ DCHECK_EQ(strcmp(kNamespacesTable, kIndexes[8].table_name), 0); |
+ // Migrate from the old "FallbackNameSpaces" to the new "Namespaces" table. |
+ sql::Transaction transaction(db_.get()); |
+ if (!transaction.Begin() || |
+ !CreateTable(db_.get(), kTables[3])) { |
+ return false; |
+ } |
+ |
+ // Move data from the old table to the new table, setting the |
+ // 'type' for all current records to the value for FALLBACK_NAMESPACE. |
+ DCHECK_EQ(0, static_cast<int>(FALLBACK_NAMESPACE)); |
+ if (!db_->Execute( |
+ "INSERT INTO Namespaces" |
+ " SELECT cache_id, origin, 0, namespace_url, fallback_entry_url" |
+ " FROM FallbackNameSpaces")) { |
+ return false; |
+ } |
+ |
+ // Drop the old table, indexes on that table are also removed by this. |
+ if (!db_->Execute("DROP TABLE FallbackNameSpaces")) |
+ return false; |
+ |
+ // Create new indexes. |
+ if (!CreateIndex(db_.get(), kIndexes[6]) || |
+ !CreateIndex(db_.get(), kIndexes[7]) || |
+ !CreateIndex(db_.get(), kIndexes[8])) { |
+ return false; |
+ } |
+ |
+ // Finally bump the version numbers and commit it. |
+ meta_table_->SetVersionNumber(4); |
+ meta_table_->SetCompatibleVersionNumber(4); |
+ return transaction.Commit(); |
+ } |
+ |
// If there is no upgrade path for the version on disk to the current |
// version, nuke everything and start over. |
return DeleteExistingAndCreateNewDatabase(); |