diff options
author | dumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-13 01:30:45 +0000 |
---|---|---|
committer | dumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-13 01:30:45 +0000 |
commit | 3c5ed2c5747de75351c18fbf1e969eccc263d1d5 (patch) | |
tree | 75ba30df50a1f0bd4ecd90d51051b3bb057c2a51 | |
parent | dad1e3bc1d2894be09c2a5bcb98708044aa1664d (diff) | |
download | chromium_src-3c5ed2c5747de75351c18fbf1e969eccc263d1d5.zip chromium_src-3c5ed2c5747de75351c18fbf1e969eccc263d1d5.tar.gz chromium_src-3c5ed2c5747de75351c18fbf1e969eccc263d1d5.tar.bz2 |
Changing the file naming scheme. Creating a directory for each origin,
and naming files according to the row ID of the respective DB in the
tracker database. Also, fixing a bug: caching the renderer process
handle in DatabaseDispatcherHost after it was set in
ResourceMessageFilter.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/385051
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31874 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/renderer_host/database_dispatcher_host.cc | 94 | ||||
-rw-r--r-- | chrome/browser/renderer_host/database_dispatcher_host.h | 8 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.cc | 4 | ||||
-rw-r--r-- | webkit/database/database_tracker.cc | 12 | ||||
-rw-r--r-- | webkit/database/database_tracker_unittest.cc | 17 | ||||
-rw-r--r-- | webkit/database/database_util.cc | 58 | ||||
-rw-r--r-- | webkit/database/database_util.h | 28 | ||||
-rw-r--r-- | webkit/database/database_util_unittest.cc | 45 | ||||
-rw-r--r-- | webkit/database/databases_table.cc | 14 | ||||
-rw-r--r-- | webkit/database/databases_table.h | 2 | ||||
-rw-r--r-- | webkit/database/databases_table_unittest.cc | 6 | ||||
-rw-r--r-- | webkit/database/vfs_backend.cc | 83 | ||||
-rw-r--r-- | webkit/database/vfs_backend.h | 21 | ||||
-rw-r--r-- | webkit/tools/test_shell/simple_database_system.cc | 14 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell.gyp | 1 | ||||
-rw-r--r-- | webkit/webkit_glue.gyp | 2 |
16 files changed, 283 insertions, 126 deletions
diff --git a/chrome/browser/renderer_host/database_dispatcher_host.cc b/chrome/browser/renderer_host/database_dispatcher_host.cc index 171a0ad..e143364 100644 --- a/chrome/browser/renderer_host/database_dispatcher_host.cc +++ b/chrome/browser/renderer_host/database_dispatcher_host.cc @@ -20,9 +20,11 @@ #include "chrome/browser/chrome_thread.h" #include "chrome/browser/renderer_host/browser_render_process_host.h" #include "chrome/common/render_messages.h" +#include "webkit/database/database_util.h" #include "webkit/database/vfs_backend.h" using webkit_database::DatabaseTracker; +using webkit_database::DatabaseUtil; using webkit_database::VfsBackend; const int kNumDeleteRetries = 2; @@ -30,17 +32,24 @@ const int kDelayDeleteRetryMs = 100; DatabaseDispatcherHost::DatabaseDispatcherHost( DatabaseTracker* db_tracker, - IPC::Message::Sender* message_sender, - base::ProcessHandle process_handle) + IPC::Message::Sender* message_sender) : db_tracker_(db_tracker), message_sender_(message_sender), - process_handle_(process_handle), + process_handle_(0), observer_added_(false), shutdown_(false) { DCHECK(db_tracker_); DCHECK(message_sender_); } +void DatabaseDispatcherHost::Init(base::ProcessHandle process_handle) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + DCHECK(!shutdown_); + DCHECK(!process_handle_); + DCHECK(process_handle); + process_handle_ = process_handle; +} + void DatabaseDispatcherHost::Shutdown() { shutdown_ = true; message_sender_ = NULL; @@ -61,47 +70,14 @@ void DatabaseDispatcherHost::RemoveObserver() { db_tracker_->RemoveObserver(this); } -FilePath DatabaseDispatcherHost::GetDBFileFullPath( +// TODO(dumi): remove this function when switching IPC parameters +// from FilePath to string16 +FilePath DatabaseDispatcherHost::GetFullFilePathForVfsFile( const FilePath& vfs_file_name) { - // 'vfs_file_name' can be one of 3 things: - // 1. Empty string: It means the VFS wants to open a temp file. In this case - // we need to return the path to the directory that stores all databases. - // 2. origin_identifier/database_name: In this case, we need to extract - // 'origin_identifier' and 'database_name' and pass them to - // DatabaseTracker::GetFullDBFilePath(). - // 3. origin_identifier/database_name-suffix: '-suffix' could be '-journal', - // for example. In this case, we need to extract 'origin_identifier' and - // 'database_name-suffix' and pass them to - // DatabaseTracker::GetFullDBFilePath(). 'database_name-suffix' is not - // a database name as expected by DatabaseTracker::GetFullDBFilePath(), - // but due to its implementation, it's OK to pass in 'database_name-suffix' - // too. - // - // We also check that the given string doesn't contain invalid characters - // that would result in a DB file stored outside of the directory where - // all DB files are supposed to be stored. DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); - if (vfs_file_name.empty()) - return db_tracker_->DatabaseDirectory(); - - std::wstring str = vfs_file_name.ToWStringHack(); - size_t slashIndex = str.find('/'); - if (slashIndex == std::wstring::npos) - return FilePath(); // incorrect format - std::wstring origin_identifier = str.substr(0, slashIndex); - std::wstring database_name = - str.substr(slashIndex + 1, str.length() - slashIndex); - if ((origin_identifier.find('\\') != std::wstring::npos) || - (origin_identifier.find('/') != std::wstring::npos) || - (origin_identifier.find(':') != std::wstring::npos) || - (database_name.find('\\') != std::wstring::npos) || - (database_name.find('/') != std::wstring::npos) || - (database_name.find(':') != std::wstring::npos)) { - return FilePath(); - } - - return db_tracker_->GetFullDBFilePath( - WideToUTF16(origin_identifier), WideToUTF16(database_name)); + DCHECK(!vfs_file_name.empty()); + return DatabaseUtil::GetFullFilePathForVfsFile( + db_tracker_, WideToUTF16(vfs_file_name.ToWStringHack())); } bool DatabaseDispatcherHost::OnMessageReceived( @@ -180,11 +156,16 @@ void DatabaseDispatcherHost::DatabaseOpenFile(const FilePath& vfs_file_name, DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); base::PlatformFile target_handle = base::kInvalidPlatformFileValue; base::PlatformFile target_dir_handle = base::kInvalidPlatformFileValue; - FilePath db_file_name = GetDBFileFullPath(vfs_file_name); - if (!db_file_name.empty()) { - FilePath db_dir = db_tracker_->DatabaseDirectory(); - VfsBackend::OpenFile(db_file_name, db_dir, desired_flags, - process_handle_, &target_handle, &target_dir_handle); + if (vfs_file_name.empty()) { + VfsBackend::OpenTempFileInDirectory(db_tracker_->DatabaseDirectory(), + desired_flags, process_handle_, + &target_handle, &target_dir_handle); + } else { + FilePath db_file = GetFullFilePathForVfsFile(vfs_file_name); + if (!db_file.empty()) { + VfsBackend::OpenFile(db_file, desired_flags, process_handle_, + &target_handle, &target_dir_handle); + } } ViewMsg_DatabaseOpenFileResponse_Params response_params; @@ -223,10 +204,9 @@ void DatabaseDispatcherHost::DatabaseDeleteFile(const FilePath& vfs_file_name, // Return an error if the file name is invalid or if the file could not // be deleted after kNumDeleteRetries attempts. int error_code = SQLITE_IOERR_DELETE; - FilePath db_file_name = GetDBFileFullPath(vfs_file_name); - if (!db_file_name.empty()) { - FilePath db_dir = db_tracker_->DatabaseDirectory(); - error_code = VfsBackend::DeleteFile(db_file_name, db_dir, sync_dir); + FilePath db_file = GetFullFilePathForVfsFile(vfs_file_name); + if (!db_file.empty()) { + error_code = VfsBackend::DeleteFile(db_file, sync_dir); if ((error_code == SQLITE_IOERR_DELETE) && reschedule_count) { // If the file could not be deleted, try again. ChromeThread::PostDelayedTask( @@ -270,9 +250,9 @@ void DatabaseDispatcherHost::DatabaseGetFileAttributes( int32 message_id) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); int32 attributes = -1; - FilePath db_file_name = GetDBFileFullPath(vfs_file_name); - if (!db_file_name.empty()) - attributes = VfsBackend::GetFileAttributes(db_file_name); + FilePath db_file = GetFullFilePathForVfsFile(vfs_file_name); + if (!db_file.empty()) + attributes = VfsBackend::GetFileAttributes(db_file); ChromeThread::PostTask( ChromeThread::IO, FROM_HERE, NewRunnableMethod(this, @@ -299,9 +279,9 @@ void DatabaseDispatcherHost::DatabaseGetFileSize(const FilePath& vfs_file_name, int32 message_id) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); int64 size = 0; - FilePath db_file_name = GetDBFileFullPath(vfs_file_name); - if (!db_file_name.empty()) - size = VfsBackend::GetFileSize(db_file_name); + FilePath db_file = GetFullFilePathForVfsFile(vfs_file_name); + if (!db_file.empty()) + size = VfsBackend::GetFileSize(db_file); ChromeThread::PostTask( ChromeThread::IO, FROM_HERE, NewRunnableMethod(this, diff --git a/chrome/browser/renderer_host/database_dispatcher_host.h b/chrome/browser/renderer_host/database_dispatcher_host.h index 5053138..b1d31d7 100644 --- a/chrome/browser/renderer_host/database_dispatcher_host.h +++ b/chrome/browser/renderer_host/database_dispatcher_host.h @@ -18,8 +18,8 @@ class DatabaseDispatcherHost public webkit_database::DatabaseTracker::Observer { public: DatabaseDispatcherHost(webkit_database::DatabaseTracker* db_tracker, - IPC::Message::Sender* message_sender, - base::ProcessHandle process_handle); + IPC::Message::Sender* message_sender); + void Init(base::ProcessHandle process_handle); void Shutdown(); bool OnMessageReceived(const IPC::Message& message, bool* message_was_ok); @@ -55,7 +55,7 @@ class DatabaseDispatcherHost private: void AddObserver(); void RemoveObserver(); - FilePath GetDBFileFullPath(const FilePath& vfs_file_name); + FilePath GetFullFilePathForVfsFile(const FilePath& vfs_file_name); void ReceivedBadMessage(uint16 msg_type); void SendMessage(IPC::Message* message); @@ -93,7 +93,7 @@ class DatabaseDispatcherHost IPC::Message::Sender* message_sender_; // The handle of this process. - const base::ProcessHandle process_handle_; + base::ProcessHandle process_handle_; // True if and only if this instance was added as an observer // to DatabaseTracker. diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index d40e247..ba34532 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -171,8 +171,7 @@ ResourceMessageFilter::ResourceMessageFilter( new DOMStorageDispatcherHost(this, profile->GetWebKitContext(), resource_dispatcher_host->webkit_thread()))), ALLOW_THIS_IN_INITIALIZER_LIST(db_dispatcher_host_( - new DatabaseDispatcherHost(profile->GetDatabaseTracker(), - this, handle()))), + new DatabaseDispatcherHost(profile->GetDatabaseTracker(), this))), notification_prefs_( profile->GetDesktopNotificationService()->prefs_cache()), socket_stream_dispatcher_host_(new SocketStreamDispatcherHost), @@ -239,6 +238,7 @@ void ResourceMessageFilter::OnChannelConnected(int32 peer_pid) { appcache_dispatcher_host_->Initialize(this, id(), handle()); socket_stream_dispatcher_host_->Initialize(this, id()); dom_storage_dispatcher_host_->Init(handle()); + db_dispatcher_host_->Init(handle()); } void ResourceMessageFilter::OnChannelError() { diff --git a/webkit/database/database_tracker.cc b/webkit/database/database_tracker.cc index c529c28..54e52d7 100644 --- a/webkit/database/database_tracker.cc +++ b/webkit/database/database_tracker.cc @@ -96,8 +96,16 @@ void DatabaseTracker::CloseTrackerDatabaseAndClearCaches() { FilePath DatabaseTracker::GetFullDBFilePath( const string16& origin_identifier, const string16& database_name) const { - return db_dir_.Append(FilePath::FromWStringHack(UTF16ToWide( - origin_identifier + ASCIIToUTF16("_") + database_name))); + DCHECK(!origin_identifier.empty()); + DCHECK(!database_name.empty()); + int64 id = databases_table_->GetDatabaseID( + origin_identifier, database_name); + if (id < 0) + return FilePath(); + + FilePath file_name = FilePath::FromWStringHack(Int64ToWString(id)); + return db_dir_.Append(FilePath::FromWStringHack( + UTF16ToWide(origin_identifier))).Append(file_name); } bool DatabaseTracker::LazyInit() { diff --git a/webkit/database/database_tracker_unittest.cc b/webkit/database/database_tracker_unittest.cc index 7fadeff..0d0b635 100644 --- a/webkit/database/database_tracker_unittest.cc +++ b/webkit/database/database_tracker_unittest.cc @@ -82,12 +82,13 @@ TEST(DatabaseTrackerTest, TestIt) { // Open three new databases. int64 database_size = 0; int64 space_available = 0; - const string16 kOrigin1 = ASCIIToUTF16("kOrigin1"); - const string16 kOrigin2 = ASCIIToUTF16("kOrigin2"); - const string16 kDB1 = ASCIIToUTF16("kDB1"); - const string16 kDB2 = ASCIIToUTF16("kDB2"); - const string16 kDB3 = ASCIIToUTF16("kDB3"); - const string16 kDescription = ASCIIToUTF16("database_kDescription"); + const string16 kOrigin1 = ASCIIToUTF16("origin1"); + const string16 kOrigin2 = ASCIIToUTF16("origin2"); + const string16 kDB1 = ASCIIToUTF16("db1"); + const string16 kDB2 = ASCIIToUTF16("db2"); + const string16 kDB3 = ASCIIToUTF16("db3"); + const string16 kDescription = ASCIIToUTF16("database_description"); + tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, &database_size, &space_available); EXPECT_EQ(0, database_size); @@ -109,6 +110,10 @@ TEST(DatabaseTrackerTest, TestIt) { // Write some data to each file and check that the listeners are // called with the appropriate values. + EXPECT_TRUE(file_util::CreateDirectory(tracker->DatabaseDirectory().Append( + FilePath::FromWStringHack(UTF16ToWide(kOrigin1))))); + EXPECT_TRUE(file_util::CreateDirectory(tracker->DatabaseDirectory().Append( + FilePath::FromWStringHack(UTF16ToWide(kOrigin2))))); EXPECT_EQ(1, file_util::WriteFile( tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1)); EXPECT_EQ(2, file_util::WriteFile( diff --git a/webkit/database/database_util.cc b/webkit/database/database_util.cc new file mode 100644 index 0000000..b571a72 --- /dev/null +++ b/webkit/database/database_util.cc @@ -0,0 +1,58 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/database/database_util.h" + +#include "base/string_util.h" +#include "webkit/database/database_tracker.h" +#include "webkit/database/vfs_backend.h" + +namespace webkit_database { + +bool DatabaseUtil::CrackVfsFilePath(const string16& vfs_file_path, + string16* origin_identifier, + string16* database_name, + string16* sqlite_suffix) { + // 'vfs_file_path' is of the form <origin_identifier>/<db_name>#<suffix>. + // <suffix> is optional. + DCHECK(!vfs_file_path.empty()); + size_t first_slash_index = vfs_file_path.find('/'); + size_t last_pound_index = vfs_file_path.rfind('#'); + // '/' and '#' must be present in the string. Also, the string cannot start + // with a '/' (origin_identifier cannot be empty) and '/' must come before '#' + if ((first_slash_index == string16::npos) || + (last_pound_index == string16::npos) || + (first_slash_index == 0) || + (first_slash_index > last_pound_index)) { + return false; + } + + *origin_identifier = vfs_file_path.substr(0, first_slash_index); + *database_name = vfs_file_path.substr( + first_slash_index + 1, last_pound_index - first_slash_index - 1); + *sqlite_suffix = vfs_file_path.substr( + last_pound_index + 1, vfs_file_path.length() - last_pound_index - 1); + return true; +} + +FilePath DatabaseUtil::GetFullFilePathForVfsFile( + DatabaseTracker* db_tracker, const string16& vfs_file_path) { + string16 origin_identifier; + string16 database_name; + string16 sqlite_suffix; + if (!CrackVfsFilePath(vfs_file_path, &origin_identifier, + &database_name, &sqlite_suffix)) { + return FilePath(); // invalid vfs_file_name + } + + FilePath full_path = db_tracker->GetFullDBFilePath( + origin_identifier, database_name); + if (!full_path.empty() && !sqlite_suffix.empty()) { + full_path = FilePath::FromWStringHack( + full_path.ToWStringHack() + UTF16ToWide(sqlite_suffix)); + } + return full_path; +} + +} // namespace webkit_database diff --git a/webkit/database/database_util.h b/webkit/database/database_util.h new file mode 100644 index 0000000..7df1d38 --- /dev/null +++ b/webkit/database/database_util.h @@ -0,0 +1,28 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_DATABASE_DATABASE_UTIL_H_ +#define WEBKIT_DATABASE_DATABASE_UTIL_H_ + +#include "base/file_path.h" +#include "base/string16.h" + +namespace webkit_database { + +class DatabaseTracker; + +class DatabaseUtil { + public: + static bool CrackVfsFilePath(const string16& vfs_file_path, + string16* origin_identifier, + string16* database_name, + string16* sqlite_suffix); + static FilePath GetFullFilePathForVfsFile(DatabaseTracker* db_tracker, + const string16& vfs_file_path); + +}; + +} // namespace webkit_database + +#endif // WEBKIT_DATABASE_DATABASE_UTIL_H_ diff --git a/webkit/database/database_util_unittest.cc b/webkit/database/database_util_unittest.cc new file mode 100644 index 0000000..4718e89 --- /dev/null +++ b/webkit/database/database_util_unittest.cc @@ -0,0 +1,45 @@ +// Copyright (c) 2009 The Chromium Authos. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/string_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webkit/database/database_util.h" + +using webkit_database::DatabaseUtil; + +static void TestVfsFilePath(bool expected_result, + const char* vfs_file_path, + const char* expected_origin_identifier = "", + const char* expected_database_name = "", + const char* expected_sqlite_suffix = "") { + string16 origin_identifier; + string16 database_name; + string16 sqlite_suffix; + EXPECT_EQ(expected_result, + DatabaseUtil::CrackVfsFilePath(ASCIIToUTF16(vfs_file_path), + &origin_identifier, + &database_name, + &sqlite_suffix)); + EXPECT_EQ(ASCIIToUTF16(expected_origin_identifier), origin_identifier); + EXPECT_EQ(ASCIIToUTF16(expected_database_name), database_name); + EXPECT_EQ(ASCIIToUTF16(expected_sqlite_suffix), sqlite_suffix); +} + +namespace webkit_database { + +// Test DatabaseUtil::CrackVfsFilePath on various inputs. +TEST(DatabaseUtilTest, CrackVfsFilePathTest) { + TestVfsFilePath(true, "origin/#", "origin", "", ""); + TestVfsFilePath(true, "origin/#suffix", "origin", "", "suffix"); + TestVfsFilePath(true, "origin/db_name#", "origin", "db_name", ""); + TestVfsFilePath(true, "origin/db_name#suffix", "origin", "db_name", "suffix"); + TestVfsFilePath(false, "origindb_name#"); + TestVfsFilePath(false, "origindb_name#suffix"); + TestVfsFilePath(false, "origin/db_name"); + TestVfsFilePath(false, "origin#db_name/suffix"); + TestVfsFilePath(false, "/db_name#"); + TestVfsFilePath(false, "/db_name#suffix"); +} + +} // namespace webkit_database diff --git a/webkit/database/databases_table.cc b/webkit/database/databases_table.cc index af351d8..c76db8cc 100644 --- a/webkit/database/databases_table.cc +++ b/webkit/database/databases_table.cc @@ -33,6 +33,20 @@ bool DatabasesTable::Init() { "CREATE UNIQUE INDEX unique_index ON Databases (origin, name)")); } +int64 DatabasesTable::GetDatabaseID(const string16& origin_identifier, + const string16& database_name) { + sql::Statement select_statement(db_->GetCachedStatement( + SQL_FROM_HERE, "SELECT id FROM Databases WHERE origin = ? AND name = ?")); + if (select_statement.is_valid() && + select_statement.BindString(0, UTF16ToUTF8(origin_identifier)) && + select_statement.BindString(1, UTF16ToUTF8(database_name)) && + select_statement.Step()) { + return select_statement.ColumnInt64(0); + } + + return -1; +} + bool DatabasesTable::GetDatabaseDetails(const string16& origin_identifier, const string16& database_name, DatabaseDetails* details) { diff --git a/webkit/database/databases_table.h b/webkit/database/databases_table.h index cafff9f..481489f 100644 --- a/webkit/database/databases_table.h +++ b/webkit/database/databases_table.h @@ -29,6 +29,8 @@ class DatabasesTable { explicit DatabasesTable(sql::Connection* db) : db_(db) { } bool Init(); + int64 GetDatabaseID(const string16& origin_identifier, + const string16& database_name); bool GetDatabaseDetails(const string16& origin_identifier, const string16& database_name, DatabaseDetails* details); diff --git a/webkit/database/databases_table_unittest.cc b/webkit/database/databases_table_unittest.cc index 5012cc5..77e9427 100644 --- a/webkit/database/databases_table_unittest.cc +++ b/webkit/database/databases_table_unittest.cc @@ -73,6 +73,8 @@ TEST(DatabasesTableTest, TestIt) { details_in1.origin_identifier, details_in1.database_name, &details_out1)); + EXPECT_EQ(1, databases_table.GetDatabaseID(details_in1.origin_identifier, + details_in1.database_name)); // Check that the details were correctly written to the database. CheckDetailsAreEqual(details_in1, details_out1); @@ -87,6 +89,8 @@ TEST(DatabasesTableTest, TestIt) { details_in2.description = ASCIIToUTF16("description_db2"); details_in2.estimated_size = 200; EXPECT_TRUE(databases_table.InsertDatabaseDetails(details_in2)); + EXPECT_EQ(2, databases_table.GetDatabaseID(details_in2.origin_identifier, + details_in2.database_name)); // Insert details for a third database with a different origin. DatabaseDetails details_in3; @@ -95,6 +99,8 @@ TEST(DatabasesTableTest, TestIt) { details_in3.description = ASCIIToUTF16("description_db3"); details_in3.estimated_size = 300; EXPECT_TRUE(databases_table.InsertDatabaseDetails(details_in3)); + EXPECT_EQ(3, databases_table.GetDatabaseID(details_in3.origin_identifier, + details_in3.database_name)); // There should be no database with origin "origin3". std::vector<DatabaseDetails> details_out_origin3; diff --git a/webkit/database/vfs_backend.cc b/webkit/database/vfs_backend.cc index 96e0b27..2c5467f 100644 --- a/webkit/database/vfs_backend.cc +++ b/webkit/database/vfs_backend.cc @@ -12,21 +12,11 @@ #include "base/file_path.h" #include "base/file_util.h" +#include "base/logging.h" namespace webkit_database { -bool VfsBackend::OpenFileFlagsAreConsistent(const FilePath& file_name, - const FilePath& db_dir, - int desired_flags) { - // Is this a request for a temp file? - // We should be able to delete temp files when they're closed - // and create them as needed - if ((file_name == db_dir) && - (!(desired_flags & SQLITE_OPEN_DELETEONCLOSE) || - !(desired_flags & SQLITE_OPEN_CREATE))) { - return false; - } - +bool VfsBackend::OpenFileFlagsAreConsistent(int desired_flags) { const int file_type = desired_flags & 0x00007F00; const bool is_exclusive = (desired_flags & SQLITE_OPEN_EXCLUSIVE) != 0; const bool is_delete = (desired_flags & SQLITE_OPEN_DELETEONCLOSE) != 0; @@ -64,16 +54,17 @@ bool VfsBackend::OpenFileFlagsAreConsistent(const FilePath& file_name, (file_type == SQLITE_OPEN_TRANSIENT_DB); } -void VfsBackend::OpenFile(const FilePath& file_name, - const FilePath& db_dir, +void VfsBackend::OpenFile(const FilePath& file_path, int desired_flags, base::ProcessHandle handle, base::PlatformFile* target_handle, base::PlatformFile* target_dir_handle) { + DCHECK(!file_path.empty()); + // Verify the flags for consistency and create the database // directory if it doesn't exist. - if (!OpenFileFlagsAreConsistent(file_name, db_dir, desired_flags) || - !file_util::CreateDirectory(db_dir)) + if (!OpenFileFlagsAreConsistent(desired_flags) || + !file_util::CreateDirectory(file_path.DirName())) return; int flags = 0; @@ -99,19 +90,9 @@ void VfsBackend::OpenFile(const FilePath& file_name, base::PLATFORM_FILE_DELETE_ON_CLOSE; } - // If this is a request for a handle to a temp file, get a unique file name. - FilePath db_file_name; - if (file_name == db_dir) { - if (!file_util::CreateTemporaryFileInDir(db_dir, &db_file_name)) - db_file_name = FilePath(); - } else { - db_file_name = file_name; - } - // Try to open/create the DB file. - base::PlatformFile file_handle = (db_file_name.empty() ? - base::kInvalidPlatformFileValue : - base::CreatePlatformFile(db_file_name.ToWStringHack(), flags, NULL)); + base::PlatformFile file_handle = + base::CreatePlatformFile(file_path.ToWStringHack(), flags, NULL); if (file_handle != base::kInvalidPlatformFileValue) { #if defined(OS_WIN) // Duplicate the file handle. @@ -132,7 +113,7 @@ void VfsBackend::OpenFile(const FilePath& file_name, // systems the VFS might want to fsync it after changing a file. // By returning it here, we avoid an extra IPC call. *target_dir_handle = base::CreatePlatformFile( - db_dir.ToWStringHack(), + file_path.DirName().ToWStringHack(), base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, NULL); if (*target_dir_handle == base::kInvalidPlatformFileValue) { base::ClosePlatformFile(*target_handle); @@ -143,19 +124,39 @@ void VfsBackend::OpenFile(const FilePath& file_name, } } -int VfsBackend::DeleteFile(const FilePath& file_name, - const FilePath& db_dir, - bool sync_dir) { - if (!file_util::PathExists(file_name)) +void VfsBackend::OpenTempFileInDirectory( + const FilePath& dir_path, + int desired_flags, + base::ProcessHandle handle, + base::PlatformFile* target_handle, + base::PlatformFile* target_dir_handle) { + // We should be able to delete temp files when they're closed + // and create them as needed + if (!(desired_flags & SQLITE_OPEN_DELETEONCLOSE) || + !(desired_flags & SQLITE_OPEN_CREATE)) { + return; + } + + // Get a unique temp file name in the database directory. + FilePath temp_file_path; + if (!file_util::CreateTemporaryFileInDir(dir_path, &temp_file_path)) + return; + + OpenFile(temp_file_path, desired_flags, handle, + target_handle, target_dir_handle); +} + +int VfsBackend::DeleteFile(const FilePath& file_path, bool sync_dir) { + if (!file_util::PathExists(file_path)) return SQLITE_OK; - if (!file_util::Delete(file_name, false)) + if (!file_util::Delete(file_path, false)) return SQLITE_IOERR_DELETE; int error_code = SQLITE_OK; #if defined(OS_POSIX) if (sync_dir) { base::PlatformFile dir_fd = base::CreatePlatformFile( - db_dir.ToWStringHack(), base::PLATFORM_FILE_READ, NULL); + file_path.DirName().ToWStringHack(), base::PLATFORM_FILE_READ, NULL); if (dir_fd == base::kInvalidPlatformFileValue) { error_code = SQLITE_CANTOPEN; } else { @@ -168,14 +169,14 @@ int VfsBackend::DeleteFile(const FilePath& file_name, return error_code; } -uint32 VfsBackend::GetFileAttributes(const FilePath& file_name) { +uint32 VfsBackend::GetFileAttributes(const FilePath& file_path) { #if defined(OS_WIN) - uint32 attributes = ::GetFileAttributes(file_name.value().c_str()); + uint32 attributes = ::GetFileAttributes(file_path.value().c_str()); #elif defined(OS_POSIX) uint32 attributes = 0; - if (!access(file_name.value().c_str(), R_OK)) + if (!access(file_path.value().c_str(), R_OK)) attributes |= static_cast<uint32>(R_OK); - if (!access(file_name.value().c_str(), W_OK)) + if (!access(file_path.value().c_str(), W_OK)) attributes |= static_cast<uint32>(W_OK); if (!attributes) attributes = -1; @@ -183,9 +184,9 @@ uint32 VfsBackend::GetFileAttributes(const FilePath& file_name) { return attributes; } -int64 VfsBackend::GetFileSize(const FilePath& file_name) { +int64 VfsBackend::GetFileSize(const FilePath& file_path) { int64 size = 0; - return (file_util::GetFileSize(file_name, &size) ? size : 0); + return (file_util::GetFileSize(file_path, &size) ? size : 0); } } // namespace webkit_database diff --git a/webkit/database/vfs_backend.h b/webkit/database/vfs_backend.h index d57e9e2..44de808 100644 --- a/webkit/database/vfs_backend.h +++ b/webkit/database/vfs_backend.h @@ -7,6 +7,7 @@ #include "base/platform_file.h" #include "base/process.h" +#include "base/string16.h" class FilePath; @@ -14,25 +15,25 @@ namespace webkit_database { class VfsBackend { public: - static void OpenFile(const FilePath& file_name, - const FilePath& db_dir, + static void OpenFile(const FilePath& file_path, int desired_flags, base::ProcessHandle handle, base::PlatformFile* target_handle, base::PlatformFile* target_dir_handle); + static void OpenTempFileInDirectory(const FilePath& dir_path, + int desired_flags, + base::ProcessHandle handle, + base::PlatformFile* target_handle, + base::PlatformFile* target_dir_handle); - static int DeleteFile(const FilePath& file_name, - const FilePath& db_dir, - bool sync_dir); + static int DeleteFile(const FilePath& file_path, bool sync_dir); - static uint32 GetFileAttributes(const FilePath& file_name); + static uint32 GetFileAttributes(const FilePath& file_path); - static int64 GetFileSize(const FilePath& file_name); + static int64 GetFileSize(const FilePath& file_path); private: - static bool OpenFileFlagsAreConsistent(const FilePath& file_name, - const FilePath& db_dir, - int desired_flags); + static bool OpenFileFlagsAreConsistent(int desired_flags); }; } // namespace webkit_database diff --git a/webkit/tools/test_shell/simple_database_system.cc b/webkit/tools/test_shell/simple_database_system.cc index ab98e1a..dd0d032 100644 --- a/webkit/tools/test_shell/simple_database_system.cc +++ b/webkit/tools/test_shell/simple_database_system.cc @@ -41,9 +41,15 @@ base::PlatformFile SimpleDatabaseSystem::OpenFile( const FilePath& file_name, int desired_flags, base::PlatformFile* dir_handle) { base::PlatformFile file_handle = base::kInvalidPlatformFileValue; - VfsBackend::OpenFile(GetDBFileFullPath(file_name), GetDBDir(), desired_flags, - base::GetCurrentProcessHandle(), &file_handle, - dir_handle); + if (file_name.empty()) { + VfsBackend::OpenTempFileInDirectory( + GetDBDir(), desired_flags, base::GetCurrentProcessHandle(), + &file_handle, dir_handle); + } else { + VfsBackend::OpenFile(GetDBFileFullPath(file_name), desired_flags, + base::GetCurrentProcessHandle(), &file_handle, + dir_handle); + } // HACK: Currently, the DB object that keeps track of the main database // (DatabaseTracker) is a singleton that is declared as a static variable @@ -75,7 +81,7 @@ int SimpleDatabaseSystem::DeleteFile( int error_code = SQLITE_OK; do { error_code = VfsBackend::DeleteFile( - GetDBFileFullPath(file_name), GetDBDir(), sync_dir); + GetDBFileFullPath(file_name), sync_dir); } while ((++num_retries < kNumDeleteRetries) && (error_code == SQLITE_IOERR_DELETE) && (PlatformThread::Sleep(10), 1)); diff --git a/webkit/tools/test_shell/test_shell.gyp b/webkit/tools/test_shell/test_shell.gyp index 313008a..878789c 100644 --- a/webkit/tools/test_shell/test_shell.gyp +++ b/webkit/tools/test_shell/test_shell.gyp @@ -378,6 +378,7 @@ '../../appcache/mock_appcache_storage_unittest.cc', '../../database/databases_table_unittest.cc', '../../database/database_tracker_unittest.cc', + '../../database/database_util_unittest.cc', '../../glue/bookmarklet_unittest.cc', '../../glue/context_menu_unittest.cc', '../../glue/cpp_bound_class_unittest.cc', diff --git a/webkit/webkit_glue.gyp b/webkit/webkit_glue.gyp index f823dfd..972d734 100644 --- a/webkit/webkit_glue.gyp +++ b/webkit/webkit_glue.gyp @@ -193,6 +193,8 @@ 'database/databases_table.h', 'database/database_tracker.cc', 'database/database_tracker.h', + 'database/database_util.cc', + 'database/database_util.h', 'database/vfs_backend.cc', 'database/vfs_backend.h', ], |