summaryrefslogtreecommitdiffstats
path: root/WebCore/storage
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-02-02 14:57:50 +0000
committerSteve Block <steveblock@google.com>2010-02-04 15:06:55 +0000
commitd0825bca7fe65beaee391d30da42e937db621564 (patch)
tree7461c49eb5844ffd1f35d1ba2c8b7584c1620823 /WebCore/storage
parent3db770bd97c5a59b6c7574ca80a39e5a51c1defd (diff)
downloadexternal_webkit-d0825bca7fe65beaee391d30da42e937db621564.zip
external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.gz
external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.bz2
Merge webkit.org at r54127 : Initial merge by git
Change-Id: Ib661abb595522f50ea406f72d3a0ce17f7193c82
Diffstat (limited to 'WebCore/storage')
-rw-r--r--WebCore/storage/Database.cpp247
-rw-r--r--WebCore/storage/Database.h16
-rw-r--r--WebCore/storage/Database.idl3
-rw-r--r--WebCore/storage/DatabaseAuthorizer.cpp72
-rw-r--r--WebCore/storage/DatabaseAuthorizer.h5
-rw-r--r--WebCore/storage/DatabaseTask.h3
-rw-r--r--WebCore/storage/DatabaseThread.cpp12
-rw-r--r--WebCore/storage/DatabaseThread.h4
-rw-r--r--WebCore/storage/DatabaseTracker.cpp16
-rw-r--r--WebCore/storage/DatabaseTracker.h8
-rw-r--r--WebCore/storage/IDBDatabaseError.h64
-rw-r--r--WebCore/storage/IDBDatabaseError.idl37
-rw-r--r--WebCore/storage/IDBDatabaseException.h64
-rw-r--r--WebCore/storage/IDBDatabaseException.idl48
-rw-r--r--WebCore/storage/IDBRequest.cpp64
-rw-r--r--WebCore/storage/IDBRequest.h88
-rw-r--r--WebCore/storage/IDBRequest.idl45
-rw-r--r--WebCore/storage/IndexedDatabaseRequest.cpp53
-rw-r--r--WebCore/storage/IndexedDatabaseRequest.h65
-rw-r--r--WebCore/storage/IndexedDatabaseRequest.idl38
-rw-r--r--WebCore/storage/SQLError.idl3
-rw-r--r--WebCore/storage/SQLResultSet.idl3
-rw-r--r--WebCore/storage/SQLResultSetRowList.idl3
-rw-r--r--WebCore/storage/SQLTransaction.cpp5
-rw-r--r--WebCore/storage/SQLTransaction.idl3
-rw-r--r--WebCore/storage/SQLTransactionClient.cpp15
-rw-r--r--WebCore/storage/SQLTransactionClient.h4
-rw-r--r--WebCore/storage/SQLTransactionCoordinator.cpp6
-rw-r--r--WebCore/storage/SQLTransactionCoordinator.h4
-rw-r--r--WebCore/storage/Storage.idl1
-rw-r--r--WebCore/storage/StorageArea.h6
-rw-r--r--WebCore/storage/StorageAreaImpl.cpp23
-rw-r--r--WebCore/storage/StorageAreaImpl.h6
-rw-r--r--WebCore/storage/StorageEvent.cpp2
-rw-r--r--WebCore/storage/StorageEvent.idl3
-rw-r--r--WebCore/storage/StorageEventDispatcher.cpp8
-rw-r--r--WebCore/storage/StorageMap.cpp1
-rw-r--r--WebCore/storage/StorageNamespace.cpp3
-rw-r--r--WebCore/storage/StorageNamespace.h31
-rw-r--r--WebCore/storage/chromium/DatabaseTrackerChromium.cpp40
-rw-r--r--WebCore/storage/chromium/SQLTransactionClientChromium.cpp38
41 files changed, 973 insertions, 187 deletions
diff --git a/WebCore/storage/Database.cpp b/WebCore/storage/Database.cpp
index 29dec26..648492f 100644
--- a/WebCore/storage/Database.cpp
+++ b/WebCore/storage/Database.cpp
@@ -53,8 +53,8 @@
#include "SQLResultSet.h"
#include "SQLTransactionClient.h"
#include "SQLTransactionCoordinator.h"
-#include <wtf/MainThread.h>
-#endif
+
+#endif // ENABLE(DATABASE)
#if USE(JSC)
#include "JSDOMWindow.h"
@@ -73,6 +73,18 @@ const String& Database::databaseInfoTableName()
#if ENABLE(DATABASE)
+static bool isDatabaseAvailable = false;
+
+void Database::setIsAvailable(bool available)
+{
+ isDatabaseAvailable = available;
+}
+
+bool Database::isAvailable()
+{
+ return isDatabaseAvailable;
+}
+
static Mutex& guidMutex()
{
// Note: We don't have to use AtomicallyInitializedStatic here because
@@ -120,37 +132,41 @@ static const String& databaseVersionKey()
static int guidForOriginAndName(const String& origin, const String& name);
-PassRefPtr<Database> Database::openDatabase(Document* document, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, ExceptionCode& e)
+PassRefPtr<Database> Database::openDatabase(ScriptExecutionContext* context, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, ExceptionCode& e)
{
- if (!DatabaseTracker::tracker().canEstablishDatabase(document, name, displayName, estimatedSize)) {
+ if (!DatabaseTracker::tracker().canEstablishDatabase(context, name, displayName, estimatedSize)) {
// FIXME: There should be an exception raised here in addition to returning a null Database object. The question has been raised with the WHATWG.
- LOG(StorageAPI, "Database %s for origin %s not allowed to be established", name.ascii().data(), document->securityOrigin()->toString().ascii().data());
+ LOG(StorageAPI, "Database %s for origin %s not allowed to be established", name.ascii().data(), context->securityOrigin()->toString().ascii().data());
return 0;
}
- RefPtr<Database> database = adoptRef(new Database(document, name, expectedVersion, displayName, estimatedSize));
+ RefPtr<Database> database = adoptRef(new Database(context, name, expectedVersion, displayName, estimatedSize));
if (!database->openAndVerifyVersion(e)) {
- LOG(StorageAPI, "Failed to open and verify version (expected %s) of database %s", expectedVersion.ascii().data(), database->databaseDebugName().ascii().data());
- return 0;
+ LOG(StorageAPI, "Failed to open and verify version (expected %s) of database %s", expectedVersion.ascii().data(), database->databaseDebugName().ascii().data());
+ context->removeOpenDatabase(database.get());
+ DatabaseTracker::tracker().removeOpenDatabase(database.get());
+ return 0;
}
- DatabaseTracker::tracker().setDatabaseDetails(document->securityOrigin(), name, displayName, estimatedSize);
-
- document->setHasOpenDatabases();
+ DatabaseTracker::tracker().setDatabaseDetails(context->securityOrigin(), name, displayName, estimatedSize);
+ context->setHasOpenDatabases();
#if ENABLE(INSPECTOR)
- if (Page* page = document->frame()->page())
- page->inspectorController()->didOpenDatabase(database.get(), document->securityOrigin()->host(), name, expectedVersion);
+ if (context->isDocument()) {
+ Document* document = static_cast<Document*>(context);
+ if (Page* page = document->page())
+ page->inspectorController()->didOpenDatabase(database.get(), context->securityOrigin()->host(), name, expectedVersion);
+ }
#endif
return database;
}
-Database::Database(Document* document, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize)
+Database::Database(ScriptExecutionContext* context, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize)
: m_transactionInProgress(false)
, m_isTransactionQueueEnabled(true)
- , m_document(document)
+ , m_scriptExecutionContext(context)
, m_name(name.crossThreadString())
, m_guid(0)
, m_expectedVersion(expectedVersion.crossThreadString())
@@ -160,16 +176,15 @@ Database::Database(Document* document, const String& name, const String& expecte
, m_stopped(false)
, m_opened(false)
{
- ASSERT(document);
- m_mainThreadSecurityOrigin = document->securityOrigin();
+ ASSERT(m_scriptExecutionContext.get());
+ m_mainThreadSecurityOrigin = m_scriptExecutionContext->securityOrigin();
m_databaseThreadSecurityOrigin = m_mainThreadSecurityOrigin->threadsafeCopy();
-
if (m_name.isNull())
m_name = "";
ScriptController::initializeThreading();
- m_guid = guidForOriginAndName(m_mainThreadSecurityOrigin->toString(), name);
+ m_guid = guidForOriginAndName(securityOrigin()->toString(), name);
{
MutexLocker locker(guidMutex());
@@ -183,34 +198,40 @@ Database::Database(Document* document, const String& name, const String& expecte
hashSet->add(this);
}
- ASSERT(m_document->databaseThread());
-
- m_filename = DatabaseTracker::tracker().fullPathForDatabase(m_mainThreadSecurityOrigin.get(), m_name);
+ ASSERT(m_scriptExecutionContext->databaseThread());
+ m_filename = DatabaseTracker::tracker().fullPathForDatabase(securityOrigin(), m_name);
DatabaseTracker::tracker().addOpenDatabase(this);
- m_document->addOpenDatabase(this);
+ context->addOpenDatabase(this);
}
-static void derefDocument(void* document)
-{
- static_cast<Document*>(document)->deref();
-}
+class DerefContextTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<DerefContextTask> create()
+ {
+ return new DerefContextTask();
+ }
-Database::~Database()
-{
- if (m_document->databaseThread())
- m_document->databaseThread()->unscheduleDatabaseTasks(this);
+ virtual void performTask(ScriptExecutionContext* context)
+ {
+ context->deref();
+ }
- DatabaseTracker::tracker().removeOpenDatabase(this);
- m_document->removeOpenDatabase(this);
+ virtual bool isCleanupTask() const { return true; }
+};
- // Deref m_document on the main thread.
- callOnMainThread(derefDocument, m_document.release().releaseRef());
+Database::~Database()
+{
+ // The reference to the ScriptExecutionContext needs to be cleared on the JavaScript thread. If we're on that thread already, we can just let the RefPtr's destruction do the dereffing.
+ if (!m_scriptExecutionContext->isContextThread()) {
+ m_scriptExecutionContext->postTask(DerefContextTask::create());
+ m_scriptExecutionContext.release().releaseRef();
+ }
}
bool Database::openAndVerifyVersion(ExceptionCode& e)
{
- if (!m_document->databaseThread())
+ if (!m_scriptExecutionContext->databaseThread())
return false;
m_databaseAuthorizer = DatabaseAuthorizer::create();
@@ -218,7 +239,7 @@ bool Database::openAndVerifyVersion(ExceptionCode& e)
DatabaseTaskSynchronizer synchronizer;
OwnPtr<DatabaseOpenTask> task = DatabaseOpenTask::create(this, &synchronizer, e, success);
- m_document->databaseThread()->scheduleImmediateTask(task.release());
+ m_scriptExecutionContext->databaseThread()->scheduleImmediateTask(task.release());
synchronizer.waitForTaskCompletion();
return success;
@@ -313,49 +334,80 @@ bool Database::versionMatchesExpected() const
void Database::markAsDeletedAndClose()
{
- if (m_deleted || !m_document->databaseThread())
+ if (m_deleted || !m_scriptExecutionContext->databaseThread())
return;
LOG(StorageAPI, "Marking %s (%p) as deleted", stringIdentifier().ascii().data(), this);
m_deleted = true;
- if (m_document->databaseThread()->terminationRequested()) {
+ if (m_scriptExecutionContext->databaseThread()->terminationRequested()) {
LOG(StorageAPI, "Database handle %p is on a terminated DatabaseThread, cannot be marked for normal closure\n", this);
return;
}
- m_document->databaseThread()->unscheduleDatabaseTasks(this);
+ m_scriptExecutionContext->databaseThread()->unscheduleDatabaseTasks(this);
DatabaseTaskSynchronizer synchronizer;
OwnPtr<DatabaseCloseTask> task = DatabaseCloseTask::create(this, &synchronizer);
- m_document->databaseThread()->scheduleImmediateTask(task.release());
+ m_scriptExecutionContext->databaseThread()->scheduleImmediateTask(task.release());
synchronizer.waitForTaskCompletion();
}
+class ContextRemoveOpenDatabaseTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<ContextRemoveOpenDatabaseTask> create(PassRefPtr<Database> database)
+ {
+ return new ContextRemoveOpenDatabaseTask(database);
+ }
+
+ virtual void performTask(ScriptExecutionContext* context)
+ {
+ context->removeOpenDatabase(m_database.get());
+ DatabaseTracker::tracker().removeOpenDatabase(m_database.get());
+ }
+
+ virtual bool isCleanupTask() const { return true; }
+
+private:
+ ContextRemoveOpenDatabaseTask(PassRefPtr<Database> database)
+ : m_database(database)
+ {
+ }
+
+ RefPtr<Database> m_database;
+};
+
void Database::close()
{
- if (m_opened) {
- ASSERT(m_document->databaseThread());
- ASSERT(currentThread() == document()->databaseThread()->getThreadID());
- m_sqliteDatabase.close();
- m_document->databaseThread()->recordDatabaseClosed(this);
- m_opened = false;
-
- {
- MutexLocker locker(guidMutex());
-
- HashSet<Database*>* hashSet = guidToDatabaseMap().get(m_guid);
- ASSERT(hashSet);
- ASSERT(hashSet->contains(this));
- hashSet->remove(this);
- if (hashSet->isEmpty()) {
- guidToDatabaseMap().remove(m_guid);
- delete hashSet;
- guidToVersionMap().remove(m_guid);
- }
+ RefPtr<Database> protect = this;
+
+ if (!m_opened)
+ return;
+
+ ASSERT(m_scriptExecutionContext->databaseThread());
+ ASSERT(currentThread() == m_scriptExecutionContext->databaseThread()->getThreadID());
+ m_sqliteDatabase.close();
+ // Must ref() before calling databaseThread()->recordDatabaseClosed().
+ m_scriptExecutionContext->databaseThread()->recordDatabaseClosed(this);
+ m_opened = false;
+
+ {
+ MutexLocker locker(guidMutex());
+
+ HashSet<Database*>* hashSet = guidToDatabaseMap().get(m_guid);
+ ASSERT(hashSet);
+ ASSERT(hashSet->contains(this));
+ hashSet->remove(this);
+ if (hashSet->isEmpty()) {
+ guidToDatabaseMap().remove(m_guid);
+ delete hashSet;
+ guidToVersionMap().remove(m_guid);
}
}
+
+ m_scriptExecutionContext->databaseThread()->unscheduleDatabaseTasks(this);
+ m_scriptExecutionContext->postTask(ContextRemoveOpenDatabaseTask::create(this));
}
void Database::stop()
@@ -451,10 +503,6 @@ bool Database::performOpenAndVerify(ExceptionCode& e)
return false;
}
- m_opened = true;
- if (m_document->databaseThread())
- m_document->databaseThread()->recordDatabaseOpen(this);
-
ASSERT(m_databaseAuthorizer);
m_sqliteDatabase.setAuthorizer(m_databaseAuthorizer);
m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime);
@@ -475,6 +523,8 @@ bool Database::performOpenAndVerify(ExceptionCode& e)
if (!m_sqliteDatabase.executeCommand("CREATE TABLE " + databaseInfoTableName() + " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) {
LOG_ERROR("Unable to create table %s in database %s", databaseInfoTableName().ascii().data(), databaseDebugName().ascii().data());
e = INVALID_STATE_ERR;
+ // Close the handle to the database file.
+ m_sqliteDatabase.close();
return false;
}
}
@@ -482,6 +532,8 @@ bool Database::performOpenAndVerify(ExceptionCode& e)
if (!getVersionFromDatabase(currentVersion)) {
LOG_ERROR("Failed to get current version from database %s", databaseDebugName().ascii().data());
e = INVALID_STATE_ERR;
+ // Close the handle to the database file.
+ m_sqliteDatabase.close();
return false;
}
if (currentVersion.length()) {
@@ -491,6 +543,8 @@ bool Database::performOpenAndVerify(ExceptionCode& e)
if (!setVersionInDatabase(m_expectedVersion)) {
LOG_ERROR("Failed to set version %s in database %s", m_expectedVersion.ascii().data(), databaseDebugName().ascii().data());
e = INVALID_STATE_ERR;
+ // Close the handle to the database file.
+ m_sqliteDatabase.close();
return false;
}
currentVersion = m_expectedVersion;
@@ -511,9 +565,17 @@ bool Database::performOpenAndVerify(ExceptionCode& e)
LOG(StorageAPI, "page expects version %s from database %s, which actually has version name %s - openDatabase() call will fail", m_expectedVersion.ascii().data(),
databaseDebugName().ascii().data(), currentVersion.ascii().data());
e = INVALID_STATE_ERR;
+ // Close the handle to the database file.
+ m_sqliteDatabase.close();
return false;
}
+ // All checks passed and we still have a handle to this database file.
+ // Make sure DatabaseThread closes it when DatabaseThread goes away.
+ m_opened = true;
+ if (m_scriptExecutionContext->databaseThread())
+ m_scriptExecutionContext->databaseThread()->recordDatabaseOpen(this);
+
return true;
}
@@ -546,32 +608,52 @@ void Database::scheduleTransaction()
m_transactionQueue.removeFirst();
}
- if (transaction && m_document->databaseThread()) {
+ if (transaction && m_scriptExecutionContext->databaseThread()) {
OwnPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction);
LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for transaction %p\n", task.get(), task->transaction());
m_transactionInProgress = true;
- m_document->databaseThread()->scheduleTask(task.release());
+ m_scriptExecutionContext->databaseThread()->scheduleTask(task.release());
} else
m_transactionInProgress = false;
}
void Database::scheduleTransactionStep(SQLTransaction* transaction, bool immediately)
{
- if (!m_document->databaseThread())
+ if (!m_scriptExecutionContext->databaseThread())
return;
OwnPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction);
LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for the transaction step\n", task.get());
if (immediately)
- m_document->databaseThread()->scheduleImmediateTask(task.release());
+ m_scriptExecutionContext->databaseThread()->scheduleImmediateTask(task.release());
else
- m_document->databaseThread()->scheduleTask(task.release());
+ m_scriptExecutionContext->databaseThread()->scheduleTask(task.release());
}
+class DeliverPendingCallbackTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<DeliverPendingCallbackTask> create(PassRefPtr<SQLTransaction> transaction)
+ {
+ return new DeliverPendingCallbackTask(transaction);
+ }
+
+ virtual void performTask(ScriptExecutionContext*)
+ {
+ m_transaction->performPendingCallback();
+ }
+
+private:
+ DeliverPendingCallbackTask(PassRefPtr<SQLTransaction> transaction)
+ : m_transaction(transaction)
+ {
+ }
+
+ RefPtr<SQLTransaction> m_transaction;
+};
+
void Database::scheduleTransactionCallback(SQLTransaction* transaction)
{
- transaction->ref();
- callOnMainThread(deliverPendingCallback, transaction);
+ m_scriptExecutionContext->postTask(DeliverPendingCallbackTask::create(transaction));
}
Vector<String> Database::performGetTableNames()
@@ -605,12 +687,12 @@ Vector<String> Database::performGetTableNames()
SQLTransactionClient* Database::transactionClient() const
{
- return m_document->databaseThread()->transactionClient();
+ return m_scriptExecutionContext->databaseThread()->transactionClient();
}
SQLTransactionCoordinator* Database::transactionCoordinator() const
{
- return m_document->databaseThread()->transactionCoordinator();
+ return m_scriptExecutionContext->databaseThread()->transactionCoordinator();
}
String Database::version() const
@@ -621,25 +703,18 @@ String Database::version() const
return guidToVersionMap().get(m_guid).threadsafeCopy();
}
-void Database::deliverPendingCallback(void* context)
-{
- SQLTransaction* transaction = static_cast<SQLTransaction*>(context);
- transaction->performPendingCallback();
- transaction->deref(); // Was ref'd in scheduleTransactionCallback().
-}
-
Vector<String> Database::tableNames()
{
// FIXME: Not using threadsafeCopy on these strings looks ok since threads take strict turns
// in dealing with them. However, if the code changes, this may not be true anymore.
Vector<String> result;
- if (!m_document->databaseThread())
+ if (!m_scriptExecutionContext->databaseThread())
return result;
DatabaseTaskSynchronizer synchronizer;
OwnPtr<DatabaseTableNamesTask> task = DatabaseTableNamesTask::create(this, &synchronizer, result);
- m_document->databaseThread()->scheduleImmediateTask(task.release());
+ m_scriptExecutionContext->databaseThread()->scheduleImmediateTask(task.release());
synchronizer.waitForTaskCompletion();
return result;
@@ -655,9 +730,9 @@ void Database::setExpectedVersion(const String& version)
SecurityOrigin* Database::securityOrigin() const
{
- if (isMainThread())
+ if (scriptExecutionContext()->isContextThread())
return m_mainThreadSecurityOrigin.get();
- if (currentThread() == document()->databaseThread()->getThreadID())
+ if (currentThread() == m_scriptExecutionContext->databaseThread()->getThreadID())
return m_databaseThreadSecurityOrigin.get();
return 0;
}
@@ -685,6 +760,6 @@ String Database::fileName() const
return m_filename.threadsafeCopy();
}
-#endif
+#endif // ENABLE(DATABASE)
-}
+} // namespace WebCore
diff --git a/WebCore/storage/Database.h b/WebCore/storage/Database.h
index 61c9b66..0d7f33c 100644
--- a/WebCore/storage/Database.h
+++ b/WebCore/storage/Database.h
@@ -52,7 +52,7 @@ namespace WebCore {
class DatabaseAuthorizer;
class DatabaseThread;
-class Document;
+class ScriptExecutionContext;
class SQLResultSet;
class SQLTransactionCallback;
class SQLTransactionClient;
@@ -67,10 +67,13 @@ class Database : public ThreadSafeShared<Database> {
friend class SQLStatement;
friend class SQLTransaction;
public:
+ static void setIsAvailable(bool);
+ static bool isAvailable();
+
~Database();
// Direct support for the DOM API
- static PassRefPtr<Database> openDatabase(Document* document, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, ExceptionCode&);
+ static PassRefPtr<Database> openDatabase(ScriptExecutionContext* context, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, ExceptionCode&);
String version() const;
void changeVersion(const String& oldVersion, const String& newVersion,
PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback,
@@ -87,7 +90,7 @@ public:
Vector<String> tableNames();
- Document* document() const { return m_document.get(); }
+ ScriptExecutionContext* scriptExecutionContext() const { return m_scriptExecutionContext.get(); }
SecurityOrigin* securityOrigin() const;
String stringIdentifier() const;
String displayName() const;
@@ -123,8 +126,9 @@ public:
SQLTransactionCoordinator* transactionCoordinator() const;
private:
- Database(Document* document, const String& name, const String& expectedVersion,
- const String& displayName, unsigned long estimatedSize);
+ Database(ScriptExecutionContext* context, const String& name,
+ const String& expectedVersion, const String& displayName,
+ unsigned long estimatedSize);
bool openAndVerifyVersion(ExceptionCode&);
@@ -139,7 +143,7 @@ private:
static void deliverPendingCallback(void*);
- RefPtr<Document> m_document;
+ RefPtr<ScriptExecutionContext> m_scriptExecutionContext;
RefPtr<SecurityOrigin> m_mainThreadSecurityOrigin;
RefPtr<SecurityOrigin> m_databaseThreadSecurityOrigin;
String m_name;
diff --git a/WebCore/storage/Database.idl b/WebCore/storage/Database.idl
index 6ca9c95..c8a537c 100644
--- a/WebCore/storage/Database.idl
+++ b/WebCore/storage/Database.idl
@@ -29,7 +29,8 @@
module storage {
interface [
- Conditional=DATABASE
+ Conditional=DATABASE,
+ OmitConstructor
] Database {
readonly attribute DOMString version;
[Custom] void changeVersion(in DOMString oldVersion, in DOMString newVersion, in SQLTransactionCallback callback, in SQLTransactionErrorCallback errorCallback, in VoidCallback successCallback);
diff --git a/WebCore/storage/DatabaseAuthorizer.cpp b/WebCore/storage/DatabaseAuthorizer.cpp
index 93f9106..d87d4d9 100644
--- a/WebCore/storage/DatabaseAuthorizer.cpp
+++ b/WebCore/storage/DatabaseAuthorizer.cpp
@@ -38,6 +38,7 @@ DatabaseAuthorizer::DatabaseAuthorizer()
: m_securityEnabled(false)
{
reset();
+ addWhitelistedFunctions();
}
void DatabaseAuthorizer::reset()
@@ -47,6 +48,69 @@ void DatabaseAuthorizer::reset()
m_readOnly = false;
}
+void DatabaseAuthorizer::addWhitelistedFunctions()
+{
+ // SQLite functions used to help implement some operations
+ // ALTER TABLE helpers
+ m_whitelistedFunctions.add("sqlite_rename_table");
+ m_whitelistedFunctions.add("sqlite_rename_trigger");
+ // GLOB helpers
+ m_whitelistedFunctions.add("glob");
+
+ // SQLite core functions
+ m_whitelistedFunctions.add("abs");
+ m_whitelistedFunctions.add("changes");
+ m_whitelistedFunctions.add("coalesce");
+ m_whitelistedFunctions.add("glob");
+ m_whitelistedFunctions.add("ifnull");
+ m_whitelistedFunctions.add("hex");
+ m_whitelistedFunctions.add("last_insert_rowid");
+ m_whitelistedFunctions.add("length");
+ m_whitelistedFunctions.add("like");
+ m_whitelistedFunctions.add("lower");
+ m_whitelistedFunctions.add("ltrim");
+ m_whitelistedFunctions.add("max");
+ m_whitelistedFunctions.add("min");
+ m_whitelistedFunctions.add("nullif");
+ m_whitelistedFunctions.add("quote");
+ m_whitelistedFunctions.add("replace");
+ m_whitelistedFunctions.add("round");
+ m_whitelistedFunctions.add("rtrim");
+ m_whitelistedFunctions.add("soundex");
+ m_whitelistedFunctions.add("sqlite_source_id");
+ m_whitelistedFunctions.add("sqlite_version");
+ m_whitelistedFunctions.add("substr");
+ m_whitelistedFunctions.add("total_changes");
+ m_whitelistedFunctions.add("trim");
+ m_whitelistedFunctions.add("typeof");
+ m_whitelistedFunctions.add("upper");
+ m_whitelistedFunctions.add("zeroblob");
+
+ // SQLite date and time functions
+ m_whitelistedFunctions.add("date");
+ m_whitelistedFunctions.add("time");
+ m_whitelistedFunctions.add("datetime");
+ m_whitelistedFunctions.add("julianday");
+ m_whitelistedFunctions.add("strftime");
+
+ // SQLite aggregate functions
+ // max() and min() are already in the list
+ m_whitelistedFunctions.add("avg");
+ m_whitelistedFunctions.add("count");
+ m_whitelistedFunctions.add("group_concat");
+ m_whitelistedFunctions.add("sum");
+ m_whitelistedFunctions.add("total");
+
+ // SQLite FTS functions
+ m_whitelistedFunctions.add("snippet");
+ m_whitelistedFunctions.add("offsets");
+ m_whitelistedFunctions.add("optimize");
+
+ // SQLite ICU functions
+ // like(), lower() and upper() are already in the list
+ m_whitelistedFunctions.add("regexp");
+}
+
int DatabaseAuthorizer::createTable(const String& tableName)
{
if (m_readOnly && m_securityEnabled)
@@ -278,11 +342,11 @@ int DatabaseAuthorizer::allowDetach(const String&)
return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
}
-int DatabaseAuthorizer::allowFunction(const String&)
+int DatabaseAuthorizer::allowFunction(const String& functionName)
{
- // FIXME: Are there any of these we need to prevent? One might guess current_date, current_time, current_timestamp because
- // they would violate the "sandbox environment" part of 4.11.3, but scripts can generate the local client side information via
- // javascript directly, anyways. Are there any other built-ins we need to be worried about?
+ if (m_securityEnabled && !m_whitelistedFunctions.contains(functionName))
+ return SQLAuthDeny;
+
return SQLAuthAllow;
}
diff --git a/WebCore/storage/DatabaseAuthorizer.h b/WebCore/storage/DatabaseAuthorizer.h
index 248b659..037409e 100644
--- a/WebCore/storage/DatabaseAuthorizer.h
+++ b/WebCore/storage/DatabaseAuthorizer.h
@@ -28,6 +28,8 @@
#ifndef DatabaseAuthorizer_h
#define DatabaseAuthorizer_h
+#include "StringHash.h"
+#include <wtf/HashSet.h>
#include <wtf/PassRefPtr.h>
#include <wtf/Threading.h>
@@ -94,12 +96,15 @@ public:
private:
DatabaseAuthorizer();
+ void addWhitelistedFunctions();
int denyBasedOnTableName(const String&);
bool m_securityEnabled : 1;
bool m_lastActionWasInsert : 1;
bool m_lastActionChangedDatabase : 1;
bool m_readOnly : 1;
+
+ HashSet<String, CaseFoldingHash> m_whitelistedFunctions;
};
} // namespace WebCore
diff --git a/WebCore/storage/DatabaseTask.h b/WebCore/storage/DatabaseTask.h
index 97a23c7..998e373 100644
--- a/WebCore/storage/DatabaseTask.h
+++ b/WebCore/storage/DatabaseTask.h
@@ -50,16 +50,15 @@ class VersionChangeCallback;
// Can be used to wait until DatabaseTask is completed.
// Has to be passed into DatabaseTask::create to be associated with the task.
class DatabaseTaskSynchronizer : public Noncopyable {
- friend class DatabaseTask;
public:
DatabaseTaskSynchronizer();
// Called from main thread to wait until task is completed.
void waitForTaskCompletion();
-private:
// Called by the task.
void taskCompleted();
+private:
bool m_taskCompleted;
Mutex m_synchronousMutex;
diff --git a/WebCore/storage/DatabaseThread.cpp b/WebCore/storage/DatabaseThread.cpp
index 12e9251..ec4c6d1 100644
--- a/WebCore/storage/DatabaseThread.cpp
+++ b/WebCore/storage/DatabaseThread.cpp
@@ -44,6 +44,7 @@ DatabaseThread::DatabaseThread()
: m_threadID(0)
, m_transactionClient(new SQLTransactionClient())
, m_transactionCoordinator(new SQLTransactionCoordinator())
+ , m_cleanupSync(0)
{
m_selfRef = this;
}
@@ -51,6 +52,7 @@ DatabaseThread::DatabaseThread()
DatabaseThread::~DatabaseThread()
{
// FIXME: Any cleanup required here? Since the thread deletes itself after running its detached course, I don't think so. Lets be sure.
+ ASSERT(terminationRequested());
}
bool DatabaseThread::start()
@@ -65,8 +67,10 @@ bool DatabaseThread::start()
return m_threadID;
}
-void DatabaseThread::requestTermination()
+void DatabaseThread::requestTermination(DatabaseTaskSynchronizer *cleanupSync)
{
+ ASSERT(!m_cleanupSync);
+ m_cleanupSync = cleanupSync;
LOG(StorageAPI, "DatabaseThread %p was asked to terminate\n", this);
m_queue.kill();
}
@@ -115,9 +119,14 @@ void* DatabaseThread::databaseThread()
// Detach the thread so its resources are no longer of any concern to anyone else
detachThread(m_threadID);
+ DatabaseTaskSynchronizer* cleanupSync = m_cleanupSync;
+
// Clear the self refptr, possibly resulting in deletion
m_selfRef = 0;
+ if (cleanupSync) // Someone wanted to know when we were done cleaning up.
+ cleanupSync->taskCompleted();
+
return 0;
}
@@ -162,6 +171,5 @@ void DatabaseThread::unscheduleDatabaseTasks(Database* database)
SameDatabasePredicate predicate(database);
m_queue.removeIf(predicate);
}
-
} // namespace WebCore
#endif
diff --git a/WebCore/storage/DatabaseThread.h b/WebCore/storage/DatabaseThread.h
index 269a633..3702619 100644
--- a/WebCore/storage/DatabaseThread.h
+++ b/WebCore/storage/DatabaseThread.h
@@ -43,6 +43,7 @@ namespace WebCore {
class Database;
class DatabaseTask;
+class DatabaseTaskSynchronizer;
class Document;
class SQLTransactionClient;
class SQLTransactionCoordinator;
@@ -53,7 +54,7 @@ public:
~DatabaseThread();
bool start();
- void requestTermination();
+ void requestTermination(DatabaseTaskSynchronizer* cleanupSync);
bool terminationRequested() const;
void scheduleTask(PassOwnPtr<DatabaseTask>);
@@ -85,6 +86,7 @@ private:
OwnPtr<SQLTransactionClient> m_transactionClient;
OwnPtr<SQLTransactionCoordinator> m_transactionCoordinator;
+ DatabaseTaskSynchronizer* m_cleanupSync;
};
} // namespace WebCore
diff --git a/WebCore/storage/DatabaseTracker.cpp b/WebCore/storage/DatabaseTracker.cpp
index c0c4242..bed83a7 100644
--- a/WebCore/storage/DatabaseTracker.cpp
+++ b/WebCore/storage/DatabaseTracker.cpp
@@ -31,14 +31,15 @@
#if ENABLE(DATABASE)
+#include "Chrome.h"
#include "ChromeClient.h"
#include "Database.h"
#include "DatabaseThread.h"
#include "DatabaseTrackerClient.h"
-#include "Document.h"
#include "Logging.h"
#include "OriginQuotaManager.h"
#include "Page.h"
+#include "ScriptExecutionContext.h"
#include "SecurityOrigin.h"
#include "SecurityOriginHash.h"
#include "SQLiteFileSystem.h"
@@ -119,7 +120,7 @@ void DatabaseTracker::openTrackerDatabase(bool createIfDoesNotExist)
}
}
-bool DatabaseTracker::canEstablishDatabase(Document* document, const String& name, const String& displayName, unsigned long estimatedSize)
+bool DatabaseTracker::canEstablishDatabase(ScriptExecutionContext* context, const String& name, const String& displayName, unsigned long estimatedSize)
{
ASSERT(currentThread() == m_thread);
@@ -127,9 +128,9 @@ bool DatabaseTracker::canEstablishDatabase(Document* document, const String& nam
// can run on the database thread later.
populateOrigins();
- SecurityOrigin* origin = document->securityOrigin();
+ SecurityOrigin* origin = context->securityOrigin();
- // Since we're imminently opening a database within this Document's origin, make sure this origin is being tracked by the QuotaTracker
+ // Since we're imminently opening a database within this context's origin, make sure this origin is being tracked by the QuotaTracker
// by fetching it's current usage now
unsigned long long usage = usageForOrigin(origin);
@@ -146,12 +147,9 @@ bool DatabaseTracker::canEstablishDatabase(Document* document, const String& nam
// Give the chrome client a chance to increase the quota.
// Temporarily make the details of the proposed database available, so the client can get at them.
- Page* page = document->page();
- if (!page)
- return false;
pair<SecurityOrigin*, DatabaseDetails> details(origin, DatabaseDetails(name, displayName, estimatedSize, 0));
m_proposedDatabase = &details;
- page->chrome()->client()->exceededDatabaseQuota(document->frame(), name);
+ context->databaseExceededQuota(name);
m_proposedDatabase = 0;
// If the database will fit now, allow its creation.
@@ -185,7 +183,7 @@ bool DatabaseTracker::hasEntryForDatabase(SecurityOrigin* origin, const String&
unsigned long long DatabaseTracker::getMaxSizeForDatabase(const Database* database)
{
- ASSERT(currentThread() == database->document()->databaseThread()->getThreadID());
+ ASSERT(currentThread() == database->scriptExecutionContext()->databaseThread()->getThreadID());
// The maximum size for a database is the full quota for its origin, minus the current usage within the origin,
// plus the current usage of the given database
Locker<OriginQuotaManager> locker(originQuotaManager());
diff --git a/WebCore/storage/DatabaseTracker.h b/WebCore/storage/DatabaseTracker.h
index c87b26a..38a3418 100644
--- a/WebCore/storage/DatabaseTracker.h
+++ b/WebCore/storage/DatabaseTracker.h
@@ -37,6 +37,7 @@
#include "DatabaseDetails.h"
#include "SQLiteDatabase.h"
#include "StringHash.h"
+#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
#endif // !PLATFORM(CHROMIUM)
@@ -44,7 +45,7 @@
namespace WebCore {
class Database;
-class Document;
+class ScriptExecutionContext;
class SecurityOrigin;
#if !PLATFORM(CHROMIUM)
@@ -58,8 +59,11 @@ struct SecurityOriginTraits;
class DatabaseTracker : public Noncopyable {
public:
static DatabaseTracker& tracker();
+ // FIXME: Due to workers having multiple threads in a single process sharing
+ // a DatabaseTracker, this singleton will have to be synchronized or moved
+ // to TLS.
- bool canEstablishDatabase(Document*, const String& name, const String& displayName, unsigned long estimatedSize);
+ bool canEstablishDatabase(ScriptExecutionContext*, const String& name, const String& displayName, unsigned long estimatedSize);
void setDatabaseDetails(SecurityOrigin*, const String& name, const String& displayName, unsigned long estimatedSize);
String fullPathForDatabase(SecurityOrigin*, const String& name, bool createIfDoesNotExist = true);
diff --git a/WebCore/storage/IDBDatabaseError.h b/WebCore/storage/IDBDatabaseError.h
new file mode 100644
index 0000000..e8fd2dd
--- /dev/null
+++ b/WebCore/storage/IDBDatabaseError.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef IDBDatabaseError_h
+#define IDBDatabaseError_h
+
+#include "PlatformString.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+
+class IDBDatabaseError : public RefCounted<IDBDatabaseError> {
+public:
+ static PassRefPtr<IDBDatabaseError> create()
+ {
+ return adoptRef(new IDBDatabaseError());
+ }
+ ~IDBDatabaseError() { }
+
+ unsigned short code() const { return m_code; }
+ void setCode(unsigned short value) { m_code = value; }
+ String message() const { return m_message; }
+ void setMessage(const String& value) { m_message = value; }
+
+private:
+ IDBDatabaseError() { }
+
+ unsigned short m_code;
+ String m_message;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // IDBDatabaseError_h
+
diff --git a/WebCore/storage/IDBDatabaseError.idl b/WebCore/storage/IDBDatabaseError.idl
new file mode 100644
index 0000000..6c6019c
--- /dev/null
+++ b/WebCore/storage/IDBDatabaseError.idl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+module storage {
+
+ interface [
+ Conditional=INDEXED_DATABASE
+ ] IDBDatabaseError {
+ attribute unsigned short code;
+ attribute DOMString message;
+ };
+
+}
diff --git a/WebCore/storage/IDBDatabaseException.h b/WebCore/storage/IDBDatabaseException.h
new file mode 100644
index 0000000..d94a7f9
--- /dev/null
+++ b/WebCore/storage/IDBDatabaseException.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef IDBDatabaseException_h
+#define IDBDatabaseException_h
+
+#include "PlatformString.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+
+class IDBDatabaseException : public RefCounted<IDBDatabaseException> {
+public:
+ static PassRefPtr<IDBDatabaseException> create()
+ {
+ return adoptRef(new IDBDatabaseException());
+ }
+ ~IDBDatabaseException() { }
+
+ unsigned short code() const { return m_code; }
+ void setCode(unsigned short value) { m_code = value; }
+ String message() const { return m_message; }
+ void setMessage(const String& value) { m_message = value; }
+
+private:
+ IDBDatabaseException() { }
+
+ unsigned short m_code;
+ String m_message;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // IDBDatabaseException_h
+
diff --git a/WebCore/storage/IDBDatabaseException.idl b/WebCore/storage/IDBDatabaseException.idl
new file mode 100644
index 0000000..898e5f9
--- /dev/null
+++ b/WebCore/storage/IDBDatabaseException.idl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+module storage {
+
+ interface [
+ Conditional=INDEXED_DATABASE
+ ] IDBDatabaseException {
+ const unsigned short UNKNOWN_ERR = 0;
+ const unsigned short NON_TRANSIENT_ERR = 1;
+ const unsigned short NOT_FOUND_ERR = 2;
+ const unsigned short CONSTRAINT_ERR = 3;
+ const unsigned short DATA_ERR = 4;
+ const unsigned short NOT_ALLOWED_ERR = 5;
+ const unsigned short SERIAL_ERR = 11;
+ const unsigned short RECOVERABLE_ERR = 21;
+ const unsigned short TRANSIENT_ERR = 31;
+ const unsigned short TIMEOUT_ERR = 32;
+ const unsigned short DEADLOCK_ERR = 33;
+ attribute unsigned short code;
+ attribute DOMString message;
+ };
+
+}
diff --git a/WebCore/storage/IDBRequest.cpp b/WebCore/storage/IDBRequest.cpp
new file mode 100644
index 0000000..1a20499
--- /dev/null
+++ b/WebCore/storage/IDBRequest.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+#include "IDBRequest.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBDatabaseError.h"
+#include "SerializedScriptValue.h"
+
+namespace WebCore {
+
+IDBRequest::IDBRequest(ScriptExecutionContext* context)
+ : ActiveDOMObject(context, this)
+{
+}
+
+IDBRequest::~IDBRequest()
+{
+}
+
+void IDBRequest::abort()
+{
+}
+
+EventTargetData* IDBRequest::eventTargetData()
+{
+ return 0;
+}
+
+EventTargetData* IDBRequest::ensureEventTargetData()
+{
+ return 0;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
+
diff --git a/WebCore/storage/IDBRequest.h b/WebCore/storage/IDBRequest.h
new file mode 100644
index 0000000..5f00aa8
--- /dev/null
+++ b/WebCore/storage/IDBRequest.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef IDBRequest_h
+#define IDBRequest_h
+
+#include "ActiveDOMObject.h"
+#include "EventTarget.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+
+class IDBDatabaseError;
+class SerializedScriptValue;
+
+class IDBRequest : public RefCounted<IDBRequest>, public ActiveDOMObject, public EventTarget {
+public:
+ static PassRefPtr<IDBRequest> create(ScriptExecutionContext* context)
+ {
+ return adoptRef(new IDBRequest(context));
+ }
+ ~IDBRequest();
+
+ void abort();
+ unsigned short readyState() const { return m_readyState; }
+ IDBDatabaseError* error() const { return m_error.get(); }
+ SerializedScriptValue* result() const { return m_result.get(); }
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(success);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+
+ using RefCounted<IDBRequest>::ref;
+ using RefCounted<IDBRequest>::deref;
+
+ // EventTarget interface
+ virtual ScriptExecutionContext* scriptExecutionContext() const { return ActiveDOMObject::scriptExecutionContext(); }
+ virtual IDBRequest* toIDBRequest() { return this; }
+
+private:
+ explicit IDBRequest(ScriptExecutionContext* context);
+
+ // EventTarget interface
+ virtual void refEventTarget() { ref(); }
+ virtual void derefEventTarget() { deref(); }
+ virtual EventTargetData* eventTargetData();
+ virtual EventTargetData* ensureEventTargetData();
+
+ unsigned short m_readyState;
+ RefPtr<IDBDatabaseError> m_error;
+ RefPtr<SerializedScriptValue> m_result;
+
+ EventTargetData m_eventTargetData;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // IDBRequest_h
+
diff --git a/WebCore/storage/IDBRequest.idl b/WebCore/storage/IDBRequest.idl
new file mode 100644
index 0000000..b34184c
--- /dev/null
+++ b/WebCore/storage/IDBRequest.idl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+module storage {
+
+ interface [
+ Conditional=INDEXED_DATABASE,
+ EventTarget
+ ] IDBRequest {
+ void abort();
+ const unsigned short INITIAL = 0;
+ const unsigned short LOADING = 1;
+ const unsigned short DONE = 2;
+ readonly attribute unsigned short readyState;
+ readonly attribute IDBDatabaseError error;
+ readonly attribute [CustomGetter] any result;
+ attribute EventListener onsuccess;
+ attribute EventListener onerror;
+ };
+
+}
diff --git a/WebCore/storage/IndexedDatabaseRequest.cpp b/WebCore/storage/IndexedDatabaseRequest.cpp
new file mode 100644
index 0000000..827493b
--- /dev/null
+++ b/WebCore/storage/IndexedDatabaseRequest.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+#include "IndexedDatabaseRequest.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "ExceptionCode.h"
+#include "IDBRequest.h"
+
+namespace WebCore {
+
+IndexedDatabaseRequest::IndexedDatabaseRequest()
+{
+}
+
+IndexedDatabaseRequest::~IndexedDatabaseRequest()
+{
+}
+
+void IndexedDatabaseRequest::open(const String& name, const String& description, bool modifyDatabase, ExceptionCode& exception)
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
+
diff --git a/WebCore/storage/IndexedDatabaseRequest.h b/WebCore/storage/IndexedDatabaseRequest.h
new file mode 100644
index 0000000..74aada3
--- /dev/null
+++ b/WebCore/storage/IndexedDatabaseRequest.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef IndexedDatabaseRequest_h
+#define IndexedDatabaseRequest_h
+
+#include "ExceptionCode.h"
+#include "PlatformString.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+
+class IDBRequest;
+
+class IndexedDatabaseRequest : public RefCounted<IndexedDatabaseRequest> {
+public:
+ static PassRefPtr<IndexedDatabaseRequest> create()
+ {
+ return adoptRef(new IndexedDatabaseRequest());
+ }
+ ~IndexedDatabaseRequest();
+
+ IDBRequest* request() const { return m_request.get(); }
+ void open(const String& name, const String& description, bool modifyDatabase, ExceptionCode&);
+
+private:
+ IndexedDatabaseRequest();
+
+ PassRefPtr<IDBRequest> m_request;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // IndexedDatabaseRequest_h
+
diff --git a/WebCore/storage/IndexedDatabaseRequest.idl b/WebCore/storage/IndexedDatabaseRequest.idl
new file mode 100644
index 0000000..b1fc7da
--- /dev/null
+++ b/WebCore/storage/IndexedDatabaseRequest.idl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+module storage {
+
+ interface [
+ Conditional=INDEXED_DATABASE
+ ] IndexedDatabaseRequest {
+ readonly attribute IDBRequest request;
+ [Custom] void open(in DOMString name, in DOMString description, in optional boolean modifyDatabase)
+ raises(IDBDatabaseException);
+ };
+
+}
diff --git a/WebCore/storage/SQLError.idl b/WebCore/storage/SQLError.idl
index d889c5b..503fe6f 100644
--- a/WebCore/storage/SQLError.idl
+++ b/WebCore/storage/SQLError.idl
@@ -29,7 +29,8 @@
module storage {
interface [
- Conditional=DATABASE
+ Conditional=DATABASE,
+ OmitConstructor
] SQLError {
readonly attribute unsigned long code;
readonly attribute DOMString message;
diff --git a/WebCore/storage/SQLResultSet.idl b/WebCore/storage/SQLResultSet.idl
index 1db07cd..c98fff6 100644
--- a/WebCore/storage/SQLResultSet.idl
+++ b/WebCore/storage/SQLResultSet.idl
@@ -29,7 +29,8 @@
module storage {
interface [
- Conditional=DATABASE
+ Conditional=DATABASE,
+ OmitConstructor
] SQLResultSet {
readonly attribute SQLResultSetRowList rows;
diff --git a/WebCore/storage/SQLResultSetRowList.idl b/WebCore/storage/SQLResultSetRowList.idl
index 6a477e9..7ae7a9c 100644
--- a/WebCore/storage/SQLResultSetRowList.idl
+++ b/WebCore/storage/SQLResultSetRowList.idl
@@ -29,7 +29,8 @@
module storage {
interface [
- Conditional=DATABASE
+ Conditional=DATABASE,
+ OmitConstructor
] SQLResultSetRowList {
readonly attribute unsigned long length;
[Custom] DOMObject item(in unsigned long index);
diff --git a/WebCore/storage/SQLTransaction.cpp b/WebCore/storage/SQLTransaction.cpp
index 165685b..de615ca 100644
--- a/WebCore/storage/SQLTransaction.cpp
+++ b/WebCore/storage/SQLTransaction.cpp
@@ -35,11 +35,11 @@
#include "Database.h"
#include "DatabaseAuthorizer.h"
#include "DatabaseDetails.h"
-#include "Document.h"
#include "ExceptionCode.h"
#include "Logging.h"
#include "Page.h"
#include "PlatformString.h"
+#include "ScriptExecutionContext.h"
#include "Settings.h"
#include "SQLError.h"
#include "SQLiteTransaction.h"
@@ -94,8 +94,7 @@ void SQLTransaction::executeSQL(const String& sqlStatement, const Vector<SQLValu
bool readOnlyMode = m_readOnly;
if (!readOnlyMode) {
- Page* page = m_database->document()->page();
- if (!page || page->settings()->privateBrowsingEnabled())
+ if (m_database->scriptExecutionContext()->isDatabaseReadOnly())
readOnlyMode = true;
}
diff --git a/WebCore/storage/SQLTransaction.idl b/WebCore/storage/SQLTransaction.idl
index 5d4885c..7d694e8 100644
--- a/WebCore/storage/SQLTransaction.idl
+++ b/WebCore/storage/SQLTransaction.idl
@@ -29,7 +29,8 @@
module storage {
interface [
- Conditional=DATABASE
+ Conditional=DATABASE,
+ OmitConstructor
] SQLTransaction {
[Custom] void executeSql(in DOMString sqlStatement, in ObjectArray arguments, in SQLStatementCallback callback, in SQLStatementErrorCallback errorCallback);
};
diff --git a/WebCore/storage/SQLTransactionClient.cpp b/WebCore/storage/SQLTransactionClient.cpp
index 5918bd8..6064c99 100644
--- a/WebCore/storage/SQLTransactionClient.cpp
+++ b/WebCore/storage/SQLTransactionClient.cpp
@@ -31,6 +31,9 @@
#include "config.h"
#include "SQLTransactionClient.h"
+#if ENABLE(DATABASE)
+
+#include "Chrome.h"
#include "ChromeClient.h"
#include "Database.h"
#include "DatabaseThread.h"
@@ -44,7 +47,7 @@ namespace WebCore {
void SQLTransactionClient::didCommitTransaction(SQLTransaction* transaction)
{
- ASSERT(currentThread() == transaction->database()->document()->databaseThread()->getThreadID());
+ ASSERT(currentThread() == transaction->database()->scriptExecutionContext()->databaseThread()->getThreadID());
Database* database = transaction->database();
DatabaseTracker::tracker().scheduleNotifyDatabaseChanged(
database->securityOrigin(), database->stringIdentifier());
@@ -52,7 +55,7 @@ void SQLTransactionClient::didCommitTransaction(SQLTransaction* transaction)
void SQLTransactionClient::didExecuteStatement(SQLTransaction* transaction)
{
- ASSERT(currentThread() == transaction->database()->document()->databaseThread()->getThreadID());
+ ASSERT(currentThread() == transaction->database()->scriptExecutionContext()->databaseThread()->getThreadID());
OriginQuotaManager& manager(DatabaseTracker::tracker().originQuotaManager());
Locker<OriginQuotaManager> locker(manager);
manager.markDatabase(transaction->database());
@@ -60,15 +63,15 @@ void SQLTransactionClient::didExecuteStatement(SQLTransaction* transaction)
bool SQLTransactionClient::didExceedQuota(SQLTransaction* transaction)
{
- ASSERT(isMainThread());
+ ASSERT(transaction->database()->scriptExecutionContext()->isContextThread());
Database* database = transaction->database();
- Page* page = database->document()->page();
- ASSERT(page);
unsigned long long currentQuota = DatabaseTracker::tracker().quotaForOrigin(database->securityOrigin());
- page->chrome()->client()->exceededDatabaseQuota(database->document()->frame(), database->stringIdentifier());
+ database->scriptExecutionContext()->databaseExceededQuota(database->stringIdentifier());
unsigned long long newQuota = DatabaseTracker::tracker().quotaForOrigin(database->securityOrigin());
return (newQuota > currentQuota);
}
}
+
+#endif // ENABLE(DATABASE)
diff --git a/WebCore/storage/SQLTransactionClient.h b/WebCore/storage/SQLTransactionClient.h
index e822594..801647b 100644
--- a/WebCore/storage/SQLTransactionClient.h
+++ b/WebCore/storage/SQLTransactionClient.h
@@ -31,6 +31,8 @@
#ifndef SQLTransactionClient_h
#define SQLTransactionClient_h
+#if ENABLE(DATABASE)
+
#include <wtf/Noncopyable.h>
namespace WebCore {
@@ -47,4 +49,6 @@ namespace WebCore {
};
}
+#endif // ENABLE(DATABASE)
+
#endif // SQLTransactionClient_h
diff --git a/WebCore/storage/SQLTransactionCoordinator.cpp b/WebCore/storage/SQLTransactionCoordinator.cpp
index 30b0c4a..efdcd1d 100644
--- a/WebCore/storage/SQLTransactionCoordinator.cpp
+++ b/WebCore/storage/SQLTransactionCoordinator.cpp
@@ -31,6 +31,8 @@
#include "config.h"
#include "SQLTransactionCoordinator.h"
+#if ENABLE(DATABASE)
+
#include "CString.h"
#include "Database.h"
#include "SQLTransaction.h"
@@ -111,4 +113,6 @@ void SQLTransactionCoordinator::shutdown()
m_coordinationInfoMap.clear();
}
-}
+} // namespace WebCore
+
+#endif // ENABLE(DATABASE)
diff --git a/WebCore/storage/SQLTransactionCoordinator.h b/WebCore/storage/SQLTransactionCoordinator.h
index ae5674b..a51084f 100644
--- a/WebCore/storage/SQLTransactionCoordinator.h
+++ b/WebCore/storage/SQLTransactionCoordinator.h
@@ -31,6 +31,8 @@
#ifndef SQLTransactionCoordinator_h
#define SQLTransactionCoordinator_h
+#if ENABLE(DATABASE)
+
#include "CString.h"
#include "StringHash.h"
#include <wtf/Deque.h>
@@ -62,4 +64,6 @@ namespace WebCore {
};
}
+#endif // ENABLE(DATABASE)
+
#endif // SQLTransactionCoordinator_h
diff --git a/WebCore/storage/Storage.idl b/WebCore/storage/Storage.idl
index 7127efd..ffd1af1 100644
--- a/WebCore/storage/Storage.idl
+++ b/WebCore/storage/Storage.idl
@@ -26,7 +26,6 @@
module storage {
interface [
- GenerateConstructor,
HasNameGetter,
CustomDeleteProperty,
CustomGetPropertyNames,
diff --git a/WebCore/storage/StorageArea.h b/WebCore/storage/StorageArea.h
index a64d44a..6081240 100644
--- a/WebCore/storage/StorageArea.h
+++ b/WebCore/storage/StorageArea.h
@@ -50,9 +50,9 @@ namespace WebCore {
virtual unsigned length() const = 0;
virtual String key(unsigned index) const = 0;
virtual String getItem(const String& key) const = 0;
- virtual void setItem(const String& key, const String& value, ExceptionCode& ec, Frame* sourceFrame) = 0;
- virtual void removeItem(const String& key, Frame* sourceFrame) = 0;
- virtual void clear(Frame* sourceFrame) = 0;
+ virtual String setItem(const String& key, const String& value, ExceptionCode& ec, Frame* sourceFrame) = 0;
+ virtual String removeItem(const String& key, Frame* sourceFrame) = 0;
+ virtual bool clear(Frame* sourceFrame) = 0;
virtual bool contains(const String& key) const = 0;
};
diff --git a/WebCore/storage/StorageAreaImpl.cpp b/WebCore/storage/StorageAreaImpl.cpp
index 8c2a29c..aa04781 100644
--- a/WebCore/storage/StorageAreaImpl.cpp
+++ b/WebCore/storage/StorageAreaImpl.cpp
@@ -128,7 +128,7 @@ String StorageAreaImpl::getItem(const String& key) const
return m_storageMap->getItem(key);
}
-void StorageAreaImpl::setItem(const String& key, const String& value, ExceptionCode& ec, Frame* frame)
+String StorageAreaImpl::setItem(const String& key, const String& value, ExceptionCode& ec, Frame* frame)
{
ASSERT(!m_isShutdown);
ASSERT(!value.isNull());
@@ -136,7 +136,7 @@ void StorageAreaImpl::setItem(const String& key, const String& value, ExceptionC
if (privateBrowsingEnabled(frame)) {
ec = QUOTA_EXCEEDED_ERR;
- return;
+ return String();
}
String oldValue;
@@ -147,24 +147,25 @@ void StorageAreaImpl::setItem(const String& key, const String& value, ExceptionC
if (quotaException) {
ec = QUOTA_EXCEEDED_ERR;
- return;
+ return oldValue;
}
if (oldValue == value)
- return;
+ return oldValue;
if (m_storageAreaSync)
m_storageAreaSync->scheduleItemForSync(key, value);
StorageEventDispatcher::dispatch(key, oldValue, value, m_storageType, m_securityOrigin.get(), frame);
+ return oldValue;
}
-void StorageAreaImpl::removeItem(const String& key, Frame* frame)
+String StorageAreaImpl::removeItem(const String& key, Frame* frame)
{
ASSERT(!m_isShutdown);
blockUntilImportComplete();
if (privateBrowsingEnabled(frame))
- return;
+ return String();
String oldValue;
RefPtr<StorageMap> newMap = m_storageMap->removeItem(key, oldValue);
@@ -172,23 +173,24 @@ void StorageAreaImpl::removeItem(const String& key, Frame* frame)
m_storageMap = newMap.release();
if (oldValue.isNull())
- return;
+ return oldValue;
if (m_storageAreaSync)
m_storageAreaSync->scheduleItemForSync(key, String());
StorageEventDispatcher::dispatch(key, oldValue, String(), m_storageType, m_securityOrigin.get(), frame);
+ return oldValue;
}
-void StorageAreaImpl::clear(Frame* frame)
+bool StorageAreaImpl::clear(Frame* frame)
{
ASSERT(!m_isShutdown);
blockUntilImportComplete();
if (privateBrowsingEnabled(frame))
- return;
+ return false;
if (!m_storageMap->length())
- return;
+ return false;
unsigned quota = m_storageMap->quota();
m_storageMap = StorageMap::create(quota);
@@ -196,6 +198,7 @@ void StorageAreaImpl::clear(Frame* frame)
if (m_storageAreaSync)
m_storageAreaSync->scheduleClear();
StorageEventDispatcher::dispatch(String(), String(), String(), m_storageType, m_securityOrigin.get(), frame);
+ return true;
}
bool StorageAreaImpl::contains(const String& key) const
diff --git a/WebCore/storage/StorageAreaImpl.h b/WebCore/storage/StorageAreaImpl.h
index 0b2d34d..60d72cb 100644
--- a/WebCore/storage/StorageAreaImpl.h
+++ b/WebCore/storage/StorageAreaImpl.h
@@ -48,9 +48,9 @@ namespace WebCore {
virtual unsigned length() const;
virtual String key(unsigned index) const;
virtual String getItem(const String& key) const;
- virtual void setItem(const String& key, const String& value, ExceptionCode& ec, Frame* sourceFrame);
- virtual void removeItem(const String& key, Frame* sourceFrame);
- virtual void clear(Frame* sourceFrame);
+ virtual String setItem(const String& key, const String& value, ExceptionCode& ec, Frame* sourceFrame);
+ virtual String removeItem(const String& key, Frame* sourceFrame);
+ virtual bool clear(Frame* sourceFrame);
virtual bool contains(const String& key) const;
PassRefPtr<StorageAreaImpl> copy();
diff --git a/WebCore/storage/StorageEvent.cpp b/WebCore/storage/StorageEvent.cpp
index 13ccfe9..126aca0 100644
--- a/WebCore/storage/StorageEvent.cpp
+++ b/WebCore/storage/StorageEvent.cpp
@@ -47,7 +47,7 @@ PassRefPtr<StorageEvent> StorageEvent::create(const AtomicString& type, const St
}
StorageEvent::StorageEvent(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& uri, Storage* storageArea)
- : Event(type, false, true)
+ : Event(type, false, false)
, m_key(key)
, m_oldValue(oldValue)
, m_newValue(newValue)
diff --git a/WebCore/storage/StorageEvent.idl b/WebCore/storage/StorageEvent.idl
index 7c87561..3e77eda 100644
--- a/WebCore/storage/StorageEvent.idl
+++ b/WebCore/storage/StorageEvent.idl
@@ -26,10 +26,9 @@
module storage {
interface [
- GenerateConstructor,
Conditional=DOM_STORAGE
] StorageEvent : Event {
- readonly attribute DOMString key;
+ readonly attribute [ConvertNullStringTo=Null] DOMString key;
readonly attribute [ConvertNullStringTo=Null] DOMString oldValue;
readonly attribute [ConvertNullStringTo=Null] DOMString newValue;
readonly attribute DOMString uri;
diff --git a/WebCore/storage/StorageEventDispatcher.cpp b/WebCore/storage/StorageEventDispatcher.cpp
index 9763e07..dc0295b 100644
--- a/WebCore/storage/StorageEventDispatcher.cpp
+++ b/WebCore/storage/StorageEventDispatcher.cpp
@@ -50,25 +50,25 @@ void StorageEventDispatcher::dispatch(const String& key, const String& oldValue,
if (storageType == SessionStorage) {
// Send events only to our page.
for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
- if (frame->document()->securityOrigin()->equal(securityOrigin))
+ if (sourceFrame != frame && frame->document()->securityOrigin()->equal(securityOrigin))
frames.append(frame);
}
for (unsigned i = 0; i < frames.size(); ++i)
- frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->sessionStorage()));
+ frames[i]->document()->enqueueStorageEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->sessionStorage()));
} else {
// Send events to every page.
const HashSet<Page*>& pages = page->group().pages();
HashSet<Page*>::const_iterator end = pages.end();
for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
- if (frame->document()->securityOrigin()->equal(securityOrigin))
+ if (sourceFrame != frame && frame->document()->securityOrigin()->equal(securityOrigin))
frames.append(frame);
}
}
for (unsigned i = 0; i < frames.size(); ++i)
- frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->localStorage()));
+ frames[i]->document()->enqueueStorageEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->localStorage()));
}
}
diff --git a/WebCore/storage/StorageMap.cpp b/WebCore/storage/StorageMap.cpp
index bb08671..790fde2 100644
--- a/WebCore/storage/StorageMap.cpp
+++ b/WebCore/storage/StorageMap.cpp
@@ -47,6 +47,7 @@ PassRefPtr<StorageMap> StorageMap::copy()
{
RefPtr<StorageMap> newMap = create(m_quotaSize);
newMap->m_map = m_map;
+ newMap->m_currentLength = m_currentLength;
return newMap.release();
}
diff --git a/WebCore/storage/StorageNamespace.cpp b/WebCore/storage/StorageNamespace.cpp
index 6b8caeb..b54ba16 100644
--- a/WebCore/storage/StorageNamespace.cpp
+++ b/WebCore/storage/StorageNamespace.cpp
@@ -41,7 +41,8 @@ PassRefPtr<StorageNamespace> StorageNamespace::localStorageNamespace(const Strin
return StorageNamespaceImpl::localStorageNamespace(path, quota);
}
-PassRefPtr<StorageNamespace> StorageNamespace::sessionStorageNamespace()
+// The page argument is only used by the Chromium port.
+PassRefPtr<StorageNamespace> StorageNamespace::sessionStorageNamespace(Page*)
{
return StorageNamespaceImpl::sessionStorageNamespace();
}
diff --git a/WebCore/storage/StorageNamespace.h b/WebCore/storage/StorageNamespace.h
index 0ac5f86..e84e5a6 100644
--- a/WebCore/storage/StorageNamespace.h
+++ b/WebCore/storage/StorageNamespace.h
@@ -35,21 +35,22 @@
namespace WebCore {
- class SecurityOrigin;
- class StorageArea;
-
- // This interface is required for Chromium since these actions need to be proxied between processes.
- class StorageNamespace : public RefCounted<StorageNamespace> {
- public:
- static PassRefPtr<StorageNamespace> localStorageNamespace(const String& path, unsigned quota);
- static PassRefPtr<StorageNamespace> sessionStorageNamespace();
-
- virtual ~StorageNamespace() { }
- virtual PassRefPtr<StorageArea> storageArea(PassRefPtr<SecurityOrigin>) = 0;
- virtual PassRefPtr<StorageNamespace> copy() = 0;
- virtual void close() = 0;
- virtual void unlock() = 0;
- };
+class Page;
+class SecurityOrigin;
+class StorageArea;
+
+// This interface is required for Chromium since these actions need to be proxied between processes.
+class StorageNamespace : public RefCounted<StorageNamespace> {
+public:
+ static PassRefPtr<StorageNamespace> localStorageNamespace(const String& path, unsigned quota);
+ static PassRefPtr<StorageNamespace> sessionStorageNamespace(Page*);
+
+ virtual ~StorageNamespace() { }
+ virtual PassRefPtr<StorageArea> storageArea(PassRefPtr<SecurityOrigin>) = 0;
+ virtual PassRefPtr<StorageNamespace> copy() = 0;
+ virtual void close() = 0;
+ virtual void unlock() = 0;
+};
} // namespace WebCore
diff --git a/WebCore/storage/chromium/DatabaseTrackerChromium.cpp b/WebCore/storage/chromium/DatabaseTrackerChromium.cpp
index e4b8178..e18706b 100644
--- a/WebCore/storage/chromium/DatabaseTrackerChromium.cpp
+++ b/WebCore/storage/chromium/DatabaseTrackerChromium.cpp
@@ -35,11 +35,12 @@
#include "Database.h"
#include "DatabaseObserver.h"
#include "DatabaseThread.h"
-#include "Document.h"
#include "QuotaTracker.h"
+#include "ScriptExecutionContext.h"
#include "SecurityOrigin.h"
#include "SQLiteFileSystem.h"
#include <wtf/HashSet.h>
+#include <wtf/MainThread.h>
#include <wtf/StdLibExtras.h>
namespace WebCore {
@@ -55,7 +56,7 @@ DatabaseTracker::DatabaseTracker()
SQLiteFileSystem::registerSQLiteVFS();
}
-bool DatabaseTracker::canEstablishDatabase(Document*, const String&, const String&, unsigned long)
+bool DatabaseTracker::canEstablishDatabase(ScriptExecutionContext*, const String&, const String&, unsigned long)
{
// In Chromium, a database can always be established (even though we might not
// be able to write anything to it if the quota for this origin was exceeded)
@@ -74,21 +75,44 @@ String DatabaseTracker::fullPathForDatabase(SecurityOrigin* origin, const String
void DatabaseTracker::addOpenDatabase(Database* database)
{
- ASSERT(isMainThread());
+ ASSERT(database->scriptExecutionContext()->isContextThread());
DatabaseObserver::databaseOpened(database);
}
+class TrackerRemoveOpenDatabaseTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<TrackerRemoveOpenDatabaseTask> create(PassRefPtr<Database> database)
+ {
+ return new TrackerRemoveOpenDatabaseTask(database);
+ }
+
+ virtual void performTask(ScriptExecutionContext* context)
+ {
+ DatabaseTracker::tracker().removeOpenDatabase(m_database.get());
+ }
+
+private:
+ TrackerRemoveOpenDatabaseTask(PassRefPtr<Database> database)
+ : m_database(database)
+ {
+ }
+
+ RefPtr<Database> m_database;
+};
+
void DatabaseTracker::removeOpenDatabase(Database* database)
{
- // FIXME: once we know how to use this information, figure out
- // how to get this method called on the main thread
- //ASSERT(isMainThread());
- //DatabaseObserver::databaseClosed(database);
+ if (!database->scriptExecutionContext()->isContextThread()) {
+ database->scriptExecutionContext()->postTask(TrackerRemoveOpenDatabaseTask::create(database));
+ return;
+ }
+
+ DatabaseObserver::databaseClosed(database);
}
unsigned long long DatabaseTracker::getMaxSizeForDatabase(const Database* database)
{
- ASSERT(currentThread() == database->document()->databaseThread()->getThreadID());
+ ASSERT(currentThread() == database->scriptExecutionContext()->databaseThread()->getThreadID());
unsigned long long spaceAvailable = 0;
unsigned long long databaseSize = 0;
QuotaTracker::instance().getDatabaseSizeAndSpaceAvailableToOrigin(
diff --git a/WebCore/storage/chromium/SQLTransactionClientChromium.cpp b/WebCore/storage/chromium/SQLTransactionClientChromium.cpp
index 46d73ba..a10ca3e 100644
--- a/WebCore/storage/chromium/SQLTransactionClientChromium.cpp
+++ b/WebCore/storage/chromium/SQLTransactionClientChromium.cpp
@@ -38,20 +38,34 @@
#include "SQLTransaction.h"
#include <wtf/MainThread.h>
-static void notifyDatabaseChanged(void* context) {
- WebCore::Database* database = static_cast<WebCore::Database*>(context);
- WebCore::DatabaseObserver::databaseModified(database);
- database->deref(); // ref()'d in didCommitTransaction()
-}
-
namespace WebCore {
+class NotifyDatabaseChangedTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<NotifyDatabaseChangedTask> create(Database *database)
+ {
+ return new NotifyDatabaseChangedTask(database);
+ }
+
+ virtual void performTask(ScriptExecutionContext*)
+ {
+ WebCore::DatabaseObserver::databaseModified(m_database.get());
+ }
+
+private:
+ NotifyDatabaseChangedTask(PassRefPtr<Database> database)
+ : m_database(database)
+ {
+ }
+
+ RefPtr<Database> m_database;
+};
+
void SQLTransactionClient::didCommitTransaction(SQLTransaction* transaction)
{
- ASSERT(currentThread() == transaction->database()->document()->databaseThread()->getThreadID());
+ ASSERT(currentThread() == transaction->database()->scriptExecutionContext()->databaseThread()->getThreadID());
if (!transaction->isReadOnly()) {
- transaction->database()->ref(); // deref()'d in notifyDatabaseChanged()
- callOnMainThread(notifyDatabaseChanged, transaction->database());
+ transaction->database()->scriptExecutionContext()->postTask(NotifyDatabaseChangedTask::create(transaction->database()));
}
}
@@ -59,14 +73,14 @@ void SQLTransactionClient::didExecuteStatement(SQLTransaction* transaction)
{
// This method is called after executing every statement that changes the DB.
// Chromium doesn't need to do anything at that point.
- ASSERT(currentThread() == transaction->database()->document()->databaseThread()->getThreadID());
+ ASSERT(currentThread() == transaction->database()->scriptExecutionContext()->databaseThread()->getThreadID());
}
-bool SQLTransactionClient::didExceedQuota(SQLTransaction*)
+bool SQLTransactionClient::didExceedQuota(SQLTransaction* transaction)
{
// Chromium does not allow users to manually change the quota for an origin (for now, at least).
// Don't do anything.
- ASSERT(isMainThread());
+ ASSERT(transaction->database()->scriptExecutionContext()->isContextThread());
return false;
}