summaryrefslogtreecommitdiffstats
path: root/WebCore/storage
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/storage')
-rw-r--r--WebCore/storage/ChangeVersionWrapper.cpp3
-rw-r--r--WebCore/storage/ChangeVersionWrapper.h3
-rw-r--r--WebCore/storage/Database.cpp72
-rw-r--r--WebCore/storage/Database.h67
-rw-r--r--WebCore/storage/DatabaseAuthorizer.cpp44
-rw-r--r--WebCore/storage/DatabaseAuthorizer.h4
-rw-r--r--WebCore/storage/DatabaseTask.cpp7
-rw-r--r--WebCore/storage/DatabaseTask.h8
-rw-r--r--WebCore/storage/IDBCallbacks.h2
-rw-r--r--WebCore/storage/IDBDatabase.h17
-rw-r--r--WebCore/storage/IDBDatabaseImpl.cpp40
-rw-r--r--WebCore/storage/IDBDatabaseImpl.h18
-rw-r--r--WebCore/storage/IDBDatabaseRequest.cpp31
-rw-r--r--WebCore/storage/IDBDatabaseRequest.h24
-rw-r--r--WebCore/storage/IDBDatabaseRequest.idl12
-rw-r--r--WebCore/storage/IDBKeyRange.cpp47
-rw-r--r--WebCore/storage/IDBKeyRange.h73
-rw-r--r--WebCore/storage/IDBKeyRange.idl43
-rw-r--r--WebCore/storage/IDBObjectStore.h31
-rwxr-xr-x[-rw-r--r--]WebCore/storage/IDBObjectStoreImpl.cpp (renamed from WebCore/storage/IDBObjectStore.cpp)21
-rwxr-xr-xWebCore/storage/IDBObjectStoreImpl.h68
-rw-r--r--WebCore/storage/IDBObjectStoreRequest.cpp43
-rw-r--r--WebCore/storage/IDBObjectStoreRequest.h26
-rw-r--r--WebCore/storage/IDBObjectStoreRequest.idl18
-rw-r--r--WebCore/storage/IDBRequest.cpp7
-rw-r--r--WebCore/storage/IDBRequest.h2
-rw-r--r--WebCore/storage/IndexedDatabase.h2
-rw-r--r--WebCore/storage/IndexedDatabaseImpl.cpp2
-rw-r--r--WebCore/storage/IndexedDatabaseImpl.h2
-rw-r--r--WebCore/storage/IndexedDatabaseRequest.cpp42
-rw-r--r--WebCore/storage/IndexedDatabaseRequest.h20
-rw-r--r--WebCore/storage/IndexedDatabaseRequest.idl8
-rw-r--r--WebCore/storage/SQLResultSet.idl6
-rw-r--r--WebCore/storage/SQLStatement.cpp6
-rw-r--r--WebCore/storage/SQLStatement.h15
-rw-r--r--WebCore/storage/SQLTransaction.cpp63
-rw-r--r--WebCore/storage/SQLTransaction.h10
-rw-r--r--WebCore/storage/SQLTransactionCoordinator.cpp3
-rw-r--r--WebCore/storage/StorageAreaSync.cpp27
-rw-r--r--WebCore/storage/StorageAreaSync.h7
40 files changed, 689 insertions, 255 deletions
diff --git a/WebCore/storage/ChangeVersionWrapper.cpp b/WebCore/storage/ChangeVersionWrapper.cpp
index 17a9407..66ca63f 100644
--- a/WebCore/storage/ChangeVersionWrapper.cpp
+++ b/WebCore/storage/ChangeVersionWrapper.cpp
@@ -30,6 +30,9 @@
#if ENABLE(DATABASE)
#include "Database.h"
+#include "SQLError.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
namespace WebCore {
diff --git a/WebCore/storage/ChangeVersionWrapper.h b/WebCore/storage/ChangeVersionWrapper.h
index b14fe55..86cc182 100644
--- a/WebCore/storage/ChangeVersionWrapper.h
+++ b/WebCore/storage/ChangeVersionWrapper.h
@@ -32,9 +32,12 @@
#include "PlatformString.h"
#include "SQLTransaction.h"
+#include <wtf/Forward.h>
namespace WebCore {
+class SQLError;
+
class ChangeVersionWrapper : public SQLTransactionWrapper {
public:
static PassRefPtr<ChangeVersionWrapper> create(const String& oldVersion, const String& newVersion) { return adoptRef(new ChangeVersionWrapper(oldVersion, newVersion)); }
diff --git a/WebCore/storage/Database.cpp b/WebCore/storage/Database.cpp
index 0644df5..c96dfba 100644
--- a/WebCore/storage/Database.cpp
+++ b/WebCore/storage/Database.cpp
@@ -29,8 +29,6 @@
#include "config.h"
#include "Database.h"
-#include <wtf/StdLibExtras.h>
-
#if ENABLE(DATABASE)
#include "ChangeVersionWrapper.h"
#include "DatabaseAuthorizer.h"
@@ -40,21 +38,25 @@
#include "DatabaseTracker.h"
#include "Document.h"
#include "ExceptionCode.h"
-#include "Frame.h"
#include "InspectorController.h"
#include "Logging.h"
#include "NotImplemented.h"
#include "Page.h"
-#include "OriginQuotaManager.h"
-#include "ScriptController.h"
-#include "SQLiteDatabase.h"
-#include "SQLiteFileSystem.h"
-#include "SQLiteStatement.h"
-#include "SQLResultSet.h"
+#include "SQLTransactionCallback.h"
#include "SQLTransactionClient.h"
#include "SQLTransactionCoordinator.h"
-
-#endif // ENABLE(DATABASE)
+#include "SQLTransactionErrorCallback.h"
+#include "SQLiteStatement.h"
+#include "ScriptController.h"
+#include "ScriptExecutionContext.h"
+#include "SecurityOrigin.h"
+#include "StringHash.h"
+#include "VoidCallback.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/StdLibExtras.h>
#if USE(JSC)
#include "JSDOMWindow.h"
@@ -71,8 +73,6 @@ const String& Database::databaseInfoTableName()
return name;
}
-#if ENABLE(DATABASE)
-
static bool isDatabaseAvailable = true;
void Database::setIsAvailable(bool available)
@@ -213,8 +213,8 @@ Database::Database(ScriptExecutionContext* context, const String& name, const St
, m_creationCallback(creationCallback)
{
ASSERT(m_scriptExecutionContext.get());
- m_mainThreadSecurityOrigin = m_scriptExecutionContext->securityOrigin();
- m_databaseThreadSecurityOrigin = m_mainThreadSecurityOrigin->threadsafeCopy();
+ m_contextThreadSecurityOrigin = m_scriptExecutionContext->securityOrigin();
+ m_databaseThreadSecurityOrigin = m_contextThreadSecurityOrigin->threadsafeCopy();
if (m_name.isNull())
m_name = "";
@@ -491,6 +491,30 @@ void Database::setAuthorizerReadOnly()
m_databaseAuthorizer->setReadOnly();
}
+bool Database::lastActionChangedDatabase()
+{
+ ASSERT(m_databaseAuthorizer);
+ return m_databaseAuthorizer->lastActionChangedDatabase();
+}
+
+bool Database::lastActionWasInsert()
+{
+ ASSERT(m_databaseAuthorizer);
+ return m_databaseAuthorizer->lastActionWasInsert();
+}
+
+void Database::resetDeletes()
+{
+ ASSERT(m_databaseAuthorizer);
+ m_databaseAuthorizer->resetDeletes();
+}
+
+bool Database::hadDeletes()
+{
+ ASSERT(m_databaseAuthorizer);
+ return m_databaseAuthorizer->hadDeletes();
+}
+
static int guidForOriginAndName(const String& origin, const String& name)
{
String stringID;
@@ -643,14 +667,20 @@ void Database::transaction(PassRefPtr<SQLTransactionCallback> callback, PassRefP
scheduleTransaction();
}
+void Database::inProgressTransactionCompleted()
+{
+ MutexLocker locker(m_transactionInProgressMutex);
+ m_transactionInProgress = false;
+ scheduleTransaction();
+}
+
void Database::scheduleTransaction()
{
ASSERT(!m_transactionInProgressMutex.tryLock()); // Locked by caller.
RefPtr<SQLTransaction> transaction;
if (m_isTransactionQueueEnabled && !m_transactionQueue.isEmpty()) {
- transaction = m_transactionQueue.first();
- m_transactionQueue.removeFirst();
+ transaction = m_transactionQueue.takeFirst();
}
if (transaction && m_scriptExecutionContext->databaseThread()) {
@@ -780,8 +810,8 @@ void Database::setExpectedVersion(const String& version)
SecurityOrigin* Database::securityOrigin() const
{
- if (scriptExecutionContext()->isContextThread())
- return m_mainThreadSecurityOrigin.get();
+ if (m_scriptExecutionContext->isContextThread())
+ return m_contextThreadSecurityOrigin.get();
if (currentThread() == m_scriptExecutionContext->databaseThread()->getThreadID())
return m_databaseThreadSecurityOrigin.get();
return 0;
@@ -818,6 +848,6 @@ void Database::incrementalVacuumIfNeeded()
m_sqliteDatabase.runIncrementalVacuumCommand();
}
-#endif // ENABLE(DATABASE)
-
} // namespace WebCore
+
+#endif // ENABLE(DATABASE)
diff --git a/WebCore/storage/Database.h b/WebCore/storage/Database.h
index 890d98c..f9fd3cd 100644
--- a/WebCore/storage/Database.h
+++ b/WebCore/storage/Database.h
@@ -31,42 +31,31 @@
#if ENABLE(DATABASE)
#include "PlatformString.h"
-#include "SecurityOrigin.h"
#include "SQLiteDatabase.h"
-#include "SQLTransaction.h"
-#include "StringHash.h"
-#include "Timer.h"
-#include "VoidCallback.h"
+#ifndef NDEBUG
+#include "SecurityOrigin.h"
+#endif
-#include <wtf/Forward.h>
-#include <wtf/HashSet.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
#include <wtf/Deque.h>
-#else
-#include "PlatformString.h"
-#endif
+#include <wtf/Forward.h>
-#if ENABLE(DATABASE)
namespace WebCore {
class DatabaseAuthorizer;
class DatabaseCallback;
class DatabaseThread;
class ScriptExecutionContext;
-class SQLResultSet;
+class SecurityOrigin;
+class SQLTransaction;
class SQLTransactionCallback;
class SQLTransactionClient;
class SQLTransactionCoordinator;
class SQLTransactionErrorCallback;
-class SQLValue;
+class VoidCallback;
typedef int ExceptionCode;
class Database : public ThreadSafeShared<Database> {
- friend class DatabaseTransactionTask;
- friend class SQLStatement;
- friend class SQLTransaction;
public:
static void setIsAvailable(bool);
static bool isAvailable();
@@ -74,15 +63,12 @@ public:
~Database();
// Direct support for the DOM API
- static PassRefPtr<Database> openDatabase(ScriptExecutionContext* context, const String& name,
- const String& expectedVersion, const String& displayName,
- unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback,
- ExceptionCode&);
+ static PassRefPtr<Database> openDatabase(ScriptExecutionContext*, const String& name, const String& expectedVersion, const String& displayName,
+ unsigned long estimatedSize, PassRefPtr<DatabaseCallback>, ExceptionCode&);
String version() const;
- void changeVersion(const String& oldVersion, const String& newVersion,
- PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback,
- PassRefPtr<VoidCallback> successCallback);
- void transaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback,
+ void changeVersion(const String& oldVersion, const String& newVersion, PassRefPtr<SQLTransactionCallback>,
+ PassRefPtr<SQLTransactionErrorCallback>, PassRefPtr<VoidCallback> successCallback);
+ void transaction(PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>,
PassRefPtr<VoidCallback> successCallback, bool readOnly);
// Internal engine support
@@ -91,11 +77,16 @@ public:
void disableAuthorizer();
void enableAuthorizer();
void setAuthorizerReadOnly();
+ bool lastActionChangedDatabase();
+ bool lastActionWasInsert();
+ void resetDeletes();
+ bool hadDeletes();
Vector<String> tableNames();
ScriptExecutionContext* scriptExecutionContext() const { return m_scriptExecutionContext.get(); }
SecurityOrigin* securityOrigin() const;
+ SQLiteDatabase& sqliteDatabase() { return m_sqliteDatabase; }
String stringIdentifier() const;
String displayName() const;
unsigned long estimatedSize() const;
@@ -127,6 +118,10 @@ public:
bool performOpenAndVerify(ExceptionCode&);
+ void inProgressTransactionCompleted();
+ void scheduleTransactionCallback(SQLTransaction*);
+ void scheduleTransactionStep(SQLTransaction*, bool immediately = false);
+
Vector<String> performGetTableNames();
void performCreationCallback();
@@ -136,15 +131,12 @@ public:
void incrementalVacuumIfNeeded();
private:
- Database(ScriptExecutionContext* context, const String& name,
- const String& expectedVersion, const String& displayName,
- unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback);
+ Database(ScriptExecutionContext*, const String& name, const String& expectedVersion,
+ const String& displayName, unsigned long estimatedSize, PassRefPtr<DatabaseCallback>);
bool openAndVerifyVersion(ExceptionCode&);
void scheduleTransaction();
- void scheduleTransactionCallback(SQLTransaction*);
- void scheduleTransactionStep(SQLTransaction* transaction, bool immediately = false);
Deque<RefPtr<SQLTransaction> > m_transactionQueue;
Mutex m_transactionInProgressMutex;
@@ -154,7 +146,7 @@ private:
static void deliverPendingCallback(void*);
RefPtr<ScriptExecutionContext> m_scriptExecutionContext;
- RefPtr<SecurityOrigin> m_mainThreadSecurityOrigin;
+ RefPtr<SecurityOrigin> m_contextThreadSecurityOrigin;
RefPtr<SecurityOrigin> m_databaseThreadSecurityOrigin;
String m_name;
int m_guid;
@@ -177,21 +169,12 @@ private:
RefPtr<DatabaseCallback> m_creationCallback;
#ifndef NDEBUG
- String databaseDebugName() const { return m_mainThreadSecurityOrigin->toString() + "::" + m_name; }
+ String databaseDebugName() const { return m_contextThreadSecurityOrigin->toString() + "::" + m_name; }
#endif
};
} // namespace WebCore
-#else
-
-namespace WebCore {
-class Database : public ThreadSafeShared<Database> {
-public:
- static const String& databaseInfoTableName();
-};
-} // namespace WebCore
-
#endif // ENABLE(DATABASE)
#endif // Database_h
diff --git a/WebCore/storage/DatabaseAuthorizer.cpp b/WebCore/storage/DatabaseAuthorizer.cpp
index 05d9a66..1ea99d9 100644
--- a/WebCore/storage/DatabaseAuthorizer.cpp
+++ b/WebCore/storage/DatabaseAuthorizer.cpp
@@ -29,6 +29,7 @@
#include "config.h"
#include "DatabaseAuthorizer.h"
+#if ENABLE(DATABASE)
#include "Database.h"
#include "PlatformString.h"
@@ -48,6 +49,11 @@ void DatabaseAuthorizer::reset()
m_readOnly = false;
}
+void DatabaseAuthorizer::resetDeletes()
+{
+ m_hadDeletes = false;
+}
+
void DatabaseAuthorizer::addWhitelistedFunctions()
{
// SQLite functions used to help implement some operations
@@ -137,7 +143,7 @@ int DatabaseAuthorizer::dropTable(const String& tableName)
if (m_readOnly && m_securityEnabled)
return SQLAuthDeny;
- return denyBasedOnTableName(tableName);
+ return updateDeletesBasedOnTableName(tableName);
}
int DatabaseAuthorizer::dropTempTable(const String& tableName)
@@ -148,7 +154,7 @@ int DatabaseAuthorizer::dropTempTable(const String& tableName)
if (m_readOnly && m_securityEnabled)
return SQLAuthDeny;
- return denyBasedOnTableName(tableName);
+ return updateDeletesBasedOnTableName(tableName);
}
int DatabaseAuthorizer::allowAlterTable(const String&, const String& tableName)
@@ -185,7 +191,7 @@ int DatabaseAuthorizer::dropIndex(const String&, const String& tableName)
if (m_readOnly && m_securityEnabled)
return SQLAuthDeny;
- return denyBasedOnTableName(tableName);
+ return updateDeletesBasedOnTableName(tableName);
}
int DatabaseAuthorizer::dropTempIndex(const String&, const String& tableName)
@@ -196,7 +202,7 @@ int DatabaseAuthorizer::dropTempIndex(const String&, const String& tableName)
if (m_readOnly && m_securityEnabled)
return SQLAuthDeny;
- return denyBasedOnTableName(tableName);
+ return updateDeletesBasedOnTableName(tableName);
}
int DatabaseAuthorizer::createTrigger(const String&, const String& tableName)
@@ -224,7 +230,7 @@ int DatabaseAuthorizer::dropTrigger(const String&, const String& tableName)
if (m_readOnly && m_securityEnabled)
return SQLAuthDeny;
- return denyBasedOnTableName(tableName);
+ return updateDeletesBasedOnTableName(tableName);
}
int DatabaseAuthorizer::dropTempTrigger(const String&, const String& tableName)
@@ -235,7 +241,7 @@ int DatabaseAuthorizer::dropTempTrigger(const String&, const String& tableName)
if (m_readOnly && m_securityEnabled)
return SQLAuthDeny;
- return denyBasedOnTableName(tableName);
+ return updateDeletesBasedOnTableName(tableName);
}
int DatabaseAuthorizer::createView(const String&)
@@ -253,7 +259,11 @@ int DatabaseAuthorizer::createTempView(const String&)
int DatabaseAuthorizer::dropView(const String&)
{
- return (m_readOnly && m_securityEnabled ? SQLAuthDeny : SQLAuthAllow);
+ if (m_readOnly && m_securityEnabled)
+ return SQLAuthDeny;
+
+ m_hadDeletes = true;
+ return SQLAuthAllow;
}
int DatabaseAuthorizer::dropTempView(const String&)
@@ -261,7 +271,11 @@ int DatabaseAuthorizer::dropTempView(const String&)
// SQLITE_DROP_TEMP_VIEW results in a DELETE operation, which is not
// allowed in read-only transactions or private browsing, so we might as
// well disallow SQLITE_DROP_TEMP_VIEW in these cases
- return (m_readOnly && m_securityEnabled ? SQLAuthDeny : SQLAuthAllow);
+ if (m_readOnly && m_securityEnabled)
+ return SQLAuthDeny;
+
+ m_hadDeletes = true;
+ return SQLAuthAllow;
}
int DatabaseAuthorizer::createVTable(const String& tableName, const String& moduleName)
@@ -286,7 +300,7 @@ int DatabaseAuthorizer::dropVTable(const String& tableName, const String& module
if (moduleName != "fts3")
return SQLAuthDeny;
- return denyBasedOnTableName(tableName);
+ return updateDeletesBasedOnTableName(tableName);
}
int DatabaseAuthorizer::allowDelete(const String& tableName)
@@ -294,7 +308,7 @@ int DatabaseAuthorizer::allowDelete(const String& tableName)
if (m_readOnly && m_securityEnabled)
return SQLAuthDeny;
- return denyBasedOnTableName(tableName);
+ return updateDeletesBasedOnTableName(tableName);
}
int DatabaseAuthorizer::allowInsert(const String& tableName)
@@ -391,4 +405,14 @@ int DatabaseAuthorizer::denyBasedOnTableName(const String& tableName)
return SQLAuthAllow;
}
+int DatabaseAuthorizer::updateDeletesBasedOnTableName(const String& tableName)
+{
+ int allow = denyBasedOnTableName(tableName);
+ if (allow)
+ m_hadDeletes = true;
+ return allow;
+}
+
} // namespace WebCore
+
+#endif // ENABLE(DATABASE)
diff --git a/WebCore/storage/DatabaseAuthorizer.h b/WebCore/storage/DatabaseAuthorizer.h
index 037409e..7da0143 100644
--- a/WebCore/storage/DatabaseAuthorizer.h
+++ b/WebCore/storage/DatabaseAuthorizer.h
@@ -90,19 +90,23 @@ public:
void setReadOnly();
void reset();
+ void resetDeletes();
bool lastActionWasInsert() const { return m_lastActionWasInsert; }
bool lastActionChangedDatabase() const { return m_lastActionChangedDatabase; }
+ bool hadDeletes() const { return m_hadDeletes; }
private:
DatabaseAuthorizer();
void addWhitelistedFunctions();
int denyBasedOnTableName(const String&);
+ int updateDeletesBasedOnTableName(const String&);
bool m_securityEnabled : 1;
bool m_lastActionWasInsert : 1;
bool m_lastActionChangedDatabase : 1;
bool m_readOnly : 1;
+ bool m_hadDeletes : 1;
HashSet<String, CaseFoldingHash> m_whitelistedFunctions;
};
diff --git a/WebCore/storage/DatabaseTask.cpp b/WebCore/storage/DatabaseTask.cpp
index a8038c3..8d5f0a8 100644
--- a/WebCore/storage/DatabaseTask.cpp
+++ b/WebCore/storage/DatabaseTask.cpp
@@ -143,11 +143,8 @@ DatabaseTransactionTask::~DatabaseTransactionTask()
void DatabaseTransactionTask::doPerformTask()
{
- if (m_transaction->performNextStep()) {
- // The transaction is complete, we can move on to the next one.
- MutexLocker locker(m_transaction->database()->m_transactionInProgressMutex);
- m_transaction->database()->scheduleTransaction();
- }
+ if (m_transaction->performNextStep())
+ m_transaction->database()->inProgressTransactionCompleted();
}
#ifndef NDEBUG
diff --git a/WebCore/storage/DatabaseTask.h b/WebCore/storage/DatabaseTask.h
index b473f8f..1a820a5 100644
--- a/WebCore/storage/DatabaseTask.h
+++ b/WebCore/storage/DatabaseTask.h
@@ -32,6 +32,7 @@
#include "Database.h"
#include "ExceptionCode.h"
#include "PlatformString.h"
+#include "SQLTransaction.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/PassRefPtr.h>
@@ -40,13 +41,6 @@
namespace WebCore {
-class DatabaseTask;
-class DatabaseThread;
-class SQLValue;
-class SQLCallback;
-class SQLTransaction;
-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 {
diff --git a/WebCore/storage/IDBCallbacks.h b/WebCore/storage/IDBCallbacks.h
index ff6272a..c90acc5 100644
--- a/WebCore/storage/IDBCallbacks.h
+++ b/WebCore/storage/IDBCallbacks.h
@@ -32,6 +32,7 @@
#include "IDBDatabase.h"
#include "IDBDatabaseError.h"
#include "IDBIndex.h"
+#include "IDBObjectStore.h"
#include "SerializedScriptValue.h"
#include <wtf/RefCounted.h>
@@ -47,6 +48,7 @@ public:
virtual void onSuccess() = 0; // For "null".
virtual void onSuccess(PassRefPtr<IDBDatabase>) = 0;
virtual void onSuccess(PassRefPtr<IDBIndex>) = 0;
+ virtual void onSuccess(PassRefPtr<IDBObjectStore>) = 0;
virtual void onSuccess(PassRefPtr<SerializedScriptValue>) = 0;
};
diff --git a/WebCore/storage/IDBDatabase.h b/WebCore/storage/IDBDatabase.h
index 5bfb3c7..0055ad1 100644
--- a/WebCore/storage/IDBDatabase.h
+++ b/WebCore/storage/IDBDatabase.h
@@ -35,6 +35,9 @@
namespace WebCore {
class DOMStringList;
+class Frame;
+class IDBCallbacks;
+class IDBObjectStore;
// This class is shared by IDBDatabaseRequest (async) and IDBDatabaseSync (sync).
// This is implemented by IDBDatabaseImpl and optionally others (in order to proxy
@@ -44,10 +47,16 @@ class IDBDatabase : public ThreadSafeShared<IDBDatabase> {
public:
virtual ~IDBDatabase() { }
- virtual String name() = 0;
- virtual String description() = 0;
- virtual String version() = 0;
- virtual PassRefPtr<DOMStringList> objectStores() = 0;
+ virtual String name() const = 0;
+ virtual String description() const = 0;
+ virtual String version() const = 0;
+ virtual PassRefPtr<DOMStringList> objectStores() const = 0;
+
+ // FIXME: Add transaction and setVersion.
+
+ virtual void createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks>) = 0;
+ virtual PassRefPtr<IDBObjectStore> objectStore(const String& name, unsigned short mode) = 0;
+ virtual void removeObjectStore(const String& name, PassRefPtr<IDBCallbacks>) = 0;
};
} // namespace WebCore
diff --git a/WebCore/storage/IDBDatabaseImpl.cpp b/WebCore/storage/IDBDatabaseImpl.cpp
index 655bd59..712830a 100644
--- a/WebCore/storage/IDBDatabaseImpl.cpp
+++ b/WebCore/storage/IDBDatabaseImpl.cpp
@@ -27,6 +27,8 @@
#include "IDBDatabaseImpl.h"
#include "DOMStringList.h"
+#include "IDBDatabaseException.h"
+#include "IDBObjectStoreImpl.h"
#if ENABLE(INDEXED_DATABASE)
@@ -43,10 +45,42 @@ IDBDatabaseImpl::~IDBDatabaseImpl()
{
}
-PassRefPtr<DOMStringList> IDBDatabaseImpl::objectStores()
+PassRefPtr<DOMStringList> IDBDatabaseImpl::objectStores() const
{
- // FIXME: This should return the actual list.
- return DOMStringList::create();
+ RefPtr<DOMStringList> objectStoreNames = DOMStringList::create();
+ for (ObjectStoreMap::const_iterator it = m_objectStores.begin(); it != m_objectStores.end(); ++it)
+ objectStoreNames->append(it->first);
+ return objectStoreNames.release();
+}
+
+void IDBDatabaseImpl::createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks> callbacks)
+{
+ if (m_objectStores.contains(name)) {
+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "An objectStore with that name already exists."));
+ return;
+ }
+
+ RefPtr<IDBObjectStore> objectStore = IDBObjectStoreImpl::create(name, keyPath, autoIncrement);
+ m_objectStores.set(name, objectStore);
+ callbacks->onSuccess(objectStore.release());
+}
+
+PassRefPtr<IDBObjectStore> IDBDatabaseImpl::objectStore(const String& name, unsigned short mode)
+{
+ // FIXME: If no transaction is running, this should implicitly start one.
+ ASSERT(!mode); // FIXME: Handle non-standard modes.
+ return m_objectStores.get(name);
+}
+
+void IDBDatabaseImpl::removeObjectStore(const String& name, PassRefPtr<IDBCallbacks> callbacks)
+{
+ if (!m_objectStores.contains(name)) {
+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "No objectStore with that name exists."));
+ return;
+ }
+
+ m_objectStores.remove(name);
+ callbacks->onSuccess();
}
} // namespace WebCore
diff --git a/WebCore/storage/IDBDatabaseImpl.h b/WebCore/storage/IDBDatabaseImpl.h
index 679017d..7203c5a 100644
--- a/WebCore/storage/IDBDatabaseImpl.h
+++ b/WebCore/storage/IDBDatabaseImpl.h
@@ -26,7 +26,10 @@
#ifndef IDBDatabaseImpl_h
#define IDBDatabaseImpl_h
+#include "IDBCallbacks.h"
#include "IDBDatabase.h"
+#include "StringHash.h"
+#include <wtf/HashMap.h>
#if ENABLE(INDEXED_DATABASE)
@@ -41,10 +44,14 @@ public:
virtual ~IDBDatabaseImpl();
// Implements IDBDatabase
- virtual String name() { return m_name; }
- virtual String description() { return m_description; }
- virtual String version() { return m_version; }
- virtual PassRefPtr<DOMStringList> objectStores();
+ virtual String name() const { return m_name; }
+ virtual String description() const { return m_description; }
+ virtual String version() const { return m_version; }
+ virtual PassRefPtr<DOMStringList> objectStores() const;
+
+ virtual void createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks>);
+ virtual PassRefPtr<IDBObjectStore> objectStore(const String& name, unsigned short mode);
+ virtual void removeObjectStore(const String& name, PassRefPtr<IDBCallbacks>);
private:
IDBDatabaseImpl(const String& name, const String& description, const String& version);
@@ -52,6 +59,9 @@ private:
String m_name;
String m_description;
String m_version;
+
+ typedef HashMap<String, RefPtr<IDBObjectStore> > ObjectStoreMap;
+ ObjectStoreMap m_objectStores;
};
} // namespace WebCore
diff --git a/WebCore/storage/IDBDatabaseRequest.cpp b/WebCore/storage/IDBDatabaseRequest.cpp
index 311fb25..c620279 100644
--- a/WebCore/storage/IDBDatabaseRequest.cpp
+++ b/WebCore/storage/IDBDatabaseRequest.cpp
@@ -26,21 +26,48 @@
#include "config.h"
#include "IDBDatabaseRequest.h"
+#include "IDBAny.h"
+#include "IDBObjectStoreRequest.h"
+#include "IDBRequest.h"
#include "IndexedDatabase.h"
+#include "ScriptExecutionContext.h"
#if ENABLE(INDEXED_DATABASE)
namespace WebCore {
-IDBDatabaseRequest::IDBDatabaseRequest(PassRefPtr<IDBDatabase> idbDatabase)
- : m_idbDatabase(idbDatabase)
+IDBDatabaseRequest::IDBDatabaseRequest(PassRefPtr<IDBDatabase> database)
+ : m_database(database)
{
+ m_this = IDBAny::create();
+ m_this->set(this);
}
IDBDatabaseRequest::~IDBDatabaseRequest()
{
}
+PassRefPtr<IDBRequest> IDBDatabaseRequest::createObjectStore(ScriptExecutionContext* context, const String& name, const String& keyPath, bool autoIncrement)
+{
+ RefPtr<IDBRequest> request = IDBRequest::create(context, m_this);
+ m_database->createObjectStore(name, keyPath, autoIncrement, request);
+ return request;
+}
+
+PassRefPtr<IDBObjectStoreRequest> IDBDatabaseRequest::objectStore(const String& name, unsigned short mode)
+{
+ RefPtr<IDBObjectStore> objectStore = m_database->objectStore(name, mode);
+ ASSERT(objectStore); // FIXME: If this is null, we should raise a NOT_FOUND_ERR.
+ return IDBObjectStoreRequest::create(objectStore.release());
+}
+
+PassRefPtr<IDBRequest> IDBDatabaseRequest::removeObjectStore(ScriptExecutionContext* context, const String& name)
+{
+ RefPtr<IDBRequest> request = IDBRequest::create(context, m_this);
+ m_database->removeObjectStore(name, request);
+ return request;
+}
+
} // namespace WebCore
#endif // ENABLE(INDEXED_DATABASE)
diff --git a/WebCore/storage/IDBDatabaseRequest.h b/WebCore/storage/IDBDatabaseRequest.h
index 26f6a86..6b9e107 100644
--- a/WebCore/storage/IDBDatabaseRequest.h
+++ b/WebCore/storage/IDBDatabaseRequest.h
@@ -36,24 +36,34 @@
namespace WebCore {
+class IDBAny;
+class IDBObjectStoreRequest;
+class IDBRequest;
+class ScriptExecutionContext;
+
class IDBDatabaseRequest : public RefCounted<IDBDatabaseRequest> {
public:
- static PassRefPtr<IDBDatabaseRequest> create(PassRefPtr<IDBDatabase> idbDatabase)
+ static PassRefPtr<IDBDatabaseRequest> create(PassRefPtr<IDBDatabase> database)
{
- return adoptRef(new IDBDatabaseRequest(idbDatabase));
+ return adoptRef(new IDBDatabaseRequest(database));
}
~IDBDatabaseRequest();
// Implement the IDL
- String name() const { return m_idbDatabase->name(); }
- String description() const { return m_idbDatabase->description(); }
- String version() const { return m_idbDatabase->version(); }
- PassRefPtr<DOMStringList> objectStores() const { return m_idbDatabase->objectStores(); }
+ String name() const { return m_database->name(); }
+ String description() const { return m_database->description(); }
+ String version() const { return m_database->version(); }
+ PassRefPtr<DOMStringList> objectStores() const { return m_database->objectStores(); }
+
+ PassRefPtr<IDBRequest> createObjectStore(ScriptExecutionContext*, const String& name, const String& keyPath = "", bool autoIncrement = false);
+ PassRefPtr<IDBObjectStoreRequest> objectStore(const String& name, unsigned short mode = 0); // FIXME: Use constant rather than 0.
+ PassRefPtr<IDBRequest> removeObjectStore(ScriptExecutionContext*, const String& name);
private:
IDBDatabaseRequest(PassRefPtr<IDBDatabase>);
- RefPtr<IDBDatabase> m_idbDatabase;
+ RefPtr<IDBDatabase> m_database;
+ RefPtr<IDBAny> m_this;
};
} // namespace WebCore
diff --git a/WebCore/storage/IDBDatabaseRequest.idl b/WebCore/storage/IDBDatabaseRequest.idl
index b835ace..c018bbf 100644
--- a/WebCore/storage/IDBDatabaseRequest.idl
+++ b/WebCore/storage/IDBDatabaseRequest.idl
@@ -28,12 +28,18 @@ module storage {
interface [
Conditional=INDEXED_DATABASE
] IDBDatabaseRequest {
- // FIXME: Complete this file.
-
readonly attribute DOMString name;
- // readonly attribute DOMString description;
+ readonly attribute DOMString description;
readonly attribute DOMString version;
readonly attribute DOMStringList objectStores;
+
+ // FIXME: Add transaction.
+ // FIXME: Add setVersion.
+
+ [CallWith=ScriptExecutionContext] IDBRequest createObjectStore(in DOMString name, in [Optional] DOMString path, in [Optional] boolean autoIncrement);
+ // FIXME: objectStore needs to be able to raise an IDBDatabaseException.
+ IDBObjectStoreRequest objectStore(in DOMString name, in [Optional] unsigned short mode);
+ [CallWith=ScriptExecutionContext] IDBRequest removeObjectStore(in DOMString name);
};
}
diff --git a/WebCore/storage/IDBKeyRange.cpp b/WebCore/storage/IDBKeyRange.cpp
new file mode 100644
index 0000000..34c11fe
--- /dev/null
+++ b/WebCore/storage/IDBKeyRange.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ *
+ * 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 "IDBKeyRange.h"
+
+#include "IDBAny.h"
+#include "SerializedScriptValue.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+
+IDBKeyRange::IDBKeyRange(PassRefPtr<SerializedScriptValue> left, PassRefPtr<SerializedScriptValue> right, unsigned short flags)
+ : m_left(IDBAny::create())
+ , m_right(IDBAny::create())
+ , m_flags(flags)
+{
+ m_left->set(left);
+ m_right->set(right);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
diff --git a/WebCore/storage/IDBKeyRange.h b/WebCore/storage/IDBKeyRange.h
new file mode 100644
index 0000000..58c1399
--- /dev/null
+++ b/WebCore/storage/IDBKeyRange.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ *
+ * 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 IDBKeyRange_h
+#define IDBKeyRange_h
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBAny.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class SerializedScriptValue;
+
+class IDBKeyRange : public RefCounted<IDBKeyRange> {
+public:
+ // Keep in sync with what's in the .idl file.
+ enum Flags {
+ SINGLE = 0,
+ LEFT_OPEN = 1,
+ RIGHT_OPEN = 2,
+ LEFT_BOUND = 4,
+ RIGHT_BOUND = 8,
+ };
+
+ static PassRefPtr<IDBKeyRange> create(PassRefPtr<SerializedScriptValue> left, PassRefPtr<SerializedScriptValue> right, unsigned short flags)
+ {
+ return adoptRef(new IDBKeyRange(left, right, flags));
+ }
+ ~IDBKeyRange() { }
+
+
+ PassRefPtr<IDBAny> left() const { return m_left; }
+ PassRefPtr<IDBAny> right() const { return m_right; }
+ unsigned short flags() const { return m_flags; }
+
+private:
+ IDBKeyRange(PassRefPtr<SerializedScriptValue> left, PassRefPtr<SerializedScriptValue> right, unsigned short flags);
+
+ RefPtr<IDBAny> m_left;
+ RefPtr<IDBAny> m_right;
+ unsigned short m_flags;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // IDBKeyRange_h
diff --git a/WebCore/storage/IDBKeyRange.idl b/WebCore/storage/IDBKeyRange.idl
new file mode 100644
index 0000000..05f6505
--- /dev/null
+++ b/WebCore/storage/IDBKeyRange.idl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ *
+ * 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
+ ] IDBKeyRange {
+ // Keep in sync with what's in the .h file.
+ const unsigned short SINGLE = 0;
+ const unsigned short LEFT_OPEN = 1;
+ const unsigned short RIGHT_OPEN = 2;
+ const unsigned short LEFT_BOUND = 4;
+ const unsigned short RIGHT_BOUND = 8;
+
+ readonly attribute IDBAny left;
+ readonly attribute IDBAny right;
+ readonly attribute unsigned short flags;
+ };
+
+}
diff --git a/WebCore/storage/IDBObjectStore.h b/WebCore/storage/IDBObjectStore.h
index c1ce129..837b65a 100644
--- a/WebCore/storage/IDBObjectStore.h
+++ b/WebCore/storage/IDBObjectStore.h
@@ -27,8 +27,6 @@
#define IDBObjectStore_h
#include "PlatformString.h"
-#include "StringHash.h"
-#include <wtf/HashMap.h>
#include <wtf/Threading.h>
#if ENABLE(INDEXED_DATABASE)
@@ -36,33 +34,20 @@
namespace WebCore {
class DOMStringList;
-class IDBIndex;
class IDBCallbacks;
+class IDBIndex;
-// FIXME: This needs to be split into an interface and Impl classes.
class IDBObjectStore : public ThreadSafeShared<IDBObjectStore> {
public:
- static PassRefPtr<IDBObjectStore> create()
- {
- return adoptRef(new IDBObjectStore());
- }
- virtual ~IDBObjectStore();
-
- String name() const { return m_name; }
- String keyPath() const { return m_keyPath; }
- PassRefPtr<DOMStringList> indexNames() const;
-
- void createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks>);
- PassRefPtr<IDBIndex> index(const String& name);
- void removeIndex(const String& name, PassRefPtr<IDBCallbacks>);
+ virtual ~IDBObjectStore() { }
-private:
- IDBObjectStore();
+ virtual String name() const = 0;
+ virtual String keyPath() const = 0;
+ virtual PassRefPtr<DOMStringList> indexNames() const = 0;
- String m_name;
- String m_keyPath;
- typedef HashMap<String, RefPtr<IDBIndex> > IndexMap;
- IndexMap m_indexes;
+ virtual void createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks>) = 0;
+ virtual PassRefPtr<IDBIndex> index(const String& name) = 0;
+ virtual void removeIndex(const String& name, PassRefPtr<IDBCallbacks>) = 0;
};
} // namespace WebCore
diff --git a/WebCore/storage/IDBObjectStore.cpp b/WebCore/storage/IDBObjectStoreImpl.cpp
index 4aef460..b84ceb2 100644..100755
--- a/WebCore/storage/IDBObjectStore.cpp
+++ b/WebCore/storage/IDBObjectStoreImpl.cpp
@@ -24,7 +24,7 @@
*/
#include "config.h"
-#include "IDBObjectStore.h"
+#include "IDBObjectStoreImpl.h"
#include "DOMStringList.h"
#include "IDBCallbacks.h"
@@ -35,15 +35,18 @@
namespace WebCore {
-IDBObjectStore::IDBObjectStore()
+IDBObjectStoreImpl::~IDBObjectStoreImpl()
{
}
-IDBObjectStore::~IDBObjectStore()
+IDBObjectStoreImpl::IDBObjectStoreImpl(const String& name, const String& keyPath, bool autoIncrement)
+ : m_name(name)
+ , m_keyPath(keyPath)
+ , m_autoIncrement(autoIncrement)
{
}
-PassRefPtr<DOMStringList> IDBObjectStore::indexNames() const
+PassRefPtr<DOMStringList> IDBObjectStoreImpl::indexNames() const
{
RefPtr<DOMStringList> indexNames = DOMStringList::create();
for (IndexMap::const_iterator it = m_indexes.begin(); it != m_indexes.end(); ++it)
@@ -51,7 +54,7 @@ PassRefPtr<DOMStringList> IDBObjectStore::indexNames() const
return indexNames.release();
}
-void IDBObjectStore::createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks> callbacks)
+void IDBObjectStoreImpl::createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks> callbacks)
{
if (m_indexes.contains(name)) {
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "Index name already exists."));
@@ -64,12 +67,12 @@ void IDBObjectStore::createIndex(const String& name, const String& keyPath, bool
callbacks->onSuccess(index.release());
}
-PassRefPtr<IDBIndex> IDBObjectStore::index(const String& name)
+PassRefPtr<IDBIndex> IDBObjectStoreImpl::index(const String& name)
{
return m_indexes.get(name);
}
-void IDBObjectStore::removeIndex(const String& name, PassRefPtr<IDBCallbacks> callbacks)
+void IDBObjectStoreImpl::removeIndex(const String& name, PassRefPtr<IDBCallbacks> callbacks)
{
if (!m_indexes.contains(name)) {
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Index name does not exist."));
@@ -80,7 +83,7 @@ void IDBObjectStore::removeIndex(const String& name, PassRefPtr<IDBCallbacks> ca
callbacks->onSuccess();
}
-} // namespace WebCore
-#endif // ENABLE(INDEXED_DATABASE)
+} // namespace WebCore
+#endif
diff --git a/WebCore/storage/IDBObjectStoreImpl.h b/WebCore/storage/IDBObjectStoreImpl.h
new file mode 100755
index 0000000..89a06db
--- /dev/null
+++ b/WebCore/storage/IDBObjectStoreImpl.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ *
+ * 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 IDBObjectStoreImpl_h
+#define IDBObjectStoreImpl_h
+
+#include "IDBObjectStore.h"
+#include "StringHash.h"
+#include <wtf/HashMap.h>
+
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+
+class IDBObjectStoreImpl : public IDBObjectStore {
+public:
+ static PassRefPtr<IDBObjectStore> create(const String& name, const String& keyPath, bool autoIncrement)
+ {
+ return adoptRef(new IDBObjectStoreImpl(name, keyPath, autoIncrement));
+ }
+ virtual ~IDBObjectStoreImpl();
+
+ String name() const { return m_name; }
+ String keyPath() const { return m_keyPath; }
+ PassRefPtr<DOMStringList> indexNames() const;
+
+ void createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks>);
+ PassRefPtr<IDBIndex> index(const String& name);
+ void removeIndex(const String& name, PassRefPtr<IDBCallbacks>);
+
+private:
+ IDBObjectStoreImpl(const String& name, const String& keyPath, bool autoIncrement);
+
+ String m_name;
+ String m_keyPath;
+ bool m_autoIncrement;
+
+ typedef HashMap<String, RefPtr<IDBIndex> > IndexMap;
+ IndexMap m_indexes;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // IDBObjectStoreImpl_h
diff --git a/WebCore/storage/IDBObjectStoreRequest.cpp b/WebCore/storage/IDBObjectStoreRequest.cpp
index 35763cb..b2c36dc 100644
--- a/WebCore/storage/IDBObjectStoreRequest.cpp
+++ b/WebCore/storage/IDBObjectStoreRequest.cpp
@@ -29,7 +29,6 @@
#include "DOMStringList.h"
#include "IDBAny.h"
#include "IDBIndexRequest.h"
-#include "ScriptExecutionContext.h"
#include "SerializedScriptValue.h"
#include <wtf/UnusedParam.h>
@@ -37,9 +36,8 @@
namespace WebCore {
-IDBObjectStoreRequest::IDBObjectStoreRequest(ScriptExecutionContext* context, PassRefPtr<IDBObjectStore> idbObjectStore)
+IDBObjectStoreRequest::IDBObjectStoreRequest(PassRefPtr<IDBObjectStore> idbObjectStore)
: m_objectStore(idbObjectStore)
- , m_scriptExecutionContext(context)
{
m_this = IDBAny::create();
m_this->set(this);
@@ -60,63 +58,68 @@ PassRefPtr<DOMStringList> IDBObjectStoreRequest::indexNames() const
return m_objectStore->indexNames();
}
-PassRefPtr<IDBRequest> IDBObjectStoreRequest::get(PassRefPtr<SerializedScriptValue> key)
+PassRefPtr<IDBRequest> IDBObjectStoreRequest::get(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> key)
{
// FIXME: implement
+ UNUSED_PARAM(context);
UNUSED_PARAM(key);
return 0;
}
-PassRefPtr<IDBRequest> IDBObjectStoreRequest::add(PassRefPtr<SerializedScriptValue> value, PassRefPtr<SerializedScriptValue> key)
+PassRefPtr<IDBRequest> IDBObjectStoreRequest::add(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, PassRefPtr<SerializedScriptValue> key)
{
// FIXME: implement
+ UNUSED_PARAM(context);
UNUSED_PARAM(value);
UNUSED_PARAM(key);
return 0;
}
-PassRefPtr<IDBRequest> IDBObjectStoreRequest::modify(PassRefPtr<SerializedScriptValue> value, PassRefPtr<SerializedScriptValue> key)
+PassRefPtr<IDBRequest> IDBObjectStoreRequest::modify(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, PassRefPtr<SerializedScriptValue> key)
{
// FIXME: implement
+ UNUSED_PARAM(context);
UNUSED_PARAM(value);
UNUSED_PARAM(key);
return 0;
}
-PassRefPtr<IDBRequest> IDBObjectStoreRequest::addOrModify(PassRefPtr<SerializedScriptValue> value, PassRefPtr<SerializedScriptValue> key)
+PassRefPtr<IDBRequest> IDBObjectStoreRequest::addOrModify(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, PassRefPtr<SerializedScriptValue> key)
{
// FIXME: implement
+ UNUSED_PARAM(context);
UNUSED_PARAM(value);
UNUSED_PARAM(key);
return 0;
}
-PassRefPtr<IDBRequest> IDBObjectStoreRequest::remove(PassRefPtr<SerializedScriptValue> key)
+PassRefPtr<IDBRequest> IDBObjectStoreRequest::remove(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> key)
{
// FIXME: implement
+ UNUSED_PARAM(context);
UNUSED_PARAM(key);
return 0;
}
-PassRefPtr<IDBRequest> IDBObjectStoreRequest::createIndex(const String& name, const String& keyPath, bool unique) const
+PassRefPtr<IDBRequest> IDBObjectStoreRequest::createIndex(ScriptExecutionContext* context, const String& name, const String& keyPath, bool unique)
{
- // FIXME: Implement.
- UNUSED_PARAM(name);
- UNUSED_PARAM(keyPath);
- UNUSED_PARAM(unique);
- return 0;
+ RefPtr<IDBRequest> request = IDBRequest::create(context, m_this);
+ m_objectStore->createIndex(name, keyPath, unique, request);
+ return request;
}
-PassRefPtr<IDBIndexRequest> IDBObjectStoreRequest::index(const String& name) const
+PassRefPtr<IDBIndexRequest> IDBObjectStoreRequest::index(const String& name)
{
- return IDBIndexRequest::create(m_objectStore->index(name));
+ RefPtr<IDBIndex> index = m_objectStore->index(name);
+ ASSERT(index); // FIXME: If this is null, we should raise a NOT_FOUND_ERR.
+ return IDBIndexRequest::create(index.release());
}
-PassRefPtr<IDBRequest> IDBObjectStoreRequest::removeIndex(const String& name) const
+PassRefPtr<IDBRequest> IDBObjectStoreRequest::removeIndex(ScriptExecutionContext* context, const String& name)
{
- // FIXME: Implement.
- UNUSED_PARAM(name);
- return 0;
+ RefPtr<IDBRequest> request = IDBRequest::create(context, m_this);
+ m_objectStore->removeIndex(name, request);
+ return request;
}
} // namespace WebCore
diff --git a/WebCore/storage/IDBObjectStoreRequest.h b/WebCore/storage/IDBObjectStoreRequest.h
index f03b406..f1a9f5b 100644
--- a/WebCore/storage/IDBObjectStoreRequest.h
+++ b/WebCore/storage/IDBObjectStoreRequest.h
@@ -40,14 +40,13 @@ namespace WebCore {
class DOMStringList;
class IDBAny;
class IDBIndexRequest;
-class ScriptExecutionContext;
class SerializedScriptValue;
class IDBObjectStoreRequest : public RefCounted<IDBObjectStoreRequest> {
public:
- static PassRefPtr<IDBObjectStoreRequest> create(ScriptExecutionContext* context, PassRefPtr<IDBObjectStore> idbObjectStore)
+ static PassRefPtr<IDBObjectStoreRequest> create(PassRefPtr<IDBObjectStore> idbObjectStore)
{
- return adoptRef(new IDBObjectStoreRequest(context, idbObjectStore));
+ return adoptRef(new IDBObjectStoreRequest(idbObjectStore));
}
~IDBObjectStoreRequest() { }
@@ -55,21 +54,20 @@ public:
String keyPath() const;
PassRefPtr<DOMStringList> indexNames() const;
- PassRefPtr<IDBRequest> get(PassRefPtr<SerializedScriptValue> key);
- PassRefPtr<IDBRequest> add(PassRefPtr<SerializedScriptValue> value, PassRefPtr<SerializedScriptValue> key = 0);
- PassRefPtr<IDBRequest> modify(PassRefPtr<SerializedScriptValue> value, PassRefPtr<SerializedScriptValue> key = 0);
- PassRefPtr<IDBRequest> addOrModify(PassRefPtr<SerializedScriptValue> value, PassRefPtr<SerializedScriptValue> key = 0);
- PassRefPtr<IDBRequest> remove(PassRefPtr<SerializedScriptValue> key);
+ PassRefPtr<IDBRequest> get(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue> key);
+ PassRefPtr<IDBRequest> add(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue> value, PassRefPtr<SerializedScriptValue> key = 0);
+ PassRefPtr<IDBRequest> modify(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue> value, PassRefPtr<SerializedScriptValue> key = 0);
+ PassRefPtr<IDBRequest> addOrModify(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue> value, PassRefPtr<SerializedScriptValue> key = 0);
+ PassRefPtr<IDBRequest> remove(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue> key);
- PassRefPtr<IDBRequest> createIndex(const String& name, const String& keyPath, bool unique = false) const;
- PassRefPtr<IDBIndexRequest> index(const String& name) const;
- PassRefPtr<IDBRequest> removeIndex(const String& name) const;
+ PassRefPtr<IDBRequest> createIndex(ScriptExecutionContext*, const String& name, const String& keyPath, bool unique = false);
+ PassRefPtr<IDBIndexRequest> index(const String& name);
+ PassRefPtr<IDBRequest> removeIndex(ScriptExecutionContext*, const String& name);
private:
- IDBObjectStoreRequest(ScriptExecutionContext*, PassRefPtr<IDBObjectStore>);
+ IDBObjectStoreRequest(PassRefPtr<IDBObjectStore>);
RefPtr<IDBObjectStore> m_objectStore;
- RefPtr<ScriptExecutionContext> m_scriptExecutionContext;
RefPtr<IDBAny> m_this;
};
@@ -77,5 +75,5 @@ private:
#endif
-#endif // IDBDatabaseRequest_h
+#endif // IDBObjectStoreRequest_h
diff --git a/WebCore/storage/IDBObjectStoreRequest.idl b/WebCore/storage/IDBObjectStoreRequest.idl
index 2d4c8be..873629d 100644
--- a/WebCore/storage/IDBObjectStoreRequest.idl
+++ b/WebCore/storage/IDBObjectStoreRequest.idl
@@ -28,16 +28,20 @@ module storage {
interface [
Conditional=INDEXED_DATABASE
] IDBObjectStoreRequest {
- IDBRequest get(in SerializedScriptValue key);
+ [CallWith=ScriptExecutionContext] IDBRequest get(in SerializedScriptValue key);
+
// FIXME: Come to concensus re getAll.
- IDBRequest add(in SerializedScriptValue value, in [Optional] SerializedScriptValue key);
- IDBRequest modify(in SerializedScriptValue value, in [Optional] SerializedScriptValue key);
- IDBRequest addOrModify(in SerializedScriptValue value, in [Optional] SerializedScriptValue key);
- IDBRequest remove(in SerializedScriptValue key);
+ // FIXME: SerializedScriptValue raises an exception if you pass in something that can't be serialized.
+ // We need to instead "raise" this error via an error callback.
+ [CallWith=ScriptExecutionContext] IDBRequest add(in SerializedScriptValue value, in [Optional] SerializedScriptValue key);
+ [CallWith=ScriptExecutionContext] IDBRequest modify(in SerializedScriptValue value, in [Optional] SerializedScriptValue key);
+ [CallWith=ScriptExecutionContext] IDBRequest addOrModify(in SerializedScriptValue value, in [Optional] SerializedScriptValue key);
+ [CallWith=ScriptExecutionContext] IDBRequest remove(in SerializedScriptValue key);
// FIXME: write openCursor
- IDBRequest createIndex(in DOMString name, in DOMString keyPath, in [Optional] boolean unique);
+ [CallWith=ScriptExecutionContext] IDBRequest createIndex(in DOMString name, in DOMString keyPath, in [Optional] boolean unique);
+ // FIXME: This needs to raise an IDBDatabaseException on errors.
IDBIndexRequest index(in DOMString name);
- IDBRequest removeIndex(in DOMString name);
+ [CallWith=ScriptExecutionContext] IDBRequest removeIndex(in DOMString name);
readonly attribute DOMString name;
readonly attribute DOMString keyPath;
diff --git a/WebCore/storage/IDBRequest.cpp b/WebCore/storage/IDBRequest.cpp
index f86abcb..f0ba25b 100644
--- a/WebCore/storage/IDBRequest.cpp
+++ b/WebCore/storage/IDBRequest.cpp
@@ -38,6 +38,7 @@
#include "IDBDatabaseRequest.h"
#include "IDBIndexRequest.h"
#include "IDBErrorEvent.h"
+#include "IDBObjectStoreRequest.h"
#include "IDBSuccessEvent.h"
#include "ScriptExecutionContext.h"
@@ -84,6 +85,12 @@ void IDBRequest::onSuccess(PassRefPtr<IDBIndex> idbIndex)
m_result->set(IDBIndexRequest::create(idbIndex));
}
+void IDBRequest::onSuccess(PassRefPtr<IDBObjectStore> idbObjectStore)
+{
+ onEventCommon();
+ m_result->set(IDBObjectStoreRequest::create(idbObjectStore));
+}
+
void IDBRequest::onSuccess(PassRefPtr<SerializedScriptValue> serializedScriptValue)
{
onEventCommon();
diff --git a/WebCore/storage/IDBRequest.h b/WebCore/storage/IDBRequest.h
index 5836f78..4fb4eed 100644
--- a/WebCore/storage/IDBRequest.h
+++ b/WebCore/storage/IDBRequest.h
@@ -66,8 +66,8 @@ public:
virtual void onSuccess(); // For "null".
virtual void onSuccess(PassRefPtr<IDBDatabase>);
virtual void onSuccess(PassRefPtr<IDBIndex>);
+ virtual void onSuccess(PassRefPtr<IDBObjectStore>);
virtual void onSuccess(PassRefPtr<SerializedScriptValue>);
- // FIXME: Have one onSuccess function for each possible result type.
// EventTarget
virtual IDBRequest* toIDBRequest() { return this; }
diff --git a/WebCore/storage/IndexedDatabase.h b/WebCore/storage/IndexedDatabase.h
index d47de72..e6abf4a 100644
--- a/WebCore/storage/IndexedDatabase.h
+++ b/WebCore/storage/IndexedDatabase.h
@@ -50,7 +50,7 @@ public:
static PassRefPtr<IndexedDatabase> create();
virtual ~IndexedDatabase() { }
- virtual void open(const String& name, const String& description, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, Frame*, ExceptionCode&) = 0;
+ virtual void open(const String& name, const String& description, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, Frame*) = 0;
};
} // namespace WebCore
diff --git a/WebCore/storage/IndexedDatabaseImpl.cpp b/WebCore/storage/IndexedDatabaseImpl.cpp
index 25502de..793af9e 100644
--- a/WebCore/storage/IndexedDatabaseImpl.cpp
+++ b/WebCore/storage/IndexedDatabaseImpl.cpp
@@ -51,7 +51,7 @@ IndexedDatabaseImpl::~IndexedDatabaseImpl()
{
}
-void IndexedDatabaseImpl::open(const String& name, const String& description, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<SecurityOrigin>, Frame*, ExceptionCode&)
+void IndexedDatabaseImpl::open(const String& name, const String& description, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<SecurityOrigin>, Frame*)
{
RefPtr<IDBDatabase> database;
IDBDatabaseMap::iterator it = m_databaseMap.find(name);
diff --git a/WebCore/storage/IndexedDatabaseImpl.h b/WebCore/storage/IndexedDatabaseImpl.h
index fa95674..b9520ee 100644
--- a/WebCore/storage/IndexedDatabaseImpl.h
+++ b/WebCore/storage/IndexedDatabaseImpl.h
@@ -41,7 +41,7 @@ public:
static PassRefPtr<IndexedDatabaseImpl> create();
virtual ~IndexedDatabaseImpl();
- virtual void open(const String& name, const String& description, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, Frame*, ExceptionCode&);
+ virtual void open(const String& name, const String& description, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, Frame*);
private:
IndexedDatabaseImpl();
diff --git a/WebCore/storage/IndexedDatabaseRequest.cpp b/WebCore/storage/IndexedDatabaseRequest.cpp
index 196fff7..93e052c 100644
--- a/WebCore/storage/IndexedDatabaseRequest.cpp
+++ b/WebCore/storage/IndexedDatabaseRequest.cpp
@@ -33,6 +33,7 @@
#include "ExceptionCode.h"
#include "Frame.h"
#include "IDBDatabase.h"
+#include "IDBKeyRange.h"
#include "IDBRequest.h"
#include "IndexedDatabase.h"
@@ -40,9 +41,8 @@
namespace WebCore {
-IndexedDatabaseRequest::IndexedDatabaseRequest(IndexedDatabase* indexedDatabase, Frame* frame)
+IndexedDatabaseRequest::IndexedDatabaseRequest(IndexedDatabase* indexedDatabase)
: m_indexedDatabase(indexedDatabase)
- , m_frame(frame)
{
m_this = IDBAny::create();
m_this->set(this);
@@ -52,13 +52,45 @@ IndexedDatabaseRequest::~IndexedDatabaseRequest()
{
}
-PassRefPtr<IDBRequest> IndexedDatabaseRequest::open(const String& name, const String& description, ExceptionCode& exception)
+PassRefPtr<IDBRequest> IndexedDatabaseRequest::open(ScriptExecutionContext* context, const String& name, const String& description)
{
- RefPtr<IDBRequest> request = IDBRequest::create(m_frame->document(), m_this);
- m_indexedDatabase->open(name, description, request, m_frame->document()->securityOrigin(), m_frame, exception);
+ if (!context->isDocument()) {
+ // FIXME: make this work with workers.
+ return 0;
+ }
+
+ Document* document = static_cast<Document*>(context);
+ if (!document->frame())
+ return 0;
+
+ RefPtr<IDBRequest> request = IDBRequest::create(document, m_this);
+ m_indexedDatabase->open(name, description, request, document->securityOrigin(), document->frame());
return request;
}
+PassRefPtr<IDBKeyRange> IndexedDatabaseRequest::makeSingleKeyRange(PassRefPtr<SerializedScriptValue> prpValue)
+{
+ RefPtr<SerializedScriptValue> value = prpValue;
+ return IDBKeyRange::create(value, value, IDBKeyRange::SINGLE);
+}
+
+PassRefPtr<IDBKeyRange> IndexedDatabaseRequest::makeLeftBoundKeyRange(PassRefPtr<SerializedScriptValue> bound, bool open)
+{
+ return IDBKeyRange::create(bound, SerializedScriptValue::create(), open ? IDBKeyRange::LEFT_OPEN : IDBKeyRange::LEFT_BOUND);
+}
+
+PassRefPtr<IDBKeyRange> IndexedDatabaseRequest::makeRightBoundKeyRange(PassRefPtr<SerializedScriptValue> bound, bool open)
+{
+ return IDBKeyRange::create(SerializedScriptValue::create(), bound, open ? IDBKeyRange::RIGHT_OPEN : IDBKeyRange::RIGHT_BOUND);
+}
+
+PassRefPtr<IDBKeyRange> IndexedDatabaseRequest::makeBoundKeyRange(PassRefPtr<SerializedScriptValue> left, PassRefPtr<SerializedScriptValue> right, bool openLeft, bool openRight)
+{
+ unsigned short flags = openLeft ? IDBKeyRange::LEFT_OPEN : IDBKeyRange::LEFT_BOUND;
+ flags |= openRight ? IDBKeyRange::RIGHT_OPEN : IDBKeyRange::RIGHT_BOUND;
+ return IDBKeyRange::create(left, right, flags);
+}
+
} // namespace WebCore
#endif // ENABLE(INDEXED_DATABASE)
diff --git a/WebCore/storage/IndexedDatabaseRequest.h b/WebCore/storage/IndexedDatabaseRequest.h
index 3f89460..9802380 100644
--- a/WebCore/storage/IndexedDatabaseRequest.h
+++ b/WebCore/storage/IndexedDatabaseRequest.h
@@ -39,28 +39,32 @@
namespace WebCore {
-class Frame;
class IDBAny;
+class IDBKeyRange;
+class IDBRequest;
class IndexedDatabase;
+class ScriptExecutionContext;
+class SerializedScriptValue;
class IndexedDatabaseRequest : public RefCounted<IndexedDatabaseRequest> {
public:
- static PassRefPtr<IndexedDatabaseRequest> create(IndexedDatabase* indexedDatabase, Frame* frame)
+ static PassRefPtr<IndexedDatabaseRequest> create(IndexedDatabase* indexedDatabase)
{
- return adoptRef(new IndexedDatabaseRequest(indexedDatabase, frame));
+ return adoptRef(new IndexedDatabaseRequest(indexedDatabase));
}
~IndexedDatabaseRequest();
- PassRefPtr<IDBRequest> open(const String& name, const String& description, ExceptionCode&);
-
- void disconnectFrame() { m_frame = 0; }
+ PassRefPtr<IDBRequest> open(ScriptExecutionContext*, const String& name, const String& description);
+ PassRefPtr<IDBKeyRange> makeSingleKeyRange(PassRefPtr<SerializedScriptValue> value);
+ PassRefPtr<IDBKeyRange> makeLeftBoundKeyRange(PassRefPtr<SerializedScriptValue> bound, bool open = false);
+ PassRefPtr<IDBKeyRange> makeRightBoundKeyRange(PassRefPtr<SerializedScriptValue> bound, bool open = false);
+ PassRefPtr<IDBKeyRange> makeBoundKeyRange(PassRefPtr<SerializedScriptValue> left, PassRefPtr<SerializedScriptValue> right, bool openLeft = false, bool openRight = false);
private:
- IndexedDatabaseRequest(IndexedDatabase*, Frame*);
+ IndexedDatabaseRequest(IndexedDatabase*);
RefPtr<IndexedDatabase> m_indexedDatabase;
RefPtr<IDBAny> m_this;
- Frame* m_frame;
};
} // namespace WebCore
diff --git a/WebCore/storage/IndexedDatabaseRequest.idl b/WebCore/storage/IndexedDatabaseRequest.idl
index a87e033..502e804 100644
--- a/WebCore/storage/IndexedDatabaseRequest.idl
+++ b/WebCore/storage/IndexedDatabaseRequest.idl
@@ -28,9 +28,11 @@ module storage {
interface [
Conditional=INDEXED_DATABASE
] IndexedDatabaseRequest {
- // FIXME: This should no longer raise.
- IDBRequest open(in DOMString name, in DOMString description)
- raises(IDBDatabaseException);
+ [CallWith=ScriptExecutionContext] IDBRequest open(in DOMString name, in DOMString description);
+ IDBKeyRange makeSingleKeyRange(in SerializedScriptValue value);
+ IDBKeyRange makeLeftBoundKeyRange(in SerializedScriptValue bound, in [Optional] boolean open);
+ IDBKeyRange makeRightBoundKeyRange(in SerializedScriptValue bound, in [Optional] boolean open);
+ IDBKeyRange makeBoundKeyRange(in SerializedScriptValue left, in SerializedScriptValue right, in [Optional] boolean openLeft, in [Optional] boolean openRight);
};
}
diff --git a/WebCore/storage/SQLResultSet.idl b/WebCore/storage/SQLResultSet.idl
index 0b70e01..52f06da 100644
--- a/WebCore/storage/SQLResultSet.idl
+++ b/WebCore/storage/SQLResultSet.idl
@@ -35,8 +35,14 @@ module storage {
] SQLResultSet {
readonly attribute SQLResultSetRowList rows;
+#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
readonly attribute long insertId
getter raises(DOMException);
+#else
+ // Explicitely choose 'long long' here to avoid a 64bit->32bit shortening warning for us.
+ readonly attribute long long insertId
+ getter raises(DOMException);
+#endif
readonly attribute long rowsAffected;
};
}
diff --git a/WebCore/storage/SQLStatement.cpp b/WebCore/storage/SQLStatement.cpp
index 2e1aea2..cd96535 100644
--- a/WebCore/storage/SQLStatement.cpp
+++ b/WebCore/storage/SQLStatement.cpp
@@ -31,12 +31,10 @@
#if ENABLE(DATABASE)
#include "Database.h"
-#include "DatabaseAuthorizer.h"
#include "Logging.h"
#include "SQLError.h"
#include "SQLiteDatabase.h"
#include "SQLiteStatement.h"
-#include "SQLResultSet.h"
#include "SQLStatementCallback.h"
#include "SQLStatementErrorCallback.h"
#include "SQLTransaction.h"
@@ -73,7 +71,7 @@ bool SQLStatement::execute(Database* db)
if (m_readOnly)
db->setAuthorizerReadOnly();
- SQLiteDatabase* database = &db->m_sqliteDatabase;
+ SQLiteDatabase* database = &db->sqliteDatabase();
SQLiteStatement statement(*database, m_statement);
int result = statement.prepare();
@@ -130,7 +128,7 @@ bool SQLStatement::execute(Database* db)
}
} else if (result == SQLResultDone) {
// Didn't find anything, or was an insert
- if (db->m_databaseAuthorizer->lastActionWasInsert())
+ if (db->lastActionWasInsert())
resultSet->setInsertId(database->lastInsertRowID());
} else if (result == SQLResultFull) {
// Return the Quota error - the delegate will be asked for more space and this statement might be re-run
diff --git a/WebCore/storage/SQLStatement.h b/WebCore/storage/SQLStatement.h
index f01f7bf..89af377 100644
--- a/WebCore/storage/SQLStatement.h
+++ b/WebCore/storage/SQLStatement.h
@@ -31,23 +31,18 @@
#if ENABLE(DATABASE)
#include "PlatformString.h"
-
-#include "SQLError.h"
#include "SQLResultSet.h"
-#include "SQLStatementCallback.h"
-#include "SQLStatementErrorCallback.h"
#include "SQLValue.h"
-
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Threading.h>
+#include <wtf/Forward.h>
#include <wtf/Vector.h>
namespace WebCore {
class Database;
+class SQLError;
+class SQLStatementCallback;
+class SQLStatementErrorCallback;
class SQLTransaction;
-class String;
class SQLStatement : public ThreadSafeShared<SQLStatement> {
public:
@@ -66,7 +61,7 @@ public:
SQLError* sqlError() const { return m_error.get(); }
private:
- SQLStatement(const String& statement, const Vector<SQLValue>& arguments, PassRefPtr<SQLStatementCallback> callback, PassRefPtr<SQLStatementErrorCallback> errorCallback, bool readOnly);
+ SQLStatement(const String& statement, const Vector<SQLValue>& arguments, PassRefPtr<SQLStatementCallback>, PassRefPtr<SQLStatementErrorCallback>, bool readOnly);
void setFailureDueToQuota();
void clearFailureDueToQuota();
diff --git a/WebCore/storage/SQLTransaction.cpp b/WebCore/storage/SQLTransaction.cpp
index 7f16b63..b06d865 100644
--- a/WebCore/storage/SQLTransaction.cpp
+++ b/WebCore/storage/SQLTransaction.cpp
@@ -31,26 +31,26 @@
#if ENABLE(DATABASE)
-#include "ChromeClient.h"
#include "Database.h"
-#include "DatabaseAuthorizer.h"
-#include "DatabaseDetails.h"
#include "DatabaseThread.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"
-#include "SQLResultSet.h"
#include "SQLStatement.h"
#include "SQLStatementCallback.h"
#include "SQLStatementErrorCallback.h"
+#include "SQLTransactionCallback.h"
#include "SQLTransactionClient.h"
#include "SQLTransactionCoordinator.h"
+#include "SQLTransactionErrorCallback.h"
#include "SQLValue.h"
+#include "VoidCallback.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
// There's no way of knowing exactly how much more space will be required when a statement hits the quota limit.
// For now, we'll arbitrarily choose currentQuota + 1mb.
@@ -65,8 +65,8 @@ PassRefPtr<SQLTransaction> SQLTransaction::create(Database* db, PassRefPtr<SQLTr
return adoptRef(new SQLTransaction(db, callback, errorCallback, successCallback, wrapper, readOnly));
}
-SQLTransaction::SQLTransaction(Database* db, PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback,
- PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly)
+SQLTransaction::SQLTransaction(Database* db, PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback,
+ PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly)
: m_nextStep(&SQLTransaction::acquireLock)
, m_executeSqlAllowed(false)
, m_database(db)
@@ -234,7 +234,7 @@ void SQLTransaction::lockAcquired()
void SQLTransaction::openTransactionAndPreflight()
{
- ASSERT(!m_database->m_sqliteDatabase.transactionInProgress());
+ ASSERT(!m_database->sqliteDatabase().transactionInProgress());
ASSERT(m_lockAcquired);
LOG(StorageAPI, "Opening and preflighting transaction %p", this);
@@ -248,18 +248,19 @@ void SQLTransaction::openTransactionAndPreflight()
// Set the maximum usage for this transaction if this transactions is not read-only
if (!m_readOnly)
- m_database->m_sqliteDatabase.setMaximumSize(m_database->maximumSize());
+ m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize());
ASSERT(!m_sqliteTransaction);
- m_sqliteTransaction.set(new SQLiteTransaction(m_database->m_sqliteDatabase, m_readOnly));
+ m_sqliteTransaction.set(new SQLiteTransaction(m_database->sqliteDatabase(), m_readOnly));
- m_database->m_databaseAuthorizer->disable();
+ m_database->resetDeletes();
+ m_database->disableAuthorizer();
m_sqliteTransaction->begin();
- m_database->m_databaseAuthorizer->enable();
+ m_database->enableAuthorizer();
// Transaction Steps 1+2 - Open a transaction to the database, jumping to the error callback if that fails
if (!m_sqliteTransaction->inProgress()) {
- ASSERT(!m_database->m_sqliteDatabase.transactionInProgress());
+ ASSERT(!m_database->sqliteDatabase().transactionInProgress());
m_sqliteTransaction.clear();
m_transactionError = SQLError::create(0, "unable to open a transaction to the database");
handleTransactionError(false);
@@ -268,7 +269,7 @@ void SQLTransaction::openTransactionAndPreflight()
// Transaction Steps 3 - Peform preflight steps, jumping to the error callback if they fail
if (m_wrapper && !m_wrapper->performPreflight(this)) {
- ASSERT(!m_database->m_sqliteDatabase.transactionInProgress());
+ ASSERT(!m_database->sqliteDatabase().transactionInProgress());
m_sqliteTransaction.clear();
m_transactionError = m_wrapper->sqlError();
if (!m_transactionError)
@@ -326,7 +327,7 @@ void SQLTransaction::runStatements()
// m_shouldRetryCurrentStatement is set to true only when a statement exceeds
// the quota, which can happen only in a read-write transaction. Therefore, there
// is no need to check here if the transaction is read-write.
- m_database->m_sqliteDatabase.setMaximumSize(m_database->maximumSize());
+ m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize());
} else {
// If the current statement has already been run, failed due to quota constraints, and we're not retrying it,
// that means it ended in an error. Handle it now
@@ -353,8 +354,7 @@ void SQLTransaction::getNextStatement()
MutexLocker locker(m_statementMutex);
if (!m_statementQueue.isEmpty()) {
- m_currentStatement = m_statementQueue.first();
- m_statementQueue.removeFirst();
+ m_currentStatement = m_statementQueue.takeFirst();
}
}
@@ -363,10 +363,10 @@ bool SQLTransaction::runCurrentStatement()
if (!m_currentStatement)
return false;
- m_database->m_databaseAuthorizer->reset();
+ m_database->resetAuthorizer();
if (m_currentStatement->execute(m_database.get())) {
- if (m_database->m_databaseAuthorizer->lastActionChangedDatabase()) {
+ if (m_database->lastActionChangedDatabase()) {
// Flag this transaction as having changed the database for later delegate notification
m_modifiedDatabase = true;
// Also dirty the size of this database file for calculating quota usage
@@ -455,9 +455,9 @@ void SQLTransaction::postflightAndCommit()
// Transacton Step 8+9 - Commit the transaction, jumping to the error callback if that fails
ASSERT(m_sqliteTransaction);
- m_database->m_databaseAuthorizer->disable();
+ m_database->disableAuthorizer();
m_sqliteTransaction->commit();
- m_database->m_databaseAuthorizer->enable();
+ m_database->enableAuthorizer();
// If the commit failed, the transaction will still be marked as "in progress"
if (m_sqliteTransaction->inProgress()) {
@@ -466,12 +466,13 @@ void SQLTransaction::postflightAndCommit()
return;
}
- // The commit was successful. If the transaction modified this database,
- // vacuum the database if needed and notify the delegates.
- if (m_modifiedDatabase) {
+ // Vacuum the database if anything was deleted.
+ if (m_database->hadDeletes())
m_database->incrementalVacuumIfNeeded();
+
+ // The commit was successful. If the transaction modified this database, notify the delegates.
+ if (m_modifiedDatabase)
m_database->transactionClient()->didCommitTransaction(this);
- }
// Now release our unneeded callbacks, to break reference cycles.
m_callback = 0;
@@ -509,7 +510,7 @@ void SQLTransaction::cleanupAfterSuccessCallback()
// Transaction Step 11 - End transaction steps
// There is no next step
LOG(StorageAPI, "Transaction %p is complete\n", this);
- ASSERT(!m_database->m_sqliteDatabase.transactionInProgress());
+ ASSERT(!m_database->sqliteDatabase().transactionInProgress());
m_sqliteTransaction.clear();
m_nextStep = 0;
@@ -559,15 +560,15 @@ void SQLTransaction::cleanupAfterTransactionErrorCallback()
{
ASSERT(m_lockAcquired);
- m_database->m_databaseAuthorizer->disable();
+ m_database->disableAuthorizer();
if (m_sqliteTransaction) {
// Transaction Step 12 - Rollback the transaction.
m_sqliteTransaction->rollback();
- ASSERT(!m_database->m_sqliteDatabase.transactionInProgress());
+ ASSERT(!m_database->sqliteDatabase().transactionInProgress());
m_sqliteTransaction.clear();
}
- m_database->m_databaseAuthorizer->enable();
+ m_database->enableAuthorizer();
// Transaction Step 12 - Any still-pending statements in the transaction are discarded.
{
@@ -577,7 +578,7 @@ void SQLTransaction::cleanupAfterTransactionErrorCallback()
// Transaction is complete! There is no next step
LOG(StorageAPI, "Transaction %p is complete with an error\n", this);
- ASSERT(!m_database->m_sqliteDatabase.transactionInProgress());
+ ASSERT(!m_database->sqliteDatabase().transactionInProgress());
m_nextStep = 0;
// Now release our callbacks, to break reference cycles.
diff --git a/WebCore/storage/SQLTransaction.h b/WebCore/storage/SQLTransaction.h
index 1b02d01..3cef036 100644
--- a/WebCore/storage/SQLTransaction.h
+++ b/WebCore/storage/SQLTransaction.h
@@ -32,14 +32,9 @@
#include <wtf/Threading.h>
-#include "SQLiteTransaction.h"
#include "SQLStatement.h"
-#include "SQLTransactionCallback.h"
-#include "SQLTransactionErrorCallback.h"
#include <wtf/Deque.h>
#include <wtf/Forward.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
@@ -48,9 +43,12 @@ typedef int ExceptionCode;
class Database;
class SQLError;
+class SQLiteTransaction;
class SQLStatementCallback;
class SQLStatementErrorCallback;
class SQLTransaction;
+class SQLTransactionCallback;
+class SQLTransactionErrorCallback;
class SQLValue;
class String;
class VoidCallback;
@@ -72,7 +70,7 @@ public:
~SQLTransaction();
void executeSQL(const String& sqlStatement, const Vector<SQLValue>& arguments,
- PassRefPtr<SQLStatementCallback> callback, PassRefPtr<SQLStatementErrorCallback> callbackError, ExceptionCode& e);
+ PassRefPtr<SQLStatementCallback>, PassRefPtr<SQLStatementErrorCallback>, ExceptionCode&);
void lockAcquired();
bool performNextStep();
diff --git a/WebCore/storage/SQLTransactionCoordinator.cpp b/WebCore/storage/SQLTransactionCoordinator.cpp
index dbd2739..104ea10 100644
--- a/WebCore/storage/SQLTransactionCoordinator.cpp
+++ b/WebCore/storage/SQLTransactionCoordinator.cpp
@@ -57,8 +57,7 @@ void SQLTransactionCoordinator::processPendingTransactions(CoordinationInfo& inf
RefPtr<SQLTransaction> firstPendingTransaction = info.pendingTransactions.first();
if (firstPendingTransaction->isReadOnly()) {
do {
- firstPendingTransaction = info.pendingTransactions.first();
- info.pendingTransactions.removeFirst();
+ firstPendingTransaction = info.pendingTransactions.takeFirst();
info.activeReadTransactions.add(firstPendingTransaction);
firstPendingTransaction->lockAcquired();
} while (!info.pendingTransactions.isEmpty() && info.pendingTransactions.first()->isReadOnly());
diff --git a/WebCore/storage/StorageAreaSync.cpp b/WebCore/storage/StorageAreaSync.cpp
index 4c385b7..59f558b 100644
--- a/WebCore/storage/StorageAreaSync.cpp
+++ b/WebCore/storage/StorageAreaSync.cpp
@@ -29,6 +29,7 @@
#if ENABLE(DOM_STORAGE)
#include "EventNames.h"
+#include "FileSystem.h"
#include "HTMLElement.h"
#include "SecurityOrigin.h"
#include "SQLiteStatement.h"
@@ -62,6 +63,7 @@ StorageAreaSync::StorageAreaSync(PassRefPtr<StorageSyncManager> storageSyncManag
, m_clearItemsWhileSyncing(false)
, m_syncScheduled(false)
, m_syncInProgress(false)
+ , m_databaseOpenFailed(false)
, m_importComplete(false)
{
ASSERT(isMainThread());
@@ -198,28 +200,47 @@ void StorageAreaSync::syncTimerFired(Timer<StorageAreaSync>*)
}
}
-void StorageAreaSync::performImport()
+void StorageAreaSync::openDatabase(OpenDatabaseParamType openingStrategy)
{
ASSERT(!isMainThread());
ASSERT(!m_database.isOpen());
+ ASSERT(!m_databaseOpenFailed);
String databaseFilename = m_syncManager->fullDatabaseFilename(m_databaseIdentifier);
+ if (!fileExists(databaseFilename) && openingStrategy == SkipIfNonExistent)
+ return;
+
if (databaseFilename.isEmpty()) {
LOG_ERROR("Filename for local storage database is empty - cannot open for persistent storage");
markImported();
+ m_databaseOpenFailed = true;
return;
}
if (!m_database.open(databaseFilename)) {
LOG_ERROR("Failed to open database file %s for local storage", databaseFilename.utf8().data());
markImported();
+ m_databaseOpenFailed = true;
return;
}
if (!m_database.executeCommand("CREATE TABLE IF NOT EXISTS ItemTable (key TEXT UNIQUE ON CONFLICT REPLACE, value TEXT NOT NULL ON CONFLICT FAIL)")) {
LOG_ERROR("Failed to create table ItemTable for local storage");
markImported();
+ m_databaseOpenFailed = true;
+ return;
+ }
+}
+
+void StorageAreaSync::performImport()
+{
+ ASSERT(!isMainThread());
+ ASSERT(!m_database.isOpen());
+
+ openDatabase(SkipIfNonExistent);
+ if (!m_database.isOpen()) {
+ markImported();
return;
}
@@ -285,6 +306,10 @@ void StorageAreaSync::sync(bool clearItems, const HashMap<String, String>& items
{
ASSERT(!isMainThread());
+ if (m_databaseOpenFailed)
+ return;
+ if (!m_database.isOpen())
+ openDatabase(CreateIfNonExistent);
if (!m_database.isOpen())
return;
diff --git a/WebCore/storage/StorageAreaSync.h b/WebCore/storage/StorageAreaSync.h
index 0e46763..d26d399 100644
--- a/WebCore/storage/StorageAreaSync.h
+++ b/WebCore/storage/StorageAreaSync.h
@@ -75,7 +75,13 @@ namespace WebCore {
void performSync();
private:
+ enum OpenDatabaseParamType {
+ CreateIfNonExistent,
+ SkipIfNonExistent
+ };
+
void syncTimerFired(Timer<StorageAreaSync>*);
+ void openDatabase(OpenDatabaseParamType openingStrategy);
void sync(bool clearItems, const HashMap<String, String>& items);
const String m_databaseIdentifier;
@@ -85,6 +91,7 @@ namespace WebCore {
bool m_clearItemsWhileSyncing;
bool m_syncScheduled;
bool m_syncInProgress;
+ bool m_databaseOpenFailed;
mutable Mutex m_importLock;
mutable ThreadCondition m_importCondition;