summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-13 01:30:45 +0000
committerdumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-13 01:30:45 +0000
commit3c5ed2c5747de75351c18fbf1e969eccc263d1d5 (patch)
tree75ba30df50a1f0bd4ecd90d51051b3bb057c2a51
parentdad1e3bc1d2894be09c2a5bcb98708044aa1664d (diff)
downloadchromium_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.cc94
-rw-r--r--chrome/browser/renderer_host/database_dispatcher_host.h8
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc4
-rw-r--r--webkit/database/database_tracker.cc12
-rw-r--r--webkit/database/database_tracker_unittest.cc17
-rw-r--r--webkit/database/database_util.cc58
-rw-r--r--webkit/database/database_util.h28
-rw-r--r--webkit/database/database_util_unittest.cc45
-rw-r--r--webkit/database/databases_table.cc14
-rw-r--r--webkit/database/databases_table.h2
-rw-r--r--webkit/database/databases_table_unittest.cc6
-rw-r--r--webkit/database/vfs_backend.cc83
-rw-r--r--webkit/database/vfs_backend.h21
-rw-r--r--webkit/tools/test_shell/simple_database_system.cc14
-rw-r--r--webkit/tools/test_shell/test_shell.gyp1
-rw-r--r--webkit/webkit_glue.gyp2
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',
],