Index: webkit/database/database_tracker.cc |
=================================================================== |
--- webkit/database/database_tracker.cc (revision 35502) |
+++ webkit/database/database_tracker.cc (working copy) |
@@ -9,11 +9,13 @@ |
#include "app/sql/connection.h" |
#include "app/sql/meta_table.h" |
#include "app/sql/statement.h" |
+#include "app/sql/transaction.h" |
#include "base/basictypes.h" |
#include "base/file_path.h" |
#include "base/file_util.h" |
#include "base/string_util.h" |
#include "webkit/database/databases_table.h" |
+#include "webkit/database/quota_table.h" |
namespace webkit_database { |
@@ -21,7 +23,7 @@ |
FILE_PATH_LITERAL("databases"); |
const FilePath::CharType kTrackerDatabaseFileName[] = |
FILE_PATH_LITERAL("Databases.db"); |
-const int kCurrentVersion = 1; |
+const int kCurrentVersion = 2; |
const int kCompatibleVersion = 1; |
const int64 kDefaultQuota = 5 * 1024 * 1024; |
const int64 kDefaultExtensionQuota = 50 * 1024 * 1024; |
@@ -53,8 +55,10 @@ |
InsertOrUpdateDatabaseDetails(origin_identifier, database_name, |
database_description, estimated_size); |
+ database_connections_.AddConnection(origin_identifier, database_name); |
- *database_size = GetCachedDatabaseFileSize(origin_identifier, database_name); |
+ CachedOriginInfo* info = GetCachedOriginInfo(origin_identifier); |
+ *database_size = (info ? info->GetDatabaseSize(database_name) : 0); |
*space_available = GetOriginSpaceAvailable(origin_identifier); |
} |
@@ -72,9 +76,13 @@ |
void DatabaseTracker::DatabaseClosed(const string16& origin_identifier, |
const string16& database_name) { |
- // TODO(dumi): figure out how to use this information at a later time |
+ database_connections_.RemoveConnection(origin_identifier, database_name); |
} |
+void DatabaseTracker::CloseDatabases(const DatabaseConnections& connections) { |
+ database_connections_.RemoveConnections(connections); |
+} |
+ |
void DatabaseTracker::AddObserver(Observer* observer) { |
observers_.AddObserver(observer); |
} |
@@ -91,6 +99,7 @@ |
ClearAllCachedOriginInfo(); |
meta_table_.reset(NULL); |
databases_table_.reset(NULL); |
+ quota_table_.reset(NULL); |
db_->Close(); |
initialized_ = false; |
} |
@@ -110,36 +119,101 @@ |
UTF16ToWide(origin_identifier))).Append(file_name); |
} |
+bool DatabaseTracker::GetAllOriginsInfo(std::vector<OriginInfo>* origins_info) { |
+ DCHECK(origins_info); |
+ DCHECK(origins_info->empty()); |
+ std::vector<string16> origins; |
+ if (!databases_table_->GetAllOrigins(&origins)) |
+ return false; |
+ |
+ for (std::vector<string16>::const_iterator it = origins.begin(); |
+ it != origins.end(); it++) { |
+ CachedOriginInfo* origin_info = GetCachedOriginInfo(*it); |
+ if (!origin_info) { |
+ // Restore 'origins_info' to its initial state. |
+ origins_info->clear(); |
+ return false; |
+ } |
+ origins_info->push_back(OriginInfo(*origin_info)); |
+ } |
+ |
+ return true; |
+} |
+ |
+void DatabaseTracker::SetOriginQuota(const string16& origin_identifier, |
+ int64 new_quota) { |
+ if (quota_table_->SetOriginQuota(origin_identifier, new_quota) && |
+ (origins_info_map_.find(origin_identifier) != origins_info_map_.end())) { |
+ origins_info_map_[origin_identifier].SetQuota(new_quota); |
+ } |
+} |
+ |
+bool DatabaseTracker::DeleteDatabase(const string16& origin_identifier, |
+ const string16& database_name) { |
+ // Check if the database is opened by any renderer. |
+ if (database_connections_.IsDatabaseOpened(origin_identifier, database_name)) |
+ return false; |
+ |
+ // Try to delete the file on the hard drive. |
+ FilePath db_file = GetFullDBFilePath(origin_identifier, database_name); |
+ if (file_util::PathExists(db_file) && !file_util::Delete(db_file, false)) |
+ return false; |
+ |
+ // Clean up the main database and invalidate the cached record. |
+ databases_table_->DeleteDatabaseDetails(origin_identifier, database_name); |
+ origins_info_map_.erase(origin_identifier); |
+ return true; |
+} |
+ |
+bool DatabaseTracker::DeleteOrigin(const string16& origin_identifier) { |
+ // Check if any database in this origin is opened by any renderer. |
+ if (database_connections_.IsOriginUsed(origin_identifier)) |
+ return false; |
+ |
+ // We need to invalidate the cached record whether file_util::Delete() |
+ // succeeds or not, because even if it fails, it might still delete some |
+ // DB files on the hard drive. |
+ origins_info_map_.erase(origin_identifier); |
+ FilePath origin_dir = db_dir_.Append(FilePath::FromWStringHack( |
+ UTF16ToWide(origin_identifier))); |
+ if (!file_util::Delete(origin_dir, true)) |
+ return false; |
+ |
+ databases_table_->DeleteOrigin(origin_identifier); |
+ return true; |
+} |
+ |
bool DatabaseTracker::LazyInit() { |
if (!initialized_) { |
DCHECK(!db_->is_open()); |
DCHECK(!databases_table_.get()); |
+ DCHECK(!quota_table_.get()); |
DCHECK(!meta_table_.get()); |
// If the tracker database exists, but it's corrupt or doesn't |
- // have a meta table, delete the database directory |
+ // have a meta table, delete the database directory. |
const FilePath kTrackerDatabaseFullPath = |
db_dir_.Append(FilePath(kTrackerDatabaseFileName)); |
if (file_util::DirectoryExists(db_dir_) && |
file_util::PathExists(kTrackerDatabaseFullPath) && |
(!db_->Open(kTrackerDatabaseFullPath) || |
- !db_->DoesTableExist("meta"))) { |
+ !sql::MetaTable::DoesTableExist(db_.get()))) { |
db_->Close(); |
if (!file_util::Delete(db_dir_, true)) |
return false; |
} |
databases_table_.reset(new DatabasesTable(db_.get())); |
+ quota_table_.reset(new QuotaTable(db_.get())); |
meta_table_.reset(new sql::MetaTable()); |
initialized_ = |
file_util::CreateDirectory(db_dir_) && |
(db_->is_open() || db_->Open(kTrackerDatabaseFullPath)) && |
- meta_table_->Init(db_.get(), kCurrentVersion, kCompatibleVersion) && |
- (meta_table_->GetCompatibleVersionNumber() <= kCurrentVersion) && |
- databases_table_->Init(); |
+ UpgradeToCurrentVersion(); |
if (!initialized_) { |
databases_table_.reset(NULL); |
+ quota_table_.reset(NULL); |
meta_table_.reset(NULL); |
db_->Close(); |
} |
@@ -147,6 +221,21 @@ |
return initialized_; |
} |
+bool DatabaseTracker::UpgradeToCurrentVersion() { |
+ sql::Transaction transaction(db_.get()); |
+ if (!transaction.Begin() || |
+ !meta_table_->Init(db_.get(), kCurrentVersion, kCompatibleVersion) || |
+ (meta_table_->GetCompatibleVersionNumber() > kCurrentVersion) || |
+ !databases_table_->Init() || |
+ !quota_table_->Init()) |
+ return false; |
+ |
+ if (meta_table_->GetVersionNumber() < kCurrentVersion) |
+ meta_table_->SetVersionNumber(kCurrentVersion); |
+ |
+ return transaction.Commit(); |
+} |
+ |
void DatabaseTracker::InsertOrUpdateDatabaseDetails( |
const string16& origin_identifier, |
const string16& database_name, |
@@ -168,21 +257,15 @@ |
} |
} |
-int64 DatabaseTracker::GetDBFileSize(const string16& origin_identifier, |
- const string16& database_name) const { |
- FilePath db_file_name = GetFullDBFilePath(origin_identifier, database_name); |
- int64 db_file_size = 0; |
- if (!file_util::GetFileSize(db_file_name, &db_file_size)) |
- db_file_size = 0; |
- return db_file_size; |
-} |
- |
void DatabaseTracker::ClearAllCachedOriginInfo() { |
origins_info_map_.clear(); |
} |
DatabaseTracker::CachedOriginInfo* DatabaseTracker::GetCachedOriginInfo( |
const string16& origin_identifier) { |
+ if (!LazyInit()) |
+ return NULL; |
+ |
// Populate the cache with data for this origin if needed. |
if (origins_info_map_.find(origin_identifier) == origins_info_map_.end()) { |
std::vector<DatabaseDetails> details; |
@@ -192,24 +275,45 @@ |
} |
CachedOriginInfo& origin_info = origins_info_map_[origin_identifier]; |
+ origin_info.SetOrigin(origin_identifier); |
for (std::vector<DatabaseDetails>::const_iterator it = details.begin(); |
it != details.end(); it++) { |
int64 db_file_size = |
- GetDBFileSize(it->origin_identifier, it->database_name); |
- origin_info.SetCachedDatabaseSize(it->database_name, db_file_size); |
+ GetDBFileSize(origin_identifier, it->database_name); |
+ origin_info.SetDatabaseSize(it->database_name, db_file_size); |
} |
+ |
+ int64 origin_quota = quota_table_->GetOriginQuota(origin_identifier); |
+ if (origin_quota > 0) { |
+ origin_info.SetQuota(origin_quota); |
+ } else if (StartsWith(origin_identifier, |
+ ASCIIToUTF16(kExtensionOriginIdentifierPrefix), |
+ true)) { |
+ origin_info.SetQuota(kDefaultExtensionQuota); |
+ } else { |
+ origin_info.SetQuota(kDefaultQuota); |
+ } |
} |
return &origins_info_map_[origin_identifier]; |
} |
-int64 DatabaseTracker::GetCachedDatabaseFileSize( |
- const string16& origin_identifier, |
- const string16& database_name) { |
+int64 DatabaseTracker::GetDBFileSize(const string16& origin_identifier, |
+ const string16& database_name) const { |
+ FilePath db_file_name = GetFullDBFilePath(origin_identifier, database_name); |
+ int64 db_file_size = 0; |
+ if (!file_util::GetFileSize(db_file_name, &db_file_size)) |
+ db_file_size = 0; |
+ return db_file_size; |
+} |
+ |
+int64 DatabaseTracker::GetOriginSpaceAvailable( |
+ const string16& origin_identifier) { |
CachedOriginInfo* origin_info = GetCachedOriginInfo(origin_identifier); |
if (!origin_info) |
return 0; |
- return origin_info->GetCachedDatabaseSize(database_name); |
+ int64 space_available = origin_info->Quota() - origin_info->TotalSize(); |
+ return (space_available < 0 ? 0 : space_available); |
} |
int64 DatabaseTracker::UpdateCachedDatabaseFileSize( |
@@ -218,32 +322,8 @@ |
int64 new_size = GetDBFileSize(origin_identifier, database_name); |
CachedOriginInfo* origin_info = GetCachedOriginInfo(origin_identifier); |
if (origin_info) |
- origin_info->SetCachedDatabaseSize(database_name, new_size); |
+ origin_info->SetDatabaseSize(database_name, new_size); |
return new_size; |
} |
-int64 DatabaseTracker::GetOriginUsage(const string16& origin_identifier) { |
- CachedOriginInfo* origin_info = GetCachedOriginInfo(origin_identifier); |
- if (!origin_info) |
- return kint64max; |
- return origin_info->TotalSize(); |
-} |
- |
-int64 DatabaseTracker::GetOriginQuota( |
- const string16& origin_identifier) const { |
- if (StartsWith(origin_identifier, |
- ASCIIToUTF16(kExtensionOriginIdentifierPrefix), true)) { |
- return kDefaultExtensionQuota; |
- } |
- |
- return kDefaultQuota; |
-} |
- |
-int64 DatabaseTracker::GetOriginSpaceAvailable( |
- const string16& origin_identifier) { |
- int64 space_available = GetOriginQuota(origin_identifier) - |
- GetOriginUsage(origin_identifier); |
- return (space_available < 0 ? 0 : space_available); |
-} |
- |
} // namespace webkit_database |