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

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: '' 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/file_util.h" 15 #include "base/file_util.h"
16 #include "base/time.h" 16 #include "base/time.h"
17 #include "googleurl/src/gurl.h" 17 #include "googleurl/src/gurl.h"
18 #include "webkit/quota/special_storage_policy.h" 18 #include "webkit/quota/special_storage_policy.h"
19 19
20 namespace { 20 namespace {
21 21
22 // Definitions for database schema. 22 // Definitions for database schema.
23 23
24 const int kCurrentVersion = 2; 24 const int kCurrentVersion = 3;
25 const int kCompatibleVersion = 2; 25 const int kCompatibleVersion = 3;
26 26
27 const char kOriginsTable[] = "Origins"; 27 const char kOriginsTable[] = "Origins";
28 const char kHostQuotaTable[] = "HostQuotaTable"; 28 const char kHostQuotaTable[] = "HostQuotaTable";
29 const char kOriginLastAccessTable[] = "OriginLastAccessTable"; 29 const char kOriginInfoTable[] = "OriginInfoTable";
30 const char kGlobalQuotaKeyPrefix[] = "GlobalQuota-"; 30 const char kGlobalQuotaKeyPrefix[] = "GlobalQuota-";
31 const char kIsOriginTableBootstrapped[] = "IsOriginTableBootstrapped"; 31 const char kIsOriginTableBootstrapped[] = "IsOriginTableBootstrapped";
32 32
33 const struct { 33 const struct {
34 const char* table_name; 34 const char* table_name;
35 const char* columns; 35 const char* columns;
36 } kTables[] = { 36 } kTables[] = {
37 { kHostQuotaTable, 37 { kHostQuotaTable,
38 "(host TEXT NOT NULL," 38 "(host TEXT NOT NULL,"
39 " type INTEGER NOT NULL," 39 " type INTEGER NOT NULL,"
40 " quota INTEGER," 40 " quota INTEGER DEFAULT 0,"
41 " UNIQUE(host, type))" }, 41 " UNIQUE(host, type))" },
42 { kOriginLastAccessTable, 42 { kOriginInfoTable,
43 "(origin TEXT NOT NULL," 43 "(origin TEXT NOT NULL,"
44 " type INTEGER NOT NULL," 44 " type INTEGER NOT NULL,"
45 " used_count INTEGER," 45 " used_count INTEGER DEFAULT 0,"
46 " last_access_time INTEGER," 46 " last_access_time INTEGER DEFAULT 0,"
47 " last_modified_time INTEGER DEFAULT 0,"
47 " UNIQUE(origin, type))" }, 48 " UNIQUE(origin, type))" },
48 }; 49 };
49 50
50 const struct { 51 const struct {
51 const char* index_name; 52 const char* index_name;
52 const char* table_name; 53 const char* table_name;
53 const char* columns; 54 const char* columns;
54 bool unique; 55 bool unique;
55 } kIndexes[] = { 56 } kIndexes[] = {
56 { "HostIndex", 57 { "HostIndex",
57 kHostQuotaTable, 58 kHostQuotaTable,
58 "(host)", 59 "(host)",
59 false }, 60 false },
60 { "OriginLastAccessIndex", 61 { "OriginInfoIndex",
61 kOriginLastAccessTable, 62 kOriginInfoTable,
62 "(origin, last_access_time)", 63 "(origin)",
64 false },
65 { "OriginLastAccessTimeIndex",
66 kOriginInfoTable,
67 "(last_access_time)",
68 false },
69 { "OriginLastModifiedTimeIndex",
70 kOriginInfoTable,
71 "(last_modified_time)",
63 false }, 72 false },
64 }; 73 };
65 74
66 const int kTableCount = ARRAYSIZE_UNSAFE(kTables); 75 const int kTableCount = ARRAYSIZE_UNSAFE(kTables);
67 const int kIndexCount = ARRAYSIZE_UNSAFE(kIndexes); 76 const int kIndexCount = ARRAYSIZE_UNSAFE(kIndexes);
68 77
69 class HistogramUniquifier { 78 class HistogramUniquifier {
70 public: 79 public:
71 static const char* name() { return "Sqlite.Quota.Error"; } 80 static const char* name() { return "Sqlite.Quota.Error"; }
72 }; 81 };
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 const GURL& origin, StorageType type, base::Time last_access_time) { 187 const GURL& origin, StorageType type, base::Time last_access_time) {
179 if (!LazyOpen(true)) 188 if (!LazyOpen(true))
180 return false; 189 return false;
181 190
182 sql::Statement statement; 191 sql::Statement statement;
183 192
184 int used_count = 1; 193 int used_count = 1;
185 if (FindOriginUsedCount(origin, type, &used_count)) { 194 if (FindOriginUsedCount(origin, type, &used_count)) {
186 ++used_count; 195 ++used_count;
187 const char* kSql = 196 const char* kSql =
188 "UPDATE OriginLastAccessTable" 197 "UPDATE OriginInfoTable"
189 " SET used_count = ?, last_access_time = ?" 198 " SET used_count = ?, last_access_time = ?"
190 " WHERE origin = ? AND type = ?"; 199 " WHERE origin = ? AND type = ?";
191 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 200 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
192 return false; 201 return false;
193 } else { 202 } else {
194 const char* kSql = 203 const char* kSql =
195 "INSERT INTO OriginLastAccessTable" 204 "INSERT INTO OriginInfoTable"
196 " (used_count, last_access_time, origin, type)" 205 " (used_count, last_access_time, origin, type)"
197 " VALUES (?, ?, ?, ?)"; 206 " VALUES (?, ?, ?, ?)";
198 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 207 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
199 return false; 208 return false;
200 } 209 }
201 210
202 statement.BindInt(0, used_count); 211 statement.BindInt(0, used_count);
203 statement.BindInt64(1, last_access_time.ToInternalValue()); 212 statement.BindInt64(1, last_access_time.ToInternalValue());
204 statement.BindString(2, origin.spec()); 213 statement.BindString(2, origin.spec());
205 statement.BindInt(3, static_cast<int>(type)); 214 statement.BindInt(3, static_cast<int>(type));
206 if (!statement.Run()) 215 if (!statement.Run())
207 return false; 216 return false;
208 217
209 ScheduleCommit(); 218 ScheduleCommit();
210 return true; 219 return true;
211 } 220 }
212 221
222 bool QuotaDatabase::SetOriginLastModifiedTime(
Mike West 2011/06/16 09:39:33 It's likely that last modified and last accessed w
kinuko 2011/06/16 12:09:06 Hmm in the current QuotaManager design we have sep
223 const GURL& origin, StorageType type, base::Time last_modified_time) {
224 if (!LazyOpen(true))
225 return false;
226
227 sql::Statement statement;
228
229 int dummy;
230 if (FindOriginUsedCount(origin, type, &dummy)) {
Mike West 2011/06/16 09:39:33 This idiom seems heavy. You do a SQL query to det
kinuko 2011/06/16 12:09:06 (I think I've looked at the same stackoverflow thr
231 const char* kSql =
232 "UPDATE OriginInfoTable"
233 " SET last_modified_time = ?"
234 " WHERE origin = ? AND type = ?";
235 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
236 return false;
237 } else {
238 const char* kSql =
239 "INSERT INTO OriginInfoTable"
240 " (last_modified_time, origin, type) VALUES (?, ?, ?)";
241 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
242 return false;
243 }
244
245 statement.BindInt64(0, last_modified_time.ToInternalValue());
246 statement.BindString(1, origin.spec());
247 statement.BindInt(2, static_cast<int>(type));
248 if (!statement.Run())
249 return false;
250
251 ScheduleCommit();
252 return true;
253 }
254
213 bool QuotaDatabase::RegisterOrigins(const std::set<GURL>& origins, 255 bool QuotaDatabase::RegisterOrigins(const std::set<GURL>& origins,
214 StorageType type, 256 StorageType type,
215 base::Time last_access_time) { 257 base::Time last_access_time) {
216 if (!LazyOpen(true)) 258 if (!LazyOpen(true))
217 return false; 259 return false;
218 260
219 typedef std::set<GURL>::const_iterator itr_type; 261 typedef std::set<GURL>::const_iterator itr_type;
220 for (itr_type itr = origins.begin(), end = origins.end(); 262 for (itr_type itr = origins.begin(), end = origins.end();
221 itr != end; ++itr) { 263 itr != end; ++itr) {
222 const char* kSql = 264 const char* kSql =
223 "INSERT OR IGNORE INTO OriginLastAccessTable" 265 "INSERT OR IGNORE INTO OriginInfoTable"
224 " (used_count, last_access_time, origin, type)" 266 " (used_count, last_access_time, last_modified_time, origin, type)"
225 " VALUES (?, ?, ?, ?)"; 267 " VALUES (?, ?, ?, ?, ?)";
226 sql::Statement statement; 268 sql::Statement statement;
227 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 269 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
228 return false; 270 return false;
229 271
230 statement.BindInt(0, 0); // used_count 272 statement.BindInt(0, 0); // used_count
231 statement.BindInt64(1, last_access_time.ToInternalValue()); 273 statement.BindInt64(1, last_access_time.ToInternalValue());
232 statement.BindString(2, itr->spec()); 274 statement.BindInt64(2, 0); // last modified time
Mike West 2011/06/16 09:39:33 Here, last_modified_time is inserted as the third
kinuko 2011/06/16 12:09:06 Done.
233 statement.BindInt(3, static_cast<int>(type)); 275 statement.BindString(3, itr->spec());
276 statement.BindInt(4, static_cast<int>(type));
234 if (!statement.Run()) 277 if (!statement.Run())
235 return false; 278 return false;
236 } 279 }
237 280
238 ScheduleCommit(); 281 ScheduleCommit();
239 return true; 282 return true;
240 } 283 }
241 284
242 bool QuotaDatabase::DeleteHostQuota( 285 bool QuotaDatabase::DeleteHostQuota(
243 const std::string& host, StorageType type) { 286 const std::string& host, StorageType type) {
(...skipping 10 matching lines...) Expand all
254 297
255 statement.BindString(0, host); 298 statement.BindString(0, host);
256 statement.BindInt(1, static_cast<int>(type)); 299 statement.BindInt(1, static_cast<int>(type));
257 if (!statement.Run()) 300 if (!statement.Run())
258 return false; 301 return false;
259 302
260 ScheduleCommit(); 303 ScheduleCommit();
261 return true; 304 return true;
262 } 305 }
263 306
264 bool QuotaDatabase::DeleteOriginLastAccessTime( 307 bool QuotaDatabase::DeleteOriginInfo(
265 const GURL& origin, StorageType type) { 308 const GURL& origin, StorageType type) {
266 if (!LazyOpen(false)) 309 if (!LazyOpen(false))
267 return false; 310 return false;
268 311
269 const char* kSql = 312 const char* kSql =
270 "DELETE FROM OriginLastAccessTable" 313 "DELETE FROM OriginInfoTable"
271 " WHERE origin = ? AND type = ?"; 314 " WHERE origin = ? AND type = ?";
272 315
273 sql::Statement statement; 316 sql::Statement statement;
274 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 317 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
275 return false; 318 return false;
276 319
277 statement.BindString(0, origin.spec()); 320 statement.BindString(0, origin.spec());
278 statement.BindInt(1, static_cast<int>(type)); 321 statement.BindInt(1, static_cast<int>(type));
279 if (!statement.Run()) 322 if (!statement.Run())
280 return false; 323 return false;
(...skipping 16 matching lines...) Expand all
297 340
298 bool QuotaDatabase::GetLRUOrigin( 341 bool QuotaDatabase::GetLRUOrigin(
299 StorageType type, 342 StorageType type,
300 const std::set<GURL>& exceptions, 343 const std::set<GURL>& exceptions,
301 SpecialStoragePolicy* special_storage_policy, 344 SpecialStoragePolicy* special_storage_policy,
302 GURL* origin) { 345 GURL* origin) {
303 DCHECK(origin); 346 DCHECK(origin);
304 if (!LazyOpen(false)) 347 if (!LazyOpen(false))
305 return false; 348 return false;
306 349
307 const char* kSql = "SELECT origin FROM OriginLastAccessTable" 350 const char* kSql = "SELECT origin FROM OriginInfoTable"
308 " WHERE type = ?" 351 " WHERE type = ?"
309 " ORDER BY last_access_time ASC"; 352 " ORDER BY last_access_time ASC";
310 353
311 sql::Statement statement; 354 sql::Statement statement;
312 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 355 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
313 return false; 356 return false;
314 statement.BindInt(0, static_cast<int>(type)); 357 statement.BindInt(0, static_cast<int>(type));
315 358
316 while (statement.Step()) { 359 while (statement.Step()) {
317 GURL url(statement.ColumnString(0)); 360 GURL url(statement.ColumnString(0));
318 if (exceptions.find(url) != exceptions.end()) 361 if (exceptions.find(url) != exceptions.end())
319 continue; 362 continue;
320 if (special_storage_policy && 363 if (special_storage_policy &&
321 special_storage_policy->IsStorageUnlimited(url)) 364 special_storage_policy->IsStorageUnlimited(url))
322 continue; 365 continue;
323 *origin = url; 366 *origin = url;
324 return true; 367 return true;
325 } 368 }
326 369
327 *origin = GURL(); 370 *origin = GURL();
328 return statement.Succeeded(); 371 return statement.Succeeded();
329 } 372 }
330 373
374 bool QuotaDatabase::GetOriginsModifiedSince(
375 StorageType type, std::set<GURL>* origins, base::Time modified_since) {
376 DCHECK(origins);
377 if (!LazyOpen(false))
378 return false;
379
380 const char* kSql = "SELECT origin FROM OriginInfoTable"
381 " WHERE type = ? AND last_modified_time > ?";
382
383 sql::Statement statement;
384 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
385 return false;
386 statement.BindInt(0, static_cast<int>(type));
387 statement.BindInt64(1, modified_since.ToInternalValue());
388
389 origins->clear();
390 while (statement.Step())
391 origins->insert(GURL(statement.ColumnString(0)));
392
393 return statement.Succeeded();
394 }
395
331 bool QuotaDatabase::IsOriginDatabaseBootstrapped() { 396 bool QuotaDatabase::IsOriginDatabaseBootstrapped() {
332 if (!LazyOpen(true)) 397 if (!LazyOpen(true))
333 return false; 398 return false;
334 399
335 int flag = 0; 400 int flag = 0;
336 return meta_table_->GetValue(kIsOriginTableBootstrapped, &flag) && flag; 401 return meta_table_->GetValue(kIsOriginTableBootstrapped, &flag) && flag;
337 } 402 }
338 403
339 bool QuotaDatabase::SetOriginDatabaseBootstrapped(bool bootstrap_flag) { 404 bool QuotaDatabase::SetOriginDatabaseBootstrapped(bool bootstrap_flag) {
340 if (!LazyOpen(true)) 405 if (!LazyOpen(true))
(...skipping 21 matching lines...) Expand all
362 &QuotaDatabase::Commit); 427 &QuotaDatabase::Commit);
363 } 428 }
364 429
365 bool QuotaDatabase::FindOriginUsedCount( 430 bool QuotaDatabase::FindOriginUsedCount(
366 const GURL& origin, StorageType type, int* used_count) { 431 const GURL& origin, StorageType type, int* used_count) {
367 DCHECK(used_count); 432 DCHECK(used_count);
368 if (!LazyOpen(false)) 433 if (!LazyOpen(false))
369 return false; 434 return false;
370 435
371 const char* kSql = 436 const char* kSql =
372 "SELECT used_count FROM OriginLastAccessTable" 437 "SELECT used_count FROM OriginInfoTable"
373 " WHERE origin = ? AND type = ?"; 438 " WHERE origin = ? AND type = ?";
374 439
375 sql::Statement statement; 440 sql::Statement statement;
376 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 441 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
377 return false; 442 return false;
378 443
379 statement.BindString(0, origin.spec()); 444 statement.BindString(0, origin.spec());
380 statement.BindInt(1, static_cast<int>(type)); 445 statement.BindInt(1, static_cast<int>(type));
381 if (!statement.Step() || !statement.Succeeded()) 446 if (!statement.Step() || !statement.Succeeded())
382 return false; 447 return false;
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 statement.ColumnInt64(2) 598 statement.ColumnInt64(2)
534 }; 599 };
535 600
536 if (!callback->Run(entry)) 601 if (!callback->Run(entry))
537 return true; 602 return true;
538 } 603 }
539 604
540 return statement.Succeeded(); 605 return statement.Succeeded();
541 } 606 }
542 607
543 bool QuotaDatabase::DumpLastAccessTimeTable( 608 bool QuotaDatabase::DumpOriginInfoTable(
544 LastAccessTimeTableCallback* callback) { 609 OriginInfoTableCallback* callback) {
545 scoped_ptr<LastAccessTimeTableCallback> callback_deleter(callback); 610 scoped_ptr<OriginInfoTableCallback> callback_deleter(callback);
546 611
547 if (!LazyOpen(true)) 612 if (!LazyOpen(true))
548 return false; 613 return false;
549 614
550 const char* kSql = "SELECT * FROM OriginLastAccessTable"; 615 const char* kSql = "SELECT * FROM OriginInfoTable";
551 sql::Statement statement; 616 sql::Statement statement;
552 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 617 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
553 return false; 618 return false;
554 619
555 while (statement.Step()) { 620 while (statement.Step()) {
556 LastAccessTimeTableEntry entry = { 621 OriginInfoTableEntry entry = {
557 GURL(statement.ColumnString(0)), 622 GURL(statement.ColumnString(0)),
558 static_cast<StorageType>(statement.ColumnInt(1)), 623 static_cast<StorageType>(statement.ColumnInt(1)),
559 statement.ColumnInt(2), 624 statement.ColumnInt(2),
560 base::Time::FromInternalValue(statement.ColumnInt64(3)) 625 base::Time::FromInternalValue(statement.ColumnInt64(3)),
626 base::Time::FromInternalValue(statement.ColumnInt64(4))
561 }; 627 };
562 628
563 if (!callback->Run(entry)) 629 if (!callback->Run(entry))
564 return true; 630 return true;
565 } 631 }
566 632
567 return statement.Succeeded(); 633 return statement.Succeeded();
568 } 634 }
569 635
570 bool operator<(const QuotaDatabase::QuotaTableEntry& lhs, 636 bool operator<(const QuotaDatabase::QuotaTableEntry& lhs,
571 const QuotaDatabase::QuotaTableEntry& rhs) { 637 const QuotaDatabase::QuotaTableEntry& rhs) {
572 if (lhs.host < rhs.host) return true; 638 if (lhs.host < rhs.host) return true;
573 if (rhs.host < lhs.host) return false; 639 if (rhs.host < lhs.host) return false;
574 if (lhs.type < rhs.type) return true; 640 if (lhs.type < rhs.type) return true;
575 if (rhs.type < lhs.type) return false; 641 if (rhs.type < lhs.type) return false;
576 return lhs.quota < rhs.quota; 642 return lhs.quota < rhs.quota;
577 } 643 }
578 644
579 bool operator<(const QuotaDatabase::LastAccessTimeTableEntry& lhs, 645 bool operator<(const QuotaDatabase::OriginInfoTableEntry& lhs,
580 const QuotaDatabase::LastAccessTimeTableEntry& rhs) { 646 const QuotaDatabase::OriginInfoTableEntry& rhs) {
581 if (lhs.origin < rhs.origin) return true; 647 if (lhs.origin < rhs.origin) return true;
582 if (rhs.origin < lhs.origin) return false; 648 if (rhs.origin < lhs.origin) return false;
583 if (lhs.type < rhs.type) return true; 649 if (lhs.type < rhs.type) return true;
584 if (rhs.type < lhs.type) return false; 650 if (rhs.type < lhs.type) return false;
585 if (lhs.used_count < rhs.used_count) return true; 651 if (lhs.used_count < rhs.used_count) return true;
586 if (rhs.used_count < lhs.used_count) return false; 652 if (rhs.used_count < lhs.used_count) return false;
587 return lhs.last_access_time < rhs.last_access_time; 653 return lhs.last_access_time < rhs.last_access_time;
588 } 654 }
589 } // quota namespace 655 } // quota namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698