Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Side by Side Diff: webkit/dom_storage/dom_storage_database.cc

Issue 9159020: Create a class to represent a DOM Storage Database. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Add DOM Storage database class. Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/dom_storage_database.h"
6
7 #include <string>
8
9 #include "base/logging.h"
10 #include "base/utf_string_conversions.h"
11 #include "sql/diagnostic_error_delegate.h"
12 #include "sql/statement.h"
13 #include "sql/transaction.h"
14
15 namespace {
16
17 class HistogramUniquifier {
18 public:
19 static const char* name() { return "Sqlite.DomStorageDatabase.Error"; }
20 };
21
22 sql::ErrorDelegate* GetErrorHandlerForDomStorageDatabase() {
23 return new sql::DiagnosticErrorDelegate<HistogramUniquifier>();
24 }
25
26 } // anon namespace
27
28 namespace dom_storage {
29
30 DomStorageDatabase::DomStorageDatabase(const FilePath& file_path)
31 : file_path_(file_path),
32 db_(NULL) {
33 DCHECK(!file_path_.empty());
34 }
35
36 DomStorageDatabase::~DomStorageDatabase() {
37 if (IsOpen())
38 Close();
39 }
40
41 bool DomStorageDatabase::Open() {
42 if (IsOpen())
43 return true;
44
45 db_.reset(new sql::Connection());
46 bool is_open = db_->Open(file_path_);
47 db_->set_error_delegate(GetErrorHandlerForDomStorageDatabase());
48
49 if (!is_open) {
50 LOG(WARNING) << "Unable to open Database at " << file_path_.value();
51 return false;
52 }
53
54 // sql::Connection uses UTF-8 encoding, but WebCore style databases use
55 // UTF-16, so ensure we match.
56 ignore_result(db_->Execute("PRAGMA encoding=\"UTF-16\""));
57
58 return is_open;
59 }
60
61 bool DomStorageDatabase::Init() {
62 if (!IsOpen())
63 return false;
64
65 if (db_->DoesTableExist("ItemTable")) {
66 if (UpgradeVersion1To2IfNeeded())
67 return true;
68 else {
69 // Upgrade failed, drop table and start fresh.
70 if (db_->Execute("DROP TABLE ItemTable"))
71 return CreateTable();
72 else
73 return false;
74 }
75 } else
76 return CreateTable();
77 }
78
79 void DomStorageDatabase::Close() {
80 if (!IsOpen())
81 return;
82
83 db_->Close();
84 db_.reset(NULL);
85 }
86
87 bool DomStorageDatabase::CreateTable() {
88 // Current version is 2.
89 return CreateTableV2();
90 }
91
92 bool DomStorageDatabase::CreateTableV2() {
93 if (!IsOpen())
94 return false;
95
96 return db_->Execute(
97 "CREATE TABLE IF NOT EXISTS ItemTable ("
98 "key TEXT UNIQUE ON CONFLICT REPLACE, "
99 "value BLOB NOT NULL ON CONFLICT FAIL)");
100 }
101
102 DomStorageDatabase::ValuesMap DomStorageDatabase::ReadAllValues() const {
103 ValuesMap values;
104 if (!IsOpen())
105 return values;
106
107 sql::Statement stmt(db_->GetCachedStatement(SQL_FROM_HERE,
108 "SELECT * from ItemTable"));
109 DCHECK(stmt.is_valid());
110 if (stmt) {
111 while (stmt.Step()) {
112 string16 key = stmt.ColumnString16(0);
113 string16 value(reinterpret_cast<const char16*>(stmt.ColumnBlob(1)));
michaeln 2012/01/31 03:11:16 Can these values have embedded NULLs in them and i
benm (inactive) 2012/01/31 15:10:53 I'm writing out using c_str(), so I think it shoul
114 values[key] = value;
115
116 }
117 }
118
119 return values;
120 }
121
122 bool DomStorageDatabase::WriteValues(const ValuesMap& values) {
123 if (!IsOpen())
124 return false;
125
126 ValuesMap::const_iterator it = values.begin();
127 for(; it != values.end(); ++it) {
128 sql::Statement stmt(db_->GetCachedStatement(SQL_FROM_HERE,
129 "INSERT INTO ItemTable VALUES (?,?)"));
130 string16 key = it->first;
131 string16 value = it->second;
132 stmt.BindString16(0, key);
133 stmt.BindBlob(1, value.c_str(), -1);
michaeln 2012/01/31 03:11:16 do we have to be explicit about the length here?
benm (inactive) 2012/01/31 15:10:53 -1 says to write up to the first null, so not as l
134 DCHECK(stmt.is_valid());
135 stmt.Run();
136 }
137 return true;
138 }
139
140 bool DomStorageDatabase::RemoveValues(const ValuesSet& keys) {
141 if (!IsOpen())
142 return false;
143
144 ValuesSet::const_iterator it = keys.begin();
145 for ( ; it != keys.end(); ++it) {
michaeln 2012/01/31 03:11:16 We'll want to put multiple write statements in a t
benm (inactive) 2012/01/31 15:10:53 Done (and for Write above).
146 sql::Statement stmt(db_->GetCachedStatement(SQL_FROM_HERE,
147 "DELETE FROM ItemTable WHERE key=?"));
148 stmt.BindString16(0, *it);
149 DCHECK(stmt.is_valid());
150 stmt.Run();
151 }
152
153 return true;
154 }
155
156 bool DomStorageDatabase::UpgradeVersion1To2IfNeeded() {
157 sql::Statement stmt(db_->GetCachedStatement(SQL_FROM_HERE,
158 "SELECT * FROM ItemTable"));
159 DCHECK(stmt.is_valid());
160 if (!stmt)
161 return false;
162
163 // Quick check to see if we need to upgrade or not. The single
164 // effect of V1 -> V2 is to change the value column from type
165 // TEXT to type BLOB.
166 sql::ColType valueColumnType = stmt.DeclaredColumnType(1);
167 if (valueColumnType == sql::COLUMN_TYPE_BLOB)
168 return true;
169
170 if (valueColumnType != sql::COLUMN_TYPE_TEXT) {
171 // Something is messed up. This is not a V1 database.
172 return false;
173 }
174
175 // Need to migrate from TEXT value column to BLOB.
176 ValuesMap values;
177 while (stmt.Step()) {
178 string16 key = stmt.ColumnString16(0);
179 string16 value = stmt.ColumnString16(1);
180 values[key] = value;
181 }
182
183 {
184 sql::Transaction migration(db_.get());
185 if (migration.Begin()) {
186 if (db_->Execute("DROP TABLE ItemTable")) {
187 CreateTableV2();
188 if (WriteValues(values)) {
189 migration.Commit();
190 return true;
191 }
192 }
193 }
194 }
195 return false;
196 }
197
198 } // namespace dom_storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698