summaryrefslogtreecommitdiffstats
path: root/webkit/database
diff options
context:
space:
mode:
authordumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-22 20:41:20 +0000
committerdumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-22 20:41:20 +0000
commitda34ae09d568bf23b586b49f9ee13d730a3d71c9 (patch)
tree51177ece300917952d5a1d3c1a32ece5fe70aa0e /webkit/database
parent35eea2e6ac7a392b22efe089c7c2675be4142237 (diff)
downloadchromium_src-da34ae09d568bf23b586b49f9ee13d730a3d71c9.zip
chromium_src-da34ae09d568bf23b586b49f9ee13d730a3d71c9.tar.gz
chromium_src-da34ae09d568bf23b586b49f9ee13d730a3d71c9.tar.bz2
Refactor the DB code to make it accessible from test_shell.
BUG=21442 TEST=none Review URL: http://codereview.chromium.org/203074 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26855 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/database')
-rw-r--r--webkit/database/vfs_backend.cc210
-rw-r--r--webkit/database/vfs_backend.h33
2 files changed, 243 insertions, 0 deletions
diff --git a/webkit/database/vfs_backend.cc b/webkit/database/vfs_backend.cc
new file mode 100644
index 0000000..cc06215
--- /dev/null
+++ b/webkit/database/vfs_backend.cc
@@ -0,0 +1,210 @@
+// 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/vfs_backend.h"
+
+#if defined(USE_SYSTEM_SQLITE)
+#include <sqlite3.h>
+#else
+#include "third_party/sqlite/preprocessed/sqlite3.h"
+#endif
+
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/process.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;
+ }
+
+ 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;
+ const bool is_create = (desired_flags & SQLITE_OPEN_CREATE) != 0;
+ const bool is_read_only = (desired_flags & SQLITE_OPEN_READONLY) != 0;
+ const bool is_read_write = (desired_flags & SQLITE_OPEN_READWRITE) != 0;
+
+ // All files should be opened either read-write or read-only.
+ if (!(is_read_only ^ is_read_write)) {
+ return false;
+ }
+
+ // If a new file is created, it must also be writtable.
+ if (is_create && !is_read_write) {
+ return false;
+ }
+
+ // We must be able to create a new file, if exclusive access is desired.
+ if (is_exclusive && !is_create) {
+ return false;
+ }
+
+ // We cannot delete the files that we expect to already exist.
+ if (is_delete && !is_create) {
+ return false;
+ }
+
+ // The main DB, main journal and master journal cannot be auto-deleted.
+ if (((file_type == SQLITE_OPEN_MAIN_DB) ||
+ (file_type == SQLITE_OPEN_MAIN_JOURNAL) ||
+ (file_type == SQLITE_OPEN_MASTER_JOURNAL)) &&
+ is_delete) {
+ return false;
+ }
+
+ // Make sure we're opening the DB directory or that a file type is set.
+ if ((file_type != SQLITE_OPEN_MAIN_DB) &&
+ (file_type != SQLITE_OPEN_TEMP_DB) &&
+ (file_type != SQLITE_OPEN_MAIN_JOURNAL) &&
+ (file_type != SQLITE_OPEN_TEMP_JOURNAL) &&
+ (file_type != SQLITE_OPEN_SUBJOURNAL) &&
+ (file_type != SQLITE_OPEN_MASTER_JOURNAL) &&
+ (file_type != SQLITE_OPEN_TRANSIENT_DB)) {
+ return false;
+ }
+
+ return true;
+}
+
+void VfsBackend::OpenFile(
+ const FilePath& file_name, const FilePath& db_dir, int desired_flags,
+ base::ProcessHandle handle, base::PlatformFile* target_handle,
+ base::PlatformFile* target_dir_handle) {
+ // 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)) {
+ int flags = 0;
+ flags |= base::PLATFORM_FILE_READ;
+ if (desired_flags & SQLITE_OPEN_READWRITE) {
+ flags |= base::PLATFORM_FILE_WRITE;
+ }
+
+ if (!(desired_flags & SQLITE_OPEN_MAIN_DB)) {
+ flags |= base::PLATFORM_FILE_EXCLUSIVE_READ |
+ base::PLATFORM_FILE_EXCLUSIVE_WRITE;
+ }
+
+ if (desired_flags & SQLITE_OPEN_CREATE) {
+ flags |= base::PLATFORM_FILE_OPEN_ALWAYS;
+ } else {
+ flags |= base::PLATFORM_FILE_OPEN;
+ }
+
+ if (desired_flags & SQLITE_OPEN_EXCLUSIVE) {
+ flags |= base::PLATFORM_FILE_EXCLUSIVE_READ |
+ base::PLATFORM_FILE_EXCLUSIVE_WRITE;
+ }
+
+ if (desired_flags & SQLITE_OPEN_DELETEONCLOSE) {
+ flags |= base::PLATFORM_FILE_TEMPORARY | base::PLATFORM_FILE_HIDDEN |
+ 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));
+ if (file_handle != base::kInvalidPlatformFileValue) {
+#if defined(OS_WIN)
+ // Duplicate the file handle.
+ if (!DuplicateHandle(GetCurrentProcess(), file_handle,
+ handle, target_handle, 0, false,
+ DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
+ // file_handle is closed whether or not DuplicateHandle succeeds.
+ *target_handle = INVALID_HANDLE_VALUE;
+ }
+#elif defined(OS_POSIX)
+ *target_handle = file_handle;
+
+ int file_type = desired_flags & 0x00007F00;
+ bool creating_new_file = (desired_flags & SQLITE_OPEN_CREATE);
+ if (creating_new_file && ((file_type == SQLITE_OPEN_MASTER_JOURNAL) ||
+ (file_type == SQLITE_OPEN_MAIN_JOURNAL))) {
+ // We return a handle to the containing directory because on POSIX
+ // 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(),
+ base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, NULL);
+ if (*target_dir_handle == base::kInvalidPlatformFileValue) {
+ base::ClosePlatformFile(*target_handle);
+ *target_handle = base::kInvalidPlatformFileValue;
+ }
+ }
+#endif
+ }
+ }
+}
+
+int VfsBackend::DeleteFile(
+ const FilePath& file_name, const FilePath& db_dir, bool sync_dir) {
+ if (!file_util::PathExists(file_name)) {
+ return SQLITE_OK;
+ }
+ if (!file_util::Delete(file_name, 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);
+ if (dir_fd == base::kInvalidPlatformFileValue) {
+ error_code = SQLITE_CANTOPEN;
+ } else {
+ if (fsync(dir_fd)) {
+ error_code = SQLITE_IOERR_DIR_FSYNC;
+ }
+ base::ClosePlatformFile(dir_fd);
+ }
+ }
+#endif
+ return error_code;
+}
+
+uint32 VfsBackend::GetFileAttributes(const FilePath& file_name) {
+#if defined(OS_WIN)
+ uint32 attributes = ::GetFileAttributes(file_name.value().c_str());
+#elif defined(OS_POSIX)
+ uint32 attributes = 0;
+ if (!access(file_name.value().c_str(), R_OK)) {
+ attributes |= static_cast<uint32>(R_OK);
+ }
+ if (!access(file_name.value().c_str(), W_OK)) {
+ attributes |= static_cast<uint32>(W_OK);
+ }
+ if (!attributes) {
+ attributes = -1;
+ }
+#endif
+ return attributes;
+}
+
+int64 VfsBackend::GetFileSize(const FilePath& file_name) {
+ int64 size = 0;
+ return (file_util::GetFileSize(file_name, &size) ? size : 0);
+}
+
+} // namespace database
diff --git a/webkit/database/vfs_backend.h b/webkit/database/vfs_backend.h
new file mode 100644
index 0000000..536ffd8
--- /dev/null
+++ b/webkit/database/vfs_backend.h
@@ -0,0 +1,33 @@
+// 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_VFS_BACKEND_H_
+#define WEBKIT_DATABASE_VFS_BACKEND_H_
+
+#include "base/platform_file.h"
+#include "base/process.h"
+
+class FilePath;
+
+namespace webkit_database {
+
+class VfsBackend {
+ public:
+ static void OpenFile(
+ const FilePath& file_name, const FilePath& db_dir, 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 uint32 GetFileAttributes(const FilePath& file_name);
+ static int64 GetFileSize(const FilePath& file_name);
+
+ private:
+ static bool OpenFileFlagsAreConsistent(
+ const FilePath& file_name, const FilePath& db_dir, int desired_flags);
+};
+
+} // namespace webkit_database
+
+#endif // WEBKIT_DATABASE_VFS_BACKEND_H_