15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/android/android_cache_database.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/android/android_time.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/statement.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time; 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace history { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AndroidCacheDatabase::AndroidCacheDatabase() { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AndroidCacheDatabase::~AndroidCacheDatabase() { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sql::InitStatus AndroidCacheDatabase::InitAndroidCacheDatabase( 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& db_name) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CreateDatabase(db_name)) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sql::INIT_FAILURE; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Attach()) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sql::INIT_FAILURE; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CreateBookmarkCacheTable()) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sql::INIT_FAILURE; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CreateSearchTermsTable()) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sql::INIT_FAILURE; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sql::INIT_OK; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AndroidCacheDatabase::AddBookmarkCacheRow(const Time& created_time, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Time& last_visit_time, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLID url_id) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "INSERT INTO android_cache_db.bookmark_cache (created_time, " 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "last_visit_time, url_id) VALUES (?, ?, ?)")); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statement.BindInt64(0, ToDatabaseTime(created_time)); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statement.BindInt64(1, ToDatabaseTime(last_visit_time)); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statement.BindInt64(2, url_id); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!statement.Run()) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << GetDB().GetErrorMessage(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AndroidCacheDatabase::ClearAllBookmarkCache() { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "DELETE FROM android_cache_db.bookmark_cache")); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!statement.Run()) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << GetDB().GetErrorMessage(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AndroidCacheDatabase::MarkURLsAsBookmarked( 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<URLID>& url_ids) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_id = false; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::ostringstream oss; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<URLID>::const_iterator i = url_ids.begin(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != url_ids.end(); ++i) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_id) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oss << ", "; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_id = true; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oss << *i; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_id) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sql("UPDATE android_cache_db.bookmark_cache " 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SET bookmark = 1 WHERE url_id in ("); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql.append(oss.str()); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql.append(")"); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetDB().Execute(sql.c_str())) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << GetDB().GetErrorMessage(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool AndroidCacheDatabase::SetFaviconID(URLID url_id, 960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch favicon_base::FaviconID favicon_id) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement update_statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "UPDATE android_cache_db.bookmark_cache " 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SET favicon_id = ? WHERE url_id = ? ")); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) update_statement.BindInt64(0, favicon_id); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) update_statement.BindInt64(1, url_id); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!update_statement.Run()) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << GetDB().GetErrorMessage(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SearchTermID AndroidCacheDatabase::AddSearchTerm( 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& term, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Time& last_visit_time) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "INSERT INTO android_cache_db.search_terms (search, " 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "date) VALUES (?, ?)")); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statement.BindString16(0, term); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statement.BindInt64(1, ToDatabaseTime(last_visit_time)); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!statement.Run()) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << GetDB().GetErrorMessage(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetDB().GetLastInsertRowId(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AndroidCacheDatabase::UpdateSearchTerm(SearchTermID id, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SearchTermRow& row) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "UPDATE android_cache_db.search_terms " 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SET search = ?, date = ? " 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WHERE _id = ?" 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) )); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statement.BindString16(0, row.term); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statement.BindInt64(1, ToDatabaseTime(row.last_visit_time)); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statement.BindInt64(2, id); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return statement.Run(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SearchTermID AndroidCacheDatabase::GetSearchTerm(const base::string16& term, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SearchTermRow* row) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SELECT _id, search, date " 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FROM android_cache_db.search_terms " 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WHERE search = ?" 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) )); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!statement.is_valid()) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << GetDB().GetErrorMessage(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statement.BindString16(0, term); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!statement.Step()) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (row) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row->id = statement.ColumnInt64(0); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row->term = statement.ColumnString16(1); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row->last_visit_time = FromDatabaseTime(statement.ColumnInt64(2)); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return statement.ColumnInt64(0); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AndroidCacheDatabase::DeleteUnusedSearchTerms() { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "DELETE FROM android_cache_db.search_terms " 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WHERE search NOT IN (SELECT DISTINCT term FROM keyword_search_terms)" 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) )); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!statement.is_valid()) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return statement.Run(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AndroidCacheDatabase::CreateDatabase(const base::FilePath& db_name) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_name_ = db_name; 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sql::Connection::Delete(db_name_); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Using a new connection, otherwise we can not create the database. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Connection connection; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The db doesn't store too much data, so we don't need that big a page 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size or cache. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection.set_page_size(2048); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection.set_cache_size(32); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run the database in exclusive mode. Nobody else should be accessing the 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // database while we're running, and this will give somewhat improved perf. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection.set_exclusive_locking(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!connection.Open(db_name_)) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << connection.GetErrorMessage(); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection.Close(); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AndroidCacheDatabase::CreateBookmarkCacheTable() { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name = "android_cache_db.bookmark_cache"; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!GetDB().DoesTableExist(name)); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sql; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql.append("CREATE TABLE "); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql.append(name); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql.append("(" 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "id INTEGER PRIMARY KEY," 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "created_time INTEGER NOT NULL," // Time in millisecond. 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "last_visit_time INTEGER NOT NULL," // Time in millisecond. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "url_id INTEGER NOT NULL," // url id in urls table. 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "favicon_id INTEGER DEFAULT NULL," // favicon id. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bookmark INTEGER DEFAULT 0" // whether is bookmark. 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ")"); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetDB().Execute(sql.c_str())) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << GetDB().GetErrorMessage(); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql.assign("CREATE INDEX "); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql.append("android_cache_db.bookmark_cache_url_id_idx ON " 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bookmark_cache(url_id)"); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetDB().Execute(sql.c_str())) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << GetDB().GetErrorMessage(); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AndroidCacheDatabase::CreateSearchTermsTable() { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name = "android_cache_db.search_terms"; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The table's column name matchs Android's definition. 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sql; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql.append("CREATE TABLE "); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql.append(name); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql.append("(" 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "_id INTEGER PRIMARY KEY," 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "date INTEGER NOT NULL," // last visit time in millisecond. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "search LONGVARCHAR NOT NULL)"); // The actual search term. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetDB().Execute(sql.c_str())) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << GetDB().GetErrorMessage(); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql.assign("CREATE INDEX " 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "android_cache_db.search_terms_term_idx ON " 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "search_terms(search)"); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetDB().Execute(sql.c_str())) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << GetDB().GetErrorMessage(); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AndroidCacheDatabase::Attach() { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Commit all open transactions to make attach succeed. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int transaction_nesting = GetDB().transaction_nesting(); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count = transaction_nesting; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (count--) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDB().CommitTransaction(); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = DoAttach(); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No matter whether the attach succeeded or not, we need to create the 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // transaction stack again. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count = transaction_nesting; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (count--) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDB().BeginTransaction(); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AndroidCacheDatabase::DoAttach() { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sql("ATTACH ? AS android_cache_db"); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement attach(GetDB().GetUniqueStatement(sql.c_str())); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!attach.is_valid()) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keep the transaction open, even though we failed. 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attach.BindString(0, db_name_.value()); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!attach.Run()) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << GetDB().GetErrorMessage(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace history 290