OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/history/thumbnail_database.h" | 5 #include "chrome/browser/history/thumbnail_database.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 21 matching lines...) Expand all Loading... | |
32 icon_mapping->mapping_id = statement.ColumnInt64(0); | 32 icon_mapping->mapping_id = statement.ColumnInt64(0); |
33 icon_mapping->icon_id = statement.ColumnInt64(1); | 33 icon_mapping->icon_id = statement.ColumnInt64(1); |
34 icon_mapping->icon_type = | 34 icon_mapping->icon_type = |
35 static_cast<history::IconType>(statement.ColumnInt(2)); | 35 static_cast<history::IconType>(statement.ColumnInt(2)); |
36 icon_mapping->page_url = page_url; | 36 icon_mapping->page_url = page_url; |
37 } | 37 } |
38 | 38 |
39 namespace history { | 39 namespace history { |
40 | 40 |
41 // Version number of the database. | 41 // Version number of the database. |
42 static const int kCurrentVersionNumber = 5; | 42 static const int kCurrentVersionNumber = 6; |
43 static const int kCompatibleVersionNumber = 5; | 43 static const int kCompatibleVersionNumber = 6; |
44 | 44 |
45 // Use 90 quality (out of 100) which is pretty high, because we're very | 45 // Use 90 quality (out of 100) which is pretty high, because we're very |
46 // sensitive to artifacts for these small sized, highly detailed images. | 46 // sensitive to artifacts for these small sized, highly detailed images. |
47 static const int kImageQuality = 90; | 47 static const int kImageQuality = 90; |
48 | 48 |
49 ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() { | 49 ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() { |
50 } | 50 } |
51 | 51 |
52 ThumbnailDatabase::IconMappingEnumerator::~IconMappingEnumerator() { | 52 ThumbnailDatabase::IconMappingEnumerator::~IconMappingEnumerator() { |
53 } | 53 } |
54 | 54 |
55 bool ThumbnailDatabase::IconMappingEnumerator::GetNextIconMapping( | 55 bool ThumbnailDatabase::IconMappingEnumerator::GetNextIconMapping( |
56 IconMapping* icon_mapping) { | 56 IconMapping* icon_mapping) { |
57 if (!statement_.Step()) | 57 if (!statement_.Step()) |
58 return false; | 58 return false; |
59 FillIconMapping(statement_, GURL(statement_.ColumnString(3)), icon_mapping); | 59 FillIconMapping(statement_, GURL(statement_.ColumnString(3)), icon_mapping); |
60 return true; | 60 return true; |
61 } | 61 } |
62 | 62 |
63 ThumbnailDatabase::ThumbnailDatabase() | 63 ThumbnailDatabase::ThumbnailDatabase() |
64 : history_publisher_(NULL), | 64 : history_publisher_(NULL), |
65 use_top_sites_(false) { | 65 use_top_sites_(false) { |
66 } | 66 } |
67 | 67 |
68 sql::InitStatus ThumbnailDatabase::CantUpgradeToVersion(int cur_version) { | 68 sql::InitStatus ThumbnailDatabase::CantUpgradeToVersion(int cur_version) { |
69 LOG(WARNING) << "Unable to update to thumbnail database to version 4" << | 69 LOG(WARNING) << "Unable to update to thumbnail database to version " << |
70 cur_version << "."; | 70 cur_version << "."; |
71 db_.Close(); | 71 db_.Close(); |
72 return sql::INIT_FAILURE; | 72 return sql::INIT_FAILURE; |
73 } | 73 } |
74 | 74 |
75 ThumbnailDatabase::~ThumbnailDatabase() { | 75 ThumbnailDatabase::~ThumbnailDatabase() { |
76 // The DBCloseScoper will delete the DB and the cache. | 76 // The DBCloseScoper will delete the DB and the cache. |
77 } | 77 } |
78 | 78 |
79 sql::InitStatus ThumbnailDatabase::Init( | 79 sql::InitStatus ThumbnailDatabase::Init( |
(...skipping 11 matching lines...) Expand all Loading... | |
91 | 91 |
92 #if defined(OS_MACOSX) | 92 #if defined(OS_MACOSX) |
93 // Exclude the thumbnails file from backups. | 93 // Exclude the thumbnails file from backups. |
94 base::mac::SetFileBackupExclusion(db_name); | 94 base::mac::SetFileBackupExclusion(db_name); |
95 #endif | 95 #endif |
96 | 96 |
97 // Create the tables. | 97 // Create the tables. |
98 if (!meta_table_.Init(&db_, kCurrentVersionNumber, | 98 if (!meta_table_.Init(&db_, kCurrentVersionNumber, |
99 kCompatibleVersionNumber) || | 99 kCompatibleVersionNumber) || |
100 !InitThumbnailTable() || | 100 !InitThumbnailTable() || |
101 !InitFaviconBitmapsTable(&db_, false) || | |
102 !InitFaviconBitmapsIndex() || | |
101 !InitFaviconsTable(&db_, false) || | 103 !InitFaviconsTable(&db_, false) || |
102 !InitFaviconsIndex() || | 104 !InitFaviconsIndex() || |
103 !InitIconMappingTable(&db_, false) || | 105 !InitIconMappingTable(&db_, false) || |
104 !InitIconMappingIndex()) { | 106 !InitIconMappingIndex()) { |
105 db_.Close(); | 107 db_.Close(); |
106 return sql::INIT_FAILURE; | 108 return sql::INIT_FAILURE; |
107 } | 109 } |
108 | 110 |
109 // Version check. We should not encounter a database too old for us to handle | 111 // Version check. We should not encounter a database too old for us to handle |
110 // in the wild, so we try to continue in that case. | 112 // in the wild, so we try to continue in that case. |
111 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { | 113 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { |
112 LOG(WARNING) << "Thumbnail database is too new."; | 114 LOG(WARNING) << "Thumbnail database is too new."; |
113 return sql::INIT_TOO_NEW; | 115 return sql::INIT_TOO_NEW; |
114 } | 116 } |
115 | 117 |
116 int cur_version = meta_table_.GetVersionNumber(); | 118 int cur_version = meta_table_.GetVersionNumber(); |
117 if (cur_version == 2) { | 119 if (cur_version == 2) { |
118 ++cur_version; | 120 ++cur_version; |
119 if (!UpgradeToVersion3()) | 121 if (!UpgradeToVersion3()) |
120 return CantUpgradeToVersion(cur_version); | 122 return CantUpgradeToVersion(cur_version); |
121 } | 123 } |
122 | 124 |
123 if (cur_version == 3) { | 125 if (cur_version == 3) { |
124 ++cur_version; | 126 ++cur_version; |
125 if (!UpgradeToVersion4() || !MigrateIconMappingData(url_db)) | 127 if (!UpgradeToVersion4() || !MigrateIconMappingData(url_db)) |
126 return CantUpgradeToVersion(cur_version); | 128 return CantUpgradeToVersion(cur_version); |
127 } | 129 } |
128 | 130 |
129 if (cur_version == 4) { | 131 if (cur_version == 4) { |
132 ++cur_version; | |
130 if (!UpgradeToVersion5()) | 133 if (!UpgradeToVersion5()) |
131 return CantUpgradeToVersion(cur_version); | 134 return CantUpgradeToVersion(cur_version); |
132 } | 135 } |
133 | 136 |
137 if (cur_version == 5) { | |
138 ++cur_version; | |
139 if (!UpgradeToVersion6()) | |
140 return CantUpgradeToVersion(cur_version); | |
141 } | |
142 | |
134 LOG_IF(WARNING, cur_version < kCurrentVersionNumber) << | 143 LOG_IF(WARNING, cur_version < kCurrentVersionNumber) << |
135 "Thumbnail database version " << cur_version << " is too old to handle."; | 144 "Thumbnail database version " << cur_version << " is too old to handle."; |
136 | 145 |
137 // Initialization is complete. | 146 // Initialization is complete. |
138 if (!transaction.Commit()) { | 147 if (!transaction.Commit()) { |
139 db_.Close(); | 148 db_.Close(); |
140 return sql::INIT_FAILURE; | 149 return sql::INIT_FAILURE; |
141 } | 150 } |
142 | 151 |
143 return sql::INIT_OK; | 152 return sql::INIT_OK; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
213 // Note: if you update the schema, don't forget to update | 222 // Note: if you update the schema, don't forget to update |
214 // CopyToTemporaryFaviconTable as well. | 223 // CopyToTemporaryFaviconTable as well. |
215 const char* name = is_temporary ? "temp_favicons" : "favicons"; | 224 const char* name = is_temporary ? "temp_favicons" : "favicons"; |
216 if (!db->DoesTableExist(name)) { | 225 if (!db->DoesTableExist(name)) { |
217 std::string sql; | 226 std::string sql; |
218 sql.append("CREATE TABLE "); | 227 sql.append("CREATE TABLE "); |
219 sql.append(name); | 228 sql.append(name); |
220 sql.append("(" | 229 sql.append("(" |
221 "id INTEGER PRIMARY KEY," | 230 "id INTEGER PRIMARY KEY," |
222 "url LONGVARCHAR NOT NULL," | 231 "url LONGVARCHAR NOT NULL," |
223 "last_updated INTEGER DEFAULT 0," | |
224 "image_data BLOB," | |
225 // Set the default icon_type as FAVICON to be consistent with | 232 // Set the default icon_type as FAVICON to be consistent with |
226 // table upgrade in UpgradeToVersion4(). | 233 // table upgrade in UpgradeToVersion4(). |
227 "icon_type INTEGER DEFAULT 1," | 234 "icon_type INTEGER DEFAULT 1," |
228 "sizes LONGVARCHAR)"); | 235 "sizes LONGVARCHAR DEFAULT '0 0')"); |
sky
2012/08/16 16:12:57
why 0 0 as a default?
pkotwicz
2012/08/16 19:22:46
The default is 0x0 because it is a very recognizab
sky
2012/08/16 20:01:41
0x0 implies there is one known size, 0x0. That isn
| |
229 if (!db->Execute(sql.c_str())) | 236 if (!db->Execute(sql.c_str())) |
230 return false; | 237 return false; |
231 } | 238 } |
232 return true; | 239 return true; |
233 } | 240 } |
234 | 241 |
235 bool ThumbnailDatabase::InitFaviconsIndex() { | 242 bool ThumbnailDatabase::InitFaviconsIndex() { |
236 // Add an index on the url column. | 243 // Add an index on the url column. |
237 return | 244 return |
238 db_.Execute("CREATE INDEX IF NOT EXISTS favicons_url ON favicons(url)"); | 245 db_.Execute("CREATE INDEX IF NOT EXISTS favicons_url ON favicons(url)"); |
239 } | 246 } |
240 | 247 |
248 bool ThumbnailDatabase::InitFaviconBitmapsTable(sql::Connection* db, | |
249 bool is_temporary) { | |
250 // Note: if you update the schema, don't forget to update | |
251 // CopyFaviconAndFaviconBitmapsToTemporaryTables as well. | |
252 const char* name = is_temporary ? "temp_favicon_bitmaps" : "favicon_bitmaps"; | |
253 if (!db->DoesTableExist(name)) { | |
254 std::string sql; | |
255 sql.append("CREATE TABLE "); | |
256 sql.append(name); | |
257 sql.append("(" | |
258 "id INTEGER PRIMARY KEY," | |
259 "icon_id INTEGER," | |
260 "last_updated INTEGER DEFAULT 0," | |
261 "image_data BLOB," | |
262 "width INTEGER DEFAULT 0," | |
263 "height INTEGER DEFAULT 0)"); | |
264 if (!db->Execute(sql.c_str())) | |
265 return false; | |
266 } | |
267 return true; | |
268 } | |
269 | |
270 bool ThumbnailDatabase::InitFaviconBitmapsIndex() { | |
271 // Add an index on the icon_id column. | |
272 return db_.Execute("CREATE INDEX IF NOT EXISTS favicon_bitmaps_icon_id ON " | |
273 "favicon_bitmaps(icon_id)"); | |
274 } | |
275 | |
241 void ThumbnailDatabase::BeginTransaction() { | 276 void ThumbnailDatabase::BeginTransaction() { |
242 db_.BeginTransaction(); | 277 db_.BeginTransaction(); |
243 } | 278 } |
244 | 279 |
245 void ThumbnailDatabase::CommitTransaction() { | 280 void ThumbnailDatabase::CommitTransaction() { |
246 db_.CommitTransaction(); | 281 db_.CommitTransaction(); |
247 } | 282 } |
248 | 283 |
249 void ThumbnailDatabase::RollbackTransaction() { | 284 void ThumbnailDatabase::RollbackTransaction() { |
250 db_.RollbackTransaction(); | 285 db_.RollbackTransaction(); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 double current_boring_score = select_statement.ColumnDouble(0); | 393 double current_boring_score = select_statement.ColumnDouble(0); |
359 bool current_clipping = select_statement.ColumnBool(1); | 394 bool current_clipping = select_statement.ColumnBool(1); |
360 bool current_at_top = select_statement.ColumnBool(2); | 395 bool current_at_top = select_statement.ColumnBool(2); |
361 base::Time last_updated = | 396 base::Time last_updated = |
362 base::Time::FromTimeT(select_statement.ColumnInt64(3)); | 397 base::Time::FromTimeT(select_statement.ColumnInt64(3)); |
363 *score = ThumbnailScore(current_boring_score, current_clipping, | 398 *score = ThumbnailScore(current_boring_score, current_clipping, |
364 current_at_top, last_updated); | 399 current_at_top, last_updated); |
365 return true; | 400 return true; |
366 } | 401 } |
367 | 402 |
368 bool ThumbnailDatabase::SetFavicon( | 403 bool ThumbnailDatabase::GetFaviconBitmaps( |
369 URLID icon_id, | 404 FaviconID icon_id, |
405 std::vector<FaviconBitmap>* favicon_bitmaps) { | |
406 DCHECK(icon_id); | |
407 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | |
408 "SELECT id, last_updated, image_data, width, height FROM favicon_bitmaps " | |
409 "WHERE icon_id=?")); | |
410 statement.BindInt64(0, icon_id); | |
411 | |
412 bool result = false; | |
sky
2012/08/16 16:12:57
Why do we need a return value here? Can't they che
pkotwicz
2012/08/16 19:22:46
We use return values in ThumbnailDatabase so that
| |
413 while (statement.Step()) { | |
414 result = true; | |
415 if (!favicon_bitmaps) | |
416 return result; | |
417 | |
418 FaviconBitmap favicon_bitmap; | |
419 favicon_bitmap.bitmap_id = statement.ColumnInt64(0); | |
420 favicon_bitmap.icon_id = icon_id; | |
421 favicon_bitmap.last_updated = | |
422 base::Time::FromTimeT(statement.ColumnInt64(1)); | |
423 if (statement.ColumnByteLength(2) > 0) { | |
424 scoped_refptr<base::RefCountedBytes> data = new base::RefCountedBytes(); | |
425 statement.ColumnBlobAsVector(2, &data->data()); | |
426 favicon_bitmap.bitmap_data = data; | |
427 } | |
428 favicon_bitmap.pixel_size = gfx::Size(statement.ColumnInt(3), | |
429 statement.ColumnInt(4)); | |
430 favicon_bitmaps->push_back(favicon_bitmap); | |
431 } | |
432 return result; | |
433 } | |
434 | |
435 FaviconBitmapID ThumbnailDatabase::AddFaviconBitmap( | |
436 FaviconID icon_id, | |
437 scoped_refptr<base::RefCountedMemory> icon_data, | |
438 base::Time time, | |
439 const gfx::Size& pixel_size) { | |
440 DCHECK(icon_id); | |
441 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | |
442 "INSERT INTO favicon_bitmaps (icon_id, image_data, last_updated, width, " | |
443 "height) VALUES (?, ?, ?, ?, ?)")); | |
444 statement.BindInt64(0, icon_id); | |
445 if (icon_data->size()) { | |
446 statement.BindBlob(1, icon_data->front(), | |
447 static_cast<int>(icon_data->size())); | |
448 } else { | |
449 statement.BindNull(1); | |
450 } | |
451 statement.BindInt64(2, time.ToTimeT()); | |
452 statement.BindInt(3, pixel_size.width()); | |
453 statement.BindInt(4, pixel_size.height()); | |
454 | |
455 if (!statement.Run()) | |
456 return 0; | |
457 return db_.GetLastInsertRowId(); | |
458 } | |
459 | |
460 bool ThumbnailDatabase::SetFaviconBitmap( | |
461 FaviconID icon_id, | |
370 scoped_refptr<base::RefCountedMemory> icon_data, | 462 scoped_refptr<base::RefCountedMemory> icon_data, |
371 base::Time time) { | 463 base::Time time) { |
372 DCHECK(icon_id); | 464 DCHECK(icon_id); |
373 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 465 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
374 "UPDATE favicons SET image_data=?, last_updated=? WHERE id=?")); | 466 "UPDATE favicon_bitmaps SET image_data=?, last_updated=? " |
sky
2012/08/16 16:12:57
This might reset multiple rows. Shouldn't the wher
pkotwicz
2012/08/16 19:22:46
Changed this to remove and insert as you suggested
| |
467 "WHERE icon_id=?")); | |
375 if (icon_data->size()) { | 468 if (icon_data->size()) { |
376 statement.BindBlob(0, icon_data->front(), | 469 statement.BindBlob(0, icon_data->front(), |
377 static_cast<int>(icon_data->size())); | 470 static_cast<int>(icon_data->size())); |
378 } else { | 471 } else { |
379 statement.BindNull(0); | 472 statement.BindNull(0); |
380 } | 473 } |
381 statement.BindInt64(1, time.ToTimeT()); | 474 statement.BindInt64(1, time.ToTimeT()); |
382 statement.BindInt64(2, icon_id); | 475 statement.BindInt64(2, icon_id); |
383 | 476 |
384 return statement.Run(); | 477 return statement.Run(); |
385 } | 478 } |
386 | 479 |
387 bool ThumbnailDatabase::SetFaviconLastUpdateTime(FaviconID icon_id, | 480 bool ThumbnailDatabase::SetFaviconSizes(FaviconID icon_id, |
388 base::Time time) { | 481 const std::string& sizes) { |
389 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 482 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
390 "UPDATE favicons SET last_updated=? WHERE id=?")); | 483 "UPDATE favicons SET sizes=? WHERE id=?")); |
391 statement.BindInt64(0, time.ToTimeT()); | 484 statement.BindString(0, sizes); |
392 statement.BindInt64(1, icon_id); | 485 statement.BindInt64(1, icon_id); |
393 | 486 |
394 return statement.Run(); | 487 return statement.Run(); |
488 } | |
489 | |
490 bool ThumbnailDatabase::SetFaviconOutOfDate(FaviconID icon_id) { | |
491 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | |
492 "UPDATE favicon_bitmaps SET last_updated=? WHERE icon_id=?")); | |
493 statement.BindInt64(0, 0); | |
494 statement.BindInt64(1, icon_id); | |
495 | |
496 return statement.Run(); | |
395 } | 497 } |
396 | 498 |
397 FaviconID ThumbnailDatabase::GetFaviconIDForFaviconURL(const GURL& icon_url, | 499 FaviconID ThumbnailDatabase::GetFaviconIDForFaviconURL(const GURL& icon_url, |
398 int required_icon_type, | 500 int required_icon_type, |
399 IconType* icon_type) { | 501 IconType* icon_type) { |
400 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 502 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
401 "SELECT id, icon_type FROM favicons WHERE url=? AND (icon_type & ? > 0) " | 503 "SELECT id, icon_type FROM favicons WHERE url=? AND (icon_type & ? > 0) " |
402 "ORDER BY icon_type DESC")); | 504 "ORDER BY icon_type DESC")); |
403 statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url)); | 505 statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url)); |
404 statement.BindInt(1, required_icon_type); | 506 statement.BindInt(1, required_icon_type); |
405 | 507 |
406 if (!statement.Step()) | 508 if (!statement.Step()) |
407 return 0; // not cached | 509 return 0; // not cached |
408 | 510 |
409 if (icon_type) | 511 if (icon_type) |
410 *icon_type = static_cast<IconType>(statement.ColumnInt(1)); | 512 *icon_type = static_cast<IconType>(statement.ColumnInt(1)); |
411 return statement.ColumnInt64(0); | 513 return statement.ColumnInt64(0); |
412 } | 514 } |
413 | 515 |
414 bool ThumbnailDatabase::GetFavicon( | 516 bool ThumbnailDatabase::GetFavicon( |
415 FaviconID icon_id, | 517 FaviconID icon_id, |
416 base::Time* last_updated, | 518 base::Time* last_updated, |
417 std::vector<unsigned char>* png_icon_data, | 519 scoped_refptr<base::RefCountedMemory>* png_icon_data, |
418 GURL* icon_url, | 520 GURL* icon_url, |
419 IconType* icon_type) { | 521 IconType* icon_type) { |
420 DCHECK(icon_id); | 522 DCHECK(icon_id); |
421 | 523 |
524 std::vector<FaviconBitmap> favicon_bitmaps; | |
525 if (!GetFaviconBitmaps(icon_id, &favicon_bitmaps)) | |
526 return false; | |
527 | |
528 if (favicon_bitmaps.size() == 0) | |
sky
2012/08/16 16:12:57
empty
pkotwicz
2012/08/16 19:22:46
Done.
| |
529 return false; | |
530 | |
531 if (last_updated) | |
532 *last_updated = favicon_bitmaps[0].last_updated; | |
533 | |
534 *png_icon_data = favicon_bitmaps[0].bitmap_data; | |
535 | |
536 return GetFaviconHeader(icon_id, icon_url, icon_type, NULL); | |
537 } | |
538 | |
539 bool ThumbnailDatabase::GetFaviconHeader( | |
540 FaviconID icon_id, | |
541 GURL* icon_url, | |
542 IconType* icon_type, | |
543 std::string* sizes) { | |
544 DCHECK(icon_id); | |
545 | |
422 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 546 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
423 "SELECT last_updated, image_data, url, icon_type " | 547 "SELECT url, icon_type, sizes FROM favicons WHERE id=?")); |
424 "FROM favicons WHERE id=?")); | |
425 statement.BindInt64(0, icon_id); | 548 statement.BindInt64(0, icon_id); |
426 | 549 |
427 if (!statement.Step()) | 550 if (!statement.Step()) |
428 return false; // No entry for the id. | 551 return false; // No entry for the id. |
429 | 552 |
430 if (last_updated) | |
431 *last_updated = base::Time::FromTimeT(statement.ColumnInt64(0)); | |
432 if (statement.ColumnByteLength(1) > 0) | |
433 statement.ColumnBlobAsVector(1, png_icon_data); | |
434 if (icon_url) | 553 if (icon_url) |
435 *icon_url = GURL(statement.ColumnString(2)); | 554 *icon_url = GURL(statement.ColumnString(0)); |
436 if (icon_type) | 555 if (icon_type) |
437 *icon_type = static_cast<history::IconType>(statement.ColumnInt(3)); | 556 *icon_type = static_cast<history::IconType>(statement.ColumnInt(1)); |
557 if (sizes) | |
558 *sizes = statement.ColumnString(2); | |
438 | 559 |
439 return true; | 560 return true; |
440 } | 561 } |
441 | 562 |
442 FaviconID ThumbnailDatabase::AddFavicon(const GURL& icon_url, | 563 FaviconID ThumbnailDatabase::AddFavicon(const GURL& icon_url, |
443 IconType icon_type) { | 564 IconType icon_type) { |
444 | 565 |
445 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 566 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, |
446 "INSERT INTO favicons (url, icon_type) VALUES (?, ?)")); | 567 "INSERT INTO favicons (url, icon_type) VALUES (?, ?)")); |
447 statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url)); | 568 statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url)); |
448 statement.BindInt(1, icon_type); | 569 statement.BindInt(1, icon_type); |
449 | 570 |
450 if (!statement.Run()) | 571 if (!statement.Run()) |
451 return 0; | 572 return 0; |
452 return db_.GetLastInsertRowId(); | 573 return db_.GetLastInsertRowId(); |
453 } | 574 } |
454 | 575 |
576 FaviconID ThumbnailDatabase::AddFavicon( | |
577 const GURL& icon_url, | |
578 IconType icon_type, | |
579 const std::string& sizes, | |
580 scoped_refptr<base::RefCountedMemory> icon_data, | |
581 base::Time time, | |
582 const gfx::Size& pixel_size) { | |
583 FaviconID icon_id = AddFavicon(icon_url, icon_type); | |
584 if (!icon_id || | |
585 !SetFaviconSizes(icon_id, sizes) || | |
586 !AddFaviconBitmap(icon_id, icon_data, time, pixel_size)) { | |
587 return 0; | |
588 } | |
589 return icon_id; | |
590 } | |
591 | |
455 bool ThumbnailDatabase::DeleteFavicon(FaviconID id) { | 592 bool ThumbnailDatabase::DeleteFavicon(FaviconID id) { |
456 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | 593 sql::Statement statement; |
594 statement.Assign(db_.GetCachedStatement(SQL_FROM_HERE, | |
457 "DELETE FROM favicons WHERE id = ?")); | 595 "DELETE FROM favicons WHERE id = ?")); |
458 statement.BindInt64(0, id); | 596 statement.BindInt64(0, id); |
597 if (!statement.Run()) | |
598 return false; | |
459 | 599 |
600 statement.Assign(db_.GetCachedStatement(SQL_FROM_HERE, | |
601 "DELETE FROM favicon_bitmaps WHERE icon_id = ?")); | |
602 statement.BindInt64(0, id); | |
460 return statement.Run(); | 603 return statement.Run(); |
461 } | 604 } |
462 | 605 |
463 bool ThumbnailDatabase::GetIconMappingForPageURL(const GURL& page_url, | 606 bool ThumbnailDatabase::GetIconMappingForPageURL(const GURL& page_url, |
464 IconType required_icon_type, | 607 IconType required_icon_type, |
465 IconMapping* icon_mapping) { | 608 IconMapping* icon_mapping) { |
466 std::vector<IconMapping> icon_mappings; | 609 std::vector<IconMapping> icon_mappings; |
467 if (!GetIconMappingsForPageURL(page_url, &icon_mappings)) | 610 if (!GetIconMappingsForPageURL(page_url, &icon_mappings)) |
468 return false; | 611 return false; |
469 | 612 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
581 | 724 |
582 IconMapping info; | 725 IconMapping info; |
583 while (e.GetNextIconMapping(&info)) { | 726 while (e.GetNextIconMapping(&info)) { |
584 // TODO: Using bulk insert to improve the performance. | 727 // TODO: Using bulk insert to improve the performance. |
585 if (!AddIconMapping(info.page_url, info.icon_id)) | 728 if (!AddIconMapping(info.page_url, info.icon_id)) |
586 return false; | 729 return false; |
587 } | 730 } |
588 return true; | 731 return true; |
589 } | 732 } |
590 | 733 |
734 bool ThumbnailDatabase::InitTemporaryTables() { | |
735 return InitIconMappingTable(&db_, true) && | |
736 InitFaviconsTable(&db_, true) && | |
737 InitFaviconBitmapsTable(&db_, true); | |
738 } | |
739 | |
740 bool ThumbnailDatabase::CommitTemporaryTables() { | |
741 const char* main_tables[] = { "icon_mapping", | |
742 "favicons", | |
743 "favicon_bitmaps" }; | |
744 const char* temporary_tables[] = { "temp_icon_mapping", | |
745 "temp_favicons", | |
746 "temp_favicon_bitmaps" }; | |
747 | |
sky
2012/08/16 16:12:57
DCHECK_EQ(arraysize(main_tables), arraysize(tempor
pkotwicz
2012/08/16 19:22:46
Done.
| |
748 for (size_t i = 0; i < arraysize(main_tables); ++i) { | |
749 // Delete the main table. | |
750 std::string sql; | |
751 sql.append("DROP TABLE "); | |
752 sql.append(main_tables[i]); | |
753 if (!db_.Execute(sql.c_str())) | |
754 return false; | |
755 | |
756 // Rename the temporary table. | |
757 sql.clear(); | |
758 sql.append("ALTER TABLE "); | |
759 sql.append(temporary_tables[i]); | |
760 sql.append(" RENAME TO "); | |
761 sql.append(main_tables[i]); | |
762 if (!db_.Execute(sql.c_str())) | |
763 return false; | |
764 } | |
765 | |
766 // The renamed tables needs indices (the temporary tables don't have any). | |
767 return InitIconMappingIndex() && | |
768 InitFaviconsIndex() && | |
769 InitFaviconBitmapsIndex(); | |
770 } | |
771 | |
591 IconMappingID ThumbnailDatabase::AddToTemporaryIconMappingTable( | 772 IconMappingID ThumbnailDatabase::AddToTemporaryIconMappingTable( |
592 const GURL& page_url, const FaviconID icon_id) { | 773 const GURL& page_url, const FaviconID icon_id) { |
593 return AddIconMapping(page_url, icon_id, true); | 774 return AddIconMapping(page_url, icon_id, true); |
594 } | 775 } |
595 | 776 |
596 bool ThumbnailDatabase::CommitTemporaryIconMappingTable() { | 777 FaviconID ThumbnailDatabase::CopyFaviconAndFaviconBitmapsToTemporaryTables( |
597 // Delete the old icon_mapping table. | 778 FaviconID source) { |
598 if (!db_.Execute("DROP TABLE icon_mapping")) | 779 sql::Statement statement; |
599 return false; | 780 statement.Assign(db_.GetCachedStatement(SQL_FROM_HERE, |
600 | 781 "INSERT INTO temp_favicons (url, icon_type, sizes) " |
601 // Rename the temporary one. | 782 "SELECT url, icon_type, sizes FROM favicons WHERE id = ?")); |
602 if (!db_.Execute("ALTER TABLE temp_icon_mapping RENAME TO icon_mapping")) | |
603 return false; | |
604 | |
605 // The renamed table needs the index (the temporary table doesn't have one). | |
606 return InitIconMappingIndex(); | |
607 } | |
608 | |
609 FaviconID ThumbnailDatabase::CopyToTemporaryFaviconTable(FaviconID source) { | |
610 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, | |
611 "INSERT INTO temp_favicons (url, last_updated, image_data, icon_type)" | |
612 "SELECT url, last_updated, image_data, icon_type " | |
613 "FROM favicons WHERE id = ?")); | |
614 statement.BindInt64(0, source); | 783 statement.BindInt64(0, source); |
615 | 784 |
616 if (!statement.Run()) | 785 if (!statement.Run()) |
617 return 0; | 786 return 0; |
618 | 787 |
619 // We return the ID of the newly inserted favicon. | 788 FaviconID new_favicon_id = db_.GetLastInsertRowId(); |
620 return db_.GetLastInsertRowId(); | |
621 } | |
622 | 789 |
623 bool ThumbnailDatabase::CommitTemporaryFaviconTable() { | 790 statement.Assign(db_.GetCachedStatement(SQL_FROM_HERE, |
624 // Delete the old favicons table. | 791 "INSERT INTO temp_favicon_bitmaps (icon_id, last_updated, image_data, " |
625 if (!db_.Execute("DROP TABLE favicons")) | 792 "width, height) " |
626 return false; | 793 "SELECT ?, last_updated, image_data, width, height " |
794 "FROM favicon_bitmaps WHERE icon_id = ?")); | |
795 statement.BindInt64(0, new_favicon_id); | |
796 statement.BindInt64(1, source); | |
797 if (!statement.Run()) | |
798 return 0; | |
627 | 799 |
628 // Rename the temporary one. | 800 return new_favicon_id; |
629 if (!db_.Execute("ALTER TABLE temp_favicons RENAME TO favicons")) | |
630 return false; | |
631 | |
632 // The renamed table needs the index (the temporary table doesn't have one). | |
633 return InitFaviconsIndex(); | |
634 } | 801 } |
635 | 802 |
636 bool ThumbnailDatabase::NeedsMigrationToTopSites() { | 803 bool ThumbnailDatabase::NeedsMigrationToTopSites() { |
637 return !use_top_sites_; | 804 return !use_top_sites_; |
638 } | 805 } |
639 | 806 |
640 bool ThumbnailDatabase::RenameAndDropThumbnails(const FilePath& old_db_file, | 807 bool ThumbnailDatabase::RenameAndDropThumbnails(const FilePath& old_db_file, |
641 const FilePath& new_db_file) { | 808 const FilePath& new_db_file) { |
642 // Init favicons table - same schema as the thumbnails. | 809 // Init favicons tables - same schema as the thumbnails. |
643 sql::Connection favicons; | 810 sql::Connection favicons; |
644 if (OpenDatabase(&favicons, new_db_file) != sql::INIT_OK) | 811 if (OpenDatabase(&favicons, new_db_file) != sql::INIT_OK) |
645 return false; | 812 return false; |
646 | 813 |
647 if (!InitFaviconsTable(&favicons, false) || | 814 if (!InitFaviconBitmapsTable(&favicons, false) || |
815 !InitFaviconsTable(&favicons, false) || | |
648 !InitIconMappingTable(&favicons, false)) { | 816 !InitIconMappingTable(&favicons, false)) { |
649 favicons.Close(); | 817 favicons.Close(); |
650 return false; | 818 return false; |
651 } | 819 } |
652 favicons.Close(); | 820 favicons.Close(); |
653 | 821 |
654 // Can't attach within a transaction. | 822 // Can't attach within a transaction. |
655 if (transaction_nesting()) | 823 if (transaction_nesting()) |
656 CommitTransaction(); | 824 CommitTransaction(); |
657 | 825 |
(...skipping 13 matching lines...) Expand all Loading... | |
671 #else | 839 #else |
672 attach.BindString(0, WideToUTF8(new_db_file.value())); | 840 attach.BindString(0, WideToUTF8(new_db_file.value())); |
673 #endif | 841 #endif |
674 | 842 |
675 if (!attach.Run()) { | 843 if (!attach.Run()) { |
676 BeginTransaction(); | 844 BeginTransaction(); |
677 return false; | 845 return false; |
678 } | 846 } |
679 } | 847 } |
680 | 848 |
681 // Move favicons to the new DB. | 849 // Move favicons and favicon_bitmaps to new DB. |
682 if (!db_.Execute("INSERT OR REPLACE INTO new_favicons.favicons " | 850 bool successfully_moved_data = |
683 "SELECT * FROM favicons")) { | 851 db_.Execute("INSERT OR REPLACE INTO new_favicons.favicon_bitmaps " |
684 DLOG(FATAL) << "Unable to copy favicons."; | 852 "SELECT * FROM favicon_bitmaps") && |
853 db_.Execute("INSERT OR REPLACE INTO new_favicons.favicons " | |
854 "SELECT * FROM favicons"); | |
855 if (!successfully_moved_data) { | |
856 DLOG(FATAL) << "Unable to copy favicons and bitmap_bitmaps."; | |
685 BeginTransaction(); | 857 BeginTransaction(); |
686 return false; | 858 return false; |
687 } | 859 } |
688 | 860 |
689 if (!db_.Execute("DETACH new_favicons")) { | 861 if (!db_.Execute("DETACH new_favicons")) { |
690 DLOG(FATAL) << "Unable to detach database."; | 862 DLOG(FATAL) << "Unable to detach database."; |
691 BeginTransaction(); | 863 BeginTransaction(); |
692 return false; | 864 return false; |
693 } | 865 } |
694 | 866 |
695 db_.Close(); | 867 db_.Close(); |
696 | 868 |
697 // Reset the DB to point to new file. | 869 // Reset the DB to point to new file. |
698 if (OpenDatabase(&db_, new_db_file) != sql::INIT_OK) | 870 if (OpenDatabase(&db_, new_db_file) != sql::INIT_OK) |
699 return false; | 871 return false; |
700 | 872 |
701 file_util::Delete(old_db_file, false); | 873 file_util::Delete(old_db_file, false); |
702 | 874 |
703 meta_table_.Reset(); | 875 meta_table_.Reset(); |
704 if (!meta_table_.Init(&db_, kCurrentVersionNumber, kCompatibleVersionNumber)) | 876 if (!meta_table_.Init(&db_, kCurrentVersionNumber, kCompatibleVersionNumber)) |
705 return false; | 877 return false; |
706 | 878 |
707 if (!InitFaviconsIndex()) | 879 if (!InitFaviconBitmapsIndex() || !InitFaviconsIndex()) |
708 return false; | 880 return false; |
709 | 881 |
710 // Reopen the transaction. | 882 // Reopen the transaction. |
711 BeginTransaction(); | 883 BeginTransaction(); |
712 use_top_sites_ = true; | 884 use_top_sites_ = true; |
713 return true; | 885 return true; |
714 } | 886 } |
715 | 887 |
716 bool ThumbnailDatabase::InitIconMappingTable(sql::Connection* db, | 888 bool ThumbnailDatabase::InitIconMappingTable(sql::Connection* db, |
717 bool is_temporary) { | 889 bool is_temporary) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
779 | 951 |
780 bool ThumbnailDatabase::UpgradeToVersion5() { | 952 bool ThumbnailDatabase::UpgradeToVersion5() { |
781 if (!db_.Execute("ALTER TABLE favicons ADD sizes LONGVARCHAR")) { | 953 if (!db_.Execute("ALTER TABLE favicons ADD sizes LONGVARCHAR")) { |
782 return false; | 954 return false; |
783 } | 955 } |
784 meta_table_.SetVersionNumber(5); | 956 meta_table_.SetVersionNumber(5); |
785 meta_table_.SetCompatibleVersionNumber(std::min(5, kCompatibleVersionNumber)); | 957 meta_table_.SetCompatibleVersionNumber(std::min(5, kCompatibleVersionNumber)); |
786 return true; | 958 return true; |
787 } | 959 } |
788 | 960 |
961 bool ThumbnailDatabase::UpgradeToVersion6() { | |
962 bool success = | |
963 db_.Execute("INSERT INTO favicon_bitmaps (icon_id, last_updated, " | |
964 "image_data)" | |
965 "SELECT id, last_updated, image_data FROM favicons") && | |
sky
2012/08/16 16:12:57
Don't you need to set the width/height?
pkotwicz
2012/08/16 19:22:46
Done.
| |
966 db_.Execute("CREATE TABLE temp_favicons (" | |
967 "id INTEGER PRIMARY KEY," | |
968 "url LONGVARCHAR NOT NULL," | |
969 "icon_type INTEGER DEFAULT 1," | |
sky
2012/08/16 16:12:57
Document what 1 is here.
pkotwicz
2012/08/16 19:22:46
Done.
| |
970 "sizes LONGVARCHAR DEFAULT '0 0')") && | |
sky
2012/08/16 16:12:57
Why default to 0x0?
pkotwicz
2012/08/16 19:22:46
The default is 0x0 because it is a very recognizab
| |
971 db_.Execute("INSERT INTO temp_favicons (id, url, icon_type) " | |
972 "SELECT id, url, icon_type FROM favicons") && | |
973 db_.Execute("DROP TABLE favicons") && | |
974 db_.Execute("ALTER TABLE temp_favicons RENAME TO favicons"); | |
975 | |
976 meta_table_.SetVersionNumber(6); | |
sky
2012/08/16 16:12:57
Early return if execute fails on the previous line
pkotwicz
2012/08/16 19:22:46
Done.
| |
977 meta_table_.SetCompatibleVersionNumber(std::min(6, kCompatibleVersionNumber)); | |
978 return success; | |
979 } | |
980 | |
789 } // namespace history | 981 } // namespace history |
OLD | NEW |