Chromium Code Reviews| Index: components/previews/core/previews_opt_out_store_sql.cc |
| diff --git a/components/previews/core/previews_opt_out_store_sql.cc b/components/previews/core/previews_opt_out_store_sql.cc |
| index a6fe9e7ea690cdba8274d72cbb8c90c75c69e98f..10e526493fe70eccc5e8e2ae4de28fd1b34183e9 100644 |
| --- a/components/previews/core/previews_opt_out_store_sql.cc |
| +++ b/components/previews/core/previews_opt_out_store_sql.cc |
| @@ -55,18 +55,28 @@ int MaxRowsInOptOutDB() { |
| return base::StringToInt(max_rows, &value) ? value : 3200; |
| } |
| -// This is a macro instead of a const, so it can be used inline in other SQL |
| -// statements below. |
| +// Table names use a macro instead of a const, so the can be used inline in |
| +// other SQL statements below. |
| #define PREVIEWS_TABLE_NAME "previews_v1" |
| +#define PREVIEWS_TYPE_VERSION_TABLE_NAME "previews_type_version" |
| void CreateSchema(sql::Connection* db) { |
| - const char kSql[] = "CREATE TABLE IF NOT EXISTS " PREVIEWS_TABLE_NAME |
| - " (host_name VARCHAR NOT NULL," |
| - " time INTEGER NOT NULL," |
| - " opt_out INTEGER NOT NULL," |
| - " type INTEGER NOT NULL," |
| - " PRIMARY KEY(host_name, time DESC, opt_out, type))"; |
| - if (!db->Execute(kSql)) |
| + const char kSqlCreatePreviewsTable[] = |
| + "CREATE TABLE IF NOT EXISTS " PREVIEWS_TABLE_NAME |
| + " (host_name VARCHAR NOT NULL," |
| + " time INTEGER NOT NULL," |
| + " opt_out INTEGER NOT NULL," |
| + " type INTEGER NOT NULL," |
| + " PRIMARY KEY(host_name, time DESC, opt_out, type))"; |
| + if (!db->Execute(kSqlCreatePreviewsTable)) |
| + return; |
| + |
| + const char kSqlCreateTypeVersionTable[] = |
| + "CREATE TABLE IF NOT EXISTS " PREVIEWS_TYPE_VERSION_TABLE_NAME |
| + " (type INTEGER NOT NULL," |
| + " version INTEGER NOT NULL," |
| + " PRIMARY KEY(type))"; |
| + if (!db->Execute(kSqlCreateTypeVersionTable)) |
| return; |
| } |
| @@ -168,10 +178,92 @@ void MaybeEvictHostEntryFromDataBase(sql::Connection* db, |
| statement_delete_by_host.Run(); |
| } |
| +// Deletes every preview navigation entry for |type|. |
| +void ClearBlacklistForTypeInDataBase( |
| + sql::Connection* db, |
| + scoped_refptr<base::SingleThreadTaskRunner> runner, |
| + PreviewsType type) { |
| + const char kSql[] = "DELETE FROM " PREVIEWS_TABLE_NAME " WHERE type == ?"; |
| + sql::Statement statement(db->GetUniqueStatement(kSql)); |
| + statement.BindInt(0, static_cast<int>(type)); |
| + statement.Run(); |
| +} |
| + |
| +void InsertPreviewsVersionInDataBase( |
| + sql::Connection* db, |
| + scoped_refptr<base::SingleThreadTaskRunner> runner, |
| + PreviewsType type, |
| + int version) { |
| + const char kSqlInsert[] = "INSERT INTO " PREVIEWS_TYPE_VERSION_TABLE_NAME |
| + " (type, version)" |
| + " VALUES " |
| + " (?, ?)"; |
| + |
| + sql::Statement statement_insert( |
| + db->GetCachedStatement(SQL_FROM_HERE, kSqlInsert)); |
| + statement_insert.BindInt(0, static_cast<int>(type)); |
| + statement_insert.BindInt(1, version); |
| + statement_insert.Run(); |
| +} |
| + |
| +void UpdatePreviewsVersionInDataBase( |
| + sql::Connection* db, |
| + scoped_refptr<base::SingleThreadTaskRunner> runner, |
| + PreviewsType type, |
| + int version) { |
| + const char kSqlUpdate[] = "UPDATE " PREVIEWS_TYPE_VERSION_TABLE_NAME |
| + " SET version = ?" |
| + " WHERE type = ?"; |
| + |
| + sql::Statement statement_update( |
| + db->GetCachedStatement(SQL_FROM_HERE, kSqlUpdate)); |
| + statement_update.BindInt(0, version); |
| + statement_update.BindInt(1, static_cast<int>(type)); |
| + statement_update.Run(); |
| +} |
| + |
| +void CheckAndReconcileEnabledPreviewsVersionWithDataBase( |
|
tbansal1
2017/01/23 20:06:11
May be add a function comment.
dougarnett
2017/01/24 00:52:38
Done.
|
| + sql::Connection* db, |
| + scoped_refptr<base::SingleThreadTaskRunner> runner) { |
| + const char kSqlLoadPreviewsVersions[] = |
| + "SELECT type version FROM " PREVIEWS_TYPE_VERSION_TABLE_NAME; |
|
tbansal1
2017/01/23 20:06:11
missing comma
s/type/type,/
dougarnett
2017/01/24 00:52:38
Done.
|
| + |
| + sql::Statement statement(db->GetUniqueStatement(kSqlLoadPreviewsVersions)); |
| + |
| + std::unique_ptr<std::map<PreviewsType, int>> stored_versions( |
|
tbansal1
2017/01/23 20:06:11
This could be just a regular map..right? instead o
dougarnett
2017/01/24 00:52:38
Done.
|
| + new std::map<PreviewsType, int>()); |
| + while (statement.Step()) { |
| + PreviewsType type = static_cast<PreviewsType>(statement.ColumnInt(0)); |
| + int version = statement.ColumnInt(1); |
| + stored_versions->insert({type, version}); |
| + } |
| + |
| + std::unique_ptr<std::vector<std::pair<PreviewsType, int>>> enabled_previews( |
| + GetEnabledPreviews()); |
| + |
| + for (std::vector<std::pair<PreviewsType, int>>::iterator it = |
|
tbansal1
2017/01/23 20:06:11
Can this be a const_iterator?
dougarnett
2017/01/24 00:52:38
Done.
|
| + enabled_previews->begin(); |
| + it != enabled_previews->end(); ++it) { |
| + PreviewsType type = it->first; |
| + int current_version = it->second; |
| + std::map<PreviewsType, int>::iterator stored_it = |
| + stored_versions->find(type); |
| + if (stored_it == stored_versions->end()) { |
| + InsertPreviewsVersionInDataBase(db, runner, type, current_version); |
| + } else if (stored_it->second != current_version) { |
| + ClearBlacklistForTypeInDataBase(db, runner, type); |
|
tbansal1
2017/01/23 20:06:11
IIUC,
DCHECK_GE(current_version, stored_it->secon
dougarnett
2017/01/24 00:52:38
sg
|
| + UpdatePreviewsVersionInDataBase(db, runner, type, current_version); |
| + } |
| + } |
| +} |
| + |
| void LoadBlackListFromDataBase( |
| sql::Connection* db, |
| scoped_refptr<base::SingleThreadTaskRunner> runner, |
| LoadBlackListCallback callback) { |
| + // First handle any update needed wrt version of enabled previews. |
| + CheckAndReconcileEnabledPreviewsVersionWithDataBase(db, runner); |
| + |
| // Gets the table sorted by host and time. Limits the number of hosts using |
| // most recent opt_out time as the limiting function. Sorting is free due to |
| // the table structure, and it improves performance in the loop below. |