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/webdata/web_intents_table.h" 6 7 #include <string> 8 9 #include "base/i18n/case_conversion.h" 10 #include "base/logging.h" 11 #include "base/strings/string_util.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "components/webdata/common/web_database.h" 14 #include "net/base/mime_util.h" 15 #include "sql/statement.h" 16 #include "third_party/sqlite/sqlite3.h" 17 #include "url/gurl.h" 18 19 namespace { 20 21 WebDatabaseTable::TypeKey GetKey() { 22 // We just need a unique constant. Use the address of a static that 23 // COMDAT folding won't touch in an optimizing linker. 24 static int table_key = 0; 25 return reinterpret_cast<void*>(&table_key); 26 } 27 28 } // namespace 29 30 WebIntentsTable::WebIntentsTable() { 31 } 32 33 WebIntentsTable::~WebIntentsTable() { 34 } 35 36 WebIntentsTable* WebIntentsTable::FromWebDatabase(WebDatabase* db) { 37 return static_cast<WebIntentsTable*>(db->GetTable(GetKey())); 38 } 39 40 WebDatabaseTable::TypeKey WebIntentsTable::GetTypeKey() const { 41 return GetKey(); 42 } 43 44 bool WebIntentsTable::Init(sql::Connection* db, sql::MetaTable* meta_table) { 45 WebDatabaseTable::Init(db, meta_table); 46 47 if (!db_->DoesTableExist("web_intents")) { 48 if (!db_->Execute("CREATE TABLE web_intents (" 49 " service_url LONGVARCHAR," 50 " action VARCHAR," 51 " type VARCHAR," 52 " title LONGVARCHAR," 53 " disposition VARCHAR," 54 " scheme VARCHAR," 55 " UNIQUE (service_url, action, scheme, type))")) { 56 return false; 57 } 58 if (!db_->Execute("CREATE INDEX IF NOT EXISTS web_intents_index" 59 " ON web_intents (action)")) 60 return false; 61 if (!db_->Execute("CREATE INDEX IF NOT EXISTS web_intents_index" 62 " ON web_intents (scheme)")) 63 return false; 64 } 65 66 if (!db_->DoesTableExist("web_intents_defaults")) { 67 if (!db_->Execute("CREATE TABLE web_intents_defaults (" 68 " action VARCHAR," 69 " type VARCHAR," 70 " url_pattern LONGVARCHAR," 71 " user_date INTEGER," 72 " suppression INTEGER," 73 " service_url LONGVARCHAR," 74 " scheme VARCHAR," 75 " UNIQUE (action, scheme, type, url_pattern))")) { 76 return false; 77 } 78 if (!db_->Execute("CREATE INDEX IF NOT EXISTS web_intents_default_index" 79 " ON web_intents_defaults (action)")) 80 return false; 81 82 if (!db_->Execute("CREATE INDEX IF NOT EXISTS web_intents_default_index" 83 " ON web_intents_defaults (scheme)")) 84 return false; 85 } 86 87 return true; 88 } 89 90 // TODO(jhawkins): Figure out Sync story. 91 bool WebIntentsTable::IsSyncable() { 92 return false; 93 } 94 95 bool WebIntentsTable::MigrateToVersion(int version, 96 bool* update_compatible_version) { 97 if (version == 46) { 98 *update_compatible_version = true; 99 return MigrateToVersion46AddSchemeColumn(); 100 } 101 102 return true; 103 } 104 105 // Updates the table by way of renaming the old tables, rerunning 106 // the Init method, then selecting old values into the new tables. 107 bool WebIntentsTable::MigrateToVersion46AddSchemeColumn() { 108 109 if (!db_->Execute("ALTER TABLE web_intents RENAME TO old_web_intents")) { 110 DLOG(WARNING) << "Could not backup web_intents table."; 111 return false; 112 } 113 114 if (!db_->Execute("ALTER TABLE web_intents_defaults" 115 " RENAME TO old_web_intents_defaults")) { 116 DLOG(WARNING) << "Could not backup web_intents_defaults table."; 117 return false; 118 } 119 120 if (!Init(db_, meta_table_)) return false; 121 122 int error = db_->ExecuteAndReturnErrorCode( 123 "INSERT INTO web_intents" 124 " (service_url, action, type, title, disposition)" 125 " SELECT " 126 " service_url, action, type, title, disposition" 127 " FROM old_web_intents"); 128 129 if (error != SQLITE_OK) { 130 DLOG(WARNING) << "Could not copy old intent data to upgraded table." 131 << db_->GetErrorMessage(); 132 } 133 134 135 error = db_->ExecuteAndReturnErrorCode( 136 "INSERT INTO web_intents_defaults" 137 " (service_url, action, type, url_pattern, user_date, suppression)" 138 " SELECT " 139 " service_url, action, type, url_pattern, user_date, suppression" 140 " FROM old_web_intents_defaults"); 141 142 if (error != SQLITE_OK) { 143 DLOG(WARNING) << "Could not copy old intent defaults to upgraded table." 144 << db_->GetErrorMessage(); 145 } 146 147 if (!db_->Execute("DROP table old_web_intents")) { 148 LOG(WARNING) << "Could not drop backup web_intents table."; 149 return false; 150 } 151 152 if (!db_->Execute("DROP table old_web_intents_defaults")) { 153 DLOG(WARNING) << "Could not drop backup web_intents_defaults table."; 154 return false; 155 } 156 157 return true; 158 } 159