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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/history/android/android_urls_database.h" 6 7 #include "base/logging.h" 8 9 namespace history { 10 11 AndroidURLsDatabase::AndroidURLsDatabase() { 12 } 13 14 AndroidURLsDatabase::~AndroidURLsDatabase() { 15 } 16 17 bool AndroidURLsDatabase::CreateAndroidURLsTable() { 18 const char* name = "android_urls"; 19 if (!GetDB().DoesTableExist(name)) { 20 std::string sql; 21 sql.append("CREATE TABLE "); 22 sql.append(name); 23 sql.append("(" 24 "id INTEGER PRIMARY KEY," 25 "raw_url LONGVARCHAR," // Passed in raw url. 26 "url_id INTEGER NOT NULL" // url id in urls table. 27 ")"); 28 if (!GetDB().Execute(sql.c_str())) { 29 LOG(ERROR) << GetDB().GetErrorMessage(); 30 return false; 31 } 32 33 if (!GetDB().Execute("CREATE INDEX android_urls_raw_url_idx" 34 " ON android_urls(raw_url)")) { 35 LOG(ERROR) << GetDB().GetErrorMessage(); 36 return false; 37 } 38 39 if (!GetDB().Execute("CREATE INDEX android_urls_url_id_idx" 40 " ON android_urls(url_id)")) { 41 LOG(ERROR) << GetDB().GetErrorMessage(); 42 return false; 43 } 44 } 45 return true; 46 } 47 48 AndroidURLID AndroidURLsDatabase::AddAndroidURLRow(const std::string& raw_url, 49 URLID url_id) { 50 if (GetAndroidURLRow(url_id, NULL)) { 51 LOG(ERROR) << "url_id already exist"; 52 return 0; 53 } 54 55 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 56 "INSERT INTO android_urls (raw_url, url_id) VALUES (?, ?)")); 57 58 statement.BindString(0, raw_url); 59 statement.BindInt64(1, static_cast<int64>(url_id)); 60 61 if (!statement.Run()) { 62 LOG(ERROR) << GetDB().GetErrorMessage(); 63 return 0; 64 } 65 return GetDB().GetLastInsertRowId(); 66 } 67 68 bool AndroidURLsDatabase::GetAndroidURLRow(URLID url_id, AndroidURLRow* row) { 69 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 70 "SELECT id, raw_url, url_id FROM android_urls WHERE url_id = ?")); 71 72 statement.BindInt64(0, url_id); 73 74 if (!statement.Step()) 75 return false; 76 if (row) { 77 row->id = statement.ColumnInt64(0); 78 row->raw_url = statement.ColumnString(1); 79 row->url_id = statement.ColumnInt64(2); 80 } 81 return true; 82 } 83 84 bool AndroidURLsDatabase::DeleteAndroidURLRows( 85 const std::vector<URLID>& url_ids) { 86 if (url_ids.empty()) 87 return true; 88 89 std::string sql; 90 sql.append("DELETE FROM android_urls "); 91 std::ostringstream oss; 92 bool has_id = false; 93 for (std::vector<URLID>::const_iterator i = url_ids.begin(); 94 i != url_ids.end(); ++i) { 95 if (has_id) 96 oss << ", "; 97 else 98 has_id = true; 99 oss << *i; 100 } 101 102 if (has_id) { 103 sql.append(" WHERE url_id in ( "); 104 sql.append(oss.str()); 105 sql.append(" )"); 106 } 107 108 if (!GetDB().Execute(sql.c_str())) { 109 LOG(ERROR) << GetDB().GetErrorMessage(); 110 return false; 111 } 112 return true; 113 } 114 115 bool AndroidURLsDatabase::DeleteUnusedAndroidURLs() { 116 return GetDB().Execute("DELETE FROM android_urls WHERE url_id NOT IN (" 117 "SELECT id FROM urls)"); 118 } 119 120 bool AndroidURLsDatabase::UpdateAndroidURLRow(AndroidURLID id, 121 const std::string& raw_url, 122 URLID url_id) { 123 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, 124 "UPDATE android_urls SET raw_url = ?, url_id = ? WHERE id = ?")); 125 126 statement.BindString(0, raw_url); 127 statement.BindInt64(1, url_id); 128 statement.BindInt64(2, id); 129 130 if (!statement.is_valid()) { 131 LOG(ERROR) << GetDB().GetErrorMessage(); 132 return false; 133 } 134 135 if (!statement.Run()) { 136 LOG(ERROR) << GetDB().GetErrorMessage(); 137 return false; 138 } 139 140 return true; 141 } 142 143 bool AndroidURLsDatabase::ClearAndroidURLRows() { 144 // The android_urls table might not exist if the Android content provider is 145 // never used, especially in the unit tests. See http://b/6385692. 146 if (GetDB().DoesTableExist("android_urls")) 147 return GetDB().Execute("DELETE FROM android_urls"); 148 149 return true; 150 } 151 152 bool AndroidURLsDatabase::MigrateToVersion22() { 153 if (!GetDB().DoesTableExist("android_urls")) 154 return true; 155 156 if (!GetDB().Execute("ALTER TABLE android_urls RENAME TO android_urls_tmp")) 157 return false; 158 159 if (!GetDB().Execute("DROP INDEX android_urls_raw_url_idx")) 160 return false; 161 162 if (!GetDB().Execute("DROP INDEX android_urls_url_id_idx")) 163 return false; 164 165 if (!CreateAndroidURLsTable()) 166 return false; 167 168 if (!GetDB().Execute( 169 "INSERT INTO android_urls (id, raw_url, url_id) " 170 "SELECT id, raw_url, url_id FROM android_urls_tmp")) 171 return false; 172 173 if (!GetDB().Execute("DROP TABLE android_urls_tmp")) 174 return false; 175 176 return true; 177 } 178 179 } // namespace history 180