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

Side by Side Diff: webkit/quota/quota_database.cc

Issue 7322005: Revert 91690 - Implement QM::GetOriginsModifiedSince for browser data deleter support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « webkit/quota/quota_database.h ('k') | webkit/quota/quota_database_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "webkit/quota/quota_database.h" 5 #include "webkit/quota/quota_database.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "app/sql/connection.h" 9 #include "app/sql/connection.h"
10 #include "app/sql/diagnostic_error_delegate.h" 10 #include "app/sql/diagnostic_error_delegate.h"
11 #include "app/sql/meta_table.h" 11 #include "app/sql/meta_table.h"
12 #include "app/sql/statement.h" 12 #include "app/sql/statement.h"
13 #include "app/sql/transaction.h" 13 #include "app/sql/transaction.h"
14 #include "base/auto_reset.h" 14 #include "base/auto_reset.h"
15 #include "base/bind.h"
16 #include "base/file_util.h" 15 #include "base/file_util.h"
17 #include "base/time.h" 16 #include "base/time.h"
18 #include "googleurl/src/gurl.h" 17 #include "googleurl/src/gurl.h"
19 #include "webkit/quota/special_storage_policy.h" 18 #include "webkit/quota/special_storage_policy.h"
20 19
21 namespace quota {
22 namespace { 20 namespace {
23 21
24 // Definitions for database schema. 22 // Definitions for database schema.
25 23
26 const int kCurrentVersion = 3; 24 const int kCurrentVersion = 2;
27 const int kCompatibleVersion = 2; 25 const int kCompatibleVersion = 2;
28 26
27 const char kOriginsTable[] = "Origins";
29 const char kHostQuotaTable[] = "HostQuotaTable"; 28 const char kHostQuotaTable[] = "HostQuotaTable";
30 const char kOriginInfoTable[] = "OriginInfoTable"; 29 const char kOriginLastAccessTable[] = "OriginLastAccessTable";
31 const char kGlobalQuotaKeyPrefix[] = "GlobalQuota-"; 30 const char kGlobalQuotaKeyPrefix[] = "GlobalQuota-";
32 const char kIsOriginTableBootstrapped[] = "IsOriginTableBootstrapped"; 31 const char kIsOriginTableBootstrapped[] = "IsOriginTableBootstrapped";
33 32
33 const struct {
34 const char* table_name;
35 const char* columns;
36 } kTables[] = {
37 { kHostQuotaTable,
38 "(host TEXT NOT NULL,"
39 " type INTEGER NOT NULL,"
40 " quota INTEGER,"
41 " UNIQUE(host, type))" },
42 { kOriginLastAccessTable,
43 "(origin TEXT NOT NULL,"
44 " type INTEGER NOT NULL,"
45 " used_count INTEGER,"
46 " last_access_time INTEGER,"
47 " UNIQUE(origin, type))" },
48 };
49
50 const struct {
51 const char* index_name;
52 const char* table_name;
53 const char* columns;
54 bool unique;
55 } kIndexes[] = {
56 { "HostIndex",
57 kHostQuotaTable,
58 "(host)",
59 false },
60 { "OriginLastAccessIndex",
61 kOriginLastAccessTable,
62 "(origin, last_access_time)",
63 false },
64 };
65
66 const int kTableCount = ARRAYSIZE_UNSAFE(kTables);
67 const int kIndexCount = ARRAYSIZE_UNSAFE(kIndexes);
68
34 class HistogramUniquifier { 69 class HistogramUniquifier {
35 public: 70 public:
36 static const char* name() { return "Sqlite.Quota.Error"; } 71 static const char* name() { return "Sqlite.Quota.Error"; }
37 }; 72 };
38 73
39 bool PrepareCachedStatement( 74 bool PrepareCachedStatement(
40 sql::Connection* db, const sql::StatementID& id, 75 sql::Connection* db, const sql::StatementID& id,
41 const char* sql, sql::Statement* statement) { 76 const char* sql, sql::Statement* statement) {
42 DCHECK(db && sql && statement); 77 DCHECK(db && sql && statement);
43 statement->Assign(db->GetCachedStatement(id, sql)); 78 statement->Assign(db->GetCachedStatement(id, sql));
(...skipping 10 matching lines...) Expand all
54 else if (type == quota::kStorageTypePersistent) 89 else if (type == quota::kStorageTypePersistent)
55 return std::string(kGlobalQuotaKeyPrefix) + "persistent"; 90 return std::string(kGlobalQuotaKeyPrefix) + "persistent";
56 NOTREACHED() << "Unknown storage type " << type; 91 NOTREACHED() << "Unknown storage type " << type;
57 return std::string(); 92 return std::string();
58 } 93 }
59 94
60 const int kCommitIntervalMs = 30000; 95 const int kCommitIntervalMs = 30000;
61 96
62 } // anonymous namespace 97 } // anonymous namespace
63 98
64 // static 99 namespace quota {
65 const QuotaDatabase::TableSchema QuotaDatabase::kTables[] = {
66 { kHostQuotaTable,
67 "(host TEXT NOT NULL,"
68 " type INTEGER NOT NULL,"
69 " quota INTEGER DEFAULT 0,"
70 " UNIQUE(host, type))" },
71 { kOriginInfoTable,
72 "(origin TEXT NOT NULL,"
73 " type INTEGER NOT NULL,"
74 " used_count INTEGER DEFAULT 0,"
75 " last_access_time INTEGER DEFAULT 0,"
76 " last_modified_time INTEGER DEFAULT 0,"
77 " UNIQUE(origin, type))" },
78 };
79
80 // static
81 const QuotaDatabase::IndexSchema QuotaDatabase::kIndexes[] = {
82 { "HostIndex",
83 kHostQuotaTable,
84 "(host)",
85 false },
86 { "OriginInfoIndex",
87 kOriginInfoTable,
88 "(origin)",
89 false },
90 { "OriginLastAccessTimeIndex",
91 kOriginInfoTable,
92 "(last_access_time)",
93 false },
94 { "OriginLastModifiedTimeIndex",
95 kOriginInfoTable,
96 "(last_modified_time)",
97 false },
98 };
99
100 struct QuotaDatabase::QuotaTableImporter {
101 bool Append(const QuotaTableEntry& entry) {
102 entries.push_back(entry);
103 return true;
104 }
105 std::vector<QuotaTableEntry> entries;
106 };
107 100
108 QuotaDatabase::QuotaDatabase(const FilePath& path) 101 QuotaDatabase::QuotaDatabase(const FilePath& path)
109 : db_file_path_(path), 102 : db_file_path_(path),
110 is_recreating_(false), 103 is_recreating_(false),
111 is_disabled_(false) { 104 is_disabled_(false) {
112 } 105 }
113 106
114 QuotaDatabase::~QuotaDatabase() { 107 QuotaDatabase::~QuotaDatabase() {
115 if (db_.get()) { 108 if (db_.get()) {
116 db_->CommitTransaction(); 109 db_->CommitTransaction();
(...skipping 29 matching lines...) Expand all
146 return true; 139 return true;
147 } 140 }
148 141
149 bool QuotaDatabase::SetHostQuota( 142 bool QuotaDatabase::SetHostQuota(
150 const std::string& host, StorageType type, int64 quota) { 143 const std::string& host, StorageType type, int64 quota) {
151 DCHECK_GE(quota, 0); 144 DCHECK_GE(quota, 0);
152 if (!LazyOpen(true)) 145 if (!LazyOpen(true))
153 return false; 146 return false;
154 147
155 sql::Statement statement; 148 sql::Statement statement;
156 const char* kSql = 149
157 "INSERT OR REPLACE INTO HostQuotaTable" 150 int64 dummy;
158 " (quota, host, type)" 151 if (GetHostQuota(host, type, &dummy)) {
159 " VALUES (?, ?, ?)"; 152 const char* kSql =
160 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 153 "UPDATE HostQuotaTable"
161 return false; 154 " SET quota = ?"
155 " WHERE host = ? AND type = ?";
156 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
157 return false;
158 } else {
159 const char* kSql =
160 "INSERT INTO HostQuotaTable"
161 " (quota, host, type)"
162 " VALUES (?, ?, ?)";
163 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
164 return false;
165 }
162 166
163 statement.BindInt64(0, quota); 167 statement.BindInt64(0, quota);
164 statement.BindString(1, host); 168 statement.BindString(1, host);
165 statement.BindInt(2, static_cast<int>(type)); 169 statement.BindInt(2, static_cast<int>(type));
166 if (!statement.Run()) 170 if (!statement.Run())
167 return false; 171 return false;
168 172
169 ScheduleCommit(); 173 ScheduleCommit();
170 return true; 174 return true;
171 } 175 }
172 176
173 bool QuotaDatabase::SetOriginLastAccessTime( 177 bool QuotaDatabase::SetOriginLastAccessTime(
174 const GURL& origin, StorageType type, base::Time last_access_time) { 178 const GURL& origin, StorageType type, base::Time last_access_time) {
175 if (!LazyOpen(true)) 179 if (!LazyOpen(true))
176 return false; 180 return false;
177 181
178 sql::Statement statement; 182 sql::Statement statement;
179 183
180 int used_count = 1; 184 int used_count = 1;
181 if (FindOriginUsedCount(origin, type, &used_count)) { 185 if (FindOriginUsedCount(origin, type, &used_count)) {
182 ++used_count; 186 ++used_count;
183 const char* kSql = 187 const char* kSql =
184 "UPDATE OriginInfoTable" 188 "UPDATE OriginLastAccessTable"
185 " SET used_count = ?, last_access_time = ?" 189 " SET used_count = ?, last_access_time = ?"
186 " WHERE origin = ? AND type = ?"; 190 " WHERE origin = ? AND type = ?";
187 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 191 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
188 return false; 192 return false;
189 } else { 193 } else {
190 const char* kSql = 194 const char* kSql =
191 "INSERT INTO OriginInfoTable" 195 "INSERT INTO OriginLastAccessTable"
192 " (used_count, last_access_time, origin, type)" 196 " (used_count, last_access_time, origin, type)"
193 " VALUES (?, ?, ?, ?)"; 197 " VALUES (?, ?, ?, ?)";
194 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 198 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
195 return false; 199 return false;
196 } 200 }
197 201
198 statement.BindInt(0, used_count); 202 statement.BindInt(0, used_count);
199 statement.BindInt64(1, last_access_time.ToInternalValue()); 203 statement.BindInt64(1, last_access_time.ToInternalValue());
200 statement.BindString(2, origin.spec()); 204 statement.BindString(2, origin.spec());
201 statement.BindInt(3, static_cast<int>(type)); 205 statement.BindInt(3, static_cast<int>(type));
202 if (!statement.Run()) 206 if (!statement.Run())
203 return false; 207 return false;
204 208
205 ScheduleCommit(); 209 ScheduleCommit();
206 return true; 210 return true;
207 } 211 }
208 212
209 bool QuotaDatabase::SetOriginLastModifiedTime( 213 bool QuotaDatabase::RegisterOrigins(const std::set<GURL>& origins,
210 const GURL& origin, StorageType type, base::Time last_modified_time) { 214 StorageType type,
211 if (!LazyOpen(true)) 215 base::Time last_access_time) {
212 return false;
213
214 sql::Statement statement;
215
216 int dummy;
217 if (FindOriginUsedCount(origin, type, &dummy)) {
218 const char* kSql =
219 "UPDATE OriginInfoTable"
220 " SET last_modified_time = ?"
221 " WHERE origin = ? AND type = ?";
222 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
223 return false;
224 } else {
225 const char* kSql =
226 "INSERT INTO OriginInfoTable"
227 " (last_modified_time, origin, type) VALUES (?, ?, ?)";
228 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
229 return false;
230 }
231
232 statement.BindInt64(0, last_modified_time.ToInternalValue());
233 statement.BindString(1, origin.spec());
234 statement.BindInt(2, static_cast<int>(type));
235 if (!statement.Run())
236 return false;
237
238 ScheduleCommit();
239 return true;
240 }
241
242 bool QuotaDatabase::RegisterInitialOriginInfo(
243 const std::set<GURL>& origins, StorageType type) {
244 if (!LazyOpen(true)) 216 if (!LazyOpen(true))
245 return false; 217 return false;
246 218
247 typedef std::set<GURL>::const_iterator itr_type; 219 typedef std::set<GURL>::const_iterator itr_type;
248 for (itr_type itr = origins.begin(), end = origins.end(); 220 for (itr_type itr = origins.begin(), end = origins.end();
249 itr != end; ++itr) { 221 itr != end; ++itr) {
250 const char* kSql = 222 const char* kSql =
251 "INSERT OR IGNORE INTO OriginInfoTable" 223 "INSERT OR IGNORE INTO OriginLastAccessTable"
252 " (origin, type) VALUES (?, ?)"; 224 " (used_count, last_access_time, origin, type)"
225 " VALUES (?, ?, ?, ?)";
253 sql::Statement statement; 226 sql::Statement statement;
254 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 227 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
255 return false; 228 return false;
256 229
257 statement.BindString(0, itr->spec()); 230 statement.BindInt(0, 0); // used_count
258 statement.BindInt(1, static_cast<int>(type)); 231 statement.BindInt64(1, last_access_time.ToInternalValue());
232 statement.BindString(2, itr->spec());
233 statement.BindInt(3, static_cast<int>(type));
259 if (!statement.Run()) 234 if (!statement.Run())
260 return false; 235 return false;
261 } 236 }
262 237
263 ScheduleCommit(); 238 ScheduleCommit();
264 return true; 239 return true;
265 } 240 }
266 241
267 bool QuotaDatabase::DeleteHostQuota( 242 bool QuotaDatabase::DeleteHostQuota(
268 const std::string& host, StorageType type) { 243 const std::string& host, StorageType type) {
(...skipping 10 matching lines...) Expand all
279 254
280 statement.BindString(0, host); 255 statement.BindString(0, host);
281 statement.BindInt(1, static_cast<int>(type)); 256 statement.BindInt(1, static_cast<int>(type));
282 if (!statement.Run()) 257 if (!statement.Run())
283 return false; 258 return false;
284 259
285 ScheduleCommit(); 260 ScheduleCommit();
286 return true; 261 return true;
287 } 262 }
288 263
289 bool QuotaDatabase::DeleteOriginInfo( 264 bool QuotaDatabase::DeleteOriginLastAccessTime(
290 const GURL& origin, StorageType type) { 265 const GURL& origin, StorageType type) {
291 if (!LazyOpen(false)) 266 if (!LazyOpen(false))
292 return false; 267 return false;
293 268
294 const char* kSql = 269 const char* kSql =
295 "DELETE FROM OriginInfoTable" 270 "DELETE FROM OriginLastAccessTable"
296 " WHERE origin = ? AND type = ?"; 271 " WHERE origin = ? AND type = ?";
297 272
298 sql::Statement statement; 273 sql::Statement statement;
299 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 274 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
300 return false; 275 return false;
301 276
302 statement.BindString(0, origin.spec()); 277 statement.BindString(0, origin.spec());
303 statement.BindInt(1, static_cast<int>(type)); 278 statement.BindInt(1, static_cast<int>(type));
304 if (!statement.Run()) 279 if (!statement.Run())
305 return false; 280 return false;
(...skipping 16 matching lines...) Expand all
322 297
323 bool QuotaDatabase::GetLRUOrigin( 298 bool QuotaDatabase::GetLRUOrigin(
324 StorageType type, 299 StorageType type,
325 const std::set<GURL>& exceptions, 300 const std::set<GURL>& exceptions,
326 SpecialStoragePolicy* special_storage_policy, 301 SpecialStoragePolicy* special_storage_policy,
327 GURL* origin) { 302 GURL* origin) {
328 DCHECK(origin); 303 DCHECK(origin);
329 if (!LazyOpen(false)) 304 if (!LazyOpen(false))
330 return false; 305 return false;
331 306
332 const char* kSql = "SELECT origin FROM OriginInfoTable" 307 const char* kSql = "SELECT origin FROM OriginLastAccessTable"
333 " WHERE type = ?" 308 " WHERE type = ?"
334 " ORDER BY last_access_time ASC"; 309 " ORDER BY last_access_time ASC";
335 310
336 sql::Statement statement; 311 sql::Statement statement;
337 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 312 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
338 return false; 313 return false;
339 statement.BindInt(0, static_cast<int>(type)); 314 statement.BindInt(0, static_cast<int>(type));
340 315
341 while (statement.Step()) { 316 while (statement.Step()) {
342 GURL url(statement.ColumnString(0)); 317 GURL url(statement.ColumnString(0));
343 if (exceptions.find(url) != exceptions.end()) 318 if (exceptions.find(url) != exceptions.end())
344 continue; 319 continue;
345 if (special_storage_policy && 320 if (special_storage_policy &&
346 special_storage_policy->IsStorageUnlimited(url)) 321 special_storage_policy->IsStorageUnlimited(url))
347 continue; 322 continue;
348 *origin = url; 323 *origin = url;
349 return true; 324 return true;
350 } 325 }
351 326
352 *origin = GURL(); 327 *origin = GURL();
353 return statement.Succeeded(); 328 return statement.Succeeded();
354 } 329 }
355 330
356 bool QuotaDatabase::GetOriginsModifiedSince(
357 StorageType type, std::set<GURL>* origins, base::Time modified_since) {
358 DCHECK(origins);
359 if (!LazyOpen(false))
360 return false;
361
362 const char* kSql = "SELECT origin FROM OriginInfoTable"
363 " WHERE type = ? AND last_modified_time > ?";
364
365 sql::Statement statement;
366 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
367 return false;
368 statement.BindInt(0, static_cast<int>(type));
369 statement.BindInt64(1, modified_since.ToInternalValue());
370
371 origins->clear();
372 while (statement.Step())
373 origins->insert(GURL(statement.ColumnString(0)));
374
375 return statement.Succeeded();
376 }
377
378 bool QuotaDatabase::IsOriginDatabaseBootstrapped() { 331 bool QuotaDatabase::IsOriginDatabaseBootstrapped() {
379 if (!LazyOpen(true)) 332 if (!LazyOpen(true))
380 return false; 333 return false;
381 334
382 int flag = 0; 335 int flag = 0;
383 return meta_table_->GetValue(kIsOriginTableBootstrapped, &flag) && flag; 336 return meta_table_->GetValue(kIsOriginTableBootstrapped, &flag) && flag;
384 } 337 }
385 338
386 bool QuotaDatabase::SetOriginDatabaseBootstrapped(bool bootstrap_flag) { 339 bool QuotaDatabase::SetOriginDatabaseBootstrapped(bool bootstrap_flag) {
387 if (!LazyOpen(true)) 340 if (!LazyOpen(true))
388 return false; 341 return false;
389 342
390 return meta_table_->SetValue(kIsOriginTableBootstrapped, bootstrap_flag); 343 return meta_table_->SetValue(kIsOriginTableBootstrapped, bootstrap_flag);
391 } 344 }
392 345
393 void QuotaDatabase::Commit() { 346 void QuotaDatabase::Commit() {
394 if (!db_.get()) 347 if (!db_.get())
395 return; 348 return;
396 349
397 if (timer_.IsRunning()) 350 // Note: for now this will be called only by ScheduleCommit, but when it
398 timer_.Stop(); 351 // becomes untrue we should call timer_.Stop() here.
352 DCHECK(!timer_.IsRunning());
399 353
400 db_->CommitTransaction(); 354 db_->CommitTransaction();
401 db_->BeginTransaction(); 355 db_->BeginTransaction();
402 } 356 }
403 357
404 void QuotaDatabase::ScheduleCommit() { 358 void QuotaDatabase::ScheduleCommit() {
405 if (timer_.IsRunning()) 359 if (timer_.IsRunning())
406 return; 360 return;
407 timer_.Start(base::TimeDelta::FromMilliseconds(kCommitIntervalMs), this, 361 timer_.Start(base::TimeDelta::FromMilliseconds(kCommitIntervalMs), this,
408 &QuotaDatabase::Commit); 362 &QuotaDatabase::Commit);
409 } 363 }
410 364
411 bool QuotaDatabase::FindOriginUsedCount( 365 bool QuotaDatabase::FindOriginUsedCount(
412 const GURL& origin, StorageType type, int* used_count) { 366 const GURL& origin, StorageType type, int* used_count) {
413 DCHECK(used_count); 367 DCHECK(used_count);
414 if (!LazyOpen(false)) 368 if (!LazyOpen(false))
415 return false; 369 return false;
416 370
417 const char* kSql = 371 const char* kSql =
418 "SELECT used_count FROM OriginInfoTable" 372 "SELECT used_count FROM OriginLastAccessTable"
419 " WHERE origin = ? AND type = ?"; 373 " WHERE origin = ? AND type = ?";
420 374
421 sql::Statement statement; 375 sql::Statement statement;
422 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 376 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
423 return false; 377 return false;
424 378
425 statement.BindString(0, origin.spec()); 379 statement.BindString(0, origin.spec());
426 statement.BindInt(1, static_cast<int>(type)); 380 statement.BindInt(1, static_cast<int>(type));
427 if (!statement.Step() || !statement.Succeeded()) 381 if (!statement.Step() || !statement.Succeeded())
428 return false; 382 return false;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 return false; 422 return false;
469 } 423 }
470 424
471 // Start a long-running transaction. 425 // Start a long-running transaction.
472 db_->BeginTransaction(); 426 db_->BeginTransaction();
473 427
474 return true; 428 return true;
475 } 429 }
476 430
477 bool QuotaDatabase::EnsureDatabaseVersion() { 431 bool QuotaDatabase::EnsureDatabaseVersion() {
478 static const size_t kTableCount = ARRAYSIZE_UNSAFE(kTables);
479 static const size_t kIndexCount = ARRAYSIZE_UNSAFE(kIndexes);
480 if (!sql::MetaTable::DoesTableExist(db_.get())) 432 if (!sql::MetaTable::DoesTableExist(db_.get()))
481 return CreateSchema(db_.get(), meta_table_.get(), 433 return CreateSchema();
482 kCurrentVersion, kCompatibleVersion,
483 kTables, kTableCount,
484 kIndexes, kIndexCount);
485 434
486 if (!meta_table_->Init(db_.get(), kCurrentVersion, kCompatibleVersion)) 435 if (!meta_table_->Init(db_.get(), kCurrentVersion, kCompatibleVersion))
487 return false; 436 return false;
488 437
489 if (meta_table_->GetCompatibleVersionNumber() > kCurrentVersion) { 438 if (meta_table_->GetCompatibleVersionNumber() > kCurrentVersion) {
490 LOG(WARNING) << "Quota database is too new."; 439 LOG(WARNING) << "Quota database is too new.";
491 return false; 440 return false;
492 } 441 }
493 442
494 if (meta_table_->GetVersionNumber() < kCurrentVersion) { 443 if (meta_table_->GetVersionNumber() < kCurrentVersion) {
495 if (!UpgradeSchema(meta_table_->GetVersionNumber())) 444 // TODO(kinuko): Support schema upgrade.
496 return ResetSchema(); 445 return ResetSchema();
497 } 446 }
498 447
499 #ifndef NDEBUG 448 #ifndef NDEBUG
500 DCHECK(sql::MetaTable::DoesTableExist(db_.get())); 449 DCHECK(sql::MetaTable::DoesTableExist(db_.get()));
501 for (size_t i = 0; i < kTableCount; ++i) { 450 for (int i = 0; i < kTableCount; ++i) {
502 DCHECK(db_->DoesTableExist(kTables[i].table_name)); 451 DCHECK(db_->DoesTableExist(kTables[i].table_name));
503 } 452 }
504 #endif 453 #endif
505 454
506 return true; 455 return true;
507 } 456 }
508 457
509 // static 458 bool QuotaDatabase::CreateSchema() {
510 bool QuotaDatabase::CreateSchema(
511 sql::Connection* database,
512 sql::MetaTable* meta_table,
513 int schema_version, int compatible_version,
514 const TableSchema* tables, size_t tables_size,
515 const IndexSchema* indexes, size_t indexes_size) {
516 // TODO(kinuko): Factor out the common code to create databases. 459 // TODO(kinuko): Factor out the common code to create databases.
517 sql::Transaction transaction(database); 460 sql::Transaction transaction(db_.get());
518 if (!transaction.Begin()) 461 if (!transaction.Begin())
519 return false; 462 return false;
520 463
521 if (!meta_table->Init(database, schema_version, compatible_version)) 464 if (!meta_table_->Init(db_.get(), kCurrentVersion, kCompatibleVersion))
522 return false; 465 return false;
523 466
524 for (size_t i = 0; i < tables_size; ++i) { 467 for (int i = 0; i < kTableCount; ++i) {
525 std::string sql("CREATE TABLE "); 468 std::string sql("CREATE TABLE ");
526 sql += tables[i].table_name; 469 sql += kTables[i].table_name;
527 sql += tables[i].columns; 470 sql += kTables[i].columns;
528 if (!database->Execute(sql.c_str())) { 471 if (!db_->Execute(sql.c_str())) {
529 VLOG(1) << "Failed to execute " << sql; 472 VLOG(1) << "Failed to execute " << sql;
530 return false; 473 return false;
531 } 474 }
532 } 475 }
533 476
534 for (size_t i = 0; i < indexes_size; ++i) { 477 for (int i = 0; i < kIndexCount; ++i) {
535 std::string sql; 478 std::string sql;
536 if (indexes[i].unique) 479 if (kIndexes[i].unique)
537 sql += "CREATE UNIQUE INDEX "; 480 sql += "CREATE UNIQUE INDEX ";
538 else 481 else
539 sql += "CREATE INDEX "; 482 sql += "CREATE INDEX ";
540 sql += indexes[i].index_name; 483 sql += kIndexes[i].index_name;
541 sql += " ON "; 484 sql += " ON ";
542 sql += indexes[i].table_name; 485 sql += kIndexes[i].table_name;
543 sql += indexes[i].columns; 486 sql += kIndexes[i].columns;
544 if (!database->Execute(sql.c_str())) { 487 if (!db_->Execute(sql.c_str())) {
545 VLOG(1) << "Failed to execute " << sql; 488 VLOG(1) << "Failed to execute " << sql;
546 return false; 489 return false;
547 } 490 }
548 } 491 }
549 492
550 return transaction.Commit(); 493 return transaction.Commit();
551 } 494 }
552 495
553 bool QuotaDatabase::ResetSchema() { 496 bool QuotaDatabase::ResetSchema() {
554 DCHECK(!db_file_path_.empty()); 497 DCHECK(!db_file_path_.empty());
(...skipping 11 matching lines...) Expand all
566 return false; 509 return false;
567 510
568 // So we can't go recursive. 511 // So we can't go recursive.
569 if (is_recreating_) 512 if (is_recreating_)
570 return false; 513 return false;
571 514
572 AutoReset<bool> auto_reset(&is_recreating_, true); 515 AutoReset<bool> auto_reset(&is_recreating_, true);
573 return LazyOpen(true); 516 return LazyOpen(true);
574 } 517 }
575 518
576 bool QuotaDatabase::UpgradeSchema(int current_version) {
577 if (current_version == 2) {
578 QuotaTableImporter importer;
579 typedef std::vector<QuotaTableEntry> QuotaTableEntries;
580 if (!DumpQuotaTable(new QuotaTableCallback(base::Bind(
581 &QuotaTableImporter::Append, base::Unretained(&importer)))))
582 return false;
583 ResetSchema();
584 for (QuotaTableEntries::const_iterator iter = importer.entries.begin();
585 iter != importer.entries.end(); ++iter) {
586 if (!SetHostQuota(iter->host, iter->type, iter->quota))
587 return false;
588 }
589 Commit();
590 return true;
591 }
592 return false;
593 }
594
595 bool QuotaDatabase::DumpQuotaTable(QuotaTableCallback* callback) { 519 bool QuotaDatabase::DumpQuotaTable(QuotaTableCallback* callback) {
596 scoped_ptr<QuotaTableCallback> callback_deleter(callback); 520 scoped_ptr<QuotaTableCallback> callback_deleter(callback);
597 if (!LazyOpen(true)) 521 if (!LazyOpen(true))
598 return false; 522 return false;
599 523
600 const char* kSql = "SELECT * FROM HostQuotaTable"; 524 const char* kSql = "SELECT * FROM HostQuotaTable";
601 sql::Statement statement; 525 sql::Statement statement;
602 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 526 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
603 return false; 527 return false;
604 528
605 while (statement.Step()) { 529 while (statement.Step()) {
606 QuotaTableEntry entry = { 530 QuotaTableEntry entry = {
607 statement.ColumnString(0), 531 statement.ColumnString(0),
608 static_cast<StorageType>(statement.ColumnInt(1)), 532 static_cast<StorageType>(statement.ColumnInt(1)),
609 statement.ColumnInt64(2) 533 statement.ColumnInt64(2)
610 }; 534 };
611 535
612 if (!callback->Run(entry)) 536 if (!callback->Run(entry))
613 return true; 537 return true;
614 } 538 }
615 539
616 return statement.Succeeded(); 540 return statement.Succeeded();
617 } 541 }
618 542
619 bool QuotaDatabase::DumpOriginInfoTable( 543 bool QuotaDatabase::DumpLastAccessTimeTable(
620 OriginInfoTableCallback* callback) { 544 LastAccessTimeTableCallback* callback) {
621 scoped_ptr<OriginInfoTableCallback> callback_deleter(callback); 545 scoped_ptr<LastAccessTimeTableCallback> callback_deleter(callback);
622 546
623 if (!LazyOpen(true)) 547 if (!LazyOpen(true))
624 return false; 548 return false;
625 549
626 const char* kSql = "SELECT * FROM OriginInfoTable"; 550 const char* kSql = "SELECT * FROM OriginLastAccessTable";
627 sql::Statement statement; 551 sql::Statement statement;
628 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 552 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
629 return false; 553 return false;
630 554
631 while (statement.Step()) { 555 while (statement.Step()) {
632 OriginInfoTableEntry entry = { 556 LastAccessTimeTableEntry entry = {
633 GURL(statement.ColumnString(0)), 557 GURL(statement.ColumnString(0)),
634 static_cast<StorageType>(statement.ColumnInt(1)), 558 static_cast<StorageType>(statement.ColumnInt(1)),
635 statement.ColumnInt(2), 559 statement.ColumnInt(2),
636 base::Time::FromInternalValue(statement.ColumnInt64(3)), 560 base::Time::FromInternalValue(statement.ColumnInt64(3))
637 base::Time::FromInternalValue(statement.ColumnInt64(4))
638 }; 561 };
639 562
640 if (!callback->Run(entry)) 563 if (!callback->Run(entry))
641 return true; 564 return true;
642 } 565 }
643 566
644 return statement.Succeeded(); 567 return statement.Succeeded();
645 } 568 }
646 569
647 bool operator<(const QuotaDatabase::QuotaTableEntry& lhs, 570 bool operator<(const QuotaDatabase::QuotaTableEntry& lhs,
648 const QuotaDatabase::QuotaTableEntry& rhs) { 571 const QuotaDatabase::QuotaTableEntry& rhs) {
649 if (lhs.host < rhs.host) return true; 572 if (lhs.host < rhs.host) return true;
650 if (rhs.host < lhs.host) return false; 573 if (rhs.host < lhs.host) return false;
651 if (lhs.type < rhs.type) return true; 574 if (lhs.type < rhs.type) return true;
652 if (rhs.type < lhs.type) return false; 575 if (rhs.type < lhs.type) return false;
653 return lhs.quota < rhs.quota; 576 return lhs.quota < rhs.quota;
654 } 577 }
655 578
656 bool operator<(const QuotaDatabase::OriginInfoTableEntry& lhs, 579 bool operator<(const QuotaDatabase::LastAccessTimeTableEntry& lhs,
657 const QuotaDatabase::OriginInfoTableEntry& rhs) { 580 const QuotaDatabase::LastAccessTimeTableEntry& rhs) {
658 if (lhs.origin < rhs.origin) return true; 581 if (lhs.origin < rhs.origin) return true;
659 if (rhs.origin < lhs.origin) return false; 582 if (rhs.origin < lhs.origin) return false;
660 if (lhs.type < rhs.type) return true; 583 if (lhs.type < rhs.type) return true;
661 if (rhs.type < lhs.type) return false; 584 if (rhs.type < lhs.type) return false;
662 if (lhs.used_count < rhs.used_count) return true; 585 if (lhs.used_count < rhs.used_count) return true;
663 if (rhs.used_count < lhs.used_count) return false; 586 if (rhs.used_count < lhs.used_count) return false;
664 return lhs.last_access_time < rhs.last_access_time; 587 return lhs.last_access_time < rhs.last_access_time;
665 } 588 }
666
667 } // quota namespace 589 } // quota namespace
OLDNEW
« no previous file with comments | « webkit/quota/quota_database.h ('k') | webkit/quota/quota_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698