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 // it can be used inline in other SQL statements below. | 26 // it can be used inline in other SQL statements below. |
27 #define OFFLINE_PAGES_TABLE_NAME "offlinepages_v1" | 27 #define OFFLINE_PAGES_TABLE_NAME "offlinepages_v1" |
28 | 28 |
29 bool CreateOfflinePagesTable(sql::Connection* db) { | 29 bool CreateOfflinePagesTable(sql::Connection* db) { |
30 const char kSql[] = "CREATE TABLE IF NOT EXISTS " OFFLINE_PAGES_TABLE_NAME | 30 const char kSql[] = "CREATE TABLE IF NOT EXISTS " OFFLINE_PAGES_TABLE_NAME |
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," | |
37 " client_namespace VARCHAR NOT NULL," | 36 " client_namespace VARCHAR NOT NULL," |
38 " client_id VARCHAR NOT NULL," | 37 " client_id VARCHAR NOT NULL," |
39 " online_url VARCHAR NOT NULL," | 38 " online_url VARCHAR NOT NULL," |
40 " file_path VARCHAR NOT NULL," | 39 " file_path VARCHAR NOT NULL," |
41 " title VARCHAR NOT NULL DEFAULT ''," | 40 " title VARCHAR NOT NULL DEFAULT ''," |
42 " original_url VARCHAR NOT NULL DEFAULT ''" | 41 " original_url VARCHAR NOT NULL DEFAULT ''" |
43 ")"; | 42 ")"; |
44 return db->Execute(kSql); | 43 return db->Execute(kSql); |
45 } | 44 } |
46 | 45 |
(...skipping 22 matching lines...) Expand all Loading... |
69 "access_count, client_namespace, client_id, " | 68 "access_count, client_namespace, client_id, " |
70 "online_url, file_path " | 69 "online_url, file_path " |
71 "FROM temp_" OFFLINE_PAGES_TABLE_NAME; | 70 "FROM temp_" OFFLINE_PAGES_TABLE_NAME; |
72 return UpgradeWithQuery(db, kSql); | 71 return UpgradeWithQuery(db, kSql); |
73 } | 72 } |
74 | 73 |
75 bool UpgradeFrom53(sql::Connection* db) { | 74 bool UpgradeFrom53(sql::Connection* db) { |
76 const char kSql[] = | 75 const char kSql[] = |
77 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME | 76 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME |
78 " (offline_id, creation_time, file_size, last_access_time, " | 77 " (offline_id, creation_time, file_size, last_access_time, " |
79 "access_count, expiration_time, client_namespace, client_id, " | 78 "access_count, client_namespace, client_id, online_url, " |
80 "online_url, file_path) " | 79 "file_path) " |
81 "SELECT " | 80 "SELECT " |
82 "offline_id, creation_time, file_size, last_access_time, " | 81 "offline_id, creation_time, file_size, last_access_time, " |
83 "access_count, expiration_time, client_namespace, client_id, " | 82 "access_count, client_namespace, client_id, online_url, " |
84 "online_url, file_path " | 83 "file_path " |
85 "FROM temp_" OFFLINE_PAGES_TABLE_NAME; | 84 "FROM temp_" OFFLINE_PAGES_TABLE_NAME; |
86 return UpgradeWithQuery(db, kSql); | 85 return UpgradeWithQuery(db, kSql); |
87 } | 86 } |
88 | 87 |
89 bool UpgradeFrom54(sql::Connection* db) { | 88 bool UpgradeFrom54(sql::Connection* db) { |
90 const char kSql[] = | 89 const char kSql[] = |
91 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME | 90 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME |
92 " (offline_id, creation_time, file_size, last_access_time, " | 91 " (offline_id, creation_time, file_size, last_access_time, " |
93 "access_count, expiration_time, client_namespace, client_id, " | 92 "access_count, client_namespace, client_id, online_url, " |
94 "online_url, file_path, title) " | 93 "file_path, title) " |
95 "SELECT " | 94 "SELECT " |
96 "offline_id, creation_time, file_size, last_access_time, " | 95 "offline_id, creation_time, file_size, last_access_time, " |
97 "access_count, expiration_time, client_namespace, client_id, " | 96 "access_count, client_namespace, client_id, online_url, " |
98 "online_url, file_path, title " | 97 "file_path, title " |
99 "FROM temp_" OFFLINE_PAGES_TABLE_NAME; | 98 "FROM temp_" OFFLINE_PAGES_TABLE_NAME; |
100 return UpgradeWithQuery(db, kSql); | 99 return UpgradeWithQuery(db, kSql); |
101 } | 100 } |
102 | 101 |
103 bool UpgradeFrom55(sql::Connection* db) { | 102 bool UpgradeFrom55(sql::Connection* db) { |
104 const char kSql[] = | 103 const char kSql[] = |
105 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME | 104 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME |
106 " (offline_id, creation_time, file_size, last_access_time, " | 105 " (offline_id, creation_time, file_size, last_access_time, " |
107 "access_count, expiration_time, client_namespace, client_id, " | 106 "access_count, client_namespace, client_id, online_url, " |
108 "online_url, file_path, title) " | 107 "file_path, title) " |
109 "SELECT " | 108 "SELECT " |
110 "offline_id, creation_time, file_size, last_access_time, " | 109 "offline_id, creation_time, file_size, last_access_time, " |
111 "access_count, expiration_time, client_namespace, client_id, " | 110 "access_count, client_namespace, client_id, online_url, " |
112 "online_url, file_path, title " | 111 "file_path, title " |
113 "FROM temp_" OFFLINE_PAGES_TABLE_NAME; | 112 "FROM temp_" OFFLINE_PAGES_TABLE_NAME; |
114 return UpgradeWithQuery(db, kSql); | 113 return UpgradeWithQuery(db, kSql); |
115 } | 114 } |
| 115 |
| 116 bool UpgradeFrom56(sql::Connection* db) { |
| 117 const char kSql[] = |
| 118 "INSERT INTO " OFFLINE_PAGES_TABLE_NAME |
| 119 " (offline_id, creation_time, file_size, last_access_time, " |
| 120 "access_count, client_namespace, client_id, online_url, " |
| 121 "file_path, title, original_url) " |
| 122 "SELECT " |
| 123 "offline_id, creation_time, file_size, last_access_time, " |
| 124 "access_count, client_namespace, client_id, online_url, " |
| 125 "file_path, title, original_url " |
| 126 "FROM temp_" OFFLINE_PAGES_TABLE_NAME; |
| 127 return UpgradeWithQuery(db, kSql); |
| 128 } |
116 | 129 |
117 bool CreateSchema(sql::Connection* db) { | 130 bool CreateSchema(sql::Connection* db) { |
118 // If you create a transaction but don't Commit() it is automatically | 131 // If you create a transaction but don't Commit() it is automatically |
119 // rolled back by its destructor when it falls out of scope. | 132 // rolled back by its destructor when it falls out of scope. |
120 sql::Transaction transaction(db); | 133 sql::Transaction transaction(db); |
121 if (!transaction.Begin()) | 134 if (!transaction.Begin()) |
122 return false; | 135 return false; |
123 | 136 |
124 if (!db->DoesTableExist(OFFLINE_PAGES_TABLE_NAME)) { | 137 if (!db->DoesTableExist(OFFLINE_PAGES_TABLE_NAME)) { |
125 if (!CreateOfflinePagesTable(db)) | 138 if (!CreateOfflinePagesTable(db)) |
126 return false; | 139 return false; |
127 } | 140 } |
128 | 141 |
129 // Upgrade section. Details are described in the header file. | 142 // Upgrade section. Details are described in the header file. |
130 if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "expiration_time")) { | 143 if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "expiration_time") && |
| 144 !db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "title")) { |
131 if (!UpgradeFrom52(db)) | 145 if (!UpgradeFrom52(db)) |
132 return false; | 146 return false; |
133 } else if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "title")) { | 147 } else if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "title")) { |
134 if (!UpgradeFrom53(db)) | 148 if (!UpgradeFrom53(db)) |
135 return false; | 149 return false; |
136 } else if (db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "offline_url")) { | 150 } else if (db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "offline_url")) { |
137 if (!UpgradeFrom54(db)) | 151 if (!UpgradeFrom54(db)) |
138 return false; | 152 return false; |
139 } else if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "original_url")) { | 153 } else if (!db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "original_url")) { |
140 if (!UpgradeFrom55(db)) | 154 if (!UpgradeFrom55(db)) |
141 return false; | 155 return false; |
| 156 } else if (db->DoesColumnExist(OFFLINE_PAGES_TABLE_NAME, "expiration_time")) { |
| 157 if (!UpgradeFrom56(db)) |
| 158 return false; |
142 } | 159 } |
143 | 160 |
144 // TODO(fgorski): Add indices here. | 161 // TODO(fgorski): Add indices here. |
145 return transaction.Commit(); | 162 return transaction.Commit(); |
146 } | 163 } |
147 | 164 |
148 bool DeleteByOfflineId(sql::Connection* db, int64_t offline_id) { | 165 bool DeleteByOfflineId(sql::Connection* db, int64_t offline_id) { |
149 static const char kSql[] = | 166 static const char kSql[] = |
150 "DELETE FROM " OFFLINE_PAGES_TABLE_NAME " WHERE offline_id=?"; | 167 "DELETE FROM " OFFLINE_PAGES_TABLE_NAME " WHERE offline_id=?"; |
151 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 168 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
(...skipping 24 matching lines...) Expand all Loading... |
176 // Create an offline page item from a SQL result. Expects complete rows with | 193 // Create an offline page item from a SQL result. Expects complete rows with |
177 // all columns present. | 194 // all columns present. |
178 OfflinePageItem MakeOfflinePageItem(sql::Statement* statement) { | 195 OfflinePageItem MakeOfflinePageItem(sql::Statement* statement) { |
179 int64_t id = statement->ColumnInt64(0); | 196 int64_t id = statement->ColumnInt64(0); |
180 base::Time creation_time = | 197 base::Time creation_time = |
181 base::Time::FromInternalValue(statement->ColumnInt64(1)); | 198 base::Time::FromInternalValue(statement->ColumnInt64(1)); |
182 int64_t file_size = statement->ColumnInt64(2); | 199 int64_t file_size = statement->ColumnInt64(2); |
183 base::Time last_access_time = | 200 base::Time last_access_time = |
184 base::Time::FromInternalValue(statement->ColumnInt64(3)); | 201 base::Time::FromInternalValue(statement->ColumnInt64(3)); |
185 int access_count = statement->ColumnInt(4); | 202 int access_count = statement->ColumnInt(4); |
186 base::Time expiration_time = | 203 ClientId client_id(statement->ColumnString(5), statement->ColumnString(6)); |
187 base::Time::FromInternalValue(statement->ColumnInt64(5)); | 204 GURL url(statement->ColumnString(7)); |
188 ClientId client_id(statement->ColumnString(6), statement->ColumnString(7)); | 205 base::FilePath path(GetPathFromUTF8String(statement->ColumnString(8))); |
189 GURL url(statement->ColumnString(8)); | 206 base::string16 title = statement->ColumnString16(9); |
190 base::FilePath path(GetPathFromUTF8String(statement->ColumnString(9))); | 207 GURL original_url(statement->ColumnString(10)); |
191 base::string16 title = statement->ColumnString16(10); | |
192 GURL original_url(statement->ColumnString(11)); | |
193 | 208 |
194 OfflinePageItem item(url, id, client_id, path, file_size, creation_time); | 209 OfflinePageItem item(url, id, client_id, path, file_size, creation_time); |
195 item.last_access_time = last_access_time; | 210 item.last_access_time = last_access_time; |
196 item.access_count = access_count; | 211 item.access_count = access_count; |
197 item.expiration_time = expiration_time; | |
198 item.title = title; | 212 item.title = title; |
199 item.original_url = original_url; | 213 item.original_url = original_url; |
200 return item; | 214 return item; |
201 } | 215 } |
202 | 216 |
203 ItemActionStatus Insert(sql::Connection* db, const OfflinePageItem& item) { | 217 ItemActionStatus Insert(sql::Connection* db, const OfflinePageItem& item) { |
204 // Using 'INSERT OR FAIL' or 'INSERT OR ABORT' in the query below causes debug | 218 // Using 'INSERT OR FAIL' or 'INSERT OR ABORT' in the query below causes debug |
205 // builds to DLOG. | 219 // builds to DLOG. |
206 const char kSql[] = | 220 const char kSql[] = |
207 "INSERT OR IGNORE INTO " OFFLINE_PAGES_TABLE_NAME | 221 "INSERT OR IGNORE INTO " OFFLINE_PAGES_TABLE_NAME |
208 " (offline_id, online_url, client_namespace, client_id, file_path, " | 222 " (offline_id, online_url, client_namespace, client_id, file_path, " |
209 "file_size, creation_time, last_access_time, access_count, " | 223 "file_size, creation_time, last_access_time, access_count, " |
210 "expiration_time, title, original_url)" | 224 "title, original_url)" |
211 " VALUES " | 225 " VALUES " |
212 " (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; | 226 " (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
213 | 227 |
214 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 228 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
215 statement.BindInt64(0, item.offline_id); | 229 statement.BindInt64(0, item.offline_id); |
216 statement.BindString(1, item.url.spec()); | 230 statement.BindString(1, item.url.spec()); |
217 statement.BindString(2, item.client_id.name_space); | 231 statement.BindString(2, item.client_id.name_space); |
218 statement.BindString(3, item.client_id.id); | 232 statement.BindString(3, item.client_id.id); |
219 statement.BindString(4, GetUTF8StringFromPath(item.file_path)); | 233 statement.BindString(4, GetUTF8StringFromPath(item.file_path)); |
220 statement.BindInt64(5, item.file_size); | 234 statement.BindInt64(5, item.file_size); |
221 statement.BindInt64(6, item.creation_time.ToInternalValue()); | 235 statement.BindInt64(6, item.creation_time.ToInternalValue()); |
222 statement.BindInt64(7, item.last_access_time.ToInternalValue()); | 236 statement.BindInt64(7, item.last_access_time.ToInternalValue()); |
223 statement.BindInt(8, item.access_count); | 237 statement.BindInt(8, item.access_count); |
224 statement.BindInt64(9, item.expiration_time.ToInternalValue()); | 238 statement.BindString16(9, item.title); |
225 statement.BindString16(10, item.title); | 239 statement.BindString(10, item.original_url.spec()); |
226 statement.BindString(11, item.original_url.spec()); | |
227 if (!statement.Run()) | 240 if (!statement.Run()) |
228 return ItemActionStatus::STORE_ERROR; | 241 return ItemActionStatus::STORE_ERROR; |
229 if (db->GetLastChangeCount() == 0) | 242 if (db->GetLastChangeCount() == 0) |
230 return ItemActionStatus::ALREADY_EXISTS; | 243 return ItemActionStatus::ALREADY_EXISTS; |
231 return ItemActionStatus::SUCCESS; | 244 return ItemActionStatus::SUCCESS; |
232 } | 245 } |
233 | 246 |
234 bool Update(sql::Connection* db, const OfflinePageItem& item) { | 247 bool Update(sql::Connection* db, const OfflinePageItem& item) { |
235 const char kSql[] = | 248 const char kSql[] = |
236 "UPDATE OR IGNORE " OFFLINE_PAGES_TABLE_NAME | 249 "UPDATE OR IGNORE " OFFLINE_PAGES_TABLE_NAME |
237 " SET online_url = ?, client_namespace = ?, client_id = ?, file_path = ?," | 250 " SET online_url = ?, client_namespace = ?, client_id = ?, file_path = ?," |
238 " file_size = ?, creation_time = ?, last_access_time = ?," | 251 " file_size = ?, creation_time = ?, last_access_time = ?," |
239 " access_count = ?, expiration_time = ?, title = ?, original_url = ?" | 252 " access_count = ?, title = ?, original_url = ?" |
240 " WHERE offline_id = ?"; | 253 " WHERE offline_id = ?"; |
241 | 254 |
242 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); | 255 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
243 statement.BindString(0, item.url.spec()); | 256 statement.BindString(0, item.url.spec()); |
244 statement.BindString(1, item.client_id.name_space); | 257 statement.BindString(1, item.client_id.name_space); |
245 statement.BindString(2, item.client_id.id); | 258 statement.BindString(2, item.client_id.id); |
246 statement.BindString(3, GetUTF8StringFromPath(item.file_path)); | 259 statement.BindString(3, GetUTF8StringFromPath(item.file_path)); |
247 statement.BindInt64(4, item.file_size); | 260 statement.BindInt64(4, item.file_size); |
248 statement.BindInt64(5, item.creation_time.ToInternalValue()); | 261 statement.BindInt64(5, item.creation_time.ToInternalValue()); |
249 statement.BindInt64(6, item.last_access_time.ToInternalValue()); | 262 statement.BindInt64(6, item.last_access_time.ToInternalValue()); |
250 statement.BindInt(7, item.access_count); | 263 statement.BindInt(7, item.access_count); |
251 statement.BindInt64(8, item.expiration_time.ToInternalValue()); | 264 statement.BindString16(8, item.title); |
252 statement.BindString16(9, item.title); | 265 statement.BindString(9, item.original_url.spec()); |
253 statement.BindString(10, item.original_url.spec()); | 266 statement.BindInt64(10, item.offline_id); |
254 statement.BindInt64(11, item.offline_id); | |
255 return statement.Run() && db->GetLastChangeCount() > 0; | 267 return statement.Run() && db->GetLastChangeCount() > 0; |
256 } | 268 } |
257 | 269 |
258 bool InitDatabase(sql::Connection* db, base::FilePath path) { | 270 bool InitDatabase(sql::Connection* db, base::FilePath path) { |
259 db->set_page_size(4096); | 271 db->set_page_size(4096); |
260 db->set_cache_size(500); | 272 db->set_cache_size(500); |
261 db->set_histogram_tag("OfflinePageMetadata"); | 273 db->set_histogram_tag("OfflinePageMetadata"); |
262 db->set_exclusive_locking(); | 274 db->set_exclusive_locking(); |
263 | 275 |
264 base::File::Error err; | 276 base::File::Error err; |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 db_.reset(); | 606 db_.reset(); |
595 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 607 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
596 base::Bind(callback, success)); | 608 base::Bind(callback, success)); |
597 } | 609 } |
598 | 610 |
599 bool OfflinePageMetadataStoreSQL::CheckDb() { | 611 bool OfflinePageMetadataStoreSQL::CheckDb() { |
600 return db_ && state_ == StoreState::LOADED; | 612 return db_ && state_ == StoreState::LOADED; |
601 } | 613 } |
602 | 614 |
603 } // namespace offline_pages | 615 } // namespace offline_pages |
OLD | NEW |