Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 "webkit/dom_storage/local_storage_database.h" | |
| 6 | |
| 7 #include <string> | |
| 8 | |
| 9 #include "base/logging.h" | |
| 10 #include "base/utf_string_conversions.h" | |
| 11 #include "sql/statement.h" | |
| 12 #include "sql/transaction.h" | |
| 13 | |
| 14 namespace dom_storage { | |
| 15 | |
| 16 LocalStorageDatabase::LocalStorageDatabase(const FilePath& file_path) | |
| 17 : file_path_(file_path), | |
| 18 db_(NULL) { | |
| 19 } | |
| 20 | |
| 21 LocalStorageDatabase::~LocalStorageDatabase() { | |
| 22 if (IsOpen()) | |
| 23 Close(); | |
| 24 } | |
| 25 | |
| 26 bool LocalStorageDatabase::Open() { | |
| 27 if (IsOpen()) | |
| 28 return true; | |
| 29 | |
| 30 db_.reset(new sql::Connection()); | |
| 31 bool is_open = db_->Open(file_path_); | |
|
michaeln
2012/01/24 00:18:16
WebCore uses sqlite3_open16 where as the sql::Conn
benm (inactive)
2012/01/24 10:47:01
Good spot!
| |
| 32 | |
| 33 if (!is_open) | |
| 34 LOG(WARNING) << "Unable to open Database at " << file_path_.value(); | |
| 35 | |
| 36 meta_table_.Init(db_.get(), 1, 1); | |
|
michaeln
2012/01/24 00:18:16
... similarly, since this isn't in the current sch
benm (inactive)
2012/01/24 10:47:01
Fair enough, but this won't stop us using a WebCor
| |
| 37 | |
| 38 return is_open; | |
| 39 } | |
| 40 | |
| 41 bool LocalStorageDatabase::Init() { | |
| 42 if (!IsOpen()) | |
| 43 return false; | |
| 44 | |
| 45 if (db_->DoesTableExist("ItemTable")) { | |
| 46 bool success = UpgradeVersion1To2IfNeeded(); | |
| 47 if (success) | |
| 48 meta_table_.SetVersionNumber(2); | |
| 49 return success; | |
| 50 } else | |
| 51 return CreateTable(); | |
| 52 } | |
| 53 | |
| 54 void LocalStorageDatabase::Close() { | |
| 55 if (!IsOpen()) | |
| 56 return; | |
| 57 | |
| 58 DCHECK(db_.get()); | |
| 59 | |
| 60 meta_table_.Reset(); | |
| 61 | |
| 62 db_->Close(); | |
| 63 db_.reset(NULL); | |
| 64 } | |
| 65 | |
| 66 bool LocalStorageDatabase::CreateTable() { | |
| 67 if (!IsOpen()) | |
| 68 return false; | |
| 69 | |
| 70 bool success = db_->Execute( | |
| 71 "CREATE TABLE IF NOT EXISTS ItemTable (" | |
| 72 "key TEXT UNIQUE ON CONFLICT REPLACE, " | |
| 73 "value BLOB NOT NULL ON CONFLICT FAIL)"); | |
| 74 if (success) | |
| 75 meta_table_.SetVersionNumber(2); | |
| 76 return success; | |
| 77 } | |
| 78 | |
| 79 std::map<string16, string16> LocalStorageDatabase::ReadAllValues() const { | |
| 80 std::map<string16, string16> values; | |
| 81 if (!IsOpen()) | |
| 82 return values; | |
| 83 | |
| 84 sql::Statement stmt(db_->GetCachedStatement(SQL_FROM_HERE, | |
| 85 "SELECT * from ItemTable")); | |
| 86 DCHECK(stmt.is_valid()); | |
| 87 if (stmt) { | |
| 88 while (stmt.Step()) { | |
| 89 string16 key = stmt.ColumnString16(0); | |
| 90 | |
| 91 std::string result; | |
| 92 stmt.ColumnBlobAsString(1, &result); | |
| 93 string16 value = UTF8ToUTF16(result); | |
| 94 values[key] = value; | |
| 95 } | |
| 96 } | |
| 97 | |
| 98 return values; | |
| 99 } | |
| 100 | |
| 101 bool LocalStorageDatabase::WriteAllValues( | |
| 102 const std::map<string16, string16>& values) { | |
| 103 if (!IsOpen()) | |
| 104 return false; | |
| 105 | |
| 106 std::map<string16, string16>::const_iterator it = values.begin(); | |
| 107 for(; it != values.end(); ++it) { | |
| 108 sql::Statement stmt(db_->GetCachedStatement(SQL_FROM_HERE, | |
| 109 "INSERT INTO ItemTable VALUES (?,?)")); | |
| 110 string16 key = it->first; | |
| 111 string16 value = it->second; | |
| 112 stmt.BindString16(0, key); | |
| 113 stmt.BindBlob(1, UTF16ToUTF8(value).c_str(), value.size()); | |
| 114 DCHECK(stmt.is_valid()); | |
| 115 stmt.Run(); | |
| 116 } | |
| 117 return true; | |
| 118 } | |
| 119 | |
| 120 bool LocalStorageDatabase::UpgradeVersion1To2IfNeeded() { | |
|
michaeln
2012/01/24 00:18:16
Code to utilize the new schema has been in used fo
benm (inactive)
2012/01/24 10:47:01
I wondered about that too, but the upgrade process
| |
| 121 sql::Statement stmt(db_->GetCachedStatement(SQL_FROM_HERE, | |
| 122 "SELECT value FROM ItemTable")); | |
| 123 DCHECK(stmt.is_valid()); | |
| 124 if (!stmt) | |
| 125 return false; | |
| 126 | |
| 127 // Quick check to see if we need to upgrade or not. | |
| 128 if (stmt.DeclaredColumnType(0) == sql::COLUMN_TYPE_BLOB) | |
| 129 return true; | |
| 130 | |
| 131 // Need to migrate from TEXT value column to BLOB. | |
| 132 std::map<string16, string16> values; | |
| 133 while (stmt.Step()) { | |
| 134 string16 key = stmt.ColumnString16(0); | |
| 135 string16 value = stmt.ColumnString16(1); | |
| 136 values[key] = value; | |
| 137 } | |
| 138 | |
| 139 { | |
| 140 sql::Transaction migration(db_.get()); | |
| 141 if (migration.Begin()) { | |
| 142 if (db_->Execute("DROP TABLE ItemTable")) { | |
| 143 CreateTable(); | |
| 144 if (WriteAllValues(values)) { | |
| 145 migration.Commit(); | |
| 146 return true; | |
| 147 } | |
| 148 } | |
| 149 } | |
| 150 } | |
| 151 return false; | |
| 152 } | |
| 153 | |
| 154 } // namespace dom_storage | |
| OLD | NEW |