• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetKey()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 
WebIntentsTable()30 WebIntentsTable::WebIntentsTable() {
31 }
32 
~WebIntentsTable()33 WebIntentsTable::~WebIntentsTable() {
34 }
35 
FromWebDatabase(WebDatabase * db)36 WebIntentsTable* WebIntentsTable::FromWebDatabase(WebDatabase* db) {
37   return static_cast<WebIntentsTable*>(db->GetTable(GetKey()));
38 }
39 
GetTypeKey() const40 WebDatabaseTable::TypeKey WebIntentsTable::GetTypeKey() const {
41   return GetKey();
42 }
43 
CreateTablesIfNecessary()44 bool WebIntentsTable::CreateTablesIfNecessary() {
45   if (!db_->DoesTableExist("web_intents")) {
46     if (!db_->Execute("CREATE TABLE web_intents ("
47                       " service_url LONGVARCHAR,"
48                       " action VARCHAR,"
49                       " type VARCHAR,"
50                       " title LONGVARCHAR,"
51                       " disposition VARCHAR,"
52                       " scheme VARCHAR,"
53                       " UNIQUE (service_url, action, scheme, type))")) {
54       return false;
55     }
56     if (!db_->Execute("CREATE INDEX IF NOT EXISTS web_intents_index"
57                       " ON web_intents (action)"))
58       return false;
59     if (!db_->Execute("CREATE INDEX IF NOT EXISTS web_intents_index"
60                       " ON web_intents (scheme)"))
61       return false;
62   }
63 
64   if (!db_->DoesTableExist("web_intents_defaults")) {
65     if (!db_->Execute("CREATE TABLE web_intents_defaults ("
66                       " action VARCHAR,"
67                       " type VARCHAR,"
68                       " url_pattern LONGVARCHAR,"
69                       " user_date INTEGER,"
70                       " suppression INTEGER,"
71                       " service_url LONGVARCHAR,"
72                       " scheme VARCHAR,"
73                       " UNIQUE (action, scheme, type, url_pattern))")) {
74       return false;
75     }
76     if (!db_->Execute("CREATE INDEX IF NOT EXISTS web_intents_default_index"
77                       " ON web_intents_defaults (action)"))
78       return false;
79 
80     if (!db_->Execute("CREATE INDEX IF NOT EXISTS web_intents_default_index"
81                       " ON web_intents_defaults (scheme)"))
82       return false;
83   }
84 
85   return true;
86 }
87 
88 // TODO(jhawkins): Figure out Sync story.
IsSyncable()89 bool WebIntentsTable::IsSyncable() {
90   return false;
91 }
92 
MigrateToVersion(int version,bool * update_compatible_version)93 bool WebIntentsTable::MigrateToVersion(int version,
94                                        bool* update_compatible_version) {
95   if (version == 46) {
96     *update_compatible_version = true;
97     return MigrateToVersion46AddSchemeColumn();
98   }
99 
100   return true;
101 }
102 
103 // Updates the table by way of renaming the old tables, rerunning
104 // the Init method, then selecting old values into the new tables.
MigrateToVersion46AddSchemeColumn()105 bool WebIntentsTable::MigrateToVersion46AddSchemeColumn() {
106   // If the old table doesn't exist, there's nothing to migrate.
107   if (!db_->DoesTableExist("web_intents"))
108     return true;
109 
110   if (!db_->Execute("ALTER TABLE web_intents RENAME TO old_web_intents"))
111     return false;
112 
113   if (!db_->Execute("ALTER TABLE web_intents_defaults"
114                     " RENAME TO old_web_intents_defaults"))
115     return false;
116 
117   if (!CreateTablesIfNecessary())
118     return false;
119 
120   int error = db_->ExecuteAndReturnErrorCode(
121       "INSERT INTO web_intents"
122       " (service_url, action, type, title, disposition)"
123       " SELECT "
124       " service_url, action, type, title, disposition"
125       " FROM old_web_intents");
126 
127   if (error != SQLITE_OK) {
128     DLOG(WARNING) << "Could not copy old intent data to upgraded table."
129         << db_->GetErrorMessage();
130   }
131 
132 
133   error = db_->ExecuteAndReturnErrorCode(
134       "INSERT INTO web_intents_defaults"
135       " (service_url, action, type, url_pattern, user_date, suppression)"
136       " SELECT "
137       " service_url, action, type, url_pattern, user_date, suppression"
138       " FROM old_web_intents_defaults");
139 
140   if (error != SQLITE_OK) {
141     DLOG(WARNING) << "Could not copy old intent defaults to upgraded table."
142         << db_->GetErrorMessage();
143   }
144 
145   if (!db_->Execute("DROP table old_web_intents")) {
146     LOG(WARNING) << "Could not drop backup web_intents table.";
147     return false;
148   }
149 
150   if (!db_->Execute("DROP table old_web_intents_defaults")) {
151     DLOG(WARNING) << "Could not drop backup web_intents_defaults table.";
152     return false;
153   }
154 
155   return true;
156 }
157