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

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

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

Powered by Google App Engine
This is Rietveld 408576698