| 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 20 matching lines...) Expand all Loading... |
| 31 "(offline_id INTEGER PRIMARY KEY NOT NULL," | 31 "(offline_id INTEGER PRIMARY KEY NOT NULL," |
| 32 " creation_time INTEGER NOT NULL," | 32 " creation_time INTEGER NOT NULL," |
| 33 " file_size INTEGER NOT NULL," | 33 " file_size INTEGER NOT NULL," |
| 34 " last_access_time INTEGER NOT NULL," | 34 " last_access_time INTEGER NOT NULL," |
| 35 " access_count INTEGER NOT NULL," | 35 " access_count INTEGER NOT NULL," |
| 36 " expiration_time INTEGER NOT NULL DEFAULT 0," | 36 " expiration_time INTEGER NOT NULL DEFAULT 0," |
| 37 " client_namespace VARCHAR NOT NULL," | 37 " client_namespace VARCHAR NOT NULL," |
| 38 " client_id VARCHAR NOT NULL," | 38 " client_id VARCHAR NOT NULL," |
| 39 " online_url VARCHAR NOT NULL," | 39 " online_url VARCHAR NOT NULL," |
| 40 " file_path VARCHAR NOT NULL," | 40 " file_path VARCHAR NOT NULL," |
| 41 " title VARCHAR NOT NULL DEFAULT ''" | 41 " title VARCHAR NOT NULL DEFAULT ''," |
| 42 " original_url VARCHAR NOT NULL DEFAULT ''" |
| 42 ")"; | 43 ")"; |
| 43 return db->Execute(kSql); | 44 return db->Execute(kSql); |
| 44 } | 45 } |
| 45 | 46 |
| 46 bool UpgradeWithQuery(sql::Connection* db, const char* upgrade_sql) { | 47 bool UpgradeWithQuery(sql::Connection* db, const char* upgrade_sql) { |
| 47 if (!db->Execute("ALTER TABLE " OFFLINE_PAGES_TABLE_NAME | 48 if (!db->Execute("ALTER TABLE " OFFLINE_PAGES_TABLE_NAME |
| 48 " RENAME TO temp_" OFFLINE_PAGES_TABLE_NAME)) { | 49 " RENAME TO temp_" OFFLINE_PAGES_TABLE_NAME)) { |
| 49 return false; | 50 return false; |
| 50 } | 51 } |
| 51 if (!CreateOfflinePagesTable(db)) | 52 if (!CreateOfflinePagesTable(db)) |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 "access_count, expiration_time, client_namespace, client_id, " | 93 "access_count, expiration_time, client_namespace, client_id, " |
| 93 "online_url, file_path, title) " | 94 "online_url, file_path, title) " |
| 94 "SELECT " | 95 "SELECT " |
| 95 "offline_id, creation_time, file_size, last_access_time, " | 96 "offline_id, creation_time, file_size, last_access_time, " |
| 96 "access_count, expiration_time, client_namespace, client_id, " | 97 "access_count, expiration_time, client_namespace, client_id, " |
| 97 "online_url, file_path, title " | 98 "online_url, file_path, title " |
| 98 "FROM temp_" OFFLINE_PAGES_TABLE_NAME; | 99 "FROM temp_" OFFLINE_PAGES_TABLE_NAME; |
| 99 return UpgradeWithQuery(db, kSql); | 100 return UpgradeWithQuery(db, kSql); |
| 100 } | 101 } |
| 101 | 102 |
| 103 bool UpgradeFrom55(sql::Connection* db) { |
| 104 const char kSql[] = |
| 105 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME |
| 106 " (offline_id, creation_time, file_size, last_access_time, " |
| 107 "access_count, expiration_time, client_namespace, client_id, " |
| 108 "online_url, file_path, title) " |
| 109 "SELECT " |
| 110 "offline_id, creation_time, file_size, last_access_time, " |
| 111 "access_count, expiration_time, client_namespace, client_id, " |
| 112 "online_url, file_path, title " |
| 113 "FROM temp_" OFFLINE_PAGES_TABLE_NAME; |
| 114 return UpgradeWithQuery(db, kSql); |
| 115 } |
| 116 |
| 102 bool CreateSchema(sql::Connection* db) { | 117 bool CreateSchema(sql::Connection* db) { |
| 103 // If you create a transaction but don't Commit() it is automatically | 118 // If you create a transaction but don't Commit() it is automatically |
| 104 // rolled back by its destructor when it falls out of scope. | 119 // rolled back by its destructor when it falls out of scope. |
| 105 sql::Transaction transaction(db); | 120 sql::Transaction transaction(db); |
| 106 if (!transaction.Begin()) | 121 if (!transaction.Begin()) |
| 107 return false; | 122 return false; |
| 108 | 123 |
| 109 if (!db->DoesTableExist(OFFLINE_PAGES_TABLE_NAME)) { | 124 if (!db->DoesTableExist(OFFLINE_PAGES_TABLE_NAME)) { |
| 110 if (!CreateOfflinePagesTable(db)) | 125 if (!CreateOfflinePagesTable(db)) |
| 111 return false; | 126 return false; |
| 112 } | 127 } |
| 113 | 128 |
| 114 // Upgrade section. Details are described in the header file. | 129 // Upgrade section. Details are described in the header file. |
| 115 if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "expiration_time")) { | 130 if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "expiration_time")) { |
| 116 if (!UpgradeFrom52(db)) | 131 if (!UpgradeFrom52(db)) |
| 117 return false; | 132 return false; |
| 118 } else if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "title")) { | 133 } else if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "title")) { |
| 119 if (!UpgradeFrom53(db)) | 134 if (!UpgradeFrom53(db)) |
| 120 return false; | 135 return false; |
| 121 } else if (db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "offline_url")) { | 136 } else if (db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "offline_url")) { |
| 122 if (!UpgradeFrom54(db)) | 137 if (!UpgradeFrom54(db)) |
| 123 return false; | 138 return false; |
| 139 } else if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "original_url")) { |
| 140 if (!UpgradeFrom55(db)) |
| 141 return false; |
| 124 } | 142 } |
| 125 | 143 |
| 126 // TODO(fgorski): Add indices here. | 144 // TODO(fgorski): Add indices here. |
| 127 return transaction.Commit(); | 145 return transaction.Commit(); |
| 128 } | 146 } |
| 129 | 147 |
| 130 bool DeleteByOfflineId(sql::Connection* db, int64_t offline_id) { | 148 bool DeleteByOfflineId(sql::Connection* db, int64_t offline_id) { |
| 131 static const char kSql[] = | 149 static const char kSql[] = |
| 132 "DELETE FROM " OFFLINE_PAGES_TABLE_NAME " WHERE offline_id=?"; | 150 "DELETE FROM " OFFLINE_PAGES_TABLE_NAME " WHERE offline_id=?"; |
| 133 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 151 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 164 int64_t file_size = statement->ColumnInt64(2); | 182 int64_t file_size = statement->ColumnInt64(2); |
| 165 base::Time last_access_time = | 183 base::Time last_access_time = |
| 166 base::Time::FromInternalValue(statement->ColumnInt64(3)); | 184 base::Time::FromInternalValue(statement->ColumnInt64(3)); |
| 167 int access_count = statement->ColumnInt(4); | 185 int access_count = statement->ColumnInt(4); |
| 168 base::Time expiration_time = | 186 base::Time expiration_time = |
| 169 base::Time::FromInternalValue(statement->ColumnInt64(5)); | 187 base::Time::FromInternalValue(statement->ColumnInt64(5)); |
| 170 ClientId client_id(statement->ColumnString(6), statement->ColumnString(7)); | 188 ClientId client_id(statement->ColumnString(6), statement->ColumnString(7)); |
| 171 GURL url(statement->ColumnString(8)); | 189 GURL url(statement->ColumnString(8)); |
| 172 base::FilePath path(GetPathFromUTF8String(statement->ColumnString(9))); | 190 base::FilePath path(GetPathFromUTF8String(statement->ColumnString(9))); |
| 173 base::string16 title = statement->ColumnString16(10); | 191 base::string16 title = statement->ColumnString16(10); |
| 192 GURL original_url(statement->ColumnString(11)); |
| 174 | 193 |
| 175 OfflinePageItem item(url, id, client_id, path, file_size, creation_time); | 194 OfflinePageItem item(url, id, client_id, path, file_size, creation_time); |
| 176 item.last_access_time = last_access_time; | 195 item.last_access_time = last_access_time; |
| 177 item.access_count = access_count; | 196 item.access_count = access_count; |
| 178 item.expiration_time = expiration_time; | 197 item.expiration_time = expiration_time; |
| 179 item.title = title; | 198 item.title = title; |
| 199 item.original_url = original_url; |
| 180 return item; | 200 return item; |
| 181 } | 201 } |
| 182 | 202 |
| 183 ItemActionStatus Insert(sql::Connection* db, const OfflinePageItem& item) { | 203 ItemActionStatus Insert(sql::Connection* db, const OfflinePageItem& item) { |
| 184 // Using 'INSERT OR FAIL' or 'INSERT OR ABORT' in the query below causes debug | 204 // Using 'INSERT OR FAIL' or 'INSERT OR ABORT' in the query below causes debug |
| 185 // builds to DLOG. | 205 // builds to DLOG. |
| 186 const char kSql[] = | 206 const char kSql[] = |
| 187 "INSERT OR IGNORE INTO " OFFLINE_PAGES_TABLE_NAME | 207 "INSERT OR IGNORE INTO " OFFLINE_PAGES_TABLE_NAME |
| 188 " (offline_id, online_url, client_namespace, client_id, file_path, " | 208 " (offline_id, online_url, client_namespace, client_id, file_path, " |
| 189 "file_size, creation_time, last_access_time, access_count, " | 209 "file_size, creation_time, last_access_time, access_count, " |
| 190 "expiration_time, title)" | 210 "expiration_time, title, original_url)" |
| 191 " VALUES " | 211 " VALUES " |
| 192 " (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; | 212 " (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
| 193 | 213 |
| 194 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 214 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 195 statement.BindInt64(0, item.offline_id); | 215 statement.BindInt64(0, item.offline_id); |
| 196 statement.BindString(1, item.url.spec()); | 216 statement.BindString(1, item.url.spec()); |
| 197 statement.BindString(2, item.client_id.name_space); | 217 statement.BindString(2, item.client_id.name_space); |
| 198 statement.BindString(3, item.client_id.id); | 218 statement.BindString(3, item.client_id.id); |
| 199 statement.BindString(4, GetUTF8StringFromPath(item.file_path)); | 219 statement.BindString(4, GetUTF8StringFromPath(item.file_path)); |
| 200 statement.BindInt64(5, item.file_size); | 220 statement.BindInt64(5, item.file_size); |
| 201 statement.BindInt64(6, item.creation_time.ToInternalValue()); | 221 statement.BindInt64(6, item.creation_time.ToInternalValue()); |
| 202 statement.BindInt64(7, item.last_access_time.ToInternalValue()); | 222 statement.BindInt64(7, item.last_access_time.ToInternalValue()); |
| 203 statement.BindInt(8, item.access_count); | 223 statement.BindInt(8, item.access_count); |
| 204 statement.BindInt64(9, item.expiration_time.ToInternalValue()); | 224 statement.BindInt64(9, item.expiration_time.ToInternalValue()); |
| 205 statement.BindString16(10, item.title); | 225 statement.BindString16(10, item.title); |
| 226 statement.BindString(11, item.original_url.spec()); |
| 206 if (!statement.Run()) | 227 if (!statement.Run()) |
| 207 return ItemActionStatus::STORE_ERROR; | 228 return ItemActionStatus::STORE_ERROR; |
| 208 if (db->GetLastChangeCount() == 0) | 229 if (db->GetLastChangeCount() == 0) |
| 209 return ItemActionStatus::ALREADY_EXISTS; | 230 return ItemActionStatus::ALREADY_EXISTS; |
| 210 return ItemActionStatus::SUCCESS; | 231 return ItemActionStatus::SUCCESS; |
| 211 } | 232 } |
| 212 | 233 |
| 213 bool Update(sql::Connection* db, const OfflinePageItem& item) { | 234 bool Update(sql::Connection* db, const OfflinePageItem& item) { |
| 214 const char kSql[] = | 235 const char kSql[] = |
| 215 "UPDATE OR IGNORE " OFFLINE_PAGES_TABLE_NAME | 236 "UPDATE OR IGNORE " OFFLINE_PAGES_TABLE_NAME |
| 216 " SET online_url = ?, client_namespace = ?, client_id = ?, file_path = ?," | 237 " SET online_url = ?, client_namespace = ?, client_id = ?, file_path = ?," |
| 217 " file_size = ?, creation_time = ?, last_access_time = ?," | 238 " file_size = ?, creation_time = ?, last_access_time = ?," |
| 218 " access_count = ?, expiration_time = ?, title = ?" | 239 " access_count = ?, expiration_time = ?, title = ?, original_url = ?" |
| 219 " WHERE offline_id = ?"; | 240 " WHERE offline_id = ?"; |
| 220 | 241 |
| 221 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 242 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 222 statement.BindString(0, item.url.spec()); | 243 statement.BindString(0, item.url.spec()); |
| 223 statement.BindString(1, item.client_id.name_space); | 244 statement.BindString(1, item.client_id.name_space); |
| 224 statement.BindString(2, item.client_id.id); | 245 statement.BindString(2, item.client_id.id); |
| 225 statement.BindString(3, GetUTF8StringFromPath(item.file_path)); | 246 statement.BindString(3, GetUTF8StringFromPath(item.file_path)); |
| 226 statement.BindInt64(4, item.file_size); | 247 statement.BindInt64(4, item.file_size); |
| 227 statement.BindInt64(5, item.creation_time.ToInternalValue()); | 248 statement.BindInt64(5, item.creation_time.ToInternalValue()); |
| 228 statement.BindInt64(6, item.last_access_time.ToInternalValue()); | 249 statement.BindInt64(6, item.last_access_time.ToInternalValue()); |
| 229 statement.BindInt(7, item.access_count); | 250 statement.BindInt(7, item.access_count); |
| 230 statement.BindInt64(8, item.expiration_time.ToInternalValue()); | 251 statement.BindInt64(8, item.expiration_time.ToInternalValue()); |
| 231 statement.BindString16(9, item.title); | 252 statement.BindString16(9, item.title); |
| 232 statement.BindInt64(10, item.offline_id); | 253 statement.BindString(10, item.original_url.spec()); |
| 254 statement.BindInt64(11, item.offline_id); |
| 233 return statement.Run() && db->GetLastChangeCount() > 0; | 255 return statement.Run() && db->GetLastChangeCount() > 0; |
| 234 } | 256 } |
| 235 | 257 |
| 236 bool InitDatabase(sql::Connection* db, base::FilePath path) { | 258 bool InitDatabase(sql::Connection* db, base::FilePath path) { |
| 237 db->set_page_size(4096); | 259 db->set_page_size(4096); |
| 238 db->set_cache_size(500); | 260 db->set_cache_size(500); |
| 239 db->set_histogram_tag("OfflinePageMetadata"); | 261 db->set_histogram_tag("OfflinePageMetadata"); |
| 240 db->set_exclusive_locking(); | 262 db->set_exclusive_locking(); |
| 241 | 263 |
| 242 base::File::Error err; | 264 base::File::Error err; |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 | 600 |
| 579 bool OfflinePageMetadataStoreSQL::CheckDb(const base::Closure& callback) { | 601 bool OfflinePageMetadataStoreSQL::CheckDb(const base::Closure& callback) { |
| 580 if (!db_.get() || state_ != StoreState::LOADED) { | 602 if (!db_.get() || state_ != StoreState::LOADED) { |
| 581 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); | 603 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); |
| 582 return false; | 604 return false; |
| 583 } | 605 } |
| 584 return true; | 606 return true; |
| 585 } | 607 } |
| 586 | 608 |
| 587 } // namespace offline_pages | 609 } // namespace offline_pages |
| OLD | NEW |