Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Unified Diff: chrome/browser/predictors/resource_prefetch_predictor_tables.cc

Issue 2285673002: predictors: Version the resource_prefetch_predictor database. (Closed)
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/predictors/resource_prefetch_predictor_tables.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/predictors/resource_prefetch_predictor_tables.cc
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables.cc b/chrome/browser/predictors/resource_prefetch_predictor_tables.cc
index a3dd8c1e429adf005511c75f364ad9f0f19045ca..86c687a5c0b487e9103112db37d724868759111f 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_tables.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor_tables.cc
@@ -14,7 +14,9 @@
#include "base/metrics/histogram.h"
#include "base/strings/stringprintf.h"
#include "content/public/browser/browser_thread.h"
+#include "sql/meta_table.h"
#include "sql/statement.h"
+#include "sql/transaction.h"
using content::BrowserThread;
using sql::Statement;
@@ -23,18 +25,39 @@ namespace {
using ResourceRow = predictors::ResourcePrefetchPredictorTables::ResourceRow;
+const char kMetadataTableName[] = "resource_prefetch_predictor_metadata";
const char kUrlResourceTableName[] = "resource_prefetch_predictor_url";
const char kUrlMetadataTableName[] = "resource_prefetch_predictor_url_metadata";
const char kHostResourceTableName[] = "resource_prefetch_predictor_host";
const char kHostMetadataTableName[] =
"resource_prefetch_predictor_host_metadata";
+const char kCreateGlobalMetadataStatementTemplate[] =
+ "CREATE TABLE %s ( "
+ "key TEXT, value INTEGER, "
+ "PRIMARY KEY (key))";
+const char kCreateResourceTableStatementTemplate[] =
+ "CREATE TABLE %s ( "
+ "main_page_url TEXT, "
+ "resource_url TEXT, "
+ "proto BLOB, "
+ "PRIMARY KEY(main_page_url, resource_url))";
+const char kCreateMetadataTableStatementTemplate[] =
+ "CREATE TABLE %s ( "
+ "main_page_url TEXT, "
+ "last_visit_time INTEGER, "
+ "PRIMARY KEY(main_page_url))";
+
const char kInsertResourceTableStatementTemplate[] =
"INSERT INTO %s (main_page_url, resource_url, proto) VALUES (?,?,?)";
const char kInsertMetadataTableStatementTemplate[] =
"INSERT INTO %s (main_page_url, last_visit_time) VALUES (?,?)";
const char kDeleteStatementTemplate[] = "DELETE FROM %s WHERE main_page_url=?";
+// Database version. Always increment it when any change is made to the data
+// schema (including the .proto).
pasko 2016/08/26 14:37:18 is this mandatory? We might be OK with default bac
Benoit L 2016/08/26 14:52:39 I prefer to err on the side of caution.
+const int kDatabaseVersion = 1;
+
void BindResourceRowToStatement(const ResourceRow& row,
const std::string& primary_key,
Statement* statement) {
@@ -435,17 +458,46 @@ bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit(
return true;
}
+// static
bool ResourcePrefetchPredictorTables::DropTablesIfOutdated(
sql::Connection* db) {
+ int tables_version = 0;
+ if (db->DoesTableExist(kMetadataTableName)) {
+ sql::Statement statement(db->GetUniqueStatement(
+ base::StringPrintf("SELECT value FROM %s WHERE key='version'",
+ kMetadataTableName)
+ .c_str()));
+ if (statement.Step())
+ tables_version = statement.ColumnInt(0);
+ }
+
bool success = true;
- for (const char* table_name :
- {kUrlResourceTableName, kHostResourceTableName}) {
- if (db->DoesTableExist(table_name) &&
- !db->DoesColumnExist(table_name, "proto")) {
- success &=
- db->Execute(base::StringPrintf("DROP TABLE %s", table_name).c_str());
+ // Too new is also a problem.
+ bool incompatible_version = tables_version != kDatabaseVersion;
+
+ if (incompatible_version) {
+ for (const char* table_name :
+ {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName,
+ kUrlMetadataTableName, kHostMetadataTableName}) {
+ success &= db->Execute(
+ base::StringPrintf("DROP TABLE IF EXISTS %s", table_name).c_str());
}
}
+
+ if (incompatible_version) {
+ success &=
+ db->Execute(base::StringPrintf(kCreateGlobalMetadataStatementTemplate,
+ kMetadataTableName)
+ .c_str());
+
+ sql::Statement statement(db->GetUniqueStatement(
+ base::StringPrintf(
+ "INSERT OR REPLACE INTO %s (key,value) VALUES ('version',%d)",
+ kMetadataTableName, kDatabaseVersion)
+ .c_str()));
+ success &= statement.Run();
+ }
+
return success;
}
@@ -454,36 +506,36 @@ void ResourcePrefetchPredictorTables::CreateTableIfNonExistent() {
if (CantAccessDatabase())
return;
- const char resource_table_creator[] =
- "CREATE TABLE %s ( "
- "main_page_url TEXT, "
- "resource_url TEXT, "
- "proto BLOB, "
- "PRIMARY KEY(main_page_url, resource_url))";
- const char* metadata_table_creator =
- "CREATE TABLE %s ( "
- "main_page_url TEXT, "
- "last_visit_time INTEGER, "
- "PRIMARY KEY(main_page_url))";
-
+ // Database initialization is all-or-nothing.
sql::Connection* db = DB();
- bool success = DropTablesIfOutdated(db) &&
- (db->DoesTableExist(kUrlResourceTableName) ||
- db->Execute(base::StringPrintf(resource_table_creator,
- kUrlResourceTableName)
- .c_str())) &&
- (db->DoesTableExist(kUrlMetadataTableName) ||
- db->Execute(base::StringPrintf(metadata_table_creator,
- kUrlMetadataTableName)
- .c_str())) &&
- (db->DoesTableExist(kHostResourceTableName) ||
- db->Execute(base::StringPrintf(resource_table_creator,
- kHostResourceTableName)
- .c_str())) &&
- (db->DoesTableExist(kHostMetadataTableName) ||
- db->Execute(base::StringPrintf(metadata_table_creator,
- kHostMetadataTableName)
- .c_str()));
+ sql::Transaction transaction{db};
+ bool success = transaction.Begin();
+
+ success &= DropTablesIfOutdated(db);
+
+ success &=
+ (db->DoesTableExist(kUrlResourceTableName) ||
pasko 2016/08/26 14:37:18 what if we decided to drop the table because its v
Benoit L 2016/08/26 14:52:39 We are within the transaction, so it's fine.
+ db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate,
+ kUrlResourceTableName)
+ .c_str())) &&
+ (db->DoesTableExist(kUrlMetadataTableName) ||
+ db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate,
+ kUrlMetadataTableName)
+ .c_str())) &&
+ (db->DoesTableExist(kHostResourceTableName) ||
+ db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate,
+ kHostResourceTableName)
+ .c_str())) &&
+ (db->DoesTableExist(kHostMetadataTableName) ||
+ db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate,
+ kHostMetadataTableName)
+ .c_str()));
+
+ if (success) {
+ success = transaction.Commit();
+ } else {
+ transaction.Rollback();
+ }
pasko 2016/08/26 14:37:18 nit: I think chromium style suggests no braces in
Benoit L 2016/08/26 14:52:39 Done.
if (!success)
ResetDB();
« no previous file with comments | « chrome/browser/predictors/resource_prefetch_predictor_tables.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698