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

Side by Side Diff: webkit/database/database_tracker.cc

Issue 600104: Actually delete databases in CookiesTreeModel. (Closed)
Patch Set: fixed comments Created 10 years, 10 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
« no previous file with comments | « webkit/database/database_tracker.h ('k') | webkit/database/database_tracker_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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/database/database_tracker.h" 5 #include "webkit/database/database_tracker.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "app/sql/connection.h" 9 #include "app/sql/connection.h"
10 #include "app/sql/meta_table.h" 10 #include "app/sql/meta_table.h"
(...skipping 18 matching lines...) Expand all
29 const int kCompatibleVersion = 1; 29 const int kCompatibleVersion = 1;
30 const int64 kDefaultExtensionQuota = 50 * 1024 * 1024; 30 const int64 kDefaultExtensionQuota = 50 * 1024 * 1024;
31 const char* kExtensionOriginIdentifierPrefix = "chrome-extension_"; 31 const char* kExtensionOriginIdentifierPrefix = "chrome-extension_";
32 32
33 DatabaseTracker::DatabaseTracker(const FilePath& profile_path) 33 DatabaseTracker::DatabaseTracker(const FilePath& profile_path)
34 : initialized_(false), 34 : initialized_(false),
35 db_dir_(profile_path.Append(FilePath(kDatabaseDirectoryName))), 35 db_dir_(profile_path.Append(FilePath(kDatabaseDirectoryName))),
36 db_(new sql::Connection()), 36 db_(new sql::Connection()),
37 databases_table_(NULL), 37 databases_table_(NULL),
38 meta_table_(NULL), 38 meta_table_(NULL),
39 dbs_deleted_callback_(NULL),
40 default_quota_(5 * 1024 * 1024) { 39 default_quota_(5 * 1024 * 1024) {
41 } 40 }
42 41
43 DatabaseTracker::~DatabaseTracker() { 42 DatabaseTracker::~DatabaseTracker() {
44 DCHECK(observers_.size() == 0); 43 DCHECK(observers_.size() == 0);
45 DCHECK(dbs_to_be_deleted_.empty()); 44 DCHECK(dbs_to_be_deleted_.empty());
46 DCHECK(!dbs_deleted_callback_); 45 DCHECK(deletion_callbacks_.empty());
47 } 46 }
48 47
49 void DatabaseTracker::SetDefaultQuota(int64 quota) { 48 void DatabaseTracker::SetDefaultQuota(int64 quota) {
50 default_quota_ = quota; 49 default_quota_ = quota;
51 ClearAllCachedOriginInfo(); 50 ClearAllCachedOriginInfo();
52 } 51 }
53 52
54 void DatabaseTracker::DatabaseOpened(const string16& origin_identifier, 53 void DatabaseTracker::DatabaseOpened(const string16& origin_identifier,
55 const string16& database_name, 54 const string16& database_name,
56 const string16& database_description, 55 const string16& database_description,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 closed_dbs.begin(); it != closed_dbs.end(); ++it) { 97 closed_dbs.begin(); it != closed_dbs.end(); ++it) {
99 DeleteDatabaseIfNeeded(it->first, it->second); 98 DeleteDatabaseIfNeeded(it->first, it->second);
100 } 99 }
101 } 100 }
102 101
103 void DatabaseTracker::DeleteDatabaseIfNeeded(const string16& origin_identifier, 102 void DatabaseTracker::DeleteDatabaseIfNeeded(const string16& origin_identifier,
104 const string16& database_name) { 103 const string16& database_name) {
105 DCHECK(!database_connections_.IsDatabaseOpened(origin_identifier, 104 DCHECK(!database_connections_.IsDatabaseOpened(origin_identifier,
106 database_name)); 105 database_name));
107 if (IsDatabaseScheduledForDeletion(origin_identifier, database_name)) { 106 if (IsDatabaseScheduledForDeletion(origin_identifier, database_name)) {
108 DeleteDatabase(origin_identifier, database_name); 107 DeleteClosedDatabase(origin_identifier, database_name);
109 dbs_to_be_deleted_[origin_identifier].erase(database_name); 108 dbs_to_be_deleted_[origin_identifier].erase(database_name);
110 if (dbs_to_be_deleted_[origin_identifier].empty()) 109 if (dbs_to_be_deleted_[origin_identifier].empty())
111 dbs_to_be_deleted_.erase(origin_identifier); 110 dbs_to_be_deleted_.erase(origin_identifier);
112 if (dbs_to_be_deleted_.empty()) { 111
113 DCHECK(dbs_deleted_callback_); 112 std::vector<net::CompletionCallback*> to_be_deleted;
114 dbs_deleted_callback_->Run(net::OK); 113 for (PendingCompletionMap::iterator callback = deletion_callbacks_.begin();
115 dbs_deleted_callback_ = NULL; 114 callback != deletion_callbacks_.end(); ++callback) {
115 DatabaseSet::iterator found_origin =
116 callback->second.find(origin_identifier);
117 if (found_origin != callback->second.end()) {
118 std::set<string16>& databases = found_origin->second;
119 databases.erase(database_name);
120 if (databases.empty()) {
121 callback->second.erase(found_origin);
122 if (callback->second.empty()) {
123 net::CompletionCallback* cb = callback->first;
124 cb->Run(net::OK);
125 to_be_deleted.push_back(cb);
126 }
127 }
128 }
116 } 129 }
130 for (std::vector<net::CompletionCallback*>::iterator cb =
131 to_be_deleted.begin(); cb != to_be_deleted.end(); ++cb)
132 deletion_callbacks_.erase(*cb);
117 } 133 }
118 } 134 }
119 135
120 void DatabaseTracker::AddObserver(Observer* observer) { 136 void DatabaseTracker::AddObserver(Observer* observer) {
121 observers_.AddObserver(observer); 137 observers_.AddObserver(observer);
122 } 138 }
123 139
124 void DatabaseTracker::RemoveObserver(Observer* observer) { 140 void DatabaseTracker::RemoveObserver(Observer* observer) {
125 // When we remove a listener, we do not know which cached information 141 // When we remove a listener, we do not know which cached information
126 // is still needed and which information can be discarded. So we just 142 // is still needed and which information can be discarded. So we just
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 } 194 }
179 195
180 void DatabaseTracker::SetOriginQuota(const string16& origin_identifier, 196 void DatabaseTracker::SetOriginQuota(const string16& origin_identifier,
181 int64 new_quota) { 197 int64 new_quota) {
182 if (quota_table_->SetOriginQuota(origin_identifier, new_quota) && 198 if (quota_table_->SetOriginQuota(origin_identifier, new_quota) &&
183 (origins_info_map_.find(origin_identifier) != origins_info_map_.end())) { 199 (origins_info_map_.find(origin_identifier) != origins_info_map_.end())) {
184 origins_info_map_[origin_identifier].SetQuota(new_quota); 200 origins_info_map_[origin_identifier].SetQuota(new_quota);
185 } 201 }
186 } 202 }
187 203
188 bool DatabaseTracker::DeleteDatabase(const string16& origin_identifier, 204 bool DatabaseTracker::DeleteClosedDatabase(const string16& origin_identifier,
189 const string16& database_name) { 205 const string16& database_name) {
190 // Check if the database is opened by any renderer. 206 // Check if the database is opened by any renderer.
191 if (database_connections_.IsDatabaseOpened(origin_identifier, database_name)) 207 if (database_connections_.IsDatabaseOpened(origin_identifier, database_name))
192 return false; 208 return false;
193 209
194 // Try to delete the file on the hard drive. 210 // Try to delete the file on the hard drive.
195 // TODO(jochen): Delete directory if this was the last database.
196 // TODO(jochen): Delete journal files associated with this database. 211 // TODO(jochen): Delete journal files associated with this database.
197 FilePath db_file = GetFullDBFilePath(origin_identifier, database_name); 212 FilePath db_file = GetFullDBFilePath(origin_identifier, database_name);
198 if (file_util::PathExists(db_file) && !file_util::Delete(db_file, false)) 213 if (file_util::PathExists(db_file) && !file_util::Delete(db_file, false))
199 return false; 214 return false;
200 215
201 // Clean up the main database and invalidate the cached record. 216 // Clean up the main database and invalidate the cached record.
202 databases_table_->DeleteDatabaseDetails(origin_identifier, database_name); 217 databases_table_->DeleteDatabaseDetails(origin_identifier, database_name);
203 origins_info_map_.erase(origin_identifier); 218 origins_info_map_.erase(origin_identifier);
219
220 // Try to delete the origin in case this was the last database.
221 std::vector<DatabaseDetails> details;
222 if (databases_table_->GetAllDatabaseDetailsForOrigin(
223 origin_identifier, &details) && details.empty())
224 DeleteOrigin(origin_identifier);
204 return true; 225 return true;
205 } 226 }
206 227
207 bool DatabaseTracker::DeleteOrigin(const string16& origin_identifier) { 228 bool DatabaseTracker::DeleteOrigin(const string16& origin_identifier) {
208 // Check if any database in this origin is opened by any renderer. 229 // Check if any database in this origin is opened by any renderer.
209 if (database_connections_.IsOriginUsed(origin_identifier)) 230 if (database_connections_.IsOriginUsed(origin_identifier))
210 return false; 231 return false;
211 232
212 // We need to invalidate the cached record whether file_util::Delete() 233 // We need to invalidate the cached record whether file_util::Delete()
213 // succeeds or not, because even if it fails, it might still delete some 234 // succeeds or not, because even if it fails, it might still delete some
214 // DB files on the hard drive. 235 // DB files on the hard drive.
215 origins_info_map_.erase(origin_identifier); 236 origins_info_map_.erase(origin_identifier);
216 FilePath origin_dir = db_dir_.Append(FilePath::FromWStringHack( 237 FilePath origin_dir = db_dir_.Append(FilePath::FromWStringHack(
217 UTF16ToWide(origin_identifier))); 238 UTF16ToWide(origin_identifier)));
218 if (!file_util::Delete(origin_dir, true)) 239 if (!file_util::Delete(origin_dir, true))
219 return false; 240 return false;
220 241
221 databases_table_->DeleteOrigin(origin_identifier); 242 databases_table_->DeleteOrigin(origin_identifier);
222 return true; 243 return true;
223 } 244 }
224 245
225 bool DatabaseTracker::IsDatabaseScheduledForDeletion( 246 bool DatabaseTracker::IsDatabaseScheduledForDeletion(
226 const string16& origin_identifier, 247 const string16& origin_identifier,
227 const string16& database_name) { 248 const string16& database_name) {
228 std::map<string16, std::set<string16> >::iterator it = 249 DatabaseSet::iterator it = dbs_to_be_deleted_.find(origin_identifier);
229 dbs_to_be_deleted_.find(origin_identifier);
230 if (it == dbs_to_be_deleted_.end()) 250 if (it == dbs_to_be_deleted_.end())
231 return false; 251 return false;
232 252
233 std::set<string16>& databases = it->second; 253 std::set<string16>& databases = it->second;
234 return (databases.find(database_name) != databases.end()); 254 return (databases.find(database_name) != databases.end());
235 } 255 }
236 256
237 bool DatabaseTracker::LazyInit() { 257 bool DatabaseTracker::LazyInit() {
238 if (!initialized_) { 258 if (!initialized_) {
239 DCHECK(!db_->is_open()); 259 DCHECK(!db_->is_open());
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 void DatabaseTracker::ScheduleDatabaseForDeletion( 401 void DatabaseTracker::ScheduleDatabaseForDeletion(
382 const string16& origin_identifier, 402 const string16& origin_identifier,
383 const string16& database_name) { 403 const string16& database_name) {
384 DCHECK(database_connections_.IsDatabaseOpened(origin_identifier, 404 DCHECK(database_connections_.IsDatabaseOpened(origin_identifier,
385 database_name)); 405 database_name));
386 dbs_to_be_deleted_[origin_identifier].insert(database_name); 406 dbs_to_be_deleted_[origin_identifier].insert(database_name);
387 FOR_EACH_OBSERVER(Observer, observers_, OnDatabaseScheduledForDeletion( 407 FOR_EACH_OBSERVER(Observer, observers_, OnDatabaseScheduledForDeletion(
388 origin_identifier, database_name)); 408 origin_identifier, database_name));
389 } 409 }
390 410
411 int DatabaseTracker::DeleteDatabase(const string16& origin_identifier,
412 const string16& database_name,
413 net::CompletionCallback* callback) {
414 if (!LazyInit())
415 return net::ERR_FAILED;
416
417 DCHECK(!callback ||
418 deletion_callbacks_.find(callback) == deletion_callbacks_.end());
419
420 if (database_connections_.IsDatabaseOpened(origin_identifier,
421 database_name)) {
422 if (callback)
423 deletion_callbacks_[callback][origin_identifier].insert(database_name);
424 ScheduleDatabaseForDeletion(origin_identifier, database_name);
425 return net::ERR_IO_PENDING;
426 }
427 DeleteClosedDatabase(origin_identifier, database_name);
428 return net::OK;
429 }
430
391 int DatabaseTracker::DeleteDataModifiedSince( 431 int DatabaseTracker::DeleteDataModifiedSince(
392 const base::Time& cutoff, 432 const base::Time& cutoff,
393 net::CompletionCallback* callback) { 433 net::CompletionCallback* callback) {
394 // Check for reentrancy. 434 if (!LazyInit())
395 if (dbs_deleted_callback_ || !LazyInit())
396 return net::ERR_FAILED; 435 return net::ERR_FAILED;
397 436
398 DCHECK(callback); 437 DCHECK(!callback ||
399 dbs_deleted_callback_ = callback; 438 deletion_callbacks_.find(callback) == deletion_callbacks_.end());
439 DatabaseSet to_be_deleted;
400 440
401 std::vector<string16> origins; 441 std::vector<string16> origins;
402 if (!databases_table_->GetAllOrigins(&origins)) { 442 if (!databases_table_->GetAllOrigins(&origins))
403 dbs_deleted_callback_ = NULL;
404 return net::ERR_FAILED; 443 return net::ERR_FAILED;
405 }
406 int rv = net::OK; 444 int rv = net::OK;
407 for (std::vector<string16>::const_iterator ori = origins.begin(); 445 for (std::vector<string16>::const_iterator ori = origins.begin();
408 ori != origins.end(); ++ori) { 446 ori != origins.end(); ++ori) {
409 if (StartsWith(*ori, ASCIIToUTF16(kExtensionOriginIdentifierPrefix), true)) 447 if (StartsWith(*ori, ASCIIToUTF16(kExtensionOriginIdentifierPrefix), true))
410 continue; 448 continue;
411 std::vector<DatabaseDetails> details; 449 std::vector<DatabaseDetails> details;
412 if (!databases_table_->GetAllDatabaseDetailsForOrigin(*ori, &details)) { 450 if (!databases_table_->GetAllDatabaseDetailsForOrigin(*ori, &details))
413 rv = net::ERR_FAILED; 451 rv = net::ERR_FAILED;
414 continue;
415 }
416 for (std::vector<DatabaseDetails>::const_iterator db = details.begin(); 452 for (std::vector<DatabaseDetails>::const_iterator db = details.begin();
417 db != details.end(); ++db) { 453 db != details.end(); ++db) {
418 FilePath db_file = GetFullDBFilePath(*ori, db->database_name); 454 FilePath db_file = GetFullDBFilePath(*ori, db->database_name);
419 file_util::FileInfo file_info; 455 file_util::FileInfo file_info;
420 file_util::GetFileInfo(db_file, &file_info); 456 file_util::GetFileInfo(db_file, &file_info);
421 if (file_info.last_modified < cutoff) 457 if (file_info.last_modified < cutoff)
422 continue; 458 continue;
423 459
424 // Check if the database is opened by any renderer. 460 // Check if the database is opened by any renderer.
425 if (database_connections_.IsDatabaseOpened(*ori, db->database_name)) { 461 if (database_connections_.IsDatabaseOpened(*ori, db->database_name))
426 ScheduleDatabaseForDeletion(*ori, db->database_name); 462 to_be_deleted[*ori].insert(db->database_name);
427 rv = net::ERR_IO_PENDING; 463 else
428 } else { 464 DeleteClosedDatabase(*ori, db->database_name);
429 DeleteDatabase(*ori, db->database_name);
430 }
431 } 465 }
432 } 466 }
433 467
434 if (rv != net::ERR_IO_PENDING) { 468 if (!to_be_deleted.empty()) {
435 dbs_to_be_deleted_.clear(); 469 if (callback)
436 dbs_deleted_callback_ = NULL; 470 deletion_callbacks_[callback] = to_be_deleted;
471 for (DatabaseSet::iterator ori = to_be_deleted.begin();
472 ori != to_be_deleted.end(); ++ori) {
473 for (std::set<string16>::iterator db = ori->second.begin();
474 db != ori->second.end(); ++db)
475 ScheduleDatabaseForDeletion(ori->first, *db);
476 }
477 rv = net::ERR_IO_PENDING;
437 } 478 }
438 return rv; 479 return rv;
439 } 480 }
440 481
441 // static 482 // static
442 void DatabaseTracker::ClearLocalState(const FilePath& profile_path) { 483 void DatabaseTracker::ClearLocalState(const FilePath& profile_path) {
443 FilePath db_dir = profile_path.Append(FilePath(kDatabaseDirectoryName)); 484 FilePath db_dir = profile_path.Append(FilePath(kDatabaseDirectoryName));
444 FilePath db_tracker = db_dir.Append(FilePath(kTrackerDatabaseFileName)); 485 FilePath db_tracker = db_dir.Append(FilePath(kTrackerDatabaseFileName));
445 if (file_util::DirectoryExists(db_dir) && 486 if (file_util::DirectoryExists(db_dir) &&
446 file_util::PathExists(db_tracker)) { 487 file_util::PathExists(db_tracker)) {
(...skipping 22 matching lines...) Expand all
469 file_path = file_enumerator.Next()) { 510 file_path = file_enumerator.Next()) {
470 if (file_path.BaseName() != FilePath(kTrackerDatabaseFileName)) { 511 if (file_path.BaseName() != FilePath(kTrackerDatabaseFileName)) {
471 if (!StartsWith(file_path.BaseName().ToWStringHack(), 512 if (!StartsWith(file_path.BaseName().ToWStringHack(),
472 ASCIIToWide(kExtensionOriginIdentifierPrefix), true)) 513 ASCIIToWide(kExtensionOriginIdentifierPrefix), true))
473 file_util::Delete(file_path, true); 514 file_util::Delete(file_path, true);
474 } 515 }
475 } 516 }
476 } 517 }
477 518
478 } // namespace webkit_database 519 } // namespace webkit_database
OLDNEW
« no previous file with comments | « webkit/database/database_tracker.h ('k') | webkit/database/database_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698