| OLD | NEW |
| 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/database/database_tracker.h" | 5 #include "webkit/database/database_tracker.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "app/sql/connection.h" | 10 #include "app/sql/connection.h" |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 return; | 135 return; |
| 136 } | 136 } |
| 137 | 137 |
| 138 InsertOrUpdateDatabaseDetails(origin_identifier, database_name, | 138 InsertOrUpdateDatabaseDetails(origin_identifier, database_name, |
| 139 database_description, estimated_size); | 139 database_description, estimated_size); |
| 140 database_connections_.AddConnection(origin_identifier, database_name); | 140 database_connections_.AddConnection(origin_identifier, database_name); |
| 141 | 141 |
| 142 CachedOriginInfo* info = GetCachedOriginInfo(origin_identifier); | 142 CachedOriginInfo* info = GetCachedOriginInfo(origin_identifier); |
| 143 *database_size = (info ? info->GetDatabaseSize(database_name) : 0); | 143 *database_size = (info ? info->GetDatabaseSize(database_name) : 0); |
| 144 *space_available = GetOriginSpaceAvailable(origin_identifier); | 144 *space_available = GetOriginSpaceAvailable(origin_identifier); |
| 145 |
| 146 if (quota_manager_proxy_) { |
| 147 // So we can compute deltas as modifications are made. |
| 148 database_connections_.SetOpenDatabaseSize( |
| 149 origin_identifier, database_name, *database_size); |
| 150 quota_manager_proxy_->NotifyStorageAccessed( |
| 151 quota::QuotaClient::kDatabase, |
| 152 DatabaseUtil::GetOriginFromIdentifier(origin_identifier), |
| 153 quota::kStorageTypeTemporary); |
| 154 } |
| 145 } | 155 } |
| 146 | 156 |
| 147 void DatabaseTracker::DatabaseModified(const string16& origin_identifier, | 157 void DatabaseTracker::DatabaseModified(const string16& origin_identifier, |
| 148 const string16& database_name) { | 158 const string16& database_name) { |
| 149 if (!LazyInit()) | 159 if (!LazyInit()) |
| 150 return; | 160 return; |
| 151 | 161 |
| 152 int64 updated_db_size = | 162 int64 new_size = |
| 153 UpdateCachedDatabaseFileSize(origin_identifier, database_name); | 163 UpdateCachedDatabaseFileSize(origin_identifier, database_name); |
| 154 int64 space_available = GetOriginSpaceAvailable(origin_identifier); | 164 int64 space_available = GetOriginSpaceAvailable(origin_identifier); |
| 155 FOR_EACH_OBSERVER(Observer, observers_, OnDatabaseSizeChanged( | 165 FOR_EACH_OBSERVER(Observer, observers_, OnDatabaseSizeChanged( |
| 156 origin_identifier, database_name, updated_db_size, space_available)); | 166 origin_identifier, database_name, new_size, space_available)); |
| 157 | 167 |
| 158 if (quota_manager_proxy_) { | 168 if (quota_manager_proxy_) { |
| 159 // TODO(michaeln): notify the quota manager | 169 int64 old_size = database_connections_.GetOpenDatabaseSize( |
| 160 // CachedOriginInfo* origin_info = GetCachedOriginInfo(origin_identifier); | 170 origin_identifier, database_name); |
| 161 // if (origin_info) | 171 if (old_size != new_size) { |
| 162 // quota_manager_proxy_->NotifyStorageConsumed( | 172 database_connections_.SetOpenDatabaseSize( |
| 163 // quota::QuotaClient::kDatabase, | 173 origin_identifier, database_name, new_size); |
| 164 // DatabaseUtil::GetOriginFromIdentifier(origin_identifier), | 174 quota_manager_proxy_->NotifyStorageModified( |
| 165 // quota::kStorageTypeTemporary, | 175 quota::QuotaClient::kDatabase, |
| 166 // origin_info->TotalSize()); | 176 DatabaseUtil::GetOriginFromIdentifier(origin_identifier), |
| 177 quota::kStorageTypeTemporary, |
| 178 new_size - old_size); |
| 179 } |
| 167 } | 180 } |
| 168 } | 181 } |
| 169 | 182 |
| 170 void DatabaseTracker::DatabaseClosed(const string16& origin_identifier, | 183 void DatabaseTracker::DatabaseClosed(const string16& origin_identifier, |
| 171 const string16& database_name) { | 184 const string16& database_name) { |
| 172 if (database_connections_.IsEmpty()) { | 185 if (database_connections_.IsEmpty()) { |
| 173 DCHECK(!is_initialized_); | 186 DCHECK(!is_initialized_); |
| 174 return; | 187 return; |
| 175 } | 188 } |
| 176 database_connections_.RemoveConnection(origin_identifier, database_name); | 189 database_connections_.RemoveConnection(origin_identifier, database_name); |
| 177 if (!database_connections_.IsDatabaseOpened(origin_identifier, database_name)) | 190 if (!database_connections_.IsDatabaseOpened(origin_identifier, database_name)) |
| 178 DeleteDatabaseIfNeeded(origin_identifier, database_name); | 191 DeleteDatabaseIfNeeded(origin_identifier, database_name); |
| 179 } | 192 } |
| 180 | 193 |
| 181 void DatabaseTracker::CloseDatabases(const DatabaseConnections& connections) { | 194 void DatabaseTracker::CloseDatabases(const DatabaseConnections& connections) { |
| 182 if (database_connections_.IsEmpty()) { | 195 if (database_connections_.IsEmpty()) { |
| 183 DCHECK(!is_initialized_ || connections.IsEmpty()); | 196 DCHECK(!is_initialized_ || connections.IsEmpty()); |
| 184 return; | 197 return; |
| 185 } | 198 } |
| 199 |
| 200 if (quota_manager_proxy_) { |
| 201 // When being closed by this route, there's a chance that |
| 202 // the tracker missed some DatabseModified calls. This method is used |
| 203 // when a renderer crashes to cleanup it's open resources. |
| 204 // We need to examine what we have in connections for the |
| 205 // size of each open databases and notify any differences between the |
| 206 // actual file sizes now. |
| 207 std::vector<std::pair<string16, string16> > open_dbs; |
| 208 connections.ListConnections(&open_dbs); |
| 209 for (std::vector<std::pair<string16, string16> >::iterator it = |
| 210 open_dbs.begin(); it != open_dbs.end(); ++it) { |
| 211 int64 old_size = database_connections_.GetOpenDatabaseSize( |
| 212 it->first, it->second); |
| 213 int64 new_size = GetDBFileSize(it->first, it->second); |
| 214 if (new_size != old_size) |
| 215 quota_manager_proxy_->NotifyStorageModified( |
| 216 quota::QuotaClient::kDatabase, |
| 217 DatabaseUtil::GetOriginFromIdentifier(it->first), |
| 218 quota::kStorageTypeTemporary, |
| 219 new_size - old_size); |
| 220 } |
| 221 } |
| 222 |
| 186 std::vector<std::pair<string16, string16> > closed_dbs; | 223 std::vector<std::pair<string16, string16> > closed_dbs; |
| 187 database_connections_.RemoveConnections(connections, &closed_dbs); | 224 database_connections_.RemoveConnections(connections, &closed_dbs); |
| 188 for (std::vector<std::pair<string16, string16> >::iterator it = | 225 for (std::vector<std::pair<string16, string16> >::iterator it = |
| 189 closed_dbs.begin(); it != closed_dbs.end(); ++it) { | 226 closed_dbs.begin(); it != closed_dbs.end(); ++it) { |
| 190 DeleteDatabaseIfNeeded(it->first, it->second); | 227 DeleteDatabaseIfNeeded(it->first, it->second); |
| 191 } | 228 } |
| 192 } | 229 } |
| 193 | 230 |
| 194 void DatabaseTracker::DeleteDatabaseIfNeeded(const string16& origin_identifier, | 231 void DatabaseTracker::DeleteDatabaseIfNeeded(const string16& origin_identifier, |
| 195 const string16& database_name) { | 232 const string16& database_name) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 | 376 |
| 340 bool DatabaseTracker::DeleteClosedDatabase(const string16& origin_identifier, | 377 bool DatabaseTracker::DeleteClosedDatabase(const string16& origin_identifier, |
| 341 const string16& database_name) { | 378 const string16& database_name) { |
| 342 if (!LazyInit()) | 379 if (!LazyInit()) |
| 343 return false; | 380 return false; |
| 344 | 381 |
| 345 // Check if the database is opened by any renderer. | 382 // Check if the database is opened by any renderer. |
| 346 if (database_connections_.IsDatabaseOpened(origin_identifier, database_name)) | 383 if (database_connections_.IsDatabaseOpened(origin_identifier, database_name)) |
| 347 return false; | 384 return false; |
| 348 | 385 |
| 386 int64 db_file_size = quota_manager_proxy_ ? |
| 387 GetDBFileSize(origin_identifier, database_name) : 0; |
| 388 |
| 349 // Try to delete the file on the hard drive. | 389 // Try to delete the file on the hard drive. |
| 350 // TODO(jochen): Delete journal files associated with this database. | |
| 351 FilePath db_file = GetFullDBFilePath(origin_identifier, database_name); | 390 FilePath db_file = GetFullDBFilePath(origin_identifier, database_name); |
| 352 if (file_util::PathExists(db_file) && !file_util::Delete(db_file, false)) | 391 if (file_util::PathExists(db_file) && !file_util::Delete(db_file, false)) |
| 353 return false; | 392 return false; |
| 354 | 393 |
| 394 // Also delete any orphaned journal file. |
| 395 DCHECK(db_file.Extension().empty()); |
| 396 file_util::Delete(db_file.InsertBeforeExtensionASCII("-journal"), false); |
| 397 |
| 398 if (quota_manager_proxy_ && db_file_size) |
| 399 quota_manager_proxy_->NotifyStorageModified( |
| 400 quota::QuotaClient::kDatabase, |
| 401 DatabaseUtil::GetOriginFromIdentifier(origin_identifier), |
| 402 quota::kStorageTypeTemporary, |
| 403 -db_file_size); |
| 404 |
| 355 // Clean up the main database and invalidate the cached record. | 405 // Clean up the main database and invalidate the cached record. |
| 356 databases_table_->DeleteDatabaseDetails(origin_identifier, database_name); | 406 databases_table_->DeleteDatabaseDetails(origin_identifier, database_name); |
| 357 origins_info_map_.erase(origin_identifier); | 407 origins_info_map_.erase(origin_identifier); |
| 358 | 408 |
| 359 std::vector<DatabaseDetails> details; | 409 std::vector<DatabaseDetails> details; |
| 360 if (databases_table_->GetAllDatabaseDetailsForOrigin( | 410 if (databases_table_->GetAllDatabaseDetailsForOrigin( |
| 361 origin_identifier, &details) && details.empty()) { | 411 origin_identifier, &details) && details.empty()) { |
| 362 // Try to delete the origin in case this was the last database. | 412 // Try to delete the origin in case this was the last database. |
| 363 DeleteOrigin(origin_identifier); | 413 DeleteOrigin(origin_identifier); |
| 364 } else if (quota_manager_proxy_) { | |
| 365 // TODO(michaeln): notify the quota manager | |
| 366 // CachedOriginInfo* origin_info = GetCachedOriginInfo(origin_identifier); | |
| 367 // if (origin_info) | |
| 368 // quota_manager_proxy_->NotifyStorageConsumed( | |
| 369 // quota::QuotaClient::kDatabase, | |
| 370 // DatabaseUtil::GetOriginFromIdentifier(origin_identifier), | |
| 371 // quota::kStorageTypeTemporary, | |
| 372 // origin_info->TotalSize()); | |
| 373 } | 414 } |
| 374 return true; | 415 return true; |
| 375 } | 416 } |
| 376 | 417 |
| 377 bool DatabaseTracker::DeleteOrigin(const string16& origin_identifier) { | 418 bool DatabaseTracker::DeleteOrigin(const string16& origin_identifier) { |
| 378 if (!LazyInit()) | 419 if (!LazyInit()) |
| 379 return false; | 420 return false; |
| 380 | 421 |
| 381 // Check if any database in this origin is opened by any renderer. | 422 // Check if any database in this origin is opened by any renderer. |
| 382 if (database_connections_.IsOriginUsed(origin_identifier)) | 423 if (database_connections_.IsOriginUsed(origin_identifier)) |
| 383 return false; | 424 return false; |
| 384 | 425 |
| 426 int64 deleted_size = 0; |
| 427 if (quota_manager_proxy_) { |
| 428 CachedOriginInfo* origin_info = GetCachedOriginInfo(origin_identifier); |
| 429 if (origin_info) |
| 430 deleted_size = origin_info->TotalSize(); |
| 431 } |
| 432 |
| 385 // We need to invalidate the cached record whether file_util::Delete() | 433 // We need to invalidate the cached record whether file_util::Delete() |
| 386 // succeeds or not, because even if it fails, it might still delete some | 434 // succeeds or not, because even if it fails, it might still delete some |
| 387 // DB files on the hard drive. | 435 // DB files on the hard drive. |
| 388 origins_info_map_.erase(origin_identifier); | 436 origins_info_map_.erase(origin_identifier); |
| 389 FilePath origin_dir = db_dir_.Append(FilePath::FromWStringHack( | 437 FilePath origin_dir = db_dir_.Append(FilePath::FromWStringHack( |
| 390 UTF16ToWide(origin_identifier))); | 438 UTF16ToWide(origin_identifier))); |
| 391 if (!file_util::Delete(origin_dir, true)) | 439 if (!file_util::Delete(origin_dir, true)) |
| 392 return false; | 440 return false; |
| 393 | 441 |
| 394 databases_table_->DeleteOrigin(origin_identifier); | 442 databases_table_->DeleteOrigin(origin_identifier); |
| 395 | 443 |
| 396 if (quota_manager_proxy_) { | 444 if (quota_manager_proxy_ && deleted_size) { |
| 397 // TODO(michaeln): notify the quota manager | 445 quota_manager_proxy_->NotifyStorageModified( |
| 398 // quota_manager_proxy_->NotifyStorageConsumed( | 446 quota::QuotaClient::kDatabase, |
| 399 // quota::QuotaClient::kDatabase, | 447 DatabaseUtil::GetOriginFromIdentifier(origin_identifier), |
| 400 // DatabaseUtil::GetOriginFromIdentifier(origin_identifier), | 448 quota::kStorageTypeTemporary, |
| 401 // quota::kStorageTypeTemporary, | 449 -deleted_size); |
| 402 // 0); | |
| 403 } | 450 } |
| 404 | 451 |
| 405 return true; | 452 return true; |
| 406 } | 453 } |
| 407 | 454 |
| 408 bool DatabaseTracker::IsDatabaseScheduledForDeletion( | 455 bool DatabaseTracker::IsDatabaseScheduledForDeletion( |
| 409 const string16& origin_identifier, | 456 const string16& origin_identifier, |
| 410 const string16& database_name) { | 457 const string16& database_name) { |
| 411 DatabaseSet::iterator it = dbs_to_be_deleted_.find(origin_identifier); | 458 DatabaseSet::iterator it = dbs_to_be_deleted_.find(origin_identifier); |
| 412 if (it == dbs_to_be_deleted_.end()) | 459 if (it == dbs_to_be_deleted_.end()) |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 std::string basename = file_path.BaseName().MaybeAsASCII(); | 829 std::string basename = file_path.BaseName().MaybeAsASCII(); |
| 783 if (!basename.empty() && | 830 if (!basename.empty() && |
| 784 !StartsWithASCII(basename, kExtensionOriginIdentifierPrefix, true)) { | 831 !StartsWithASCII(basename, kExtensionOriginIdentifierPrefix, true)) { |
| 785 file_util::Delete(file_path, true); | 832 file_util::Delete(file_path, true); |
| 786 } | 833 } |
| 787 } | 834 } |
| 788 } | 835 } |
| 789 } | 836 } |
| 790 | 837 |
| 791 } // namespace webkit_database | 838 } // namespace webkit_database |
| OLD | NEW |