Automated Commit: Committing new LKGM version 6953.0.0 for chromeos.
[chromium-blink-merge.git] / components / webdata / common / web_database.cc
blobf091a2a08a6a6a0782e5f5aad1a2b50243c79fde
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.
5 #include "components/webdata/common/web_database.h"
7 #include <algorithm>
9 #include "base/stl_util.h"
10 #include "sql/statement.h"
11 #include "sql/transaction.h"
13 // Current version number. Note: when changing the current version number,
14 // corresponding changes must happen in the unit tests, and new migration test
15 // added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|.
16 // static
17 const int WebDatabase::kCurrentVersionNumber = 65;
19 const int WebDatabase::kDeprecatedVersionNumber = 51;
21 namespace {
23 const int kCompatibleVersionNumber = 61;
25 // Change the version number and possibly the compatibility version of
26 // |meta_table_|.
27 void ChangeVersion(sql::MetaTable* meta_table,
28 int version_num,
29 bool update_compatible_version_num) {
30 meta_table->SetVersionNumber(version_num);
31 if (update_compatible_version_num) {
32 meta_table->SetCompatibleVersionNumber(
33 std::min(version_num, kCompatibleVersionNumber));
37 // Outputs the failed version number as a warning and always returns
38 // |sql::INIT_FAILURE|.
39 sql::InitStatus FailedMigrationTo(int version_num) {
40 LOG(WARNING) << "Unable to update web database to version "
41 << version_num << ".";
42 NOTREACHED();
43 return sql::INIT_FAILURE;
46 } // namespace
48 WebDatabase::WebDatabase() {}
50 WebDatabase::~WebDatabase() {
53 void WebDatabase::AddTable(WebDatabaseTable* table) {
54 tables_[table->GetTypeKey()] = table;
57 WebDatabaseTable* WebDatabase::GetTable(WebDatabaseTable::TypeKey key) {
58 return tables_[key];
61 void WebDatabase::BeginTransaction() {
62 db_.BeginTransaction();
65 void WebDatabase::CommitTransaction() {
66 db_.CommitTransaction();
69 sql::Connection* WebDatabase::GetSQLConnection() {
70 return &db_;
73 sql::InitStatus WebDatabase::Init(const base::FilePath& db_name) {
74 db_.set_histogram_tag("Web");
76 // We don't store that much data in the tables so use a small page size.
77 // This provides a large benefit for empty tables (which is very likely with
78 // the tables we create).
79 db_.set_page_size(2048);
81 // We shouldn't have much data and what access we currently have is quite
82 // infrequent. So we go with a small cache size.
83 db_.set_cache_size(32);
85 // Run the database in exclusive mode. Nobody else should be accessing the
86 // database while we're running, and this will give somewhat improved perf.
87 db_.set_exclusive_locking();
89 if (!db_.Open(db_name))
90 return sql::INIT_FAILURE;
92 // Clobber really old databases.
93 static_assert(kDeprecatedVersionNumber < kCurrentVersionNumber,
94 "Deprecation version must be less than current");
95 sql::MetaTable::RazeIfDeprecated(&db_, kDeprecatedVersionNumber);
97 // Scope initialization in a transaction so we can't be partially
98 // initialized.
99 sql::Transaction transaction(&db_);
100 if (!transaction.Begin())
101 return sql::INIT_FAILURE;
103 // Version check.
104 if (!meta_table_.Init(&db_, kCurrentVersionNumber, kCompatibleVersionNumber))
105 return sql::INIT_FAILURE;
106 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
107 LOG(WARNING) << "Web database is too new.";
108 return sql::INIT_TOO_NEW;
111 // Initialize the tables.
112 for (TableMap::iterator it = tables_.begin(); it != tables_.end(); ++it) {
113 it->second->Init(&db_, &meta_table_);
116 // If the file on disk is an older database version, bring it up to date.
117 // If the migration fails we return an error to caller and do not commit
118 // the migration.
119 sql::InitStatus migration_status = MigrateOldVersionsAsNeeded();
120 if (migration_status != sql::INIT_OK)
121 return migration_status;
123 // Create the desired SQL tables if they do not already exist.
124 // It's important that this happen *after* the migration code runs.
125 // Otherwise, the migration code would have to explicitly check for empty
126 // tables created in the new format, and skip the migration in that case.
127 for (TableMap::iterator it = tables_.begin(); it != tables_.end(); ++it) {
128 if (!it->second->CreateTablesIfNecessary()) {
129 LOG(WARNING) << "Unable to initialize the web database.";
130 return sql::INIT_FAILURE;
134 return transaction.Commit() ? sql::INIT_OK : sql::INIT_FAILURE;
137 sql::InitStatus WebDatabase::MigrateOldVersionsAsNeeded() {
138 // Some malware used to lower the version number, causing migration to
139 // fail. Ensure the version number is at least as high as the compatible
140 // version number.
141 int current_version = std::max(meta_table_.GetVersionNumber(),
142 meta_table_.GetCompatibleVersionNumber());
143 if (current_version > meta_table_.GetVersionNumber())
144 ChangeVersion(&meta_table_, current_version, false);
146 DCHECK_GT(current_version, kDeprecatedVersionNumber);
148 for (int next_version = current_version + 1;
149 next_version <= kCurrentVersionNumber;
150 ++next_version) {
152 // Do any database-wide migrations.
153 bool update_compatible_version = false;
154 if (!MigrateToVersion(next_version, &update_compatible_version))
155 return FailedMigrationTo(next_version);
157 ChangeVersion(&meta_table_, next_version, update_compatible_version);
159 // Give each table a chance to migrate to this version.
160 for (TableMap::iterator it = tables_.begin(); it != tables_.end(); ++it) {
161 // Any of the tables may set this to true, but by default it is false.
162 update_compatible_version = false;
163 if (!it->second->MigrateToVersion(next_version,
164 &update_compatible_version)) {
165 return FailedMigrationTo(next_version);
168 ChangeVersion(&meta_table_, next_version, update_compatible_version);
171 return sql::INIT_OK;
174 bool WebDatabase::MigrateToVersion(int version,
175 bool* update_compatible_version) {
176 // Migrate if necessary.
177 switch (version) {
178 case 58:
179 *update_compatible_version = true;
180 return MigrateToVersion58DropWebAppsAndIntents();
183 return true;
186 bool WebDatabase::MigrateToVersion58DropWebAppsAndIntents() {
187 sql::Transaction transaction(&db_);
188 return transaction.Begin() &&
189 db_.Execute("DROP TABLE IF EXISTS web_apps") &&
190 db_.Execute("DROP TABLE IF EXISTS web_app_icons") &&
191 db_.Execute("DROP TABLE IF EXISTS web_intents") &&
192 db_.Execute("DROP TABLE IF EXISTS web_intents_defaults") &&
193 transaction.Commit();