Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/precache/core/precache_url_table.h" | 5 #include "components/precache/core/precache_url_table.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "sql/connection.h" | 10 #include "sql/connection.h" |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 | 32 |
| 33 PrecacheURLTable::~PrecacheURLTable() {} | 33 PrecacheURLTable::~PrecacheURLTable() {} |
| 34 | 34 |
| 35 bool PrecacheURLTable::Init(sql::Connection* db) { | 35 bool PrecacheURLTable::Init(sql::Connection* db) { |
| 36 DCHECK(!db_); // Init must only be called once. | 36 DCHECK(!db_); // Init must only be called once. |
| 37 DCHECK(db); // The database connection must be non-NULL. | 37 DCHECK(db); // The database connection must be non-NULL. |
| 38 db_ = db; | 38 db_ = db; |
| 39 return CreateTableIfNonExistent(); | 39 return CreateTableIfNonExistent(); |
| 40 } | 40 } |
| 41 | 41 |
| 42 bool PrecacheURLTable::BindStatementAndRun(const GURL& url, | |
| 43 int64_t referrer_host_id, | |
| 44 bool is_precached, | |
| 45 const base::Time& precache_time, | |
| 46 Statement* statement) { | |
| 47 statement->BindInt64(0, is_precached ? 1 : 0); | |
| 48 statement->BindInt64(1, precache_time.ToInternalValue()); | |
| 49 statement->BindInt64(2, referrer_host_id); | |
| 50 statement->BindString(3, GetKey(url)); | |
|
twifkak
2016/12/20 01:41:59
Make the order of the bindvars and the order of th
jamartin
2016/12/20 21:09:34
NA.
| |
| 51 return statement->Run(); | |
| 52 } | |
| 53 | |
| 42 void PrecacheURLTable::AddURL(const GURL& url, | 54 void PrecacheURLTable::AddURL(const GURL& url, |
| 43 int64_t referrer_host_id, | 55 int64_t referrer_host_id, |
| 44 bool is_precached, | 56 bool is_precached, |
| 57 bool was_cached, | |
| 45 const base::Time& precache_time) { | 58 const base::Time& precache_time) { |
| 46 Statement statement( | 59 Statement statement; |
| 47 db_->GetCachedStatement(SQL_FROM_HERE, | 60 if (is_precached && !was_cached) { |
|
twifkak
2016/12/20 01:41:59
Note that "is_precached" here is a misnomer, since
jamartin
2016/12/20 21:09:34
Good catch.
This is not applicable anymore but, e
| |
| 48 "INSERT OR REPLACE INTO precache_urls (url, " | 61 // We just precached from the network. Set is_download_reported = 0. |
| 49 "referrer_host_id, was_used, is_precached, time) " | 62 Statement statement( |
| 50 "VALUES(?,?,0,?,?)")); | 63 db_->GetCachedStatement(SQL_FROM_HERE, |
| 51 | 64 "INSERT OR REPLACE INTO precache_urls " |
| 52 statement.BindString(0, GetKey(url)); | 65 "(was_used, is_precached, time, " |
| 53 statement.BindInt64(1, referrer_host_id); | 66 " is_download_reported, referrer_host_id, url) " |
| 54 statement.BindInt64(2, is_precached ? 1 : 0); | 67 "VALUES(0,?,?,0,?,?)")); |
| 55 statement.BindInt64(3, precache_time.ToInternalValue()); | 68 BindStatementAndRun(url, referrer_host_id, is_precached, precache_time, |
| 56 statement.Run(); | 69 &statement); |
| 70 } else { | |
| 71 // Update the entry but do not modify is_download_reported. | |
| 72 // We need to do an INSERT possibly followed by an UPDATE because there is | |
| 73 // no INSERT OR UPDATE in sqlite. | |
| 74 Statement insert(db_->GetCachedStatement( | |
| 75 SQL_FROM_HERE, | |
| 76 "INSERT OR ABORT INTO precache_urls " | |
| 77 "(was_used, is_precached, time, referrer_host_id, url) " | |
| 78 "VALUES(0,?,?,?,?)")); | |
| 79 // If this FAILS during tests, it is because you need to set_error_callback | |
| 80 // in the SQL connection. The default behavior in DEBUG is crash whereas | |
| 81 // the default behavior live is the expected, just to return false. | |
| 82 if (!BindStatementAndRun(url, referrer_host_id, is_precached, precache_time, | |
|
twifkak
2016/12/20 01:42:00
I'd rather move this logic out of PrecacheURLTable
jamartin
2016/12/20 21:09:34
Done.
| |
| 83 &insert)) { | |
| 84 Statement update(db_->GetCachedStatement( | |
| 85 SQL_FROM_HERE, | |
| 86 "UPDATE precache_urls SET " | |
| 87 "was_used=0, is_precached=?, time=?, referrer_host_id=?" | |
| 88 "WHERE url=?")); | |
| 89 BindStatementAndRun(url, referrer_host_id, is_precached, precache_time, | |
| 90 &update); | |
| 91 } | |
| 92 } | |
| 57 } | 93 } |
| 58 | 94 |
| 59 PrecacheURLInfo PrecacheURLTable::GetURLInfo(const GURL& url) { | 95 PrecacheURLInfo PrecacheURLTable::GetURLInfo(const GURL& url) { |
| 60 Statement statement(db_->GetCachedStatement( | 96 Statement statement(db_->GetCachedStatement( |
| 61 SQL_FROM_HERE, | 97 SQL_FROM_HERE, |
| 62 "SELECT is_precached, was_used FROM precache_urls WHERE url=?")); | 98 "SELECT is_precached, was_used FROM precache_urls WHERE url=?")); |
| 63 statement.BindString(0, GetKey(url)); | 99 statement.BindString(0, GetKey(url)); |
| 64 | 100 |
| 65 if (statement.Step()) { | 101 if (statement.Step()) { |
| 66 return {/*present=*/true, /*is_precached=*/statement.ColumnBool(0), | 102 return {/*present=*/true, /*is_precached=*/statement.ColumnBool(0), |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 86 db_->GetCachedStatement(SQL_FROM_HERE, | 122 db_->GetCachedStatement(SQL_FROM_HERE, |
| 87 "UPDATE precache_urls SET is_precached=0 " | 123 "UPDATE precache_urls SET is_precached=0 " |
| 88 "WHERE url=? and is_precached=1")); | 124 "WHERE url=? and is_precached=1")); |
| 89 statement.BindString(0, GetKey(url)); | 125 statement.BindString(0, GetKey(url)); |
| 90 statement.Run(); | 126 statement.Run(); |
| 91 } | 127 } |
| 92 | 128 |
| 93 void PrecacheURLTable::GetURLListForReferrerHost( | 129 void PrecacheURLTable::GetURLListForReferrerHost( |
| 94 int64_t referrer_host_id, | 130 int64_t referrer_host_id, |
| 95 std::vector<GURL>* used_urls, | 131 std::vector<GURL>* used_urls, |
| 96 std::vector<GURL>* unused_urls) { | 132 std::vector<GURL>* downloaded_urls) { |
| 97 Statement statement(db_->GetCachedStatement( | 133 Statement statement( |
| 98 SQL_FROM_HERE, | 134 db_->GetCachedStatement(SQL_FROM_HERE, |
| 99 "SELECT url, was_used from precache_urls where referrer_host_id=?")); | 135 "SELECT url, was_used, is_download_reported " |
| 136 "from precache_urls where referrer_host_id=?")); | |
| 100 statement.BindInt64(0, referrer_host_id); | 137 statement.BindInt64(0, referrer_host_id); |
| 101 while (statement.Step()) { | 138 while (statement.Step()) { |
| 102 GURL url(statement.ColumnString(0)); | 139 GURL url(statement.ColumnString(0)); |
| 103 if (statement.ColumnInt(1)) | 140 if (statement.ColumnInt(1)) |
| 104 used_urls->push_back(url); | 141 used_urls->push_back(url); |
| 105 else | 142 if (!statement.ColumnInt(2)) |
| 106 unused_urls->push_back(url); | 143 downloaded_urls->push_back(url); |
| 144 } | |
| 145 // Set is_download_reported for all the downloaded_urls. | |
| 146 if (!downloaded_urls->empty()) { | |
|
twifkak
2016/12/20 01:42:00
Likewise, consider moving this block into a separa
jamartin
2016/12/20 21:09:34
Done. I should have noticed this when I was testin
| |
| 147 Statement update(db_->GetCachedStatement( | |
| 148 SQL_FROM_HERE, | |
| 149 "UPDATE precache_urls SET is_download_reported=1 " | |
| 150 "WHERE referrer_host_id=?")); | |
| 151 update.BindInt64(0, referrer_host_id); | |
| 152 update.Run(); | |
| 107 } | 153 } |
| 108 } | 154 } |
| 109 | 155 |
| 110 void PrecacheURLTable::ClearAllForReferrerHost(int64_t referrer_host_id) { | 156 void PrecacheURLTable::ClearAllForReferrerHost(int64_t referrer_host_id) { |
| 111 // Delete the URLs that are not precached. | 157 // Delete the URLs that are not precached. |
| 112 Statement delete_statement( | 158 Statement delete_statement( |
| 113 db_->GetCachedStatement(SQL_FROM_HERE, | 159 db_->GetCachedStatement(SQL_FROM_HERE, |
| 114 "DELETE FROM precache_urls WHERE " | 160 "DELETE FROM precache_urls WHERE " |
| 115 "referrer_host_id=? AND is_precached=0")); | 161 "referrer_host_id=? AND is_precached=0")); |
| 116 delete_statement.BindInt64(0, referrer_host_id); | 162 delete_statement.BindInt64(0, referrer_host_id); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 146 SQL_FROM_HERE, | 192 SQL_FROM_HERE, |
| 147 "SELECT url, time FROM precache_urls where is_precached=1")); | 193 "SELECT url, time FROM precache_urls where is_precached=1")); |
| 148 | 194 |
| 149 while (statement.Step()) { | 195 while (statement.Step()) { |
| 150 GURL url = GURL(statement.ColumnString(0)); | 196 GURL url = GURL(statement.ColumnString(0)); |
| 151 (*map)[url] = base::Time::FromInternalValue(statement.ColumnInt64(1)); | 197 (*map)[url] = base::Time::FromInternalValue(statement.ColumnInt64(1)); |
| 152 } | 198 } |
| 153 } | 199 } |
| 154 | 200 |
| 155 bool PrecacheURLTable::CreateTableIfNonExistent() { | 201 bool PrecacheURLTable::CreateTableIfNonExistent() { |
| 202 // TODO(jamartin): The PRIMARY KEY should be (url, referrer_host_id). | |
| 156 if (!db_->DoesTableExist("precache_urls")) { | 203 if (!db_->DoesTableExist("precache_urls")) { |
| 157 return db_->Execute( | 204 return db_->Execute( |
| 158 "CREATE TABLE precache_urls " | 205 "CREATE TABLE precache_urls " |
| 159 "(url TEXT PRIMARY KEY, referrer_host_id INTEGER, was_used INTEGER, " | 206 "(url TEXT PRIMARY KEY, referrer_host_id INTEGER, was_used INTEGER, " |
| 160 "is_precached INTEGER, " | 207 "is_precached INTEGER, " |
| 161 "time INTEGER)"); | 208 "time INTEGER, is_download_reported INTEGER)"); |
| 162 } else { | 209 } else { |
| 163 // Migrate the table by creating the missing columns. | 210 // Migrate the table by creating the missing columns. |
| 164 if (!db_->DoesColumnExist("precache_urls", "was_used") && | 211 if (!db_->DoesColumnExist("precache_urls", "was_used") && |
| 165 !db_->Execute("ALTER TABLE precache_urls ADD COLUMN was_used INTEGER")) | 212 !db_->Execute("ALTER TABLE precache_urls " |
| 213 "ADD COLUMN was_used INTEGER")) { | |
| 166 return false; | 214 return false; |
| 215 } | |
| 167 if (!db_->DoesColumnExist("precache_urls", "is_precached") && | 216 if (!db_->DoesColumnExist("precache_urls", "is_precached") && |
| 168 !db_->Execute( | 217 !db_->Execute("ALTER TABLE precache_urls ADD COLUMN is_precached " |
| 169 "ALTER TABLE precache_urls ADD COLUMN is_precached " | 218 "INTEGER default 1")) { |
| 170 "INTEGER default 1")) | |
| 171 return false; | 219 return false; |
| 220 } | |
| 172 if (!db_->DoesColumnExist("precache_urls", "referrer_host_id") && | 221 if (!db_->DoesColumnExist("precache_urls", "referrer_host_id") && |
| 173 !db_->Execute( | 222 !db_->Execute( |
| 174 "ALTER TABLE precache_urls ADD COLUMN referrer_host_id INTEGER")) | 223 "ALTER TABLE precache_urls ADD COLUMN referrer_host_id INTEGER")) { |
| 175 return false; | 224 return false; |
| 225 } | |
| 226 if (!db_->DoesColumnExist("precache_urls", "is_download_reported") && | |
| 227 !db_->Execute("ALTER TABLE precache_urls " | |
| 228 "ADD COLUMN is_download_reported INTEGER")) { | |
| 229 // The FSM for is_download_reported has q_0 = 0 and delta of: | |
| 230 // Q Sigma (conditioned on host id) Q' | |
| 231 // 0 GetURLListForReferrerHost 1 // Reported. | |
| 232 // 1 AddUrl(is_precached && !was_cached) 0 // Downloaded from network. | |
| 233 return false; | |
| 234 } | |
| 176 } | 235 } |
| 177 return true; | 236 return true; |
| 178 } | 237 } |
| 179 | 238 |
| 180 } // namespace precache | 239 } // namespace precache |
| OLD | NEW |