| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/webdata/web_database.h" | 5 #include "chrome/browser/webdata/web_database.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "app/l10n_util.h" | 11 #include "app/l10n_util.h" |
| 12 #include "app/sql/statement.h" |
| 13 #include "app/sql/transaction.h" |
| 12 #include "base/gfx/png_decoder.h" | 14 #include "base/gfx/png_decoder.h" |
| 13 #include "base/gfx/png_encoder.h" | 15 #include "base/gfx/png_encoder.h" |
| 14 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 15 #include "base/time.h" | 17 #include "base/time.h" |
| 16 #include "chrome/browser/history/history_database.h" | 18 #include "chrome/browser/history/history_database.h" |
| 17 #include "chrome/browser/search_engines/template_url.h" | 19 #include "chrome/browser/search_engines/template_url.h" |
| 18 #include "webkit/glue/password_form.h" | 20 #include "webkit/glue/password_form.h" |
| 19 | 21 |
| 20 // Encryptor is the *wrong* way of doing things; we need to turn it into a | 22 // Encryptor is the *wrong* way of doing things; we need to turn it into a |
| 21 // bottleneck to use the platform methods (e.g. Keychain on the Mac, Gnome | 23 // bottleneck to use the platform methods (e.g. Keychain on the Mac, Gnome |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 const std::vector<std::string>& strings) { | 112 const std::vector<std::string>& strings) { |
| 111 if (strings.empty()) | 113 if (strings.empty()) |
| 112 return std::string(); | 114 return std::string(); |
| 113 std::vector<std::string>::const_iterator i(strings.begin()); | 115 std::vector<std::string>::const_iterator i(strings.begin()); |
| 114 std::string result(*i); | 116 std::string result(*i); |
| 115 while (++i != strings.end()) | 117 while (++i != strings.end()) |
| 116 result += separator + *i; | 118 result += separator + *i; |
| 117 return result; | 119 return result; |
| 118 } | 120 } |
| 119 | 121 |
| 120 WebDatabase::WebDatabase() : db_(NULL), transaction_nesting_(0) { | 122 WebDatabase::WebDatabase() { |
| 121 } | 123 } |
| 122 | 124 |
| 123 WebDatabase::~WebDatabase() { | 125 WebDatabase::~WebDatabase() { |
| 124 if (db_) { | |
| 125 DCHECK(transaction_nesting_ == 0) << | |
| 126 "Forgot to close the transaction on shutdown"; | |
| 127 sqlite3_close(db_); | |
| 128 db_ = NULL; | |
| 129 } | |
| 130 } | 126 } |
| 131 | 127 |
| 132 void WebDatabase::BeginTransaction() { | 128 void WebDatabase::BeginTransaction() { |
| 133 DCHECK(db_); | 129 db_.BeginTransaction(); |
| 134 if (transaction_nesting_ == 0) { | |
| 135 int rv = sqlite3_exec(db_, "BEGIN TRANSACTION", NULL, NULL, NULL); | |
| 136 DCHECK(rv == SQLITE_OK) << "Failed to begin transaction"; | |
| 137 } | |
| 138 transaction_nesting_++; | |
| 139 } | 130 } |
| 140 | 131 |
| 141 void WebDatabase::CommitTransaction() { | 132 void WebDatabase::CommitTransaction() { |
| 142 DCHECK(db_); | 133 db_.CommitTransaction(); |
| 143 DCHECK(transaction_nesting_ > 0) << "Committing too many transaction"; | |
| 144 transaction_nesting_--; | |
| 145 if (transaction_nesting_ == 0) { | |
| 146 int rv = sqlite3_exec(db_, "COMMIT", NULL, NULL, NULL); | |
| 147 DCHECK(rv == SQLITE_OK) << "Failed to commit transaction"; | |
| 148 } | |
| 149 } | 134 } |
| 150 | 135 |
| 151 bool WebDatabase::Init(const std::wstring& db_name) { | 136 bool WebDatabase::Init(const FilePath& db_name) { |
| 152 // Open the database, using the narrow version of open so that | |
| 153 // the DB is in UTF-8. | |
| 154 if (sqlite3_open(WideToUTF8(db_name).c_str(), &db_) != SQLITE_OK) { | |
| 155 LOG(WARNING) << "Unable to open the web database."; | |
| 156 return false; | |
| 157 } | |
| 158 | |
| 159 // We don't store that much data in the tables so use a small page size. | 137 // We don't store that much data in the tables so use a small page size. |
| 160 // This provides a large benefit for empty tables (which is very likely with | 138 // This provides a large benefit for empty tables (which is very likely with |
| 161 // the tables we create). | 139 // the tables we create). |
| 162 sqlite3_exec(db_, "PRAGMA page_size=2048", NULL, NULL, NULL); | 140 db_.set_page_size(2048); |
| 163 | 141 |
| 164 // We shouldn't have much data and what access we currently have is quite | 142 // We shouldn't have much data and what access we currently have is quite |
| 165 // infrequent. So we go with a small cache size. | 143 // infrequent. So we go with a small cache size. |
| 166 sqlite3_exec(db_, "PRAGMA cache_size=32", NULL, NULL, NULL); | 144 db_.set_cache_size(32); |
| 167 | 145 |
| 168 // Run the database in exclusive mode. Nobody else should be accessing the | 146 // Run the database in exclusive mode. Nobody else should be accessing the |
| 169 // database while we're running, and this will give somewhat improved perf. | 147 // database while we're running, and this will give somewhat improved perf. |
| 170 sqlite3_exec(db_, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, NULL); | 148 db_.set_exclusive_locking(); |
| 149 |
| 150 if (!db_.Init(db_name)) |
| 151 return false; |
| 171 | 152 |
| 172 // Initialize various tables | 153 // Initialize various tables |
| 173 SQLTransaction transaction(db_); | 154 sql::Transaction transaction(&db_); |
| 174 transaction.Begin(); | 155 if (!transaction.Begin()) |
| 156 return false; |
| 175 | 157 |
| 176 // Version check. | 158 // Version check. |
| 177 if (!meta_table_.Init(std::string(), kCurrentVersionNumber, | 159 if (!meta_table_.Init(&db_, kCurrentVersionNumber, kCompatibleVersionNumber)) |
| 178 kCompatibleVersionNumber, db_)) | |
| 179 return false; | 160 return false; |
| 180 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { | 161 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { |
| 181 LOG(WARNING) << "Web database is too new."; | 162 LOG(WARNING) << "Web database is too new."; |
| 182 return false; | 163 return false; |
| 183 } | 164 } |
| 184 | 165 |
| 185 // Initialize the tables. | 166 // Initialize the tables. |
| 186 if (!InitKeywordsTable() || !InitLoginsTable() || !InitWebAppIconsTable() || | 167 if (!InitKeywordsTable() || !InitLoginsTable() || !InitWebAppIconsTable() || |
| 187 !InitWebAppsTable() || !InitAutofillTable() || | 168 !InitWebAppsTable() || !InitAutofillTable() || |
| 188 !InitAutofillDatesTable()) { | 169 !InitAutofillDatesTable()) { |
| 189 LOG(WARNING) << "Unable to initialize the web database."; | 170 LOG(WARNING) << "Unable to initialize the web database."; |
| 190 return false; | 171 return false; |
| 191 } | 172 } |
| 192 | 173 |
| 193 // If the file on disk is an older database version, bring it up to date. | 174 // If the file on disk is an older database version, bring it up to date. |
| 194 MigrateOldVersionsAsNeeded(); | 175 MigrateOldVersionsAsNeeded(); |
| 195 | 176 |
| 196 return (transaction.Commit() == SQLITE_OK); | 177 return transaction.Commit(); |
| 197 } | 178 } |
| 198 | 179 |
| 199 bool WebDatabase::SetWebAppImage(const GURL& url, | 180 bool WebDatabase::SetWebAppImage(const GURL& url, const SkBitmap& image) { |
| 200 const SkBitmap& image) { | 181 // Don't bother with a cached statement since this will be a relatively |
| 201 SQLStatement s; | 182 // infrequent operation. |
| 202 if (s.prepare(db_, | 183 sql::Statement s(db_.GetUniqueStatement( |
| 203 "INSERT OR REPLACE INTO web_app_icons " | 184 "INSERT OR REPLACE INTO web_app_icons " |
| 204 "(url, width, height, image) VALUES (?, ?, ?, ?)") | 185 "(url, width, height, image) VALUES (?, ?, ?, ?)")); |
| 205 != SQLITE_OK) { | 186 if (!s) |
| 206 NOTREACHED() << "Statement prepare failed"; | |
| 207 return false; | 187 return false; |
| 208 } | |
| 209 | 188 |
| 210 std::vector<unsigned char> image_data; | 189 std::vector<unsigned char> image_data; |
| 211 PNGEncoder::EncodeBGRASkBitmap(image, false, &image_data); | 190 PNGEncoder::EncodeBGRASkBitmap(image, false, &image_data); |
| 212 | 191 |
| 213 s.bind_string(0, history::HistoryDatabase::GURLToDatabaseURL(url)); | 192 s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url)); |
| 214 s.bind_int(1, image.width()); | 193 s.BindInt(1, image.width()); |
| 215 s.bind_int(2, image.height()); | 194 s.BindInt(2, image.height()); |
| 216 s.bind_blob(3, &image_data.front(), static_cast<int>(image_data.size())); | 195 s.BindBlob(3, &image_data.front(), static_cast<int>(image_data.size())); |
| 217 return s.step() == SQLITE_DONE; | 196 return s.Run(); |
| 218 } | 197 } |
| 219 | 198 |
| 220 bool WebDatabase::GetWebAppImages(const GURL& url, | 199 bool WebDatabase::GetWebAppImages(const GURL& url, |
| 221 std::vector<SkBitmap>* images) const { | 200 std::vector<SkBitmap>* images) { |
| 222 SQLStatement s; | 201 sql::Statement s(db_.GetUniqueStatement( |
| 223 if (s.prepare(db_, "SELECT image FROM web_app_icons WHERE url=?") != | 202 "SELECT image FROM web_app_icons WHERE url=?")); |
| 224 SQLITE_OK) { | 203 if (!s) { |
| 225 NOTREACHED() << "Statement prepare failed"; | 204 NOTREACHED() << "Statement prepare failed"; |
| 226 return false; | 205 return false; |
| 227 } | 206 } |
| 228 s.bind_string(0, history::HistoryDatabase::GURLToDatabaseURL(url)); | 207 s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url)); |
| 229 while (s.step() == SQLITE_ROW) { | 208 while (s.Step()) { |
| 230 SkBitmap image; | 209 SkBitmap image; |
| 231 std::vector<unsigned char> image_data; | 210 std::vector<unsigned char> image_data; |
| 232 s.column_blob_as_vector(0, &image_data); | 211 int col_bytes = s.ColumnByteLength(0); |
| 233 if (PNGDecoder::Decode(&image_data, &image)) { | 212 if (col_bytes > 0) { |
| 234 images->push_back(image); | 213 image_data.resize(col_bytes); |
| 235 } else { | 214 memcpy(&image_data[0], s.ColumnBlob(0), col_bytes); |
| 236 // Should only have valid image data in the db. | 215 if (PNGDecoder::Decode(&image_data, &image)) { |
| 237 NOTREACHED(); | 216 images->push_back(image); |
| 217 } else { |
| 218 // Should only have valid image data in the db. |
| 219 NOTREACHED(); |
| 220 } |
| 238 } | 221 } |
| 239 } | 222 } |
| 240 return true; | 223 return true; |
| 241 } | 224 } |
| 242 | 225 |
| 243 bool WebDatabase::SetWebAppHasAllImages(const GURL& url, | 226 bool WebDatabase::SetWebAppHasAllImages(const GURL& url, |
| 244 bool has_all_images) { | 227 bool has_all_images) { |
| 245 SQLStatement s; | 228 sql::Statement s(db_.GetUniqueStatement( |
| 246 if (s.prepare(db_, "INSERT OR REPLACE INTO web_apps (url, has_all_images) " | 229 "INSERT OR REPLACE INTO web_apps (url, has_all_images) VALUES (?, ?)")); |
| 247 "VALUES (?, ?)") != SQLITE_OK) { | 230 if (!s) { |
| 248 NOTREACHED() << "Statement prepare failed"; | 231 NOTREACHED() << "Statement prepare failed"; |
| 249 return false; | 232 return false; |
| 250 } | 233 } |
| 251 s.bind_string(0, history::HistoryDatabase::GURLToDatabaseURL(url)); | 234 s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url)); |
| 252 s.bind_int(1, has_all_images ? 1 : 0); | 235 s.BindInt(1, has_all_images ? 1 : 0); |
| 253 return (s.step() == SQLITE_DONE); | 236 return s.Run(); |
| 254 } | 237 } |
| 255 | 238 |
| 256 bool WebDatabase::GetWebAppHasAllImages(const GURL& url) const { | 239 bool WebDatabase::GetWebAppHasAllImages(const GURL& url) { |
| 257 SQLStatement s; | 240 sql::Statement s(db_.GetUniqueStatement( |
| 258 if (s.prepare(db_, "SELECT has_all_images FROM web_apps " | 241 "SELECT has_all_images FROM web_apps WHERE url=?")); |
| 259 "WHERE url=?") != SQLITE_OK) { | 242 if (!s) { |
| 260 NOTREACHED() << "Statement prepare failed"; | 243 NOTREACHED() << "Statement prepare failed"; |
| 261 return false; | 244 return false; |
| 262 } | 245 } |
| 263 s.bind_string(0, history::HistoryDatabase::GURLToDatabaseURL(url)); | 246 s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url)); |
| 264 return (s.step() == SQLITE_ROW && s.column_int(0) == 1); | 247 return (s.Step() && s.ColumnInt(0) == 1); |
| 265 } | 248 } |
| 266 | 249 |
| 267 bool WebDatabase::RemoveWebApp(const GURL& url) { | 250 bool WebDatabase::RemoveWebApp(const GURL& url) { |
| 268 SQLStatement delete_s; | 251 sql::Statement delete_s(db_.GetUniqueStatement( |
| 269 if (delete_s.prepare(db_, "DELETE FROM web_app_icons WHERE url = ?") != | 252 "DELETE FROM web_app_icons WHERE url = ?")); |
| 270 SQLITE_OK) { | 253 if (!delete_s) { |
| 271 NOTREACHED() << "Statement prepare failed"; | 254 NOTREACHED() << "Statement prepare failed"; |
| 272 return false; | 255 return false; |
| 273 } | 256 } |
| 274 delete_s.bind_string(0, history::HistoryDatabase::GURLToDatabaseURL(url)); | 257 delete_s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url)); |
| 275 if (delete_s.step() != SQLITE_DONE) | 258 if (!delete_s.Run()) |
| 276 return false; | 259 return false; |
| 277 | 260 |
| 278 SQLStatement delete_s2; | 261 sql::Statement delete_s2(db_.GetUniqueStatement( |
| 279 if (delete_s2.prepare(db_, "DELETE FROM web_apps WHERE url = ?") != | 262 "DELETE FROM web_apps WHERE url = ?")); |
| 280 SQLITE_OK) { | 263 if (!delete_s2) { |
| 281 NOTREACHED() << "Statement prepare failed"; | 264 NOTREACHED() << "Statement prepare failed"; |
| 282 return false; | 265 return false; |
| 283 } | 266 } |
| 284 delete_s2.bind_string(0, history::HistoryDatabase::GURLToDatabaseURL(url)); | 267 delete_s2.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url)); |
| 285 return (delete_s2.step() == SQLITE_DONE); | 268 return delete_s2.Run(); |
| 286 } | 269 } |
| 287 | 270 |
| 288 bool WebDatabase::InitKeywordsTable() { | 271 bool WebDatabase::InitKeywordsTable() { |
| 289 if (!DoesSqliteTableExist(db_, "keywords")) { | 272 if (!db_.DoesTableExist("keywords")) { |
| 290 if (sqlite3_exec(db_, "CREATE TABLE keywords (" | 273 if (!db_.Execute("CREATE TABLE keywords (" |
| 291 "id INTEGER PRIMARY KEY," | 274 "id INTEGER PRIMARY KEY," |
| 292 "short_name VARCHAR NOT NULL," | 275 "short_name VARCHAR NOT NULL," |
| 293 "keyword VARCHAR NOT NULL," | 276 "keyword VARCHAR NOT NULL," |
| 294 "favicon_url VARCHAR NOT NULL," | 277 "favicon_url VARCHAR NOT NULL," |
| 295 "url VARCHAR NOT NULL," | 278 "url VARCHAR NOT NULL," |
| 296 "show_in_default_list INTEGER," | 279 "show_in_default_list INTEGER," |
| 297 "safe_for_autoreplace INTEGER," | 280 "safe_for_autoreplace INTEGER," |
| 298 "originating_url VARCHAR," | 281 "originating_url VARCHAR," |
| 299 "date_created INTEGER DEFAULT 0," | 282 "date_created INTEGER DEFAULT 0," |
| 300 "usage_count INTEGER DEFAULT 0," | 283 "usage_count INTEGER DEFAULT 0," |
| 301 "input_encodings VARCHAR," | 284 "input_encodings VARCHAR," |
| 302 "suggest_url VARCHAR," | 285 "suggest_url VARCHAR," |
| 303 "prepopulate_id INTEGER DEFAULT 0," | 286 "prepopulate_id INTEGER DEFAULT 0," |
| 304 "autogenerate_keyword INTEGER DEFAULT 0)", | 287 "autogenerate_keyword INTEGER DEFAULT 0)")) { |
| 305 NULL, NULL, NULL) != SQLITE_OK) { | |
| 306 NOTREACHED(); | 288 NOTREACHED(); |
| 307 return false; | 289 return false; |
| 308 } | 290 } |
| 309 } | 291 } |
| 310 return true; | 292 return true; |
| 311 } | 293 } |
| 312 | 294 |
| 313 bool WebDatabase::InitLoginsTable() { | 295 bool WebDatabase::InitLoginsTable() { |
| 314 if (!DoesSqliteTableExist(db_, "logins")) { | 296 if (!db_.DoesTableExist("logins")) { |
| 315 // First time | 297 if (!db_.Execute("CREATE TABLE logins (" |
| 316 if (sqlite3_exec(db_, "CREATE TABLE logins (" | |
| 317 "origin_url VARCHAR NOT NULL, " | 298 "origin_url VARCHAR NOT NULL, " |
| 318 "action_url VARCHAR, " | 299 "action_url VARCHAR, " |
| 319 "username_element VARCHAR, " | 300 "username_element VARCHAR, " |
| 320 "username_value VARCHAR, " | 301 "username_value VARCHAR, " |
| 321 "password_element VARCHAR, " | 302 "password_element VARCHAR, " |
| 322 "password_value BLOB, " | 303 "password_value BLOB, " |
| 323 "submit_element VARCHAR, " | 304 "submit_element VARCHAR, " |
| 324 "signon_realm VARCHAR NOT NULL," | 305 "signon_realm VARCHAR NOT NULL," |
| 325 "ssl_valid INTEGER NOT NULL," | 306 "ssl_valid INTEGER NOT NULL," |
| 326 "preferred INTEGER NOT NULL," | 307 "preferred INTEGER NOT NULL," |
| 327 "date_created INTEGER NOT NULL," | 308 "date_created INTEGER NOT NULL," |
| 328 "blacklisted_by_user INTEGER NOT NULL," | 309 "blacklisted_by_user INTEGER NOT NULL," |
| 329 "scheme INTEGER NOT NULL," | 310 "scheme INTEGER NOT NULL," |
| 330 "UNIQUE " | 311 "UNIQUE " |
| 331 "(origin_url, username_element, " | 312 "(origin_url, username_element, " |
| 332 "username_value, password_element, " | 313 "username_value, password_element, " |
| 333 "submit_element, signon_realm))", | 314 "submit_element, signon_realm))")) { |
| 334 NULL, NULL, NULL) != SQLITE_OK) { | |
| 335 NOTREACHED(); | 315 NOTREACHED(); |
| 336 return false; | 316 return false; |
| 337 } | 317 } |
| 338 if (sqlite3_exec(db_, "CREATE INDEX logins_signon ON " | 318 if (!db_.Execute("CREATE INDEX logins_signon ON logins (signon_realm)")) { |
| 339 "logins (signon_realm)", | |
| 340 NULL, NULL, NULL) != SQLITE_OK) { | |
| 341 NOTREACHED(); | 319 NOTREACHED(); |
| 342 return false; | 320 return false; |
| 343 } | 321 } |
| 344 } | 322 } |
| 345 | 323 |
| 346 #if defined(OS_WIN) | 324 #if defined(OS_WIN) |
| 347 if (!DoesSqliteTableExist(db_, "ie7_logins")) { | 325 if (!db_.DoesTableExist("ie7_logins")) { |
| 348 // First time | 326 if (!db_.Execute("CREATE TABLE ie7_logins (" |
| 349 if (sqlite3_exec(db_, "CREATE TABLE ie7_logins (" | |
| 350 "url_hash VARCHAR NOT NULL, " | 327 "url_hash VARCHAR NOT NULL, " |
| 351 "password_value BLOB, " | 328 "password_value BLOB, " |
| 352 "date_created INTEGER NOT NULL," | 329 "date_created INTEGER NOT NULL," |
| 353 "UNIQUE " | 330 "UNIQUE " |
| 354 "(url_hash))", | 331 "(url_hash))")) { |
| 355 NULL, NULL, NULL) != SQLITE_OK) { | |
| 356 NOTREACHED(); | 332 NOTREACHED(); |
| 357 return false; | 333 return false; |
| 358 } | 334 } |
| 359 if (sqlite3_exec(db_, "CREATE INDEX ie7_logins_hash ON " | 335 if (!db_.Execute("CREATE INDEX ie7_logins_hash ON " |
| 360 "ie7_logins (url_hash)", | 336 "ie7_logins (url_hash)")) { |
| 361 NULL, NULL, NULL) != SQLITE_OK) { | |
| 362 NOTREACHED(); | 337 NOTREACHED(); |
| 363 return false; | 338 return false; |
| 364 } | 339 } |
| 365 } | 340 } |
| 366 #endif | 341 #endif |
| 367 | 342 |
| 368 return true; | 343 return true; |
| 369 } | 344 } |
| 370 | 345 |
| 371 bool WebDatabase::InitAutofillTable() { | 346 bool WebDatabase::InitAutofillTable() { |
| 372 if (!DoesSqliteTableExist(db_, "autofill")) { | 347 if (!db_.DoesTableExist("autofill")) { |
| 373 if (sqlite3_exec(db_, | 348 if (!db_.Execute("CREATE TABLE autofill (" |
| 374 "CREATE TABLE autofill (" | |
| 375 "name VARCHAR, " | 349 "name VARCHAR, " |
| 376 "value VARCHAR, " | 350 "value VARCHAR, " |
| 377 "value_lower VARCHAR, " | 351 "value_lower VARCHAR, " |
| 378 "pair_id INTEGER PRIMARY KEY, " | 352 "pair_id INTEGER PRIMARY KEY, " |
| 379 "count INTEGER DEFAULT 1)", | 353 "count INTEGER DEFAULT 1)")) { |
| 380 NULL, NULL, NULL) != SQLITE_OK) { | |
| 381 NOTREACHED(); | 354 NOTREACHED(); |
| 382 return false; | 355 return false; |
| 383 } | 356 } |
| 384 if (sqlite3_exec(db_, | 357 if (!db_.Execute("CREATE INDEX autofill_name ON autofill (name)")) { |
| 385 "CREATE INDEX autofill_name ON " | |
| 386 "autofill (name)", | |
| 387 NULL, NULL, NULL) != SQLITE_OK) { | |
| 388 NOTREACHED(); | 358 NOTREACHED(); |
| 389 return false; | 359 return false; |
| 390 } | 360 } |
| 391 if (sqlite3_exec(db_, | 361 if (!db_.Execute("CREATE INDEX autofill_name_value_lower ON " |
| 392 "CREATE INDEX autofill_name_value_lower ON " | 362 "autofill (name, value_lower)")) { |
| 393 "autofill (name, value_lower)", | |
| 394 NULL, NULL, NULL) != SQLITE_OK) { | |
| 395 NOTREACHED(); | 363 NOTREACHED(); |
| 396 return false; | 364 return false; |
| 397 } | 365 } |
| 398 } | 366 } |
| 399 return true; | 367 return true; |
| 400 } | 368 } |
| 401 | 369 |
| 402 bool WebDatabase::InitAutofillDatesTable() { | 370 bool WebDatabase::InitAutofillDatesTable() { |
| 403 if (!DoesSqliteTableExist(db_, "autofill_dates")) { | 371 if (!db_.DoesTableExist("autofill_dates")) { |
| 404 if (sqlite3_exec(db_, | 372 if (!db_.Execute("CREATE TABLE autofill_dates ( " |
| 405 "CREATE TABLE autofill_dates ( " | |
| 406 "pair_id INTEGER DEFAULT 0, " | 373 "pair_id INTEGER DEFAULT 0, " |
| 407 "date_created INTEGER DEFAULT 0)", | 374 "date_created INTEGER DEFAULT 0)")) { |
| 408 NULL, NULL, NULL) != SQLITE_OK) { | |
| 409 NOTREACHED(); | 375 NOTREACHED(); |
| 410 return false; | 376 return false; |
| 411 } | 377 } |
| 412 if (sqlite3_exec(db_, | 378 if (!db_.Execute("CREATE INDEX autofill_dates_pair_id ON " |
| 413 "CREATE INDEX autofill_dates_pair_id ON " | 379 "autofill_dates (pair_id)")) { |
| 414 "autofill_dates (pair_id)", | 380 NOTREACHED(); |
| 415 NULL, NULL, NULL) != SQLITE_OK) { | 381 return false; |
| 416 NOTREACHED(); | |
| 417 return false; | |
| 418 } | 382 } |
| 419 } | 383 } |
| 420 return true; | 384 return true; |
| 421 } | 385 } |
| 422 | 386 |
| 423 bool WebDatabase::InitWebAppIconsTable() { | 387 bool WebDatabase::InitWebAppIconsTable() { |
| 424 if (!DoesSqliteTableExist(db_, "web_app_icons")) { | 388 if (!db_.DoesTableExist("web_app_icons")) { |
| 425 if (sqlite3_exec(db_, "CREATE TABLE web_app_icons (" | 389 if (!db_.Execute("CREATE TABLE web_app_icons (" |
| 426 "url LONGVARCHAR," | 390 "url LONGVARCHAR," |
| 427 "width int," | 391 "width int," |
| 428 "height int," | 392 "height int," |
| 429 "image BLOB, UNIQUE (url, width, height))", | 393 "image BLOB, UNIQUE (url, width, height))")) { |
| 430 NULL, NULL, NULL) != SQLITE_OK) { | |
| 431 NOTREACHED(); | 394 NOTREACHED(); |
| 432 return false; | 395 return false; |
| 433 } | 396 } |
| 434 } | 397 } |
| 435 return true; | 398 return true; |
| 436 } | 399 } |
| 437 | 400 |
| 438 bool WebDatabase::InitWebAppsTable() { | 401 bool WebDatabase::InitWebAppsTable() { |
| 439 if (!DoesSqliteTableExist(db_, "web_apps")) { | 402 if (!db_.DoesTableExist("web_apps")) { |
| 440 if (sqlite3_exec(db_, "CREATE TABLE web_apps (" | 403 if (!db_.Execute("CREATE TABLE web_apps (" |
| 441 "url LONGVARCHAR UNIQUE," | 404 "url LONGVARCHAR UNIQUE," |
| 442 "has_all_images INTEGER NOT NULL)", | 405 "has_all_images INTEGER NOT NULL)")) { |
| 443 NULL, NULL, NULL) != SQLITE_OK) { | |
| 444 NOTREACHED(); | 406 NOTREACHED(); |
| 445 return false; | 407 return false; |
| 446 } | 408 } |
| 447 if (sqlite3_exec(db_, "CREATE INDEX web_apps_url_index ON " | 409 if (!db_.Execute("CREATE INDEX web_apps_url_index ON web_apps (url)")) { |
| 448 "web_apps (url)", NULL, NULL, NULL) != SQLITE_OK) { | |
| 449 NOTREACHED(); | 410 NOTREACHED(); |
| 450 return false; | 411 return false; |
| 451 } | 412 } |
| 452 } | 413 } |
| 453 return true; | 414 return true; |
| 454 } | 415 } |
| 455 | 416 |
| 456 static void BindURLToStatement(const TemplateURL& url, SQLStatement* s) { | 417 static void BindURLToStatement(const TemplateURL& url, sql::Statement* s) { |
| 457 s->bind_wstring(0, url.short_name()); | 418 s->BindString(0, WideToUTF8(url.short_name())); |
| 458 s->bind_wstring(1, url.keyword()); | 419 s->BindString(1, WideToUTF8(url.keyword())); |
| 459 GURL favicon_url = url.GetFavIconURL(); | 420 GURL favicon_url = url.GetFavIconURL(); |
| 460 if (!favicon_url.is_valid()) { | 421 if (!favicon_url.is_valid()) { |
| 461 s->bind_string(2, ""); | 422 s->BindString(2, std::string()); |
| 462 } else { | 423 } else { |
| 463 s->bind_string(2, history::HistoryDatabase::GURLToDatabaseURL( | 424 s->BindString(2, history::HistoryDatabase::GURLToDatabaseURL( |
| 464 url.GetFavIconURL())); | 425 url.GetFavIconURL())); |
| 465 } | 426 } |
| 466 if (url.url()) | 427 if (url.url()) |
| 467 s->bind_wstring(3, url.url()->url()); | 428 s->BindString(3, WideToUTF8(url.url()->url())); |
| 468 else | 429 else |
| 469 s->bind_wstring(3, std::wstring()); | 430 s->BindString(3, std::string()); |
| 470 s->bind_int(4, url.safe_for_autoreplace() ? 1 : 0); | 431 s->BindInt(4, url.safe_for_autoreplace() ? 1 : 0); |
| 471 if (!url.originating_url().is_valid()) { | 432 if (!url.originating_url().is_valid()) { |
| 472 s->bind_string(5, std::string()); | 433 s->BindString(5, std::string()); |
| 473 } else { | 434 } else { |
| 474 s->bind_string(5, history::HistoryDatabase::GURLToDatabaseURL( | 435 s->BindString(5, history::HistoryDatabase::GURLToDatabaseURL( |
| 475 url.originating_url())); | 436 url.originating_url())); |
| 476 } | 437 } |
| 477 s->bind_int64(6, url.date_created().ToTimeT()); | 438 s->BindInt64(6, url.date_created().ToTimeT()); |
| 478 s->bind_int(7, url.usage_count()); | 439 s->BindInt(7, url.usage_count()); |
| 479 s->bind_string(8, JoinStrings(";", url.input_encodings())); | 440 s->BindString(8, JoinStrings(";", url.input_encodings())); |
| 480 s->bind_int(9, url.show_in_default_list() ? 1 : 0); | 441 s->BindInt(9, url.show_in_default_list() ? 1 : 0); |
| 481 if (url.suggestions_url()) | 442 if (url.suggestions_url()) |
| 482 s->bind_wstring(10, url.suggestions_url()->url()); | 443 s->BindString(10, WideToUTF8(url.suggestions_url()->url())); |
| 483 else | 444 else |
| 484 s->bind_wstring(10, std::wstring()); | 445 s->BindString(10, std::string()); |
| 485 s->bind_int(11, url.prepopulate_id()); | 446 s->BindInt(11, url.prepopulate_id()); |
| 486 s->bind_int(12, url.autogenerate_keyword() ? 1 : 0); | 447 s->BindInt(12, url.autogenerate_keyword() ? 1 : 0); |
| 487 } | 448 } |
| 488 | 449 |
| 489 bool WebDatabase::AddKeyword(const TemplateURL& url) { | 450 bool WebDatabase::AddKeyword(const TemplateURL& url) { |
| 490 DCHECK(url.id()); | 451 DCHECK(url.id()); |
| 491 SQLStatement s; | 452 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, |
| 492 if (s.prepare(db_, | 453 "INSERT INTO keywords " |
| 493 "INSERT INTO keywords " | 454 "(short_name, keyword, favicon_url, url, safe_for_autoreplace, " |
| 494 "(short_name, keyword, favicon_url, url, safe_for_autoreplace, " | 455 "originating_url, date_created, usage_count, input_encodings, " |
| 495 "originating_url, date_created, usage_count, input_encodings, " | 456 "show_in_default_list, suggest_url, prepopulate_id, " |
| 496 "show_in_default_list, suggest_url, prepopulate_id, " | 457 "autogenerate_keyword, id) VALUES " |
| 497 "autogenerate_keyword, id) VALUES " | 458 "(?,?,?,?,?,?,?,?,?,?,?,?,?,?)")); |
| 498 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") | 459 if (!s) { |
| 499 != SQLITE_OK) { | |
| 500 NOTREACHED() << "Statement prepare failed"; | 460 NOTREACHED() << "Statement prepare failed"; |
| 501 return false; | 461 return false; |
| 502 } | 462 } |
| 503 BindURLToStatement(url, &s); | 463 BindURLToStatement(url, &s); |
| 504 s.bind_int64(13, url.id()); | 464 s.BindInt64(13, url.id()); |
| 505 if (s.step() != SQLITE_DONE) { | 465 if (!s.Run()) { |
| 506 NOTREACHED(); | 466 NOTREACHED(); |
| 507 return false; | 467 return false; |
| 508 } | 468 } |
| 509 return true; | 469 return true; |
| 510 } | 470 } |
| 511 | 471 |
| 512 bool WebDatabase::RemoveKeyword(TemplateURL::IDType id) { | 472 bool WebDatabase::RemoveKeyword(TemplateURL::IDType id) { |
| 513 DCHECK(id); | 473 DCHECK(id); |
| 514 SQLStatement s; | 474 sql::Statement s(db_.GetUniqueStatement("DELETE FROM keywords WHERE id = ?")); |
| 515 if (s.prepare(db_, | 475 if (!s) { |
| 516 "DELETE FROM keywords WHERE id = ?") != SQLITE_OK) { | |
| 517 NOTREACHED() << "Statement prepare failed"; | 476 NOTREACHED() << "Statement prepare failed"; |
| 518 return false; | 477 return false; |
| 519 } | 478 } |
| 520 s.bind_int64(0, id); | 479 s.BindInt64(0, id); |
| 521 return s.step() == SQLITE_DONE; | 480 return s.Run(); |
| 522 } | 481 } |
| 523 | 482 |
| 524 bool WebDatabase::GetKeywords(std::vector<TemplateURL*>* urls) const { | 483 bool WebDatabase::GetKeywords(std::vector<TemplateURL*>* urls) { |
| 525 SQLStatement s; | 484 sql::Statement s(db_.GetUniqueStatement( |
| 526 if (s.prepare(db_, | 485 "SELECT id, short_name, keyword, favicon_url, url, " |
| 527 "SELECT id, short_name, keyword, favicon_url, url, " | 486 "safe_for_autoreplace, originating_url, date_created, " |
| 528 "safe_for_autoreplace, originating_url, date_created, " | 487 "usage_count, input_encodings, show_in_default_list, " |
| 529 "usage_count, input_encodings, show_in_default_list, " | 488 "suggest_url, prepopulate_id, autogenerate_keyword " |
| 530 "suggest_url, prepopulate_id, autogenerate_keyword " | 489 "FROM keywords ORDER BY id ASC")); |
| 531 "FROM keywords ORDER BY id ASC") != SQLITE_OK) { | 490 if (!s) { |
| 532 NOTREACHED() << "Statement prepare failed"; | 491 NOTREACHED() << "Statement prepare failed"; |
| 533 return false; | 492 return false; |
| 534 } | 493 } |
| 535 int result; | 494 while (s.Step()) { |
| 536 while ((result = s.step()) == SQLITE_ROW) { | |
| 537 TemplateURL* template_url = new TemplateURL(); | 495 TemplateURL* template_url = new TemplateURL(); |
| 538 std::wstring tmp; | 496 template_url->set_id(s.ColumnInt64(0)); |
| 539 template_url->set_id(s.column_int64(0)); | |
| 540 | 497 |
| 541 s.column_wstring(1, &tmp); | 498 std::string tmp; |
| 499 tmp = s.ColumnString(1); |
| 542 DCHECK(!tmp.empty()); | 500 DCHECK(!tmp.empty()); |
| 543 template_url->set_short_name(tmp); | 501 template_url->set_short_name(UTF8ToWide(tmp)); |
| 544 | 502 |
| 545 s.column_wstring(2, &tmp); | 503 tmp = s.ColumnString(2); |
| 546 template_url->set_keyword(tmp); | 504 template_url->set_keyword(UTF8ToWide(tmp)); |
| 547 | 505 |
| 548 s.column_wstring(3, &tmp); | 506 tmp = s.ColumnString(3); |
| 549 if (!tmp.empty()) | 507 if (!tmp.empty()) |
| 550 template_url->SetFavIconURL(GURL(WideToUTF8(tmp))); | 508 template_url->SetFavIconURL(GURL(tmp)); |
| 551 | 509 |
| 552 s.column_wstring(4, &tmp); | 510 tmp = s.ColumnString(4); |
| 553 template_url->SetURL(tmp, 0, 0); | 511 template_url->SetURL(UTF8ToWide(tmp), 0, 0); |
| 554 | 512 |
| 555 template_url->set_safe_for_autoreplace(s.column_int(5) == 1); | 513 template_url->set_safe_for_autoreplace(s.ColumnInt(5) == 1); |
| 556 | 514 |
| 557 s.column_wstring(6, &tmp); | 515 tmp = s.ColumnString(6); |
| 558 if (!tmp.empty()) | 516 if (!tmp.empty()) |
| 559 template_url->set_originating_url(GURL(WideToUTF8(tmp))); | 517 template_url->set_originating_url(GURL(tmp)); |
| 560 | 518 |
| 561 template_url->set_date_created(Time::FromTimeT(s.column_int64(7))); | 519 template_url->set_date_created(Time::FromTimeT(s.ColumnInt64(7))); |
| 562 | 520 |
| 563 template_url->set_usage_count(s.column_int(8)); | 521 template_url->set_usage_count(s.ColumnInt(8)); |
| 564 | 522 |
| 565 std::vector<std::string> encodings; | 523 std::vector<std::string> encodings; |
| 566 SplitString(s.column_string(9), ';', &encodings); | 524 SplitString(s.ColumnString(9), ';', &encodings); |
| 567 template_url->set_input_encodings(encodings); | 525 template_url->set_input_encodings(encodings); |
| 568 | 526 |
| 569 template_url->set_show_in_default_list(s.column_int(10) == 1); | 527 template_url->set_show_in_default_list(s.ColumnInt(10) == 1); |
| 570 | 528 |
| 571 s.column_wstring(11, &tmp); | 529 tmp = s.ColumnString(11); |
| 572 template_url->SetSuggestionsURL(tmp, 0, 0); | 530 template_url->SetSuggestionsURL(UTF8ToWide(tmp), 0, 0); |
| 573 | 531 |
| 574 template_url->set_prepopulate_id(s.column_int(12)); | 532 template_url->set_prepopulate_id(s.ColumnInt(12)); |
| 575 | 533 |
| 576 template_url->set_autogenerate_keyword(s.column_int(13) == 1); | 534 template_url->set_autogenerate_keyword(s.ColumnInt(13) == 1); |
| 577 | 535 |
| 578 urls->push_back(template_url); | 536 urls->push_back(template_url); |
| 579 } | 537 } |
| 580 return result == SQLITE_DONE; | 538 return s.Succeeded(); |
| 581 } | 539 } |
| 582 | 540 |
| 583 bool WebDatabase::UpdateKeyword(const TemplateURL& url) { | 541 bool WebDatabase::UpdateKeyword(const TemplateURL& url) { |
| 584 DCHECK(url.id()); | 542 DCHECK(url.id()); |
| 585 SQLStatement s; | 543 sql::Statement s(db_.GetUniqueStatement( |
| 586 if (s.prepare(db_, | 544 "UPDATE keywords " |
| 587 "UPDATE keywords " | 545 "SET short_name=?, keyword=?, favicon_url=?, url=?, " |
| 588 "SET short_name=?, keyword=?, favicon_url=?, url=?, " | 546 "safe_for_autoreplace=?, originating_url=?, date_created=?, " |
| 589 "safe_for_autoreplace=?, originating_url=?, date_created=?, " | 547 "usage_count=?, input_encodings=?, show_in_default_list=?, " |
| 590 "usage_count=?, input_encodings=?, show_in_default_list=?, " | 548 "suggest_url=?, prepopulate_id=?, autogenerate_keyword=? " |
| 591 "suggest_url=?, prepopulate_id=?, autogenerate_keyword=? " | 549 "WHERE id=?")); |
| 592 "WHERE id=?") | 550 if (!s) { |
| 593 != SQLITE_OK) { | |
| 594 NOTREACHED() << "Statement prepare failed"; | 551 NOTREACHED() << "Statement prepare failed"; |
| 595 return false; | 552 return false; |
| 596 } | 553 } |
| 597 BindURLToStatement(url, &s); | 554 BindURLToStatement(url, &s); |
| 598 s.bind_int64(13, url.id()); | 555 s.BindInt64(13, url.id()); |
| 599 return s.step() == SQLITE_DONE; | 556 return s.Run(); |
| 600 } | 557 } |
| 601 | 558 |
| 602 bool WebDatabase::SetDefaultSearchProviderID(int64 id) { | 559 bool WebDatabase::SetDefaultSearchProviderID(int64 id) { |
| 603 return meta_table_.SetValue(kDefaultSearchProviderKey, id); | 560 return meta_table_.SetValue(kDefaultSearchProviderKey, id); |
| 604 } | 561 } |
| 605 | 562 |
| 606 int64 WebDatabase::GetDefaulSearchProviderID() { | 563 int64 WebDatabase::GetDefaulSearchProviderID() { |
| 607 int64 value = 0; | 564 int64 value = 0; |
| 608 meta_table_.GetValue(kDefaultSearchProviderKey, &value); | 565 meta_table_.GetValue(kDefaultSearchProviderKey, &value); |
| 609 return value; | 566 return value; |
| 610 } | 567 } |
| 611 | 568 |
| 612 bool WebDatabase::SetBuitinKeywordVersion(int version) { | 569 bool WebDatabase::SetBuitinKeywordVersion(int version) { |
| 613 return meta_table_.SetValue(kBuiltinKeywordVersion, version); | 570 return meta_table_.SetValue(kBuiltinKeywordVersion, version); |
| 614 } | 571 } |
| 615 | 572 |
| 616 int WebDatabase::GetBuitinKeywordVersion() { | 573 int WebDatabase::GetBuitinKeywordVersion() { |
| 617 int version = 0; | 574 int version = 0; |
| 618 meta_table_.GetValue(kBuiltinKeywordVersion, &version); | 575 meta_table_.GetValue(kBuiltinKeywordVersion, &version); |
| 619 return version; | 576 return version; |
| 620 } | 577 } |
| 621 | 578 |
| 622 bool WebDatabase::AddLogin(const PasswordForm& form) { | 579 bool WebDatabase::AddLogin(const PasswordForm& form) { |
| 623 SQLStatement s; | 580 sql::Statement s(db_.GetUniqueStatement( |
| 624 std::string encrypted_password; | 581 "INSERT OR REPLACE INTO logins " |
| 625 if (s.prepare(db_, | 582 "(origin_url, action_url, username_element, username_value, " |
| 626 "INSERT OR REPLACE INTO logins " | 583 " password_element, password_value, submit_element, " |
| 627 "(origin_url, action_url, username_element, username_value, " | 584 " signon_realm, ssl_valid, preferred, date_created, " |
| 628 " password_element, password_value, submit_element, " | 585 " blacklisted_by_user, scheme) " |
| 629 " signon_realm, ssl_valid, preferred, date_created, " | 586 "VALUES " |
| 630 " blacklisted_by_user, scheme) " | 587 "(?,?,?,?,?,?,?,?,?,?,?,?,?)")); |
| 631 "VALUES " | 588 if (!s) { |
| 632 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") != SQLITE_OK) { | |
| 633 NOTREACHED() << "Statement prepare failed"; | 589 NOTREACHED() << "Statement prepare failed"; |
| 634 return false; | 590 return false; |
| 635 } | 591 } |
| 636 | 592 |
| 637 s.bind_string(0, form.origin.spec()); | 593 std::string encrypted_password; |
| 638 s.bind_string(1, form.action.spec()); | 594 s.BindString(0, form.origin.spec()); |
| 639 s.bind_wstring(2, form.username_element); | 595 s.BindString(1, form.action.spec()); |
| 640 s.bind_wstring(3, form.username_value); | 596 s.BindString(2, WideToUTF8(form.username_element)); |
| 641 s.bind_wstring(4, form.password_element); | 597 s.BindString(3, WideToUTF8(form.username_value)); |
| 598 s.BindString(4, WideToUTF8(form.password_element)); |
| 642 Encryptor::EncryptString16(WideToUTF16Hack(form.password_value), | 599 Encryptor::EncryptString16(WideToUTF16Hack(form.password_value), |
| 643 &encrypted_password); | 600 &encrypted_password); |
| 644 s.bind_blob(5, encrypted_password.data(), | 601 s.BindBlob(5, encrypted_password.data(), |
| 645 static_cast<int>(encrypted_password.length())); | 602 static_cast<int>(encrypted_password.length())); |
| 646 s.bind_wstring(6, form.submit_element); | 603 s.BindString(6, WideToUTF8(form.submit_element)); |
| 647 s.bind_string(7, form.signon_realm); | 604 s.BindString(7, form.signon_realm); |
| 648 s.bind_int(8, form.ssl_valid); | 605 s.BindInt(8, form.ssl_valid); |
| 649 s.bind_int(9, form.preferred); | 606 s.BindInt(9, form.preferred); |
| 650 s.bind_int64(10, form.date_created.ToTimeT()); | 607 s.BindInt64(10, form.date_created.ToTimeT()); |
| 651 s.bind_int(11, form.blacklisted_by_user); | 608 s.BindInt(11, form.blacklisted_by_user); |
| 652 s.bind_int(12, form.scheme); | 609 s.BindInt(12, form.scheme); |
| 653 if (s.step() != SQLITE_DONE) { | 610 if (!s.Run()) { |
| 654 NOTREACHED(); | 611 NOTREACHED(); |
| 655 return false; | 612 return false; |
| 656 } | 613 } |
| 657 return true; | 614 return true; |
| 658 } | 615 } |
| 659 | 616 |
| 660 bool WebDatabase::UpdateLogin(const PasswordForm& form) { | 617 bool WebDatabase::UpdateLogin(const PasswordForm& form) { |
| 661 SQLStatement s; | 618 sql::Statement s(db_.GetUniqueStatement( |
| 662 std::string encrypted_password; | 619 "UPDATE logins SET " |
| 663 if (s.prepare(db_, "UPDATE logins SET " | 620 "action_url = ?, " |
| 664 "action_url = ?, " | 621 "password_value = ?, " |
| 665 "password_value = ?, " | 622 "ssl_valid = ?, " |
| 666 "ssl_valid = ?, " | 623 "preferred = ? " |
| 667 "preferred = ? " | 624 "WHERE origin_url = ? AND " |
| 668 "WHERE origin_url = ? AND " | 625 "username_element = ? AND " |
| 669 "username_element = ? AND " | 626 "username_value = ? AND " |
| 670 "username_value = ? AND " | 627 "password_element = ? AND " |
| 671 "password_element = ? AND " | 628 "signon_realm = ?")); |
| 672 "signon_realm = ?") != SQLITE_OK) { | 629 if (!s) { |
| 673 NOTREACHED() << "Statement prepare failed"; | 630 NOTREACHED() << "Statement prepare failed"; |
| 674 return false; | 631 return false; |
| 675 } | 632 } |
| 676 | 633 |
| 677 s.bind_string(0, form.action.spec()); | 634 s.BindString(0, form.action.spec()); |
| 635 std::string encrypted_password; |
| 678 Encryptor::EncryptString16(WideToUTF16Hack(form.password_value), | 636 Encryptor::EncryptString16(WideToUTF16Hack(form.password_value), |
| 679 &encrypted_password); | 637 &encrypted_password); |
| 680 s.bind_blob(1, encrypted_password.data(), | 638 s.BindBlob(1, encrypted_password.data(), |
| 681 static_cast<int>(encrypted_password.length())); | 639 static_cast<int>(encrypted_password.length())); |
| 682 s.bind_int(2, form.ssl_valid); | 640 s.BindInt(2, form.ssl_valid); |
| 683 s.bind_int(3, form.preferred); | 641 s.BindInt(3, form.preferred); |
| 684 s.bind_string(4, form.origin.spec()); | 642 s.BindString(4, form.origin.spec()); |
| 685 s.bind_wstring(5, form.username_element); | 643 s.BindString(5, WideToUTF8(form.username_element)); |
| 686 s.bind_wstring(6, form.username_value); | 644 s.BindString(6, WideToUTF8(form.username_value)); |
| 687 s.bind_wstring(7, form.password_element); | 645 s.BindString(7, WideToUTF8(form.password_element)); |
| 688 s.bind_string(8, form.signon_realm); | 646 s.BindString(8, form.signon_realm); |
| 689 | 647 |
| 690 if (s.step() != SQLITE_DONE) { | 648 if (!s.Run()) { |
| 691 NOTREACHED(); | 649 NOTREACHED(); |
| 692 return false; | 650 return false; |
| 693 } | 651 } |
| 694 return true; | 652 return true; |
| 695 } | 653 } |
| 696 | 654 |
| 697 bool WebDatabase::RemoveLogin(const PasswordForm& form) { | 655 bool WebDatabase::RemoveLogin(const PasswordForm& form) { |
| 698 SQLStatement s; | |
| 699 // Remove a login by UNIQUE-constrained fields. | 656 // Remove a login by UNIQUE-constrained fields. |
| 700 if (s.prepare(db_, | 657 sql::Statement s(db_.GetUniqueStatement( |
| 701 "DELETE FROM logins WHERE " | 658 "DELETE FROM logins WHERE " |
| 702 "origin_url = ? AND " | 659 "origin_url = ? AND " |
| 703 "username_element = ? AND " | 660 "username_element = ? AND " |
| 704 "username_value = ? AND " | 661 "username_value = ? AND " |
| 705 "password_element = ? AND " | 662 "password_element = ? AND " |
| 706 "submit_element = ? AND " | 663 "submit_element = ? AND " |
| 707 "signon_realm = ? ") != SQLITE_OK) { | 664 "signon_realm = ?")); |
| 665 if (!s) { |
| 708 NOTREACHED() << "Statement prepare failed"; | 666 NOTREACHED() << "Statement prepare failed"; |
| 709 return false; | 667 return false; |
| 710 } | 668 } |
| 711 s.bind_string(0, form.origin.spec()); | 669 s.BindString(0, form.origin.spec()); |
| 712 s.bind_wstring(1, form.username_element); | 670 s.BindString(1, WideToUTF8(form.username_element)); |
| 713 s.bind_wstring(2, form.username_value); | 671 s.BindString(2, WideToUTF8(form.username_value)); |
| 714 s.bind_wstring(3, form.password_element); | 672 s.BindString(3, WideToUTF8(form.password_element)); |
| 715 s.bind_wstring(4, form.submit_element); | 673 s.BindString(4, WideToUTF8(form.submit_element)); |
| 716 s.bind_string(5, form.signon_realm); | 674 s.BindString(5, form.signon_realm); |
| 717 | 675 |
| 718 if (s.step() != SQLITE_DONE) { | 676 if (!s.Run()) { |
| 719 NOTREACHED(); | 677 NOTREACHED(); |
| 720 return false; | 678 return false; |
| 721 } | 679 } |
| 722 return true; | 680 return true; |
| 723 } | 681 } |
| 724 | 682 |
| 725 bool WebDatabase::RemoveLoginsCreatedBetween(const Time delete_begin, | 683 bool WebDatabase::RemoveLoginsCreatedBetween(base::Time delete_begin, |
| 726 const Time delete_end) { | 684 base::Time delete_end) { |
| 727 SQLStatement s1; | 685 sql::Statement s1(db_.GetUniqueStatement( |
| 728 if (s1.prepare(db_, | 686 "DELETE FROM logins WHERE " |
| 729 "DELETE FROM logins WHERE " | 687 "date_created >= ? AND date_created < ?")); |
| 730 "date_created >= ? AND date_created < ?") != SQLITE_OK) { | 688 if (!s1) { |
| 731 NOTREACHED() << "Statement 1 prepare failed"; | 689 NOTREACHED() << "Statement 1 prepare failed"; |
| 732 return false; | 690 return false; |
| 733 } | 691 } |
| 734 s1.bind_int64(0, delete_begin.ToTimeT()); | 692 s1.BindInt64(0, delete_begin.ToTimeT()); |
| 735 s1.bind_int64(1, | 693 s1.BindInt64(1, |
| 736 delete_end.is_null() ? | 694 delete_end.is_null() ? |
| 737 std::numeric_limits<int64>::max() : | 695 std::numeric_limits<int64>::max() : |
| 738 delete_end.ToTimeT()); | 696 delete_end.ToTimeT()); |
| 739 bool success = s1.step() == SQLITE_DONE; | 697 bool success = s1.Run(); |
| 740 | 698 |
| 741 #if defined(OS_WIN) | 699 #if defined(OS_WIN) |
| 742 SQLStatement s2; | 700 sql::Statement s2(db_.GetUniqueStatement( |
| 743 if (s2.prepare(db_, | 701 "DELETE FROM ie7_logins WHERE date_created >= ? AND date_created < ?")); |
| 744 "DELETE FROM ie7_logins WHERE " | 702 if (!s2) { |
| 745 "date_created >= ? AND date_created < ?") != SQLITE_OK) { | |
| 746 NOTREACHED() << "Statement 2 prepare failed"; | 703 NOTREACHED() << "Statement 2 prepare failed"; |
| 747 return false; | 704 return false; |
| 748 } | 705 } |
| 749 s2.bind_int64(0, delete_begin.ToTimeT()); | 706 s2.BindInt64(0, delete_begin.ToTimeT()); |
| 750 s2.bind_int64(1, | 707 s2.BindInt64(1, |
| 751 delete_end.is_null() ? | 708 delete_end.is_null() ? |
| 752 std::numeric_limits<int64>::max() : | 709 std::numeric_limits<int64>::max() : |
| 753 delete_end.ToTimeT()); | 710 delete_end.ToTimeT()); |
| 754 success = success && (s2.step() == SQLITE_DONE); | 711 success = success && s2.Run(); |
| 755 #endif | 712 #endif |
| 756 | 713 |
| 757 return success; | 714 return success; |
| 758 } | 715 } |
| 759 | 716 |
| 760 static void InitPasswordFormFromStatement(PasswordForm* form, | 717 static void InitPasswordFormFromStatement(PasswordForm* form, |
| 761 SQLStatement* s) { | 718 sql::Statement* s) { |
| 762 std::string encrypted_password; | |
| 763 std::string tmp; | 719 std::string tmp; |
| 764 string16 decrypted_password; | 720 string16 decrypted_password; |
| 765 s->column_string(0, &tmp); | 721 tmp = s->ColumnString(0); |
| 766 form->origin = GURL(tmp); | 722 form->origin = GURL(tmp); |
| 767 s->column_string(1, &tmp); | 723 tmp = s->ColumnString(1); |
| 768 form->action = GURL(tmp); | 724 form->action = GURL(tmp); |
| 769 s->column_wstring(2, &form->username_element); | 725 form->username_element = UTF8ToWide(s->ColumnString(2)); |
| 770 s->column_wstring(3, &form->username_value); | 726 form->username_value = UTF8ToWide(s->ColumnString(3)); |
| 771 s->column_wstring(4, &form->password_element); | 727 form->password_element = UTF8ToWide(s->ColumnString(4)); |
| 772 s->column_blob_as_string(5, &encrypted_password); | 728 |
| 773 Encryptor::DecryptString16(encrypted_password, &decrypted_password); | 729 int encrypted_password_len = s->ColumnByteLength(5); |
| 730 std::string encrypted_password; |
| 731 if (encrypted_password_len) { |
| 732 encrypted_password.resize(encrypted_password_len); |
| 733 memcpy(&encrypted_password[0], s->ColumnBlob(5), encrypted_password_len); |
| 734 Encryptor::DecryptString16(encrypted_password, &decrypted_password); |
| 735 } |
| 736 |
| 774 form->password_value = UTF16ToWideHack(decrypted_password); | 737 form->password_value = UTF16ToWideHack(decrypted_password); |
| 775 s->column_wstring(6, &form->submit_element); | 738 form->submit_element = UTF8ToWide(s->ColumnString(6)); |
| 776 s->column_string(7, &tmp); | 739 tmp = s->ColumnString(7); |
| 777 form->signon_realm = tmp; | 740 form->signon_realm = tmp; |
| 778 form->ssl_valid = (s->column_int(8) > 0); | 741 form->ssl_valid = (s->ColumnInt(8) > 0); |
| 779 form->preferred = (s->column_int(9) > 0); | 742 form->preferred = (s->ColumnInt(9) > 0); |
| 780 form->date_created = Time::FromTimeT(s->column_int64(10)); | 743 form->date_created = Time::FromTimeT(s->ColumnInt64(10)); |
| 781 form->blacklisted_by_user = (s->column_int(11) > 0); | 744 form->blacklisted_by_user = (s->ColumnInt(11) > 0); |
| 782 int scheme_int = s->column_int(12); | 745 int scheme_int = s->ColumnInt(12); |
| 783 DCHECK((scheme_int >= 0) && (scheme_int <= PasswordForm::SCHEME_OTHER)); | 746 DCHECK((scheme_int >= 0) && (scheme_int <= PasswordForm::SCHEME_OTHER)); |
| 784 form->scheme = static_cast<PasswordForm::Scheme>(scheme_int); | 747 form->scheme = static_cast<PasswordForm::Scheme>(scheme_int); |
| 785 } | 748 } |
| 786 | 749 |
| 787 bool WebDatabase::GetLogins(const PasswordForm& form, | 750 bool WebDatabase::GetLogins(const PasswordForm& form, |
| 788 std::vector<PasswordForm*>* forms) const { | 751 std::vector<PasswordForm*>* forms) { |
| 789 DCHECK(forms); | 752 DCHECK(forms); |
| 790 SQLStatement s; | 753 sql::Statement s(db_.GetUniqueStatement( |
| 791 if (s.prepare(db_, | |
| 792 "SELECT origin_url, action_url, " | 754 "SELECT origin_url, action_url, " |
| 793 "username_element, username_value, " | 755 "username_element, username_value, " |
| 794 "password_element, password_value, " | 756 "password_element, password_value, " |
| 795 "submit_element, signon_realm, " | 757 "submit_element, signon_realm, " |
| 796 "ssl_valid, preferred, " | 758 "ssl_valid, preferred, " |
| 797 "date_created, blacklisted_by_user, scheme FROM logins " | 759 "date_created, blacklisted_by_user, scheme FROM logins " |
| 798 "WHERE signon_realm == ? ") != SQLITE_OK) { | 760 "WHERE signon_realm == ?")); |
| 761 if (!s) { |
| 799 NOTREACHED() << "Statement prepare failed"; | 762 NOTREACHED() << "Statement prepare failed"; |
| 800 return false; | 763 return false; |
| 801 } | 764 } |
| 802 | 765 |
| 803 s.bind_string(0, form.signon_realm); | 766 s.BindString(0, form.signon_realm); |
| 804 | 767 |
| 805 int result; | 768 while (s.Step()) { |
| 806 while ((result = s.step()) == SQLITE_ROW) { | |
| 807 PasswordForm* new_form = new PasswordForm(); | 769 PasswordForm* new_form = new PasswordForm(); |
| 808 InitPasswordFormFromStatement(new_form, &s); | 770 InitPasswordFormFromStatement(new_form, &s); |
| 809 | 771 |
| 810 forms->push_back(new_form); | 772 forms->push_back(new_form); |
| 811 } | 773 } |
| 812 return result == SQLITE_DONE; | 774 return s.Succeeded(); |
| 813 } | 775 } |
| 814 | 776 |
| 815 bool WebDatabase::GetAllLogins(std::vector<PasswordForm*>* forms, | 777 bool WebDatabase::GetAllLogins(std::vector<PasswordForm*>* forms, |
| 816 bool include_blacklisted) const { | 778 bool include_blacklisted) { |
| 817 DCHECK(forms); | 779 DCHECK(forms); |
| 818 SQLStatement s; | |
| 819 std::string stmt = "SELECT origin_url, action_url, " | 780 std::string stmt = "SELECT origin_url, action_url, " |
| 820 "username_element, username_value, " | 781 "username_element, username_value, " |
| 821 "password_element, password_value, " | 782 "password_element, password_value, " |
| 822 "submit_element, signon_realm, ssl_valid, preferred, " | 783 "submit_element, signon_realm, ssl_valid, preferred, " |
| 823 "date_created, blacklisted_by_user, scheme FROM logins "; | 784 "date_created, blacklisted_by_user, scheme FROM logins "; |
| 824 if (!include_blacklisted) | 785 if (!include_blacklisted) |
| 825 stmt.append("WHERE blacklisted_by_user == 0 "); | 786 stmt.append("WHERE blacklisted_by_user == 0 "); |
| 826 stmt.append("ORDER BY origin_url"); | 787 stmt.append("ORDER BY origin_url"); |
| 827 | 788 |
| 828 if (s.prepare(db_, stmt.c_str()) != SQLITE_OK) { | 789 sql::Statement s(db_.GetUniqueStatement(stmt.c_str())); |
| 790 if (!s) { |
| 829 NOTREACHED() << "Statement prepare failed"; | 791 NOTREACHED() << "Statement prepare failed"; |
| 830 return false; | 792 return false; |
| 831 } | 793 } |
| 832 | 794 |
| 833 int result; | 795 while (s.Step()) { |
| 834 while ((result = s.step()) == SQLITE_ROW) { | |
| 835 PasswordForm* new_form = new PasswordForm(); | 796 PasswordForm* new_form = new PasswordForm(); |
| 836 InitPasswordFormFromStatement(new_form, &s); | 797 InitPasswordFormFromStatement(new_form, &s); |
| 837 | 798 |
| 838 forms->push_back(new_form); | 799 forms->push_back(new_form); |
| 839 } | 800 } |
| 840 return result == SQLITE_DONE; | 801 return s.Succeeded(); |
| 841 } | 802 } |
| 842 | 803 |
| 843 bool WebDatabase::AddAutofillFormElements( | 804 bool WebDatabase::AddAutofillFormElements( |
| 844 const std::vector<AutofillForm::Element>& elements) { | 805 const std::vector<AutofillForm::Element>& elements) { |
| 845 bool result = true; | 806 bool result = true; |
| 846 for (std::vector<AutofillForm::Element>::const_iterator | 807 for (std::vector<AutofillForm::Element>::const_iterator |
| 847 itr = elements.begin(); | 808 itr = elements.begin(); |
| 848 itr != elements.end(); | 809 itr != elements.end(); |
| 849 itr++) { | 810 itr++) { |
| 850 result = result && AddAutofillFormElement(*itr); | 811 result = result && AddAutofillFormElement(*itr); |
| 851 } | 812 } |
| 852 return result; | 813 return result; |
| 853 } | 814 } |
| 854 | 815 |
| 855 bool WebDatabase::ClearAutofillEmptyValueElements() { | 816 bool WebDatabase::ClearAutofillEmptyValueElements() { |
| 856 SQLStatement s; | 817 sql::Statement s(db_.GetUniqueStatement( |
| 857 | 818 "SELECT pair_id FROM autofill WHERE TRIM(value)= \"\"")); |
| 858 if (s.prepare(db_, "SELECT pair_id FROM autofill " | 819 if (!s) { |
| 859 "WHERE TRIM(value)= \"\"") != SQLITE_OK) { | |
| 860 NOTREACHED() << "Statement prepare failed"; | 820 NOTREACHED() << "Statement prepare failed"; |
| 861 return false; | 821 return false; |
| 862 } | 822 } |
| 863 | 823 |
| 864 std::set<int64> ids; | 824 std::set<int64> ids; |
| 865 int result; | 825 while (s.Step()) |
| 866 while ((result = s.step()) == SQLITE_ROW) | 826 ids.insert(s.ColumnInt64(0)); |
| 867 ids.insert(s.column_int64(0)); | |
| 868 | 827 |
| 869 bool success = true; | 828 bool success = true; |
| 870 for (std::set<int64>::const_iterator iter = ids.begin(); iter != ids.end(); | 829 for (std::set<int64>::const_iterator iter = ids.begin(); iter != ids.end(); |
| 871 ++iter) { | 830 ++iter) { |
| 872 if (!RemoveFormElementForID(*iter)) | 831 if (!RemoveFormElementForID(*iter)) |
| 873 success = false; | 832 success = false; |
| 874 } | 833 } |
| 875 | 834 |
| 876 return success; | 835 return success; |
| 877 } | 836 } |
| 878 | 837 |
| 879 bool WebDatabase::GetIDAndCountOfFormElement( | 838 bool WebDatabase::GetIDAndCountOfFormElement( |
| 880 const AutofillForm::Element& element, int64* pair_id, int* count) const { | 839 const AutofillForm::Element& element, |
| 881 SQLStatement s; | 840 int64* pair_id, |
| 882 | 841 int* count) { |
| 883 if (s.prepare(db_, "SELECT pair_id, count FROM autofill " | 842 sql::Statement s(db_.GetUniqueStatement( |
| 884 " WHERE name = ? AND value = ?") != SQLITE_OK) { | 843 "SELECT pair_id, count FROM autofill " |
| 844 "WHERE name = ? AND value = ?")); |
| 845 if (!s) { |
| 885 NOTREACHED() << "Statement prepare failed"; | 846 NOTREACHED() << "Statement prepare failed"; |
| 886 return false; | 847 return false; |
| 887 } | 848 } |
| 888 | 849 |
| 889 s.bind_wstring(0, element.name); | 850 s.BindString(0, WideToUTF8(element.name)); |
| 890 s.bind_wstring(1, element.value); | 851 s.BindString(1, WideToUTF8(element.value)); |
| 891 | |
| 892 int result; | |
| 893 | 852 |
| 894 *count = 0; | 853 *count = 0; |
| 895 | 854 |
| 896 if ((result = s.step()) == SQLITE_ROW) { | 855 if (s.Step()) { |
| 897 *pair_id = s.column_int64(0); | 856 *pair_id = s.ColumnInt64(0); |
| 898 *count = s.column_int(1); | 857 *count = s.ColumnInt(1); |
| 899 } | 858 } |
| 900 | 859 |
| 901 return true; | 860 return true; |
| 902 } | 861 } |
| 903 | 862 |
| 904 bool WebDatabase::GetCountOfFormElement(int64 pair_id, int* count) const { | 863 bool WebDatabase::GetCountOfFormElement(int64 pair_id, int* count) { |
| 905 SQLStatement s; | 864 sql::Statement s(db_.GetUniqueStatement( |
| 906 | 865 "SELECT count FROM autofill WHERE pair_id = ?")); |
| 907 if (s.prepare(db_, "SELECT count FROM autofill " | 866 if (!s) { |
| 908 " WHERE pair_id = ?") != SQLITE_OK) { | |
| 909 NOTREACHED() << "Statement prepare failed"; | 867 NOTREACHED() << "Statement prepare failed"; |
| 910 return false; | 868 return false; |
| 911 } | 869 } |
| 912 | 870 |
| 913 s.bind_int64(0, pair_id); | 871 s.BindInt64(0, pair_id); |
| 914 | 872 |
| 915 int result; | 873 if (s.Step()) { |
| 916 if ((result = s.step()) == SQLITE_ROW) { | 874 *count = s.ColumnInt(0); |
| 917 *count = s.column_int(0); | 875 return true; |
| 918 } else { | |
| 919 return false; | |
| 920 } | 876 } |
| 921 | 877 return false; |
| 922 return true; | |
| 923 } | 878 } |
| 924 | 879 |
| 925 bool WebDatabase::InsertFormElement(const AutofillForm::Element& element, | 880 bool WebDatabase::InsertFormElement(const AutofillForm::Element& element, |
| 926 int64* pair_id) { | 881 int64* pair_id) { |
| 927 SQLStatement s; | 882 sql::Statement s(db_.GetUniqueStatement( |
| 928 | 883 "INSERT INTO autofill (name, value, value_lower) VALUES (?,?,?)")); |
| 929 if (s.prepare(db_, "INSERT INTO autofill " | 884 if (!s) { |
| 930 "(name, value, value_lower) " | |
| 931 "VALUES (?, ?, ?)") | |
| 932 != SQLITE_OK) { | |
| 933 NOTREACHED() << "Statement prepare failed"; | 885 NOTREACHED() << "Statement prepare failed"; |
| 934 return false; | 886 return false; |
| 935 } | 887 } |
| 936 | 888 |
| 937 s.bind_wstring(0, element.name); | 889 s.BindString(0, WideToUTF8(element.name)); |
| 938 s.bind_wstring(1, element.value); | 890 s.BindString(1, WideToUTF8(element.value)); |
| 939 s.bind_wstring(2, l10n_util::ToLower(element.value)); | 891 s.BindString(2, UTF16ToUTF8( |
| 892 l10n_util::ToLower(WideToUTF16Hack(element.value)))); |
| 940 | 893 |
| 941 if (s.step() != SQLITE_DONE) { | 894 if (!s.Run()) { |
| 942 NOTREACHED(); | 895 NOTREACHED(); |
| 943 return false; | 896 return false; |
| 944 } | 897 } |
| 945 | 898 |
| 946 *pair_id = sqlite3_last_insert_rowid(db_); | 899 *pair_id = db_.GetLastInsertRowId(); |
| 947 | |
| 948 return true; | 900 return true; |
| 949 } | 901 } |
| 950 | 902 |
| 951 bool WebDatabase::InsertPairIDAndDate(int64 pair_id, | 903 bool WebDatabase::InsertPairIDAndDate(int64 pair_id, |
| 952 const Time date_created) { | 904 base::Time date_created) { |
| 953 SQLStatement s; | 905 sql::Statement s(db_.GetUniqueStatement( |
| 954 | 906 "INSERT INTO autofill_dates " |
| 955 if (s.prepare(db_, | 907 "(pair_id, date_created) VALUES (?, ?)")); |
| 956 "INSERT INTO autofill_dates " | 908 if (!s) { |
| 957 "(pair_id, date_created) VALUES (?, ?)") | |
| 958 != SQLITE_OK) { | |
| 959 NOTREACHED() << "Statement prepare failed"; | 909 NOTREACHED() << "Statement prepare failed"; |
| 960 return false; | 910 return false; |
| 961 } | 911 } |
| 962 | 912 |
| 963 s.bind_int64(0, pair_id); | 913 s.BindInt64(0, pair_id); |
| 964 s.bind_int64(1, date_created.ToTimeT()); | 914 s.BindInt64(1, date_created.ToTimeT()); |
| 965 | 915 |
| 966 if (s.step() != SQLITE_DONE) { | 916 if (!s.Run()) { |
| 967 NOTREACHED(); | 917 NOTREACHED(); |
| 968 return false; | 918 return false; |
| 969 } | 919 } |
| 970 | 920 |
| 971 return true; | 921 return true; |
| 972 } | 922 } |
| 973 | 923 |
| 974 bool WebDatabase::SetCountOfFormElement(int64 pair_id, int count) { | 924 bool WebDatabase::SetCountOfFormElement(int64 pair_id, int count) { |
| 975 SQLStatement s; | 925 sql::Statement s(db_.GetUniqueStatement( |
| 976 | 926 "UPDATE autofill SET count = ? WHERE pair_id = ?")); |
| 977 if (s.prepare(db_, | 927 if (!s) { |
| 978 "UPDATE autofill SET count = ? " | |
| 979 "WHERE pair_id = ?") | |
| 980 != SQLITE_OK) { | |
| 981 NOTREACHED() << "Statement prepare failed"; | 928 NOTREACHED() << "Statement prepare failed"; |
| 982 return false; | 929 return false; |
| 983 } | 930 } |
| 984 | 931 |
| 985 s.bind_int(0, count); | 932 s.BindInt(0, count); |
| 986 s.bind_int64(1, pair_id); | 933 s.BindInt64(1, pair_id); |
| 987 | 934 if (!s.Run()) { |
| 988 if (s.step() != SQLITE_DONE) { | |
| 989 NOTREACHED(); | 935 NOTREACHED(); |
| 990 return false; | 936 return false; |
| 991 } | 937 } |
| 992 | 938 |
| 993 return true; | 939 return true; |
| 994 } | 940 } |
| 995 | 941 |
| 996 bool WebDatabase::AddAutofillFormElement(const AutofillForm::Element& element) { | 942 bool WebDatabase::AddAutofillFormElement(const AutofillForm::Element& element) { |
| 997 SQLStatement s; | |
| 998 int count = 0; | 943 int count = 0; |
| 999 int64 pair_id; | 944 int64 pair_id; |
| 1000 | 945 |
| 1001 if (!GetIDAndCountOfFormElement(element, &pair_id, &count)) | 946 if (!GetIDAndCountOfFormElement(element, &pair_id, &count)) |
| 1002 return false; | 947 return false; |
| 1003 | 948 |
| 1004 if (count == 0 && !InsertFormElement(element, &pair_id)) | 949 if (count == 0 && !InsertFormElement(element, &pair_id)) |
| 1005 return false; | 950 return false; |
| 1006 | 951 |
| 1007 return SetCountOfFormElement(pair_id, count + 1) && | 952 return SetCountOfFormElement(pair_id, count + 1) && |
| 1008 InsertPairIDAndDate(pair_id, Time::Now()); | 953 InsertPairIDAndDate(pair_id, Time::Now()); |
| 1009 } | 954 } |
| 1010 | 955 |
| 1011 bool WebDatabase::GetFormValuesForElementName(const std::wstring& name, | 956 bool WebDatabase::GetFormValuesForElementName(const std::wstring& name, |
| 1012 const std::wstring& prefix, | 957 const std::wstring& prefix, |
| 1013 std::vector<std::wstring>* values, | 958 std::vector<std::wstring>* values, |
| 1014 int limit) const { | 959 int limit) { |
| 1015 DCHECK(values); | 960 DCHECK(values); |
| 1016 SQLStatement s; | 961 sql::Statement s; |
| 1017 | 962 |
| 1018 if (prefix.empty()) { | 963 if (prefix.empty()) { |
| 1019 if (s.prepare(db_, "SELECT value FROM autofill " | 964 s.Assign(db_.GetUniqueStatement( |
| 1020 "WHERE name = ? " | 965 "SELECT value FROM autofill " |
| 1021 "ORDER BY count DESC " | 966 "WHERE name = ? " |
| 1022 "LIMIT ?") != SQLITE_OK) { | 967 "ORDER BY count DESC " |
| 968 "LIMIT ?")); |
| 969 if (!s) { |
| 1023 NOTREACHED() << "Statement prepare failed"; | 970 NOTREACHED() << "Statement prepare failed"; |
| 1024 return false; | 971 return false; |
| 1025 } | 972 } |
| 1026 | 973 |
| 1027 s.bind_wstring(0, name); | 974 s.BindString(0, WideToUTF8(name)); |
| 1028 s.bind_int(1, limit); | 975 s.BindInt(1, limit); |
| 1029 } else { | 976 } else { |
| 1030 std::wstring prefix_lower = l10n_util::ToLower(prefix); | 977 string16 prefix_lower = l10n_util::ToLower(WideToUTF16Hack(prefix)); |
| 1031 std::wstring next_prefix = prefix_lower; | 978 string16 next_prefix = prefix_lower; |
| 1032 next_prefix[next_prefix.length() - 1]++; | 979 next_prefix[next_prefix.length() - 1]++; |
| 1033 | 980 |
| 1034 if (s.prepare(db_, "SELECT value FROM autofill " | 981 s.Assign(db_.GetUniqueStatement( |
| 1035 "WHERE name = ? AND " | 982 "SELECT value FROM autofill " |
| 1036 "value_lower >= ? AND " | 983 "WHERE name = ? AND " |
| 1037 "value_lower < ? " | 984 "value_lower >= ? AND " |
| 1038 "ORDER BY count DESC " | 985 "value_lower < ? " |
| 1039 "LIMIT ?") != SQLITE_OK) { | 986 "ORDER BY count DESC " |
| 987 "LIMIT ?")); |
| 988 if (!s) { |
| 1040 NOTREACHED() << "Statement prepare failed"; | 989 NOTREACHED() << "Statement prepare failed"; |
| 1041 return false; | 990 return false; |
| 1042 } | 991 } |
| 1043 | 992 |
| 1044 s.bind_wstring(0, name); | 993 s.BindString(0, WideToUTF8(name)); |
| 1045 s.bind_wstring(1, prefix_lower); | 994 s.BindString(1, UTF16ToUTF8(prefix_lower)); |
| 1046 s.bind_wstring(2, next_prefix); | 995 s.BindString(2, UTF16ToUTF8(next_prefix)); |
| 1047 s.bind_int(3, limit); | 996 s.BindInt(3, limit); |
| 1048 } | 997 } |
| 1049 | 998 |
| 1050 values->clear(); | 999 values->clear(); |
| 1051 int result; | 1000 while (s.Step()) |
| 1052 while ((result = s.step()) == SQLITE_ROW) | 1001 values->push_back(UTF8ToWide(s.ColumnString(0))); |
| 1053 values->push_back(s.column_wstring(0)); | 1002 return s.Succeeded(); |
| 1054 | |
| 1055 return result == SQLITE_DONE; | |
| 1056 } | 1003 } |
| 1057 | 1004 |
| 1058 bool WebDatabase::RemoveFormElementsAddedBetween(const Time delete_begin, | 1005 bool WebDatabase::RemoveFormElementsAddedBetween(base::Time delete_begin, |
| 1059 const Time delete_end) { | 1006 base::Time delete_end) { |
| 1060 SQLStatement s; | 1007 sql::Statement s(db_.GetUniqueStatement( |
| 1061 if (s.prepare(db_, | 1008 "SELECT DISTINCT pair_id FROM autofill_dates " |
| 1062 "SELECT DISTINCT pair_id FROM autofill_dates WHERE " | 1009 "WHERE date_created >= ? AND date_created < ?")); |
| 1063 "date_created >= ? AND date_created < ?") != SQLITE_OK) { | 1010 if (!s) { |
| 1064 NOTREACHED() << "Statement 1 prepare failed"; | 1011 NOTREACHED() << "Statement 1 prepare failed"; |
| 1065 return false; | 1012 return false; |
| 1066 } | 1013 } |
| 1067 s.bind_int64(0, delete_begin.ToTimeT()); | 1014 s.BindInt64(0, delete_begin.ToTimeT()); |
| 1068 s.bind_int64(1, | 1015 s.BindInt64(1, |
| 1069 delete_end.is_null() ? | 1016 delete_end.is_null() ? |
| 1070 std::numeric_limits<int64>::max() : | 1017 std::numeric_limits<int64>::max() : |
| 1071 delete_end.ToTimeT()); | 1018 delete_end.ToTimeT()); |
| 1072 | 1019 |
| 1073 std::vector<int64> pair_ids; | 1020 std::vector<int64> pair_ids; |
| 1074 int result; | 1021 while (s.Step()) |
| 1075 while ((result = s.step()) == SQLITE_ROW) | 1022 pair_ids.push_back(s.ColumnInt64(0)); |
| 1076 pair_ids.push_back(s.column_int64(0)); | |
| 1077 | 1023 |
| 1078 if (result != SQLITE_DONE) { | 1024 if (!s.Succeeded()) { |
| 1079 NOTREACHED(); | 1025 NOTREACHED(); |
| 1080 return false; | 1026 return false; |
| 1081 } | 1027 } |
| 1082 | 1028 |
| 1083 for (std::vector<int64>::iterator itr = pair_ids.begin(); | 1029 for (std::vector<int64>::iterator itr = pair_ids.begin(); |
| 1084 itr != pair_ids.end(); | 1030 itr != pair_ids.end(); |
| 1085 itr++) { | 1031 itr++) { |
| 1086 int how_many = 0; | 1032 int how_many = 0; |
| 1087 if (!RemoveFormElementForTimeRange(*itr, delete_begin, delete_end, | 1033 if (!RemoveFormElementForTimeRange(*itr, delete_begin, delete_end, |
| 1088 &how_many)) { | 1034 &how_many)) { |
| 1089 return false; | 1035 return false; |
| 1090 } | 1036 } |
| 1091 if (!AddToCountOfFormElement(*itr, -how_many)) | 1037 if (!AddToCountOfFormElement(*itr, -how_many)) |
| 1092 return false; | 1038 return false; |
| 1093 } | 1039 } |
| 1094 | 1040 |
| 1095 return true; | 1041 return true; |
| 1096 } | 1042 } |
| 1097 | 1043 |
| 1098 bool WebDatabase::RemoveFormElementForTimeRange(int64 pair_id, | 1044 bool WebDatabase::RemoveFormElementForTimeRange(int64 pair_id, |
| 1099 const Time delete_begin, | 1045 const Time delete_begin, |
| 1100 const Time delete_end, | 1046 const Time delete_end, |
| 1101 int* how_many) { | 1047 int* how_many) { |
| 1102 SQLStatement s; | 1048 sql::Statement s(db_.GetUniqueStatement( |
| 1103 if (s.prepare(db_, | 1049 "DELETE FROM autofill_dates WHERE pair_id = ? AND " |
| 1104 "DELETE FROM autofill_dates WHERE pair_id = ? AND " | 1050 "date_created >= ? AND date_created < ?")); |
| 1105 "date_created >= ? AND date_created < ?") != SQLITE_OK) { | 1051 if (!s) { |
| 1106 NOTREACHED() << "Statement 1 prepare failed"; | 1052 NOTREACHED() << "Statement 1 prepare failed"; |
| 1107 return false; | 1053 return false; |
| 1108 } | 1054 } |
| 1109 s.bind_int64(0, pair_id); | 1055 s.BindInt64(0, pair_id); |
| 1110 s.bind_int64(1, delete_begin.is_null() ? 0 : delete_begin.ToTimeT()); | 1056 s.BindInt64(1, delete_begin.is_null() ? 0 : delete_begin.ToTimeT()); |
| 1111 s.bind_int64(2, delete_end.is_null() ? std::numeric_limits<int64>::max() : | 1057 s.BindInt64(2, delete_end.is_null() ? std::numeric_limits<int64>::max() : |
| 1112 delete_end.ToTimeT()); | 1058 delete_end.ToTimeT()); |
| 1113 | 1059 |
| 1114 bool result = (s.step() == SQLITE_DONE); | 1060 bool result = s.Run(); |
| 1115 if (how_many) | 1061 if (how_many) |
| 1116 *how_many = sqlite3_changes(db_); | 1062 *how_many = db_.GetLastChangeCount(); |
| 1117 | 1063 |
| 1118 return result; | 1064 return result; |
| 1119 } | 1065 } |
| 1120 | 1066 |
| 1121 bool WebDatabase::RemoveFormElement(const std::wstring& name, | 1067 bool WebDatabase::RemoveFormElement(const std::wstring& name, |
| 1122 const std::wstring& value) { | 1068 const std::wstring& value) { |
| 1123 // Find the id for that pair. | 1069 // Find the id for that pair. |
| 1124 SQLStatement s; | 1070 sql::Statement s(db_.GetUniqueStatement( |
| 1125 if (s.prepare(db_, | 1071 "SELECT pair_id FROM autofill WHERE name = ? AND value= ?")); |
| 1126 "SELECT pair_id FROM autofill WHERE name = ? AND value= ?") != | 1072 if (!s) { |
| 1127 SQLITE_OK) { | |
| 1128 NOTREACHED() << "Statement 1 prepare failed"; | 1073 NOTREACHED() << "Statement 1 prepare failed"; |
| 1129 return false; | 1074 return false; |
| 1130 } | 1075 } |
| 1131 s.bind_wstring(0, name); | 1076 s.BindString(0, WideToUTF8(name)); |
| 1132 s.bind_wstring(1, value); | 1077 s.BindString(1, WideToUTF8(value)); |
| 1133 | 1078 |
| 1134 int result = s.step(); | 1079 if (s.Step()) |
| 1135 if (result != SQLITE_ROW) | 1080 return RemoveFormElementForID(s.ColumnInt64(0)); |
| 1136 return false; | 1081 return false; |
| 1137 | |
| 1138 return RemoveFormElementForID(s.column_int64(0)); | |
| 1139 } | 1082 } |
| 1140 | 1083 |
| 1141 bool WebDatabase::AddToCountOfFormElement(int64 pair_id, int delta) { | 1084 bool WebDatabase::AddToCountOfFormElement(int64 pair_id, int delta) { |
| 1142 int count = 0; | 1085 int count = 0; |
| 1143 | 1086 |
| 1144 if (!GetCountOfFormElement(pair_id, &count)) | 1087 if (!GetCountOfFormElement(pair_id, &count)) |
| 1145 return false; | 1088 return false; |
| 1146 | 1089 |
| 1147 if (count + delta == 0) { | 1090 if (count + delta == 0) { |
| 1148 if (!RemoveFormElementForID(pair_id)) | 1091 if (!RemoveFormElementForID(pair_id)) |
| 1149 return false; | 1092 return false; |
| 1150 } else { | 1093 } else { |
| 1151 if (!SetCountOfFormElement(pair_id, count + delta)) | 1094 if (!SetCountOfFormElement(pair_id, count + delta)) |
| 1152 return false; | 1095 return false; |
| 1153 } | 1096 } |
| 1154 return true; | 1097 return true; |
| 1155 } | 1098 } |
| 1156 | 1099 |
| 1157 bool WebDatabase::RemoveFormElementForID(int64 pair_id) { | 1100 bool WebDatabase::RemoveFormElementForID(int64 pair_id) { |
| 1158 SQLStatement s; | 1101 sql::Statement s(db_.GetUniqueStatement( |
| 1159 if (s.prepare(db_, | 1102 "DELETE FROM autofill WHERE pair_id = ?")); |
| 1160 "DELETE FROM autofill WHERE pair_id = ?") != SQLITE_OK) { | 1103 if (!s) { |
| 1161 NOTREACHED() << "Statement prepare failed"; | 1104 NOTREACHED() << "Statement prepare failed"; |
| 1162 return false; | 1105 return false; |
| 1163 } | 1106 } |
| 1164 s.bind_int64(0, pair_id); | 1107 s.BindInt64(0, pair_id); |
| 1165 if (s.step() != SQLITE_DONE) | 1108 if (s.Run()) { |
| 1166 return false; | 1109 return RemoveFormElementForTimeRange(pair_id, base::Time(), base::Time(), |
| 1167 | 1110 NULL); |
| 1168 return RemoveFormElementForTimeRange(pair_id, Time(), Time(), NULL); | 1111 } |
| 1112 return false; |
| 1169 } | 1113 } |
| 1170 | 1114 |
| 1171 void WebDatabase::MigrateOldVersionsAsNeeded() { | 1115 void WebDatabase::MigrateOldVersionsAsNeeded() { |
| 1172 // Migrate if necessary. | 1116 // Migrate if necessary. |
| 1173 int current_version = meta_table_.GetVersionNumber(); | 1117 int current_version = meta_table_.GetVersionNumber(); |
| 1174 switch (current_version) { | 1118 switch (current_version) { |
| 1175 // Versions 1 - 19 are unhandled. Version numbers greater than | 1119 // Versions 1 - 19 are unhandled. Version numbers greater than |
| 1176 // kCurrentVersionNumber should have already been weeded out by the caller. | 1120 // kCurrentVersionNumber should have already been weeded out by the caller. |
| 1177 default: | 1121 default: |
| 1178 // When the version is too old, we just try to continue anyway. There | 1122 // When the version is too old, we just try to continue anyway. There |
| 1179 // should not be a released product that makes a database too old for us | 1123 // should not be a released product that makes a database too old for us |
| 1180 // to handle. | 1124 // to handle. |
| 1181 LOG(WARNING) << "Web database version " << current_version << | 1125 LOG(WARNING) << "Web database version " << current_version << |
| 1182 " is too old to handle."; | 1126 " is too old to handle."; |
| 1183 return; | 1127 return; |
| 1184 | 1128 |
| 1185 case 20: | 1129 case 20: |
| 1186 // Add the autogenerate_keyword column. | 1130 // Add the autogenerate_keyword column. |
| 1187 if (sqlite3_exec(db_, | 1131 if (!db_.Execute("ALTER TABLE keywords ADD COLUMN autogenerate_keyword " |
| 1188 "ALTER TABLE keywords ADD COLUMN autogenerate_keyword " | 1132 "INTEGER DEFAULT 0")) { |
| 1189 "INTEGER DEFAULT 0", NULL, NULL, NULL) != SQLITE_OK) { | |
| 1190 NOTREACHED(); | 1133 NOTREACHED(); |
| 1191 LOG(WARNING) << "Unable to update web database to version 21."; | 1134 LOG(WARNING) << "Unable to update web database to version 21."; |
| 1192 return; | 1135 return; |
| 1193 } | 1136 } |
| 1194 meta_table_.SetVersionNumber(21); | 1137 meta_table_.SetVersionNumber(21); |
| 1195 meta_table_.SetCompatibleVersionNumber( | 1138 meta_table_.SetCompatibleVersionNumber( |
| 1196 std::min(21, kCompatibleVersionNumber)); | 1139 std::min(21, kCompatibleVersionNumber)); |
| 1197 // FALL THROUGH | 1140 // FALL THROUGH |
| 1198 | 1141 |
| 1199 case 21: | 1142 case 21: |
| 1200 if (!ClearAutofillEmptyValueElements()) { | 1143 if (!ClearAutofillEmptyValueElements()) { |
| 1201 NOTREACHED() << "Failed to clean-up autofill DB."; | 1144 NOTREACHED() << "Failed to clean-up autofill DB."; |
| 1202 } | 1145 } |
| 1203 meta_table_.SetVersionNumber(22); | 1146 meta_table_.SetVersionNumber(22); |
| 1204 // No change in the compatibility version number. | 1147 // No change in the compatibility version number. |
| 1205 | 1148 |
| 1206 // FALL THROUGH | 1149 // FALL THROUGH |
| 1207 | 1150 |
| 1208 // Add successive versions here. Each should set the version number and | 1151 // Add successive versions here. Each should set the version number and |
| 1209 // compatible version number as appropriate, then fall through to the next | 1152 // compatible version number as appropriate, then fall through to the next |
| 1210 // case. | 1153 // case. |
| 1211 | 1154 |
| 1212 case kCurrentVersionNumber: | 1155 case kCurrentVersionNumber: |
| 1213 // No migration needed. | 1156 // No migration needed. |
| 1214 return; | 1157 return; |
| 1215 } | 1158 } |
| 1216 } | 1159 } |
| OLD | NEW |