Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/offline_pages/offline_page_metadata_store_sql.h" | 5 #include "components/offline_pages/offline_page_metadata_store_sql.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 | 26 |
| 27 // This is a macro instead of a const so that | 27 // This is a macro instead of a const so that |
| 28 // it can be used inline in other SQL statements below. | 28 // it can be used inline in other SQL statements below. |
| 29 #define OFFLINE_PAGES_TABLE_NAME "offlinepages_v1" | 29 #define OFFLINE_PAGES_TABLE_NAME "offlinepages_v1" |
| 30 | 30 |
| 31 bool CreateOfflinePagesTable(sql::Connection* db) { | 31 bool CreateOfflinePagesTable(sql::Connection* db) { |
| 32 const char kSql[] = "CREATE TABLE IF NOT EXISTS " OFFLINE_PAGES_TABLE_NAME | 32 const char kSql[] = "CREATE TABLE IF NOT EXISTS " OFFLINE_PAGES_TABLE_NAME |
| 33 "(offline_id INTEGER PRIMARY KEY NOT NULL," | 33 "(offline_id INTEGER PRIMARY KEY NOT NULL," |
| 34 " creation_time INTEGER NOT NULL," | 34 " creation_time INTEGER NOT NULL," |
| 35 " file_size INTEGER NOT NULL," | 35 " file_size INTEGER NOT NULL," |
| 36 " version INTEGER NOT NULL," | 36 " version INTEGER NOT NULL," |
|
Dmitry Titov
2016/09/12 23:25:41
could you add this to the kill list as well? Since
fgorski
2016/09/13 17:42:26
Done.
| |
| 37 " last_access_time INTEGER NOT NULL," | 37 " last_access_time INTEGER NOT NULL," |
| 38 " access_count INTEGER NOT NULL," | 38 " access_count INTEGER NOT NULL," |
| 39 // TODO(fgorski): Remove. Never used. | |
| 40 " status INTEGER NOT NULL DEFAULT 0," | |
| 41 // A note on this field: It will be NULL for now and is | |
| 42 // reserved for later use. We will treat NULL as | |
| 43 // "Unknown" in any subsequent queries for user_initiated | |
| 44 // values. | |
| 45 " user_initiated INTEGER," // this is actually a boolean | |
| 46 " expiration_time INTEGER NOT NULL DEFAULT 0," | 39 " expiration_time INTEGER NOT NULL DEFAULT 0," |
| 47 " client_namespace VARCHAR NOT NULL," | 40 " client_namespace VARCHAR NOT NULL," |
| 48 " client_id VARCHAR NOT NULL," | 41 " client_id VARCHAR NOT NULL," |
| 49 " online_url VARCHAR NOT NULL," | 42 " online_url VARCHAR NOT NULL," |
| 50 // TODO(fgorski): Remove. Never used. | |
| 51 " offline_url VARCHAR NOT NULL DEFAULT ''," | |
| 52 " file_path VARCHAR NOT NULL," | 43 " file_path VARCHAR NOT NULL," |
| 53 " title VARCHAR NOT NULL DEFAULT ''" | 44 " title VARCHAR NOT NULL DEFAULT ''" |
| 54 ")"; | 45 ")"; |
| 55 return db->Execute(kSql); | 46 return db->Execute(kSql); |
| 56 } | 47 } |
| 57 | 48 |
| 58 bool RefreshColumnsFrom52To54(sql::Connection* db) { | 49 bool UpgradeFrom52(sql::Connection* db) { |
| 59 if (!db->Execute("ALTER TABLE " OFFLINE_PAGES_TABLE_NAME | 50 if (!db->Execute("ALTER TABLE " OFFLINE_PAGES_TABLE_NAME |
| 60 " RENAME TO temp_" OFFLINE_PAGES_TABLE_NAME)) { | 51 " RENAME TO temp_" OFFLINE_PAGES_TABLE_NAME)) { |
| 61 return false; | 52 return false; |
| 62 } | 53 } |
| 63 if (!CreateOfflinePagesTable(db)) | 54 if (!CreateOfflinePagesTable(db)) |
| 64 return false; | 55 return false; |
| 65 if (!db->Execute( | 56 if (!db->Execute( |
| 66 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME | 57 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME |
| 67 " (offline_id, creation_time, file_size, version, last_access_time, " | 58 " (offline_id, creation_time, file_size, version, last_access_time, " |
| 68 "access_count, status, user_initiated, client_namespace, client_id, " | 59 "access_count, client_namespace, client_id, " |
| 69 "online_url, offline_url, file_path) " | 60 "online_url, file_path) " |
| 70 "SELECT offline_id, creation_time, file_size, version, " | 61 "SELECT " |
| 71 "last_access_time, " | 62 "offline_id, creation_time, file_size, version, last_access_time, " |
| 72 "access_count, status, user_initiated, client_namespace, client_id, " | 63 "access_count, client_namespace, client_id, " |
| 73 "online_url, offline_url, file_path " | 64 "online_url, file_path " |
| 74 "FROM temp_" OFFLINE_PAGES_TABLE_NAME)) { | 65 "FROM temp_" OFFLINE_PAGES_TABLE_NAME)) { |
| 75 return false; | 66 return false; |
| 76 } | 67 } |
| 77 if (!db->Execute("DROP TABLE IF EXISTS temp_" OFFLINE_PAGES_TABLE_NAME)) | 68 if (!db->Execute("DROP TABLE IF EXISTS temp_" OFFLINE_PAGES_TABLE_NAME)) |
| 78 return false; | 69 return false; |
| 79 | 70 |
| 80 return true; | 71 return true; |
| 81 } | 72 } |
| 82 | 73 |
| 83 bool RefreshColumnsFrom53To54(sql::Connection* db) { | 74 bool UpgradeFrom53(sql::Connection* db) { |
| 84 if (!db->Execute("ALTER TABLE " OFFLINE_PAGES_TABLE_NAME | 75 if (!db->Execute("ALTER TABLE " OFFLINE_PAGES_TABLE_NAME |
| 85 " RENAME TO temp_" OFFLINE_PAGES_TABLE_NAME)) { | 76 " RENAME TO temp_" OFFLINE_PAGES_TABLE_NAME)) { |
| 86 return false; | 77 return false; |
| 87 } | 78 } |
| 88 if (!CreateOfflinePagesTable(db)) | 79 if (!CreateOfflinePagesTable(db)) |
| 89 return false; | 80 return false; |
| 90 if (!db->Execute( | 81 if (!db->Execute( |
| 91 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME | 82 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME |
| 92 " (offline_id, creation_time, file_size, version, last_access_time, " | 83 " (offline_id, creation_time, file_size, version, last_access_time, " |
| 93 "access_count, status, user_initiated, client_namespace, client_id, " | 84 "access_count, expiration_time, client_namespace, client_id, " |
| 94 "online_url, offline_url, file_path, expiration_time) " | 85 "online_url, file_path) " |
| 95 "SELECT offline_id, creation_time, file_size, version, " | 86 "SELECT " |
| 96 "last_access_time, " | 87 "offline_id, creation_time, file_size, version, last_access_time, " |
| 97 "access_count, status, user_initiated, client_namespace, client_id, " | 88 "access_count, expiration_time, client_namespace, client_id, " |
| 98 "online_url, offline_url, file_path, expiration_time " | 89 "online_url, file_path " |
| 99 "FROM temp_" OFFLINE_PAGES_TABLE_NAME)) { | 90 "FROM temp_" OFFLINE_PAGES_TABLE_NAME)) { |
| 100 return false; | 91 return false; |
| 101 } | 92 } |
| 93 if (!db->Execute("DROP TABLE IF EXISTS temp_" OFFLINE_PAGES_TABLE_NAME)) | |
| 94 return false; | |
| 95 | |
| 96 return true; | |
| 97 } | |
| 98 | |
| 99 bool UpgradeFrom54(sql::Connection* db) { | |
| 100 if (!db->Execute("ALTER TABLE " OFFLINE_PAGES_TABLE_NAME | |
| 101 " RENAME TO temp_" OFFLINE_PAGES_TABLE_NAME)) { | |
| 102 return false; | |
| 103 } | |
| 104 if (!CreateOfflinePagesTable(db)) | |
| 105 return false; | |
| 106 if (!db->Execute( | |
| 107 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME | |
| 108 " (offline_id, creation_time, file_size, version, last_access_time, " | |
| 109 "access_count, expiration_time, client_namespace, client_id, " | |
| 110 "online_url, file_path, title) " | |
| 111 "SELECT " | |
| 112 "offline_id, creation_time, file_size, version, last_access_time, " | |
| 113 "access_count, expiration_time, client_namespace, client_id, " | |
| 114 "online_url, file_path, title " | |
| 115 "FROM temp_" OFFLINE_PAGES_TABLE_NAME)) { | |
| 116 return false; | |
| 117 } | |
| 102 if (!db->Execute("DROP TABLE IF EXISTS temp_" OFFLINE_PAGES_TABLE_NAME)) | 118 if (!db->Execute("DROP TABLE IF EXISTS temp_" OFFLINE_PAGES_TABLE_NAME)) |
| 103 return false; | 119 return false; |
| 104 | 120 |
| 105 return true; | 121 return true; |
| 106 } | 122 } |
| 107 | 123 |
| 108 bool CreateSchema(sql::Connection* db) { | 124 bool CreateSchema(sql::Connection* db) { |
| 109 // If you create a transaction but don't Commit() it is automatically | 125 // If you create a transaction but don't Commit() it is automatically |
| 110 // rolled back by its destructor when it falls out of scope. | 126 // rolled back by its destructor when it falls out of scope. |
| 111 sql::Transaction transaction(db); | 127 sql::Transaction transaction(db); |
| 112 if (!transaction.Begin()) | 128 if (!transaction.Begin()) |
| 113 return false; | 129 return false; |
| 114 | 130 |
| 115 if (!db->DoesTableExist(OFFLINE_PAGES_TABLE_NAME)) { | 131 if (!db->DoesTableExist(OFFLINE_PAGES_TABLE_NAME)) { |
| 116 if (!CreateOfflinePagesTable(db)) | 132 if (!CreateOfflinePagesTable(db)) |
| 117 return false; | 133 return false; |
| 118 } | 134 } |
| 119 | 135 |
| 136 // Last Schema update was M55. When making a new Schema update, please update | |
| 137 // all methods below to appropriately upgrade from their respective milestones | |
| 138 // and add appropriate method to cover changes from M55. | |
| 120 if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "expiration_time")) { | 139 if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "expiration_time")) { |
| 121 if (!RefreshColumnsFrom52To54(db)) | 140 if (!UpgradeFrom52(db)) |
| 122 return false; | 141 return false; |
| 123 } else if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "title")) { | 142 } else if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "title")) { |
| 124 if (!RefreshColumnsFrom53To54(db)) | 143 if (!UpgradeFrom53(db)) |
| 144 return false; | |
| 145 } else if (db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "offline_url")) { | |
| 146 if (!UpgradeFrom54(db)) | |
| 125 return false; | 147 return false; |
| 126 } | 148 } |
| 127 | 149 |
| 128 // TODO(bburns): Add indices here. | 150 // TODO(bburns): Add indices here. |
| 129 return transaction.Commit(); | 151 return transaction.Commit(); |
| 130 } | 152 } |
| 131 | 153 |
| 132 bool DeleteByOfflineId(sql::Connection* db, int64_t offline_id) { | 154 bool DeleteByOfflineId(sql::Connection* db, int64_t offline_id) { |
| 133 static const char kSql[] = | 155 static const char kSql[] = |
| 134 "DELETE FROM " OFFLINE_PAGES_TABLE_NAME " WHERE offline_id=?"; | 156 "DELETE FROM " OFFLINE_PAGES_TABLE_NAME " WHERE offline_id=?"; |
| 135 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 157 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 136 statement.BindInt64(0, offline_id); | 158 statement.BindInt64(0, offline_id); |
| 137 return statement.Run(); | 159 return statement.Run(); |
| 138 } | 160 } |
| 139 | 161 |
| 162 base::FilePath GetPathFromString(const std::string& path_string) { | |
| 163 #if defined(OS_POSIX) | |
| 164 return base::FilePath(path_string); | |
| 165 #elif defined(OS_WIN) | |
| 166 return base::FilePath(base::UTF8ToWide(path_string)); | |
| 167 #else | |
| 168 #error Unknown OS | |
| 169 #endif | |
| 170 } | |
| 171 | |
| 172 std::string GetStringFromPath(const base::FilePath& path) { | |
| 173 #if defined(OS_POSIX) | |
| 174 return path.value(); | |
| 175 #elif defined(OS_WIN) | |
| 176 return base::WideToUTF8(path.value()); | |
| 177 #else | |
| 178 #error Unknown OS | |
| 179 #endif | |
| 180 } | |
| 181 | |
| 140 // Create an offline page item from a SQL result. Expects complete rows with | 182 // Create an offline page item from a SQL result. Expects complete rows with |
| 141 // all columns present. | 183 // all columns present. |
| 142 OfflinePageItem MakeOfflinePageItem(sql::Statement* statement) { | 184 OfflinePageItem MakeOfflinePageItem(sql::Statement* statement) { |
| 143 int64_t id = statement->ColumnInt64(0); | 185 int64_t id = statement->ColumnInt64(0); |
| 144 base::Time creation_time = | 186 base::Time creation_time = |
| 145 base::Time::FromInternalValue(statement->ColumnInt64(1)); | 187 base::Time::FromInternalValue(statement->ColumnInt64(1)); |
| 146 int64_t file_size = statement->ColumnInt64(2); | 188 int64_t file_size = statement->ColumnInt64(2); |
| 147 ClientId client_id(statement->ColumnString(9), | 189 int version = statement->ColumnInt(3); |
| 148 statement->ColumnString(10)); | 190 base::Time last_access_time = |
| 149 GURL url(statement->ColumnString(11)); | 191 base::Time::FromInternalValue(statement->ColumnInt64(4)); |
| 150 #if defined(OS_POSIX) | 192 int access_count = statement->ColumnInt(5); |
| 151 base::FilePath path(statement->ColumnString(13)); | 193 base::Time expiration_time = |
| 152 #elif defined(OS_WIN) | 194 base::Time::FromInternalValue(statement->ColumnInt64(6)); |
| 153 base::FilePath path(base::UTF8ToWide(statement->ColumnString(13))); | 195 ClientId client_id(statement->ColumnString(7), statement->ColumnString(8)); |
| 154 #else | 196 GURL url(statement->ColumnString(9)); |
| 155 #error Unknown OS | 197 base::FilePath path(GetPathFromString(statement->ColumnString(10))); |
| 156 #endif | 198 base::string16 title = statement->ColumnString16(11); |
| 157 | 199 |
| 158 OfflinePageItem item(url, id, client_id, path, file_size, creation_time); | 200 OfflinePageItem item(url, id, client_id, path, file_size, creation_time); |
| 159 item.version = statement->ColumnInt(3); | 201 item.version = version; |
| 160 item.last_access_time = base::Time::FromInternalValue( | 202 item.last_access_time = last_access_time; |
| 161 statement->ColumnInt64(4)); | 203 item.access_count = access_count; |
| 162 item.access_count = statement->ColumnInt(5); | 204 item.expiration_time = expiration_time; |
| 163 item.expiration_time = | 205 item.title = title; |
| 164 base::Time::FromInternalValue(statement->ColumnInt64(8)); | |
| 165 item.title = statement->ColumnString16(14); | |
| 166 return item; | 206 return item; |
| 167 } | 207 } |
| 168 | 208 |
| 169 bool InsertOrReplace(sql::Connection* db, const OfflinePageItem& item) { | 209 bool InsertOrReplace(sql::Connection* db, const OfflinePageItem& item) { |
| 170 const char kSql[] = | 210 const char kSql[] = |
| 171 "INSERT OR REPLACE INTO " OFFLINE_PAGES_TABLE_NAME | 211 "INSERT OR REPLACE INTO " OFFLINE_PAGES_TABLE_NAME |
| 172 " (offline_id, online_url, client_namespace, client_id, file_path, " | 212 " (offline_id, online_url, client_namespace, client_id, file_path, " |
| 173 "file_size, creation_time, last_access_time, version, access_count, " | 213 "file_size, creation_time, last_access_time, version, access_count, " |
| 174 "expiration_time, title)" | 214 "expiration_time, title)" |
| 175 " VALUES " | 215 " VALUES " |
| 176 " (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; | 216 " (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
| 177 | 217 |
| 178 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 218 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 179 statement.BindInt64(0, item.offline_id); | 219 statement.BindInt64(0, item.offline_id); |
| 180 statement.BindString(1, item.url.spec()); | 220 statement.BindString(1, item.url.spec()); |
| 181 statement.BindString(2, item.client_id.name_space); | 221 statement.BindString(2, item.client_id.name_space); |
| 182 statement.BindString(3, item.client_id.id); | 222 statement.BindString(3, item.client_id.id); |
| 183 #if defined(OS_POSIX) | 223 statement.BindString(4, GetStringFromPath(item.file_path)); |
| 184 std::string path_string = item.file_path.value(); | |
| 185 #elif defined(OS_WIN) | |
| 186 std::string path_string = base::WideToUTF8(item.file_path.value()); | |
| 187 #else | |
| 188 #error Unknown OS | |
| 189 #endif | |
| 190 statement.BindString(4, path_string); | |
| 191 statement.BindInt64(5, item.file_size); | 224 statement.BindInt64(5, item.file_size); |
| 192 statement.BindInt64(6, item.creation_time.ToInternalValue()); | 225 statement.BindInt64(6, item.creation_time.ToInternalValue()); |
| 193 statement.BindInt64(7, item.last_access_time.ToInternalValue()); | 226 statement.BindInt64(7, item.last_access_time.ToInternalValue()); |
| 194 statement.BindInt(8, item.version); | 227 statement.BindInt(8, item.version); |
| 195 statement.BindInt(9, item.access_count); | 228 statement.BindInt(9, item.access_count); |
| 196 statement.BindInt64(10, item.expiration_time.ToInternalValue()); | 229 statement.BindInt64(10, item.expiration_time.ToInternalValue()); |
| 197 statement.BindString16(11, item.title); | 230 statement.BindString16(11, item.title); |
| 198 return statement.Run(); | 231 return statement.Run(); |
| 199 } | 232 } |
| 200 | 233 |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 DCHECK(db_.get()); | 460 DCHECK(db_.get()); |
| 428 if (!db_.get()) { | 461 if (!db_.get()) { |
| 429 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 462 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
| 430 base::Bind(callback)); | 463 base::Bind(callback)); |
| 431 return false; | 464 return false; |
| 432 } | 465 } |
| 433 return true; | 466 return true; |
| 434 } | 467 } |
| 435 | 468 |
| 436 } // namespace offline_pages | 469 } // namespace offline_pages |
| OLD | NEW |