Commit 0f1c94b6 authored by beidson@apple.com's avatar beidson@apple.com

IDB: "Put" support

<rdar://problem/15779643> and https://bugs.webkit.org/show_bug.cgi?id=127401

Reviewed by Alexey Proskuryakov.

Source/WebCore:

Add persistent encode/decode for storage to the database:
* Modules/indexeddb/IDBKey.cpp:
(WebCore::IDBKey::encode):
(WebCore::IDBKey::decode):
* Modules/indexeddb/IDBKey.h:

Add a data class to represent IDBKey suitable for crossing IPC:
* Modules/indexeddb/IDBKeyData.cpp: Added.
(WebCore::IDBKeyData::IDBKeyData):
(WebCore::IDBKeyData::maybeCreateIDBKey):
(WebCore::IDBKeyData::isolatedCopy):
* Modules/indexeddb/IDBKeyData.h: Added.
(WebCore::IDBKeyData::IDBKeyData):

* platform/CrossThreadCopier.cpp:
(WebCore::IDBKeyData>::copy):
* platform/CrossThreadCopier.h:

* WebCore.exp.in:
* WebCore.xcodeproj/project.pbxproj:

Source/WebKit2:

Ship putRecord requests over to the DatabaseProcess, and listen for completion from the DatabaseProcess:
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:
(WebKit::WebIDBServerConnection::put):
(WebKit::WebIDBServerConnection::didPutRecord):
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.h:
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.messages.in:

Pass off the putRecord request to the Unique IDBDatabase:
* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp:
(WebKit::DatabaseProcessIDBConnection::putRecord):
* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.h:
* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.messages.in:

Pass off the putRecord request to the backing store:
* DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
(WebKit::UniqueIDBDatabase::putRecord):
(WebKit::UniqueIDBDatabase::putRecordInBackingStore):
(WebKit::UniqueIDBDatabase::didPutRecordInBackingStore):
* DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:

Add backing store methods related to putRecord, though only one is critical right now:
* DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::createAndPopulateInitialMetadata):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::generateKey):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::keyExistsInObjectStore):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::putRecord):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::updateKeyGenerator):
* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:

Add the IDBKeyData type to IPC:
* Scripts/webkit2/messages.py:
(struct_or_class):

* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<IDBKeyData>::encode):
(IPC::ArgumentCoder<IDBKeyData>::decode):
* Shared/WebCoreArgumentCoders.h:

* DatabaseProcess/IndexedDB/IDBSerialization.cpp:
(WebKit::serializeIDBKey):
* DatabaseProcess/IndexedDB/IDBSerialization.h:

Implement more cross-thread copying:
* Shared/WebCrossThreadCopier.cpp:
(WebCore::Vector<uint8_t>>::copy):
(WebCore::Vector<Vector<IDBKeyData>>>::copy):
(WebCore::ASCIILiteral>::copy):
* Shared/WebCrossThreadCopier.h:

Implement more numbers of generic AsyncTask templates:
* Shared/AsyncTask.h:
(WebKit::createAsyncTask):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@162566 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 81d4ed94
......@@ -811,6 +811,7 @@ set(WebCore_SOURCES
Modules/indexeddb/IDBFactoryBackendInterface.cpp
Modules/indexeddb/IDBIndex.cpp
Modules/indexeddb/IDBKey.cpp
Modules/indexeddb/IDBKeyData.cpp
Modules/indexeddb/IDBKeyPath.cpp
Modules/indexeddb/IDBKeyRange.cpp
Modules/indexeddb/IDBObjectStore.cpp
......
2014-01-21 Brady Eidson <beidson@apple.com>
IDB: "Put" support
<rdar://problem/15779643> and https://bugs.webkit.org/show_bug.cgi?id=127401
Reviewed by Alexey Proskuryakov.
Add persistent encode/decode for storage to the database:
* Modules/indexeddb/IDBKey.cpp:
(WebCore::IDBKey::encode):
(WebCore::IDBKey::decode):
* Modules/indexeddb/IDBKey.h:
Add a data class to represent IDBKey suitable for crossing IPC:
* Modules/indexeddb/IDBKeyData.cpp: Added.
(WebCore::IDBKeyData::IDBKeyData):
(WebCore::IDBKeyData::maybeCreateIDBKey):
(WebCore::IDBKeyData::isolatedCopy):
* Modules/indexeddb/IDBKeyData.h: Added.
(WebCore::IDBKeyData::IDBKeyData):
* platform/CrossThreadCopier.cpp:
(WebCore::IDBKeyData>::copy):
* platform/CrossThreadCopier.h:
* WebCore.exp.in:
* WebCore.xcodeproj/project.pbxproj:
2014-01-22 Dean Jackson <dino@apple.com>
[WebGL] Implement ANGLE_instanced_arrays
......@@ -25,7 +25,7 @@ webcore_built_sources += \
DerivedSources/WebCore/InspectorWebBackendDispatchers.cpp \
DerivedSources/WebCore/InspectorWebBackendDispatchers.h \
DerivedSources/WebCore/InspectorWebFrontendDispatchers.cpp \
DerivedSources/WebCore/InspectorWebFrontendDispatchers.h \
DerivedSources/WebCore/InspectorWebFrontendDispatchers.h \
DerivedSources/WebCore/InspectorWebTypeBuilders.cpp \
DerivedSources/WebCore/InspectorWebTypeBuilders.h \
DerivedSources/WebCore/JSANGLEInstancedArrays.cpp \
......@@ -1845,6 +1845,8 @@ webcore_modules_sources += \
Source/WebCore/Modules/indexeddb/IDBIndex.h \
Source/WebCore/Modules/indexeddb/IDBKey.cpp \
Source/WebCore/Modules/indexeddb/IDBKey.h \
Source/WebCore/Modules/indexeddb/IDBKeyData.cpp \
Source/WebCore/Modules/indexeddb/IDBKeyData.h \
Source/WebCore/Modules/indexeddb/IDBKeyPath.cpp \
Source/WebCore/Modules/indexeddb/IDBKeyPath.h \
Source/WebCore/Modules/indexeddb/IDBKeyRange.cpp \
......
......@@ -28,6 +28,8 @@
#if ENABLE(INDEXED_DATABASE)
#include "KeyedCoding.h"
namespace WebCore {
IDBKey::~IDBKey()
......@@ -96,6 +98,41 @@ bool IDBKey::isEqual(const IDBKey* other) const
return !compare(other);
}
void IDBKey::encode(KeyedEncoder& encoder) const
{
encoder.encodeEnum("type", m_type);
switch (m_type) {
case InvalidType:
return;
case ArrayType:
encoder.encodeObjects("array", m_array.begin(), m_array.end(), [](WebCore::KeyedEncoder& encoder, const RefPtr<IDBKey>& key) {
encoder.encodeObject("idbKey", *key, [](KeyedEncoder& encoder, const IDBKey& key) {
key.encode(encoder);
});
});
return;
case StringType:
encoder.encodeString("string", m_string);
return;
case DateType:
case NumberType:
encoder.encodeDouble("number", m_number);
return;
case MinType:
ASSERT_NOT_REACHED();
return;
}
ASSERT_NOT_REACHED();
}
bool IDBKey::decode(KeyedDecoder&, IDBKey&)
{
// FIXME: Implement when IDB Get support is implemented (<rdar://problem/15779644>)
return false;
}
} // namespace WebCore
#endif
......@@ -35,6 +35,9 @@
namespace WebCore {
class KeyedDecoder;
class KeyedEncoder;
class IDBKey : public RefCounted<IDBKey> {
public:
typedef Vector<RefPtr<IDBKey>> KeyArray;
......@@ -147,6 +150,9 @@ public:
using RefCounted<IDBKey>::ref;
using RefCounted<IDBKey>::deref;
void encode(KeyedEncoder&) const;
static bool decode(KeyedDecoder&, IDBKey&);
private:
IDBKey() : m_type(InvalidType), m_number(0), m_sizeEstimate(OverheadSize) { }
IDBKey(Type type, double number) : m_type(type), m_number(number), m_sizeEstimate(OverheadSize + sizeof(double)) { }
......
/*
* Copyright (C) 2014 Apple 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 INC. 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 INC. 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 "IDBKeyData.h"
#if ENABLE(INDEXED_DATABASE)
namespace WebCore {
IDBKeyData::IDBKeyData(IDBKey* key)
: type(IDBKey::InvalidType)
, numberValue(0)
, isNull(false)
{
if (!key) {
isNull = true;
return;
}
type = key->type();
numberValue = 0;
switch (type) {
case IDBKey::InvalidType:
break;
case IDBKey::ArrayType:
for (auto key2 : key->array())
arrayValue.append(IDBKeyData(key2.get()));
break;
case IDBKey::StringType:
stringValue = key->string();
break;
case IDBKey::DateType:
numberValue = key->date();
break;
case IDBKey::NumberType:
numberValue = key->number();
break;
case IDBKey::MinType:
ASSERT_NOT_REACHED();
break;
}
}
PassRefPtr<IDBKey> IDBKeyData::maybeCreateIDBKey() const
{
if (isNull)
return nullptr;
switch (type) {
case IDBKey::InvalidType:
return IDBKey::createInvalid();
case IDBKey::ArrayType:
{
IDBKey::KeyArray array;
for (auto keyData : arrayValue) {
array.append(keyData.maybeCreateIDBKey());
ASSERT(array.last());
}
return IDBKey::createArray(array);
}
case IDBKey::StringType:
return IDBKey::createString(stringValue);
case IDBKey::DateType:
return IDBKey::createDate(numberValue);
case IDBKey::NumberType:
return IDBKey::createNumber(numberValue);
case IDBKey::MinType:
ASSERT_NOT_REACHED();
return nullptr;
}
ASSERT_NOT_REACHED();
return nullptr;
}
IDBKeyData IDBKeyData::isolatedCopy() const
{
IDBKeyData result;
result.type = type;
result.isNull = isNull;
switch (type) {
case IDBKey::InvalidType:
return result;
case IDBKey::ArrayType:
for (auto key : arrayValue)
result.arrayValue.append(key.isolatedCopy());
return result;
case IDBKey::StringType:
result.stringValue = stringValue.isolatedCopy();
return result;
case IDBKey::DateType:
case IDBKey::NumberType:
result.numberValue = numberValue;
return result;
case IDBKey::MinType:
ASSERT_NOT_REACHED();
return result;
}
ASSERT_NOT_REACHED();
return result;
}
}
#endif // ENABLE(INDEXED_DATABASE)
/*
* Copyright (C) 2014 Apple 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 INC. 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 INC. 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 IDBKeyData_h
#define IDBKeyData_h
#if ENABLE(INDEXED_DATABASE)
#include "IDBKey.h"
namespace WebCore {
struct IDBKeyData {
IDBKeyData()
: type(IDBKey::InvalidType)
, numberValue(0)
, isNull(true)
{
}
IDBKeyData(IDBKey*);
PassRefPtr<IDBKey> maybeCreateIDBKey() const;
IDBKeyData isolatedCopy() const;
IDBKey::Type type;
Vector<IDBKeyData> arrayValue;
String stringValue;
double numberValue;
bool isNull;
};
} // namespace WebCore
#endif // ENABLE(INDEXED_DATABASE)
#endif // IDBKeyData_h
......@@ -106,7 +106,8 @@ void PutOperation::perform(std::function<void()> completionCallback)
RefPtr<PutOperation> operation(this);
STANDARD_DATABASE_ERROR_CALLBACK;
m_transaction->database().serverConnection().put(*m_transaction, *this, [this, operation, operationCallback](PassRefPtr<IDBKey> key, PassRefPtr<IDBDatabaseError> error) {
m_transaction->database().serverConnection().put(*m_transaction, *this, [this, operation, operationCallback](PassRefPtr<IDBKey> key, PassRefPtr<IDBDatabaseError> prpError) {
RefPtr<IDBDatabaseError> error = prpError;
if (key) {
ASSERT(!error);
m_callbacks->onSuccess(key);
......@@ -114,6 +115,7 @@ void PutOperation::perform(std::function<void()> completionCallback)
ASSERT(error);
m_callbacks->onError(error);
}
operationCallback(error.release());
});
}
......
......@@ -3077,13 +3077,19 @@ __ZN7WebCore26MockMediaPlayerMediaSource19registerMediaEngineEPFvPFN3WTF10PassOw
#endif
#if ENABLE(INDEXED_DATABASE)
__ZNK7WebCore10IDBKeyData17maybeCreateIDBKeyEv
__ZNK7WebCore10IDBKeyPath6encodeERNS_12KeyedEncoderE
__ZNK7WebCore6IDBKey6encodeERNS_12KeyedEncoderE
__ZNK7WebCore6IDBKey7isValidEv
__ZN7WebCore10IDBKeyDataC1EPNS_6IDBKeyE
__ZN7WebCore10IDBKeyPathC1ERKN3WTF6StringE
__ZN7WebCore10IDBKeyPathC1ERKN3WTF6VectorINS1_6StringELm0ENS1_15CrashOnOverflowEEE
__ZN7WebCore10IDBKeyPath6decodeERNS_12KeyedDecoderERS0_
__ZN7WebCore18IDBDatabaseBackend14openConnectionEN3WTF10PassRefPtrINS_12IDBCallbacksEEENS2_INS_20IDBDatabaseCallbacksEEExy
__ZN7WebCore18IDBDatabaseBackend6createERKN3WTF6StringES4_PNS_26IDBFactoryBackendInterfaceERNS_19IDBServerConnectionE
__ZN7WebCore18IDBDatabaseBackendD1Ev
__ZN7WebCore21CrossThreadCopierBaseILb0ELb0ENS_10IDBKeyDataEE4copyERKS1_
__ZN7WebCore21CrossThreadCopierBaseILb0ELb0ENS_22IDBObjectStoreMetadataEE4copyERKS1_
__ZN7WebCore21CrossThreadCopierBaseILb0ELb0ENS_9IndexedDB15TransactionModeEE4copyERKS2_
__ZN7WebCore6IDBKeyD1Ev
#endif
......@@ -6614,6 +6614,7 @@
<ClCompile Include="..\Modules\indexeddb\IDBFactoryBackendInterface.cpp" />
<ClCompile Include="..\Modules\indexeddb\IDBIndex.cpp" />
<ClCompile Include="..\Modules\indexeddb\IDBKey.cpp" />
<ClCompile Include="..\Modules\indexeddb\IDBKeyData.cpp" />
<ClCompile Include="..\Modules\indexeddb\IDBKeyRange.cpp" />
<ClCompile Include="..\Modules\indexeddb\IDBObjectStore.cpp" />
<ClCompile Include="..\Modules\indexeddb\IDBRequest.cpp" />
......@@ -1779,6 +1779,8 @@
510D4A38103165EE0049EA54 /* SocketStreamHandleClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 510D4A32103165EE0049EA54 /* SocketStreamHandleClient.h */; };
5112935F3D54B4B52FAF973F /* InspectorHeapProfilerAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511293613D6DB4B52FAF973F /* InspectorHeapProfilerAgent.cpp */; };
511293603D60B4B52FAF973F /* InspectorHeapProfilerAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 511293623D85B4B52FAF973F /* InspectorHeapProfilerAgent.h */; };
511EC1A6188DACA400BA3EB6 /* IDBKeyData.h in Headers */ = {isa = PBXBuildFile; fileRef = 511EC1A5188DACA400BA3EB6 /* IDBKeyData.h */; settings = {ATTRIBUTES = (Private, ); }; };
511EC1A8188DAE7B00BA3EB6 /* IDBKeyData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511EC1A7188DAE7B00BA3EB6 /* IDBKeyData.cpp */; };
511EF2C017F0FD3500E4FA16 /* JSIDBAny.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511EF2A817F0FC4800E4FA16 /* JSIDBAny.cpp */; };
511EF2C117F0FD3500E4FA16 /* JSIDBCursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511EF2A917F0FC4800E4FA16 /* JSIDBCursor.cpp */; };
511EF2C217F0FD3500E4FA16 /* JSIDBCursorWithValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511EF2AA17F0FC4800E4FA16 /* JSIDBCursorWithValue.cpp */; };
......@@ -8730,6 +8732,8 @@
510D4A32103165EE0049EA54 /* SocketStreamHandleClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocketStreamHandleClient.h; sourceTree = "<group>"; };
511293613D6DB4B52FAF973F /* InspectorHeapProfilerAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorHeapProfilerAgent.cpp; sourceTree = "<group>"; };
511293623D85B4B52FAF973F /* InspectorHeapProfilerAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorHeapProfilerAgent.h; sourceTree = "<group>"; };
511EC1A5188DACA400BA3EB6 /* IDBKeyData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBKeyData.h; sourceTree = "<group>"; };
511EC1A7188DAE7B00BA3EB6 /* IDBKeyData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBKeyData.cpp; sourceTree = "<group>"; };
511EF2A817F0FC4800E4FA16 /* JSIDBAny.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBAny.cpp; sourceTree = "<group>"; };
511EF2A917F0FC4800E4FA16 /* JSIDBCursor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBCursor.cpp; sourceTree = "<group>"; };
511EF2AA17F0FC4800E4FA16 /* JSIDBCursorWithValue.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBCursorWithValue.cpp; sourceTree = "<group>"; };
......@@ -17704,6 +17708,8 @@
51ABB5B6186D0ED1008391A1 /* IDBIndexMetadata.h */,
51D71991181106E00016DC51 /* IDBKey.cpp */,
51D71992181106E00016DC51 /* IDBKey.h */,
511EC1A7188DAE7B00BA3EB6 /* IDBKeyData.cpp */,
511EC1A5188DACA400BA3EB6 /* IDBKeyData.h */,
51D71993181106E00016DC51 /* IDBKeyPath.cpp */,
51D71994181106E00016DC51 /* IDBKeyPath.h */,
51D71995181106E00016DC51 /* IDBKeyRange.cpp */,
......@@ -24001,6 +24007,7 @@
CD8B5A49180E138B008B8E65 /* TextTrackMediaSource.h in Headers */,
A8EA7CAF0A192B9C00A8EF5F /* HTMLHRElement.h in Headers */,
A871DE270A152AC800B12A68 /* HTMLHtmlElement.h in Headers */,
511EC1A6188DACA400BA3EB6 /* IDBKeyData.h in Headers */,
07969DB417D14151007FF842 /* JSRTCPeerConnectionErrorCallback.h in Headers */,
A871DE2A0A152AC800B12A68 /* HTMLIFrameElement.h in Headers */,
A8EA7D2D0A19385500A8EF5F /* HTMLImageElement.h in Headers */,
......@@ -28813,6 +28820,7 @@
51771C8E182DB4B7008E781E /* IDBDatabaseBackend.cpp in Sources */,
1A22464B0CC98DDB00C05240 /* SQLiteStatement.cpp in Sources */,
1A22464D0CC98DDB00C05240 /* SQLiteTransaction.cpp in Sources */,
511EC1A8188DAE7B00BA3EB6 /* IDBKeyData.cpp in Sources */,
97BC6A411505F081001B74AC /* SQLResultSet.cpp in Sources */,
97BC6A441505F081001B74AC /* SQLResultSetRowList.cpp in Sources */,
97BC6A471505F081001B74AC /* SQLStatement.cpp in Sources */,
......@@ -42,6 +42,7 @@
#if ENABLE(INDEXED_DATABASE)
#include "IDBDatabaseMetadata.h"
#include "IDBKeyData.h"
#endif
namespace WebCore {
......@@ -98,6 +99,11 @@ CrossThreadCopierBase<false, false, IDBIndexMetadata>::Type CrossThreadCopierBas
return metadata.isolatedCopy();
}
CrossThreadCopierBase<false, false, IDBKeyData>::Type CrossThreadCopierBase<false, false, IDBKeyData>::copy(const IDBKeyData& keyData)
{
return keyData.isolatedCopy();
}
CrossThreadCopierBase<false, false, IDBObjectStoreMetadata>::Type CrossThreadCopierBase<false, false, IDBObjectStoreMetadata>::copy(const IDBObjectStoreMetadata& metadata)
{
return metadata.isolatedCopy();
......
......@@ -173,6 +173,12 @@ namespace WebCore {
static Type copy(const IDBIndexMetadata&);
};
struct IDBKeyData;
template<> struct CrossThreadCopierBase<false, false, IDBKeyData> {
typedef IDBKeyData Type;
static Type copy(const IDBKeyData&);
};
struct IDBObjectStoreMetadata;
template<> struct CrossThreadCopierBase<false, false, IDBObjectStoreMetadata> {
typedef IDBObjectStoreMetadata Type;
......
2014-01-21 Brady Eidson <beidson@apple.com>
IDB: "Put" support
<rdar://problem/15779643> and https://bugs.webkit.org/show_bug.cgi?id=127401
Reviewed by Alexey Proskuryakov.
Ship putRecord requests over to the DatabaseProcess, and listen for completion from the DatabaseProcess:
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:
(WebKit::WebIDBServerConnection::put):
(WebKit::WebIDBServerConnection::didPutRecord):
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.h:
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.messages.in:
Pass off the putRecord request to the Unique IDBDatabase:
* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp:
(WebKit::DatabaseProcessIDBConnection::putRecord):
* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.h:
* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.messages.in:
Pass off the putRecord request to the backing store:
* DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
(WebKit::UniqueIDBDatabase::putRecord):
(WebKit::UniqueIDBDatabase::putRecordInBackingStore):
(WebKit::UniqueIDBDatabase::didPutRecordInBackingStore):
* DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:
Add backing store methods related to putRecord, though only one is critical right now:
* DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::createAndPopulateInitialMetadata):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::generateKey):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::keyExistsInObjectStore):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::putRecord):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::updateKeyGenerator):
* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:
Add the IDBKeyData type to IPC:
* Scripts/webkit2/messages.py:
(struct_or_class):
* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<IDBKeyData>::encode):
(IPC::ArgumentCoder<IDBKeyData>::decode):
* Shared/WebCoreArgumentCoders.h:
* DatabaseProcess/IndexedDB/IDBSerialization.cpp:
(WebKit::serializeIDBKey):
* DatabaseProcess/IndexedDB/IDBSerialization.h:
Implement more cross-thread copying:
* Shared/WebCrossThreadCopier.cpp:
(WebCore::Vector<uint8_t>>::copy):
(WebCore::Vector<Vector<IDBKeyData>>>::copy):
(WebCore::ASCIILiteral>::copy):
* Shared/WebCrossThreadCopier.h:
Implement more numbers of generic AsyncTask templates:
* Shared/AsyncTask.h:
(WebKit::createAsyncTask):
2014-01-22 Anders Carlsson <andersca@apple.com>
WKProcessClass should create a WebContext
......
......@@ -177,6 +177,18 @@ void DatabaseProcessIDBConnection::deleteObjectStore(uint64_t requestID, int64_t
});
}
void DatabaseProcessIDBConnection::putRecord(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, const WebCore::IDBKeyData& key, const IPC::DataReference& value, int64_t putMode, const Vector<int64_t>& indexIDs, const Vector<Vector<WebCore::IDBKeyData>>& indexKeys)
{
ASSERT(m_uniqueIDBDatabase);
LOG(IDB, "DatabaseProcess putRecord request ID %llu, object store id %lli", requestID, objectStoreID);
RefPtr<DatabaseProcessIDBConnection> connection(this);
m_uniqueIDBDatabase->putRecord(IDBTransactionIdentifier(*this, transactionID), objectStoreID, key, value, putMode, indexIDs, indexKeys, [connection, requestID](const IDBKeyData& keyData, uint32_t errorCode, const String& errorMessage) {
connection->send(Messages::WebIDBServerConnection::DidPutRecord(requestID, keyData, errorCode, errorMessage));
});
}
IPC::Connection* DatabaseProcessIDBConnection::messageSenderConnection()
{
return m_connection->connection();
......
......@@ -34,6 +34,10 @@
#include "UniqueIDBDatabaseIdentifier.h"
#include <wtf/text/WTFString.h>
namespace WebCore {
struct IDBKeyData;
}
namespace WebKit {
class DatabaseToWebProcessConnection;
......@@ -71,6 +75,7 @@ private:
void changeDatabaseVersion(uint64_t requestID, int64_t transactionID, uint64_t newVersion);
void createObjectStore(uint64_t requestID, int64_t transactionID, WebCore::IDBObjectStoreMetadata);
void deleteObjectStore(uint64_t requestID, int64_t transactionID, int64_t objectStoreID);
void putRecord(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, const WebCore::IDBKeyData&, const IPC::DataReference& value, int64_t putMode, const Vector<int64_t>& indexIDs, const Vector<Vector<WebCore::IDBKeyData>>& indexKeys);
Ref<DatabaseToWebProcessConnection> m_connection;
uint64_t m_serverConnectionIdentifier;
......
......@@ -35,6 +35,7 @@ messages -> DatabaseProcessIDBConnection LegacyReceiver {
ChangeDatabaseVersion(uint64_t requestID, int64_t transactionID, uint64_t newVersion)
CreateObjectStore(uint64_t requestID, int64_t transactionID, WebCore::IDBObjectStoreMetadata objectStoreMetadata)
DeleteObjectStore(uint64_t requestID, int64_t transactionID, int64_t objectStoreID)
PutRecord(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, WebCore::IDBKeyData key, IPC::DataReference value, int64_t putMode, Vector<int64_t> indexIDs, Vector<Vector<WebCore::IDBKeyData>> indexKeys)
}
#endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)
......@@ -30,13 +30,14 @@
#include "ArgumentEncoder.h"
#include "KeyedDecoder.h"
#include "KeyedEncoder.h"
#include <WebCore/IDBKey.h>
#include <WebCore/IDBKeyPath.h>
using namespace WebCore;
namespace WebKit {
RefPtr<SharedBuffer> serializeIDBKeyPath(const WebCore::IDBKeyPath& keyPath)
RefPtr<SharedBuffer> serializeIDBKeyPath(const IDBKeyPath& keyPath)
{
KeyedEncoder encoder;
keyPath.encode(encoder);
......@@ -53,6 +54,13 @@ std::unique_ptr<WebCore::IDBKeyPath> deserializeIDBKeyPath(const uint8_t* data,
return result;
}
RefPtr<WebCore::SharedBuffer> serializeIDBKey(const IDBKey& key)
{
KeyedEncoder encoder;
key.encode(encoder);
return encoder.finishEncoding();
}
} // namespace WebKit
#endif // ENABLE(INDEXED_DATABASE)
......@@ -32,6 +32,7 @@
#include <wtf/Vector.h>
namespace WebCore {
class IDBKey;
class IDBKeyPath;
}
......@@ -40,6 +41,9 @@ namespace WebKit {
RefPtr<WebCore::SharedBuffer> serializeIDBKeyPath(const WebCore::IDBKeyPath&);
std::unique_ptr<WebCore::IDBKeyPath> deserializeIDBKeyPath(const uint8_t* buffer, size_t bufferSize);
RefPtr<WebCore::SharedBuffer> serializeIDBKey(const WebCore::IDBKey&);
PassRefPtr<WebCore::IDBKey> deserializeIDBKey(const uint8_t* buffer, size_t bufferSize);
} // namespace WebKit
#endif // ENABLE(INDEXED_DATABASE)
......
......@@ -30,13 +30,17 @@
#include "AsyncRequest.h"
#include "AsyncTask.h"
#include "DataReference.h"
#include "DatabaseProcess.h"
#include "DatabaseProcessIDBConnection.h"
#include "UniqueIDBDatabaseBackingStoreSQLite.h"
#include "WebCrossThreadCopier.h"
#include <WebCore/FileSystem.h>
#include <WebCore/IDBDatabaseBackend.h>
#include <WebCore/IDBDatabaseMetadata.h>
#include <WebCore/IDBKeyData.h>
#include <wtf/MainThread.h>
#include <wtf/text/WTFString.h>
using namespace WebCore;
......@@ -222,7 +226,7 @@ void UniqueIDBDatabase::didOpenBackingStoreAndReadMetadata(const IDBDatabaseMeta
}
}
void UniqueIDBDatabase::openTransaction(const IDBTransactionIdentifier& identifier, const Vector<int64_t>& objectStoreIDs, WebCore::IndexedDB::TransactionMode mode, std::function<void(bool)> successCallback)
void UniqueIDBDatabase::openTransaction(const IDBTransactionIdentifier& identifier, const Vector<int64_t>& objectStoreIDs, IndexedDB::TransactionMode mode, std::function<void(bool)> successCallback)
{
postTransactionOperation(identifier, createAsyncTask(*this, &UniqueIDBDatabase::openBackingStoreTransaction, identifier, objectStoreIDs, mode), successCallback);
}
......@@ -334,7 +338,7 @@ void UniqueIDBDatabase::didCompleteBoolRequest(uint64_t requestID, bool success)
request->completeRequest(success);
}
void UniqueIDBDatabase::createObjectStore(const IDBTransactionIdentifier& identifier, const WebCore::IDBObjectStoreMetadata& metadata, std::function<void(bool)> successCallback)
void UniqueIDBDatabase::createObjectStore(const IDBTransactionIdentifier& identifier, const IDBObjectStoreMetadata& metadata, std::function<void(bool)> successCallback)
{
ASSERT(isMainThread());
......@@ -389,7 +393,30 @@ void UniqueIDBDatabase::deleteObjectStore(const IDBTransactionIdentifier& identi
postDatabaseTask(createAsyncTask(*this, &UniqueIDBDatabase::deleteObjectStoreInBackingStore, requestID, identifier, objectStoreID));
}
void UniqueIDBDatabase::openBackingStoreTransaction(const IDBTransactionIdentifier& identifier, const Vector<int64_t>& objectStoreIDs, WebCore::IndexedDB::TransactionMode mode)
void UniqueIDBDatabase::putRecord(const IDBTransactionIdentifier& identifier, int64_t objectStoreID, const IDBKeyData& keyData, const IPC::DataReference& value, int64_t putMode, const Vector<int64_t>& indexIDs, const Vector<Vector<IDBKeyData>>& indexKeys, std::function<void(const IDBKeyData&, uint32_t, const String&)> callback)
{
ASSERT(isMainThread());
if (!m_acceptingNewRequests) {
callback(IDBKeyData(), INVALID_STATE_ERR, "Unable to put record into database because it has shut down");
return;
}
ASSERT(m_metadata->objectStores.contains(objectStoreID));
RefPtr<AsyncRequest> request = AsyncRequestImpl<const IDBKeyData&, uint32_t, const String&>::create([this, callback](const IDBKeyData& keyData, uint32_t errorCode, const String& errorMessage) {
callback(keyData, errorCode, errorMessage);
}, [this, callback]() {
callback(IDBKeyData(), INVALID_STATE_ERR, "Unable to put record into database");
});
uint64_t requestID = request->requestID();
m_pendingDatabaseTasks.add(requestID, request.release());
postDatabaseTask(createAsyncTask(*this, &UniqueIDBDatabase::putRecordInBackingStore, requestID, identifier, m_metadata->objectStores.get(objectStoreID), keyData, value.vector(), putMode, indexIDs, indexKeys));
}
void UniqueIDBDatabase::openBackingStoreTransaction(const IDBTransactionIdentifier& identifier, const Vector<int64_t>& objectStoreIDs, IndexedDB::TransactionMode mode)
{
ASSERT(!isMainThread());
ASSERT(m_backingStore);
......@@ -469,6 +496,62 @@ void UniqueIDBDatabase::deleteObjectStoreInBackingStore(uint64_t requestID, cons
postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didDeleteObjectStore, requestID, success));
}
void UniqueIDBDatabase::putRecordInBackingStore(uint64_t requestID, const IDBTransactionIdentifier& transaction, const IDBObjectStoreMetadata& objectStoreMetadata, const IDBKeyData& keyData, const Vector<uint8_t>& value, int64_t putMode, const Vector<int64_t>& indexIDs, const Vector<Vector<IDBKeyData>>& indexKeys)
{
ASSERT(!isMainThread());
ASSERT(m_backingStore);
bool keyWasGenerated = false;
RefPtr<IDBKey> key;
if (putMode != IDBDatabaseBackend::CursorUpdate && objectStoreMetadata.autoIncrement && keyData.isNull) {
key = m_backingStore->generateKey(transaction, objectStoreMetadata.id);
keyWasGenerated = true;
} else
key = keyData.maybeCreateIDBKey();
ASSERT(key);
ASSERT(key->isValid());
if (putMode == IDBDatabaseBackend::AddOnly) {
bool keyExists;
if (!m_backingStore->keyExistsInObjectStore(transaction, objectStoreMetadata.id, *key, keyExists)) {
postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didPutRecordInBackingStore, requestID, IDBKeyData(), IDBDatabaseException::UnknownError, ASCIILiteral("Internal backing store error checking for key existence")));
return;
}
if (keyExists) {
postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didPutRecordInBackingStore, requestID, IDBKeyData(), IDBDatabaseException::ConstraintError, ASCIILiteral("Key already exists in the object store")));
return;