+2015-10-31 Brady Eidson <beidson@apple.com>
+
+ IDB: Date objects don't work as keys or values.
+ https://bugs.webkit.org/show_bug.cgi?id=150743
+
+ Reviewed by Darin Adler.
+
+ * storage/indexeddb/modern/date-basic-expected.txt: Added.
+ * storage/indexeddb/modern/date-basic.html: Added.
+ * storage/indexeddb/modern/get-keyrange-expected.txt:
+ * storage/indexeddb/modern/get-keyrange.html:
+
2015-10-31 Brady Eidson <beidson@apple.com>
storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures.html is flaky.
--- /dev/null
+ALERT: Initial upgrade needed: Old version - 0 New version - 1
+ALERT: Initial upgrade versionchange transaction complete
+ALERT: Success getting key 'Fri Nov 04 1955 17:00:00 GMT-0700 (PDT)' of type object, result is 'Flux capacitor' of type string
+ALERT: Key is a Date object, btw
+ALERT: Success getting key 'Sat Nov 12 1955 10:00:00 GMT-0800 (PST)' of type object, result is 'Fish under the sea' of type string
+ALERT: Key is a Date object, btw
+ALERT: Success getting key 'Wed Oct 21 2015 09:00:00 GMT-0700 (PDT)' of type object, result is 'Hoverboards' of type string
+ALERT: Key is a Date object, btw
+ALERT: Success getting key 'a' of type string, result is 'Fri Nov 04 1955 17:00:00 GMT-0700 (PDT)' of type object
+ALERT: Result is a Date object, btw
+ALERT: Success getting key 'b' of type string, result is 'Sat Nov 12 1955 10:00:00 GMT-0800 (PST)' of type object
+ALERT: Result is a Date object, btw
+ALERT: Success getting key 'c' of type string, result is 'Wed Oct 21 2015 09:00:00 GMT-0700 (PDT)' of type object
+ALERT: Result is a Date object, btw
+ALERT: readonly transaction complete
+ALERT: Done
+This tests using Date objects as keys and values.
--- /dev/null
+This tests using Date objects as keys and values.
+<script>
+
+if (window.testRunner) {
+ testRunner.waitUntilDone();
+ testRunner.dumpAsText();
+}
+
+function done()
+{
+ alert("Done");
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+
+var createRequest = window.indexedDB.open("DateBasicDatabase", 1);
+var database;
+
+var date1 = new Date("1955-11-05T00:00:00");
+var date2 = new Date("1955-11-12T18:00:00");
+var date3 = new Date("2015-10-21T16:00:00");
+
+createRequest.onupgradeneeded = function(event) {
+ alert("Initial upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
+
+ var versionTransaction = createRequest.transaction;
+ database = event.target.result;
+ var objectStore = database.createObjectStore("TestObjectStore");
+
+ objectStore.put("Flux capacitor", date1);
+ objectStore.put("Fish under the sea", date2);
+ objectStore.put("Hoverboards", date3);
+
+ objectStore.put(date1, "a");
+ objectStore.put(date2, "b");
+ objectStore.put(date3, "c");
+
+ versionTransaction.onabort = function(event) {
+ alert("Initial upgrade versionchange transaction unexpected aborted");
+ done();
+ }
+
+ versionTransaction.oncomplete = function(event) {
+ alert("Initial upgrade versionchange transaction complete");
+ continueTest1();
+ }
+
+ versionTransaction.onerror = function(event) {
+ alert("Initial upgrade versionchange transaction unexpected error" + event);
+ done();
+ }
+}
+
+var objectStore;
+
+function testGet(key) {
+ var request = objectStore.get(key);
+ request.onsuccess = function()
+ {
+ alert("Success getting key '" + key + "' of type " + typeof(key) + ", result is '" + request.result + "' of type " + typeof(request.result));
+ if (key instanceof Date)
+ alert("Key is a Date object, btw");
+ if (request.result instanceof Date)
+ alert("Result is a Date object, btw");
+ }
+ request.onerror = function()
+ {
+ alert("Expected error getting key '" + key + "'");
+ }
+}
+
+function continueTest1()
+{
+ var transaction = database.transaction("TestObjectStore", "readonly");
+ objectStore = transaction.objectStore("TestObjectStore");
+
+ testGet(date1);
+ testGet(date2);
+ testGet(date3);
+ testGet("a");
+ testGet("b");
+ testGet("c");
+
+ transaction.onabort = function(event) {
+ alert("readonly transaction unexpected abort" + event);
+ done();
+ }
+
+ transaction.oncomplete = function(event) {
+ alert("readonly transaction complete");
+ done();
+ }
+
+ transaction.onerror = function(event) {
+ alert("readonly transaction unexpected error" + event);
+ done();
+ }
+}
+
+</script>
ALERT: Success getting keyRange [Infinity (Closed), a (Closed)]
ALERT: Result is PosInf
ALERT: Success getting keyRange [Infinity (Open), a (Closed)]
-ALERT: Result is A
+ALERT: Result is Flux capacitor
ALERT: Success getting keyRange [Infinity (Closed), a (Open)]
ALERT: Result is PosInf
ALERT: Success getting keyRange [Infinity (Open), a (Open)]
-ALERT: Result is A
+ALERT: Result is Flux capacitor
ALERT: Success getting keyRange [AS (Closed), a (Closed)]
ALERT: Result is AS
ALERT: Success getting keyRange [AS (Open), a (Closed)]
ALERT: Success getting keyRange [Infinity (Closed), (Closed)]
ALERT: Result is PosInf
ALERT: Success getting keyRange [Infinity (Open), (Closed)]
-ALERT: Result is A
+ALERT: Result is Flux capacitor
ALERT: Success getting keyRange [Infinity (Closed), (Open)]
ALERT: Result is PosInf
ALERT: Success getting keyRange [Infinity (Open), (Open)]
-ALERT: Result is A
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Infinity (Closed), a (Closed)]
+ALERT: Result is PosInf
+ALERT: Success getting keyRange [Infinity (Open), a (Closed)]
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Infinity (Closed), a (Open)]
+ALERT: Result is PosInf
+ALERT: Success getting keyRange [Infinity (Open), a (Open)]
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Infinity (Closed), a (Closed)]
+ALERT: Result is PosInf
+ALERT: Success getting keyRange [Infinity (Open), a (Closed)]
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Infinity (Closed), a (Open)]
+ALERT: Result is PosInf
+ALERT: Success getting keyRange [Infinity (Open), a (Open)]
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Fri Nov 04 1955 17:00:00 GMT-0700 (PDT) (Closed), Wed Oct 21 2015 09:00:00 GMT-0700 (PDT) (Closed)]
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Fri Nov 04 1955 17:00:00 GMT-0700 (PDT) (Open), Wed Oct 21 2015 09:00:00 GMT-0700 (PDT) (Closed)]
+ALERT: Result is Fish under the sea
+ALERT: Success getting keyRange [Fri Nov 04 1955 17:00:00 GMT-0700 (PDT) (Closed), Wed Oct 21 2015 09:00:00 GMT-0700 (PDT) (Open)]
+ALERT: Result is Flux capacitor
+ALERT: Success getting keyRange [Fri Nov 04 1955 17:00:00 GMT-0700 (PDT) (Open), Wed Oct 21 2015 09:00:00 GMT-0700 (PDT) (Open)]
+ALERT: Result is Fish under the sea
ALERT: readonly transaction complete
ALERT: Done
This test exercises IDBObjectStore.get() with an IDBKeyRange as the parameter.
var createRequest = window.indexedDB.open("GetKeyRangeDatabase", 1);
var database;
+var date1 = new Date("1955-11-05T00:00:00");
+var date2 = new Date("1955-11-12T18:00:00");
+var date3 = new Date("2015-10-21T16:00:00");
+
createRequest.onupgradeneeded = function(event) {
alert("Initial upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
var versionTransaction = createRequest.transaction;
database = event.target.result;
var objectStore = database.createObjectStore("TestObjectStore");
+
+ objectStore.put("Flux capacitor", date1);
+ objectStore.put("Fish under the sea", date2);
+ objectStore.put("Hoverboards", date3);
+
for (var i = 0; i < 100; ++i)
objectStore.put("\"" + i + "\"", i);
testGet(IDBKeyRange.bound(Infinity, [], true));
testGet(IDBKeyRange.bound(Infinity, [], false, true));
testGet(IDBKeyRange.bound(Infinity, [], true, true));
+
+ testGet(IDBKeyRange.bound(Infinity, "a"));
+ testGet(IDBKeyRange.bound(Infinity, "a", true));
+ testGet(IDBKeyRange.bound(Infinity, "a", false, true));
+ testGet(IDBKeyRange.bound(Infinity, "a", true, true));
+
+ testGet(IDBKeyRange.bound(Infinity, "a"));
+ testGet(IDBKeyRange.bound(Infinity, "a", true));
+ testGet(IDBKeyRange.bound(Infinity, "a", false, true));
+ testGet(IDBKeyRange.bound(Infinity, "a", true, true));
+
+ testGet(IDBKeyRange.bound(date1, date3));
+ testGet(IDBKeyRange.bound(date1, date3, true));
+ testGet(IDBKeyRange.bound(date1, date3, false, true));
+ testGet(IDBKeyRange.bound(date1, date3, true, true));
transaction.onabort = function(event) {
alert("readonly transaction unexpected abort" + event);
+2015-10-31 Brady Eidson <beidson@apple.com>
+
+ IDB: Date objects don't work as keys or values.
+ https://bugs.webkit.org/show_bug.cgi?id=150743
+
+ Reviewed by Darin Adler.
+
+ Test: storage/indexeddb/modern/date-basic.html
+
+ The combination of the autogenerated bindings with Deprecated::ScriptValue was
+ losing the fidelity of "Date" objects being Dates, and not just normal Objects.
+
+ This was breaking their usage as IDBKeys.
+
+ Custom binding + reworking the IDBObjectStore IDLs to use JSValue instead of ScriptValue
+ fixes this handily.
+
+ * Modules/indexeddb/IDBObjectStore.h:
+ * Modules/indexeddb/IDBObjectStore.idl:
+
+ * Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
+ (WebCore::IDBClient::IDBObjectStore::add):
+ (WebCore::IDBClient::IDBObjectStore::put):
+ (WebCore::IDBClient::IDBObjectStore::putOrAdd):
+ * Modules/indexeddb/client/IDBObjectStoreImpl.h:
+
+ * Modules/indexeddb/legacy/LegacyObjectStore.cpp:
+ (WebCore::LegacyObjectStore::add):
+ (WebCore::LegacyObjectStore::put):
+ * Modules/indexeddb/legacy/LegacyObjectStore.h:
+
+ * bindings/js/IDBBindingUtilities.cpp:
+ (WebCore::internalCreateIDBKeyFromScriptValueAndKeyPath):
+ (WebCore::maybeCreateIDBKeyFromScriptValueAndKeyPath):
+ (WebCore::canInjectIDBKeyIntoScriptValue):
+ (WebCore::scriptValueToIDBKey):
+ * bindings/js/IDBBindingUtilities.h:
+
+ * bindings/js/JSIDBObjectStoreCustom.cpp:
+ (WebCore::putOrAdd):
+ (WebCore::JSIDBObjectStore::putRecord):
+ (WebCore::JSIDBObjectStore::add):
+
2015-10-31 Andreas Kling <akling@apple.com>
Add a debug overlay with information about web process resource usage.
namespace JSC {
class ExecState;
+class JSValue;
}
namespace WebCore {
virtual RefPtr<IDBTransaction> transaction() = 0;
virtual bool autoIncrement() const = 0;
- virtual RefPtr<IDBRequest> add(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&) = 0;
- virtual RefPtr<IDBRequest> put(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&) = 0;
+ virtual RefPtr<IDBRequest> add(JSC::ExecState&, JSC::JSValue, ExceptionCode&) = 0;
+ virtual RefPtr<IDBRequest> put(JSC::ExecState&, JSC::JSValue, ExceptionCode&) = 0;
virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, ExceptionCode&) = 0;
virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
virtual RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
virtual RefPtr<IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
virtual RefPtr<IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
- virtual RefPtr<IDBRequest> add(JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
- virtual RefPtr<IDBRequest> put(JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
+ virtual RefPtr<IDBRequest> add(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&) = 0;
+ virtual RefPtr<IDBRequest> put(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&) = 0;
virtual RefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) = 0;
virtual RefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) = 0;
virtual RefPtr<IDBRequest> clear(ScriptExecutionContext*, ExceptionCode&) = 0;
readonly attribute IDBTransaction transaction;
readonly attribute boolean autoIncrement;
- [CallWith=ScriptState, RaisesException] IDBRequest put(any value, optional any key);
- [CallWith=ScriptState, RaisesException] IDBRequest add(any value, optional any key);
+ [CallWith=ScriptExecutionContext, Custom, ImplementedAs=putFunction, RaisesException] IDBRequest put(any value, optional any key);
+ [CallWith=ScriptExecutionContext, Custom, RaisesException] IDBRequest add(any value, optional any key);
[CallWith=ScriptExecutionContext, ImplementedAs=deleteFunction, RaisesException] IDBRequest delete(IDBKeyRange? keyRange);
[CallWith=ScriptExecutionContext, ImplementedAs=deleteFunction, RaisesException] IDBRequest delete(any key);
[CallWith=ScriptExecutionContext, RaisesException] IDBRequest get(IDBKeyRange? key);
return m_info.autoIncrement();
}
-RefPtr<WebCore::IDBRequest> IDBObjectStore::add(JSC::ExecState& state, Deprecated::ScriptValue& value, ExceptionCode& ec)
-{
- return putOrAdd(state, value, nullptr, IndexedDB::ObjectStoreOverwriteMode::NoOverwrite, ec);
-}
-
-RefPtr<WebCore::IDBRequest> IDBObjectStore::put(JSC::ExecState& state, Deprecated::ScriptValue& value, ExceptionCode& ec)
-{
- return putOrAdd(state, value, nullptr, IndexedDB::ObjectStoreOverwriteMode::Overwrite, ec);
-}
-
RefPtr<WebCore::IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext*, ExceptionCode&)
{
RELEASE_ASSERT_NOT_REACHED();
return WTF::move(request);
}
-RefPtr<WebCore::IDBRequest> IDBObjectStore::add(JSC::ExecState& execState, Deprecated::ScriptValue& value, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::add(JSC::ExecState& state, JSC::JSValue value, ExceptionCode& ec)
+{
+ return putOrAdd(state, value, nullptr, IndexedDB::ObjectStoreOverwriteMode::NoOverwrite, ec);
+}
+
+RefPtr<WebCore::IDBRequest> IDBObjectStore::add(JSC::ExecState& execState, JSC::JSValue value, JSC::JSValue key, ExceptionCode& ec)
{
auto idbKey = scriptValueToIDBKey(execState, key);
return putOrAdd(execState, value, idbKey, IndexedDB::ObjectStoreOverwriteMode::NoOverwrite, ec);
}
-RefPtr<WebCore::IDBRequest> IDBObjectStore::put(JSC::ExecState& execState, Deprecated::ScriptValue& value, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::put(JSC::ExecState& execState, JSC::JSValue value, JSC::JSValue key, ExceptionCode& ec)
{
auto idbKey = scriptValueToIDBKey(execState, key);
return putOrAdd(execState, value, idbKey, IndexedDB::ObjectStoreOverwriteMode::Overwrite, ec);
}
-RefPtr<WebCore::IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, Deprecated::ScriptValue& value, RefPtr<IDBKey> key, IndexedDB::ObjectStoreOverwriteMode overwriteMode, ExceptionCode& ec)
+RefPtr<WebCore::IDBRequest> IDBObjectStore::put(JSC::ExecState& state, JSC::JSValue value, ExceptionCode& ec)
+{
+ return putOrAdd(state, value, nullptr, IndexedDB::ObjectStoreOverwriteMode::Overwrite, ec);
+}
+
+RefPtr<WebCore::IDBRequest> IDBObjectStore::putOrAdd(JSC::ExecState& state, JSC::JSValue value, RefPtr<IDBKey> key, IndexedDB::ObjectStoreOverwriteMode overwriteMode, ExceptionCode& ec)
{
LOG(IndexedDB, "IDBObjectStore::putOrAdd");
return nullptr;
}
- RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(&state, value.jsValue(), nullptr, nullptr);
+ RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(&state, value, nullptr, nullptr);
if (state.hadException()) {
ec = DATA_CLONE_ERR;
return nullptr;
virtual RefPtr<WebCore::IDBTransaction> transaction() override final;
virtual bool autoIncrement() const override final;
- virtual RefPtr<WebCore::IDBRequest> add(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&) override final;
- virtual RefPtr<WebCore::IDBRequest> put(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&) override final;
+ virtual RefPtr<WebCore::IDBRequest> add(JSC::ExecState&, JSC::JSValue, ExceptionCode&) override final;
+ virtual RefPtr<WebCore::IDBRequest> put(JSC::ExecState&, JSC::JSValue, ExceptionCode&) override final;
virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, ExceptionCode&) override final;
virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
virtual RefPtr<WebCore::IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode&) override final;
virtual RefPtr<WebCore::IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
virtual RefPtr<WebCore::IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
- virtual RefPtr<WebCore::IDBRequest> add(JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
- virtual RefPtr<WebCore::IDBRequest> put(JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
+ virtual RefPtr<WebCore::IDBRequest> add(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&) override final;
+ virtual RefPtr<WebCore::IDBRequest> put(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&) override final;
virtual RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
virtual RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
virtual RefPtr<WebCore::IDBRequest> clear(ScriptExecutionContext*, ExceptionCode&) override final;
private:
IDBObjectStore(const IDBObjectStoreInfo&, IDBTransaction&);
- RefPtr<WebCore::IDBRequest> putOrAdd(JSC::ExecState&, Deprecated::ScriptValue&, RefPtr<IDBKey>, IndexedDB::ObjectStoreOverwriteMode, ExceptionCode&);
+ RefPtr<WebCore::IDBRequest> putOrAdd(JSC::ExecState&, JSC::JSValue, RefPtr<IDBKey>, IndexedDB::ObjectStoreOverwriteMode, ExceptionCode&);
IDBObjectStoreInfo m_info;
Ref<IDBTransaction> m_transaction;
return get(context, keyRange.get(), ec);
}
-RefPtr<IDBRequest> LegacyObjectStore::add(JSC::ExecState& state, Deprecated::ScriptValue& value, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<IDBRequest> LegacyObjectStore::add(JSC::ExecState& state, JSC::JSValue value, JSC::JSValue key, ExceptionCode& ec)
{
LOG(StorageAPI, "LegacyObjectStore::add");
- return put(IDBDatabaseBackend::AddOnly, LegacyAny::create(this), state, value, key, ec);
+ auto deprecatedValue = Deprecated::ScriptValue(state.vm(), value);
+ auto dKey = Deprecated::ScriptValue(state.vm(), key);
+ return put(IDBDatabaseBackend::AddOnly, LegacyAny::create(this), state, deprecatedValue, dKey, ec);
}
-RefPtr<IDBRequest> LegacyObjectStore::add(JSC::ExecState& state, Deprecated::ScriptValue& value, ExceptionCode& ec)
+RefPtr<IDBRequest> LegacyObjectStore::add(JSC::ExecState& state, JSC::JSValue value, ExceptionCode& ec)
{
LOG(StorageAPI, "LegacyObjectStore::add");
- return put(IDBDatabaseBackend::AddOnly, LegacyAny::create(this), state, value, static_cast<IDBKey*>(nullptr), ec);
+ auto deprecatedValue = Deprecated::ScriptValue(state.vm(), value);
+ return put(IDBDatabaseBackend::AddOnly, LegacyAny::create(this), state, deprecatedValue, static_cast<IDBKey*>(nullptr), ec);
}
-RefPtr<IDBRequest> LegacyObjectStore::put(JSC::ExecState& state, Deprecated::ScriptValue& value, const Deprecated::ScriptValue& key, ExceptionCode& ec)
+RefPtr<IDBRequest> LegacyObjectStore::put(JSC::ExecState& state, JSC::JSValue value, JSC::JSValue key, ExceptionCode& ec)
{
LOG(StorageAPI, "LegacyObjectStore::put");
- return put(IDBDatabaseBackend::AddOrUpdate, LegacyAny::create(this), state, value, key, ec);
+ auto deprecatedValue = Deprecated::ScriptValue(state.vm(), value);
+ return put(IDBDatabaseBackend::AddOrUpdate, LegacyAny::create(this), state, deprecatedValue, Deprecated::ScriptValue(state.vm(), key), ec);
}
-RefPtr<IDBRequest> LegacyObjectStore::put(JSC::ExecState& state, Deprecated::ScriptValue& value, ExceptionCode& ec)
+RefPtr<IDBRequest> LegacyObjectStore::put(JSC::ExecState& state, JSC::JSValue value, ExceptionCode& ec)
{
LOG(StorageAPI, "LegacyObjectStore::put");
- return put(IDBDatabaseBackend::AddOrUpdate, LegacyAny::create(this), state, value, static_cast<IDBKey*>(nullptr), ec);
+ auto deprecatedValue = Deprecated::ScriptValue(state.vm(), value);
+ return put(IDBDatabaseBackend::AddOrUpdate, LegacyAny::create(this), state, deprecatedValue, static_cast<IDBKey*>(nullptr), ec);
}
RefPtr<IDBRequest> LegacyObjectStore::put(IDBDatabaseBackend::PutMode putMode, RefPtr<LegacyAny> source, JSC::ExecState& state, Deprecated::ScriptValue& value, const Deprecated::ScriptValue& keyValue, ExceptionCode& ec)
RefPtr<IDBTransaction> transaction() { return m_transaction; }
bool autoIncrement() const { return m_metadata.autoIncrement; }
- RefPtr<IDBRequest> add(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&);
- RefPtr<IDBRequest> put(JSC::ExecState&, Deprecated::ScriptValue&, ExceptionCode&);
+ RefPtr<IDBRequest> add(JSC::ExecState&, JSC::JSValue, ExceptionCode&);
+ RefPtr<IDBRequest> put(JSC::ExecState&, JSC::JSValue, ExceptionCode&);
RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, ExceptionCode&);
RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&);
RefPtr<IDBRequest> openCursor(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&);
RefPtr<IDBRequest> get(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&);
RefPtr<IDBRequest> get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&);
- RefPtr<IDBRequest> add(JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&);
- RefPtr<IDBRequest> put(JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&);
+ RefPtr<IDBRequest> add(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&);
+ RefPtr<IDBRequest> put(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCode&);
RefPtr<IDBRequest> put(IDBDatabaseBackend::PutMode, RefPtr<LegacyAny>, JSC::ExecState&, Deprecated::ScriptValue&, RefPtr<IDBKey>, ExceptionCode&);
RefPtr<IDBRequest> put(IDBDatabaseBackend::PutMode, RefPtr<LegacyAny> source, JSC::ExecState&, Deprecated::ScriptValue&, const Deprecated::ScriptValue& key, ExceptionCode&);
return currentValue;
}
-static RefPtr<IDBKey> internalCreateIDBKeyFromScriptValueAndKeyPath(ExecState* exec, const Deprecated::ScriptValue& value, const String& keyPath)
+static RefPtr<IDBKey> internalCreateIDBKeyFromScriptValueAndKeyPath(ExecState* exec, const JSC::JSValue& value, const String& keyPath)
{
Vector<String> keyPathElements;
IDBKeyPathParseError error;
IDBParseKeyPath(keyPath, keyPathElements, error);
ASSERT(error == IDBKeyPathParseError::None);
- JSValue jsValue = value.jsValue();
+ JSValue jsValue = value;
jsValue = getNthValueOnKeyPath(exec, jsValue, keyPathElements, keyPathElements.size());
if (jsValue.isUndefined())
return nullptr;
return internalCreateIDBKeyFromScriptValueAndKeyPath(&exec, value, keyPath.string());
}
-bool canInjectIDBKeyIntoScriptValue(DOMRequestState* requestState, const Deprecated::ScriptValue& scriptValue, const IDBKeyPath& keyPath)
+RefPtr<IDBKey> maybeCreateIDBKeyFromScriptValueAndKeyPath(ExecState& exec, const JSC::JSValue& value, const IDBKeyPath& keyPath)
+{
+ ASSERT(!keyPath.isNull());
+
+ if (keyPath.type() == IndexedDB::KeyPathType::Array) {
+ const Vector<String>& array = keyPath.array();
+ Vector<RefPtr<IDBKey>> result;
+ result.reserveInitialCapacity(array.size());
+ for (auto& string : array) {
+ RefPtr<IDBKey> key = internalCreateIDBKeyFromScriptValueAndKeyPath(&exec, value, string);
+ if (!key)
+ return nullptr;
+ result.uncheckedAppend(WTF::move(key));
+ }
+ return IDBKey::createArray(WTF::move(result));
+ }
+
+ ASSERT(keyPath.type() == IndexedDB::KeyPathType::String);
+ return internalCreateIDBKeyFromScriptValueAndKeyPath(&exec, value, keyPath.string());
+}
+
+bool canInjectIDBKeyIntoScriptValue(DOMRequestState* requestState, const JSC::JSValue& scriptValue, const IDBKeyPath& keyPath)
{
LOG(StorageAPI, "canInjectIDBKeyIntoScriptValue");
return canInjectIDBKeyIntoScriptValue(*exec, scriptValue, keyPath);
}
-bool canInjectIDBKeyIntoScriptValue(JSC::ExecState& execState, const Deprecated::ScriptValue& scriptValue, const IDBKeyPath& keyPath)
+bool canInjectIDBKeyIntoScriptValue(JSC::ExecState& execState, const JSC::JSValue& scriptValue, const IDBKeyPath& keyPath)
{
LOG(StorageAPI, "canInjectIDBKeyIntoScriptValue");
if (!keyPathElements.size())
return false;
- return canInjectNthValueOnKeyPath(&execState, scriptValue.jsValue(), keyPathElements, keyPathElements.size() - 1);
+ return canInjectNthValueOnKeyPath(&execState, scriptValue, keyPathElements, keyPathElements.size() - 1);
}
Deprecated::ScriptValue deserializeIDBValue(DOMRequestState* requestState, PassRefPtr<SerializedScriptValue> prpValue)
return Deprecated::ScriptValue(exec->vm(), idbKeyToJSValue(exec, jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()), key.get()));
}
-RefPtr<IDBKey> scriptValueToIDBKey(DOMRequestState* requestState, const Deprecated::ScriptValue& scriptValue)
+RefPtr<IDBKey> scriptValueToIDBKey(DOMRequestState* requestState, const JSC::JSValue& scriptValue)
{
ExecState* exec = requestState->exec();
- return createIDBKeyFromValue(exec, scriptValue.jsValue());
+ return createIDBKeyFromValue(exec, scriptValue);
}
-RefPtr<IDBKey> scriptValueToIDBKey(ExecState& exec, const Deprecated::ScriptValue& scriptValue)
+RefPtr<IDBKey> scriptValueToIDBKey(ExecState& exec, const JSC::JSValue& scriptValue)
{
- return createIDBKeyFromValue(&exec, scriptValue.jsValue());
+ return createIDBKeyFromValue(&exec, scriptValue);
}
void generateIndexKeysForValue(ExecState* exec, const IDBIndexMetadata& indexMetadata, const Deprecated::ScriptValue& objectValue, Vector<IDBKeyData>& indexKeys)
RefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(JSC::ExecState*, const Deprecated::ScriptValue&, const IDBKeyPath&);
RefPtr<IDBKey> maybeCreateIDBKeyFromScriptValueAndKeyPath(JSC::ExecState&, const Deprecated::ScriptValue&, const IDBKeyPath&);
+RefPtr<IDBKey> maybeCreateIDBKeyFromScriptValueAndKeyPath(JSC::ExecState&, const JSC::JSValue&, const IDBKeyPath&);
-bool canInjectIDBKeyIntoScriptValue(DOMRequestState*, const Deprecated::ScriptValue&, const IDBKeyPath&);
-bool canInjectIDBKeyIntoScriptValue(JSC::ExecState&, const Deprecated::ScriptValue&, const IDBKeyPath&);
+bool canInjectIDBKeyIntoScriptValue(DOMRequestState*, const JSC::JSValue&, const IDBKeyPath&);
+bool canInjectIDBKeyIntoScriptValue(JSC::ExecState&, const JSC::JSValue&, const IDBKeyPath&);
Deprecated::ScriptValue deserializeIDBValue(DOMRequestState*, PassRefPtr<SerializedScriptValue>);
Deprecated::ScriptValue deserializeIDBValueData(ScriptExecutionContext&, const ThreadSafeDataBuffer& valueData);
Deprecated::ScriptValue deserializeIDBValueBuffer(DOMRequestState*, PassRefPtr<SharedBuffer>, bool keyIsDefined);
WEBCORE_EXPORT Deprecated::ScriptValue deserializeIDBValueBuffer(JSC::ExecState*, const Vector<uint8_t>&, bool keyIsDefined);
Deprecated::ScriptValue idbKeyToScriptValue(DOMRequestState*, PassRefPtr<IDBKey>);
-RefPtr<IDBKey> scriptValueToIDBKey(DOMRequestState*, const Deprecated::ScriptValue&);
-RefPtr<IDBKey> scriptValueToIDBKey(JSC::ExecState&, const Deprecated::ScriptValue&);
+RefPtr<IDBKey> scriptValueToIDBKey(DOMRequestState*, const JSC::JSValue&);
+RefPtr<IDBKey> scriptValueToIDBKey(JSC::ExecState&, const JSC::JSValue&);
WEBCORE_EXPORT void generateIndexKeysForValue(JSC::ExecState*, const IDBIndexMetadata&, const Deprecated::ScriptValue& objectValue, Vector<IDBKeyData>& indexKeys);
Deprecated::ScriptValue idbKeyDataToScriptValue(ScriptExecutionContext*, const IDBKeyData&);
#include "IDBObjectStore.h"
#include "JSDOMBinding.h"
#include "JSIDBIndex.h"
+#include "JSIDBRequest.h"
#include <runtime/Error.h>
#include <runtime/JSString.h>
namespace WebCore {
+static JSValue putOrAdd(JSC::ExecState& state, bool overwrite)
+{
+ JSValue thisValue = state.thisValue();
+ JSIDBObjectStore* castedThis = jsDynamicCast<JSIDBObjectStore*>(thisValue);
+ if (UNLIKELY(!castedThis))
+ return JSValue::decode(throwThisTypeError(state, "IDBObjectStore", "put"));
+
+ ASSERT_GC_OBJECT_INHERITS(castedThis, JSIDBObjectStore::info());
+ auto& impl = castedThis->impl();
+
+ size_t argsCount = state.argumentCount();
+ if (UNLIKELY(argsCount < 1))
+ return JSValue::decode(throwVMError(&state, createNotEnoughArgumentsError(&state)));
+
+ ExceptionCode ec = 0;
+ auto value = state.uncheckedArgument(0);
+
+ if (argsCount == 1) {
+ JSValue result;
+ if (overwrite)
+ result = toJS(&state, castedThis->globalObject(), impl.put(state, value, ec).get());
+ else
+ result = toJS(&state, castedThis->globalObject(), impl.add(state, value, ec).get());
+
+ setDOMException(&state, ec);
+ return result;
+ }
+
+ auto key = state.uncheckedArgument(1);
+ JSValue result;
+ if (overwrite)
+ result = toJS(&state, castedThis->globalObject(), impl.put(state, value, key, ec).get());
+ else
+ result = toJS(&state, castedThis->globalObject(), impl.add(state, value, key, ec).get());
+
+ setDOMException(&state, ec);
+ return result;
+}
+
+JSValue JSIDBObjectStore::putFunction(JSC::ExecState& state)
+{
+ return putOrAdd(state, true);
+}
+
+JSValue JSIDBObjectStore::add(JSC::ExecState& state)
+{
+ return putOrAdd(state, false);
+}
+
JSValue JSIDBObjectStore::createIndex(ExecState& state)
{
ScriptExecutionContext* context = jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject())->scriptExecutionContext();