Commit 4e595274 authored by hans@chromium.org's avatar hans@chromium.org
Browse files

2011-02-16 Hans Wennborg <hans@chromium.org>

        Reviewed by Jeremy Orlow.

        IndexedDB: Inject auto increment keys via key path on insertion
        https://bugs.webkit.org/show_bug.cgi?id=54457

        Prepare to test injection of auto increment key. Keep it commented out
        until implemented Chromium-side.

        * storage/indexeddb/objectstore-autoincrement-expected.txt:
        * storage/indexeddb/objectstore-autoincrement.html:
2011-02-16  Hans Wennborg  <hans@chromium.org>

        Reviewed by Jeremy Orlow.

        IndexedDB: Inject auto increment keys via key path on insertion
        https://bugs.webkit.org/show_bug.cgi?id=54457

        Inject auto increment keys via key path for object stores using key
        path and auto increment.

        * bindings/v8/IDBBindingUtilities.cpp:
        (WebCore::LocalContext::getNthValueOnKeyPath):
        (WebCore::createIDBKeyFromSerializedValueAndKeyPath):
        (WebCore::injectIDBKeyIntoSerializedValue):
        * bindings/v8/IDBBindingUtilities.h:
        * platform/chromium/PlatformBridge.h:
        * storage/IDBKeyPathBackendImpl.cpp:
        (IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue):
        * storage/IDBKeyPathBackendImpl.h:
        * storage/IDBObjectStoreBackendImpl.cpp:
        (WebCore::injectKeyIntoKeyPath):
        (WebCore::IDBObjectStoreBackendImpl::selectKeyForPut):
        (WebCore::IDBObjectStoreBackendImpl::putInternal):
        * storage/IDBObjectStoreBackendImpl.h:
        * storage/chromium/IDBKeyPathBackendImpl.cpp:
        (WebCore::IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue):
2011-02-16  Hans Wennborg  <hans@chromium.org>

        Reviewed by Jeremy Orlow.

        IndexedDB: Inject auto increment keys via key path on insertion
        https://bugs.webkit.org/show_bug.cgi?id=54457

        Support for injecting keys into objects via key path.

        * public/WebIDBKey.h:
        * public/WebKitClient.h:
        (WebKit::WebKitClient::injectIDBKeyIntoSerializedValue):
        * src/PlatformBridge.cpp:
        (WebCore::PlatformBridge::injectIDBKeyIntoSerializedValue):
        * src/WebIDBKey.cpp:
        (WebKit::WebIDBKey::injectIDBKeyIntoSerializedValue):
        * tests/IDBBindingUtilitiesTest.cpp:
        (WebCore::injectKey):
        (WebCore::checkInjection):
        (WebCore::checkInjectionFails):
        (WebCore::TEST):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@78721 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 33b8c685
2011-02-16 Hans Wennborg <hans@chromium.org>
Reviewed by Jeremy Orlow.
IndexedDB: Inject auto increment keys via key path on insertion
https://bugs.webkit.org/show_bug.cgi?id=54457
Prepare to test injection of auto increment key. Keep it commented out
until implemented Chromium-side.
* storage/indexeddb/objectstore-autoincrement-expected.txt:
* storage/indexeddb/objectstore-autoincrement.html:
2011-02-16 Nikolas Zimmermann <nzimmermann@rim.com>
 
Not reviewed.
......@@ -29,15 +29,10 @@ Insert into object store with auto increment and key path, with key in the objec
store.add({name: 'Jeffersson', number: '7010', id: 3})
addJefferssonSuccess():
PASS event.target.result is 3
Insert into object store with auto increment and key path, without key in the object.
store.add({name: 'Lincoln', number: '7012'})
addLincolnError():
PASS event.target.errorCode is webkitIDBDatabaseException.UNKNOWN_ERR
event.preventDefault()
store = trans.objectStore('StoreWithAutoIncrement')
Insert into object store with key gen using explicit key
store.add({name: 'Lincoln', number: '7012'}, 5)
addLincolnSuccess():
addLincolnWithExplicitKeySuccess():
PASS event.target.result is 5
store.get(5)
getLincolnSuccess():
......
......@@ -78,29 +78,45 @@ function addJefferssonSuccess()
debug("addJefferssonSuccess():");
shouldBe("event.target.result", "3");
debug("Insert into object store with auto increment and key path, without key in the object.");
request = evalAndLog("store.add({name: 'Lincoln', number: '7012'})");
request.onsuccess = unexpectedSuccessCallback;
request.onerror = addLincolnError;
//FIXME: Un-comment this code when functionality is implemented Chromium-side.
//debug("Insert into object store with auto increment and key path, without key in the object.");
//request = evalAndLog("store.add({name: 'Lincoln', number: '7012'})");
//request.onsuccess = addLincolnWithInjectKeySuccess;
//request.onerror = unexpectedErrorCallback;
window.store = evalAndLog("store = trans.objectStore('StoreWithAutoIncrement')");
debug("Insert into object store with key gen using explicit key");
request = evalAndLog("store.add({name: 'Lincoln', number: '7012'}, 5)");
request.onsuccess = addLincolnWithExplicitKeySuccess;
request.onerror = unexpectedErrorCallback;
}
function addLincolnError()
function addLincolnWithInjectKeySuccess()
{
debug("addLincolnError():");
// FIXME: This should be implemented, but we make it an error for now.
shouldBe("event.target.errorCode", "webkitIDBDatabaseException.UNKNOWN_ERR");
debug("addLincolnWithInjectKeySuccess():");
shouldBe("event.target.result", "4");
evalAndLog("event.preventDefault()");
result = evalAndLog("store.get(4)");
result.onsuccess = getLincolnAfterInjectedKeySuccess;
result.onerror = unexpectedErrorCallback;
}
function getLincolnAfterInjectedKeySuccess()
{
debug("getLincolnAfterInjectedKeySuccess():");
shouldBeEqualToString("event.target.result.name", "Lincoln");
shouldBeEqualToString("event.target.result.number", "7012");
shouldBe("event.target.result.id", "4");
window.store = evalAndLog("store = trans.objectStore('StoreWithAutoIncrement')");
debug("Insert into object store with key gen using explicit key");
request = evalAndLog("store.add({name: 'Lincoln', number: '7012'}, 5)");
request.onsuccess = addLincolnSuccess;
request.onsuccess = addLincolnWithExplicitKeySuccess;
request.onerror = unexpectedErrorCallback;
}
function addLincolnSuccess()
function addLincolnWithExplicitKeySuccess()
{
debug("addLincolnSuccess():");
debug("addLincolnWithExplicitKeySuccess():");
shouldBe("event.target.result", "5");
request = evalAndLog("store.get(5)");
......
2011-02-16 Hans Wennborg <hans@chromium.org>
Reviewed by Jeremy Orlow.
IndexedDB: Inject auto increment keys via key path on insertion
https://bugs.webkit.org/show_bug.cgi?id=54457
Inject auto increment keys via key path for object stores using key
path and auto increment.
* bindings/v8/IDBBindingUtilities.cpp:
(WebCore::LocalContext::getNthValueOnKeyPath):
(WebCore::createIDBKeyFromSerializedValueAndKeyPath):
(WebCore::injectIDBKeyIntoSerializedValue):
* bindings/v8/IDBBindingUtilities.h:
* platform/chromium/PlatformBridge.h:
* storage/IDBKeyPathBackendImpl.cpp:
(IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue):
* storage/IDBKeyPathBackendImpl.h:
* storage/IDBObjectStoreBackendImpl.cpp:
(WebCore::injectKeyIntoKeyPath):
(WebCore::IDBObjectStoreBackendImpl::selectKeyForPut):
(WebCore::IDBObjectStoreBackendImpl::putInternal):
* storage/IDBObjectStoreBackendImpl.h:
* storage/chromium/IDBKeyPathBackendImpl.cpp:
(WebCore::IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue):
2011-02-16 Sergio Villar Senin <svillar@igalia.com>
 
Reviewed by Martin Robinson.
......@@ -33,6 +33,7 @@
#include "IDBKeyPath.h"
#include "SerializedScriptValue.h"
#include "V8Binding.h"
#include "V8IDBKey.h"
#include <wtf/Vector.h>
namespace WebCore {
......@@ -51,6 +52,8 @@ PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value> value)
return 0; // Signals type error.
}
namespace {
template<typename T>
bool getValueFrom(T indexOrName, v8::Handle<v8::Value>& v8Value)
{
......@@ -61,6 +64,40 @@ bool getValueFrom(T indexOrName, v8::Handle<v8::Value>& v8Value)
return true;
}
template<typename T>
bool setValue(v8::Handle<v8::Value>& v8Object, T indexOrName, const v8::Handle<v8::Value>& v8Value)
{
v8::Local<v8::Object> object = v8Object->ToObject();
ASSERT(!object->Has(indexOrName));
return object->Set(indexOrName, v8Value);
}
bool get(v8::Handle<v8::Value>& object, const IDBKeyPathElement& keyPathElement)
{
switch (keyPathElement.type) {
case IDBKeyPathElement::IsIndexed:
return object->IsArray() && getValueFrom(keyPathElement.index, object);
case IDBKeyPathElement::IsNamed:
return object->IsObject() && getValueFrom(v8String(keyPathElement.identifier), object);
default:
ASSERT_NOT_REACHED();
}
return false;
}
bool set(v8::Handle<v8::Value>& object, const IDBKeyPathElement& keyPathElement, const v8::Handle<v8::Value>& v8Value)
{
switch (keyPathElement.type) {
case IDBKeyPathElement::IsIndexed:
return object->IsArray() && setValue(object, keyPathElement.index, v8Value);
case IDBKeyPathElement::IsNamed:
return object->IsObject() && setValue(object, v8String(keyPathElement.identifier), v8Value);
default:
ASSERT_NOT_REACHED();
}
return false;
}
class LocalContext {
public:
LocalContext()
......@@ -80,25 +117,46 @@ private:
v8::Persistent<v8::Context> m_context;
};
v8::Handle<v8::Value> getNthValueOnKeyPath(v8::Handle<v8::Value>& rootValue, const Vector<IDBKeyPathElement>& keyPathElements, size_t index)
{
v8::Handle<v8::Value> currentValue(rootValue);
ASSERT(index <= keyPathElements.size());
for (size_t i = 0; i < index; ++i) {
if (!get(currentValue, keyPathElements[i]))
return v8::Handle<v8::Value>();
}
return currentValue;
}
} // anonymous namespace
PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> value, const Vector<IDBKeyPathElement>& keyPath)
{
LocalContext localContext;
v8::Handle<v8::Value> v8Value(value->deserialize());
for (size_t i = 0; i < keyPath.size(); ++i) {
switch (keyPath[i].type) {
case IDBKeyPathElement::IsIndexed:
if (!v8Value->IsArray() || !getValueFrom(keyPath[i].index, v8Value))
return 0;
break;
case IDBKeyPathElement::IsNamed:
if (!v8Value->IsObject() || !getValueFrom(v8String(keyPath[i].identifier), v8Value))
return 0;
break;
default:
ASSERT_NOT_REACHED();
}
}
return createIDBKeyFromValue(v8Value);
v8::Handle<v8::Value> v8Key(getNthValueOnKeyPath(v8Value, keyPath, keyPath.size()));
if (v8Key.IsEmpty())
return 0;
return createIDBKeyFromValue(v8Key);
}
PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const Vector<IDBKeyPathElement>& keyPath)
{
LocalContext localContext;
if (!keyPath.size())
return 0;
v8::Handle<v8::Value> v8Value(value->deserialize());
v8::Handle<v8::Value> parent(getNthValueOnKeyPath(v8Value, keyPath, keyPath.size() - 1));
if (parent.IsEmpty())
return 0;
if (!set(parent, keyPath.last(), toV8(key.get())))
return 0;
return SerializedScriptValue::create(v8Value);
}
} // namespace WebCore
......
......@@ -39,6 +39,7 @@ struct IDBKeyPathElement;
PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value>);
PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> value, const Vector<IDBKeyPathElement, 0>& keyPath);
PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const Vector<IDBKeyPathElement, 0>&);
}
......
......@@ -173,6 +173,8 @@ public:
static PassRefPtr<IDBFactoryBackendInterface> idbFactory();
// Extracts keyPath from values and returns the corresponding keys.
static void createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue> >& values, const String& keyPath, Vector<RefPtr<IDBKey> >& keys);
// Injects key via keyPath into value. Returns true on success.
static PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const String& keyPath);
// JavaScript ---------------------------------------------------------
static void notifyJSOutOfMemory(Frame*);
......
......@@ -37,4 +37,10 @@ void IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(const Ve
// FIXME: Implement this method once JSC supports WireFormat for SerializedScriptValue.
}
PassRefPtr<SerializedScriptValue> IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
{
// FIXME: Implement this method once JSC supports WireFormat for SerializedScriptValue.
return 0;
}
#endif // ENABLE(INDEXED_DATABASE)
......@@ -38,6 +38,7 @@ class SerializedScriptValue;
class IDBKeyPathBackendImpl {
public:
static void createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue>, 0>& values, const String& keyPath, Vector<RefPtr<IDBKey>, 0>& keys);
static PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const String& keyPath);
};
}
......
......@@ -134,6 +134,11 @@ static PassRefPtr<IDBKey> fetchKeyFromKeyPath(SerializedScriptValue* value, cons
return keys[0].release();
}
static PassRefPtr<SerializedScriptValue> injectKeyIntoKeyPath(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
{
return IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue(key, value, keyPath);
}
static bool putObjectStoreData(SQLiteDatabase& db, IDBKey* key, SerializedScriptValue* value, int64_t objectStoreId, int64_t& dataRowId)
{
String sql = dataRowId != IDBObjectStoreBackendImpl::InvalidId ? "UPDATE ObjectStoreData SET keyString = ?, keyDate = ?, keyNumber = ?, value = ? WHERE id = ?"
......@@ -197,7 +202,7 @@ void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue,
ec = IDBDatabaseException::NOT_ALLOWED_ERR;
}
PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::selectKeyForPut(IDBObjectStoreBackendImpl* objectStore, SerializedScriptValue* value, IDBKey* key, PutMode putMode, IDBCallbacks* callbacks)
PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::selectKeyForPut(IDBObjectStoreBackendImpl* objectStore, IDBKey* key, PutMode putMode, IDBCallbacks* callbacks, RefPtr<SerializedScriptValue>& value)
{
if (putMode == CursorUpdate)
ASSERT(key);
......@@ -220,19 +225,24 @@ PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::selectKeyForPut(IDBObjectStoreBack
if (!hasKeyPath)
return objectStore->genAutoIncrementKey();
RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value, objectStore->m_keyPath);
RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value.get(), objectStore->m_keyPath);
if (keyPathKey) {
objectStore->resetAutoIncrementKeyCache();
return keyPathKey;
}
// FIXME: Generate auto increment key, and inject it through the key path.
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Adding data to object stores with auto increment and in-line keys not yet supported."));
return 0;
RefPtr<IDBKey> autoIncKey = objectStore->genAutoIncrementKey();
RefPtr<SerializedScriptValue> valueAfterInjection = injectKeyIntoKeyPath(autoIncKey, value, objectStore->m_keyPath);
if (!valueAfterInjection) {
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "The generated key could not be inserted into the object using the keyPath."));
return 0;
}
value = valueAfterInjection;
return autoIncKey.release();
}
if (hasKeyPath) {
RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value, objectStore->m_keyPath);
RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value.get(), objectStore->m_keyPath);
if (!keyPathKey) {
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "The key could not be fetched from the keyPath."));
......@@ -258,7 +268,7 @@ PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::selectKeyForPut(IDBObjectStoreBack
void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction)
{
RefPtr<SerializedScriptValue> value = prpValue;
RefPtr<IDBKey> key = selectKeyForPut(objectStore.get(), value.get(), prpKey.get(), putMode, callbacks.get());
RefPtr<IDBKey> key = selectKeyForPut(objectStore.get(), prpKey.get(), putMode, callbacks.get(), value);
if (!key)
return;
......
......@@ -85,7 +85,7 @@ private:
SQLiteDatabase& sqliteDatabase() const;
PassRefPtr<IDBKey> genAutoIncrementKey();
void resetAutoIncrementKeyCache() { m_autoIncrementNumber = -1; }
static PassRefPtr<IDBKey> selectKeyForPut(IDBObjectStoreBackendImpl*, SerializedScriptValue*, IDBKey*, PutMode, IDBCallbacks*);
static PassRefPtr<IDBKey> selectKeyForPut(IDBObjectStoreBackendImpl*, IDBKey*, PutMode, IDBCallbacks*, RefPtr<SerializedScriptValue>&);
static void getInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>);
static void putInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBTransactionBackendInterface>);
......
......@@ -28,7 +28,9 @@
#if ENABLE(INDEXED_DATABASE)
#include "IDBKey.h"
#include "PlatformBridge.h"
#include "SerializedScriptValue.h"
namespace WebCore {
......@@ -37,6 +39,11 @@ void IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(const Ve
PlatformBridge::createIDBKeysFromSerializedValuesAndKeyPath(values, keyPath, keys);
}
PassRefPtr<SerializedScriptValue> IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
{
return PlatformBridge::injectIDBKeyIntoSerializedValue(key, value, keyPath);
}
} // namespace WebCore
#endif
2011-02-16 Hans Wennborg <hans@chromium.org>
Reviewed by Jeremy Orlow.
IndexedDB: Inject auto increment keys via key path on insertion
https://bugs.webkit.org/show_bug.cgi?id=54457
Support for injecting keys into objects via key path.
* public/WebIDBKey.h:
* public/WebKitClient.h:
(WebKit::WebKitClient::injectIDBKeyIntoSerializedValue):
* src/PlatformBridge.cpp:
(WebCore::PlatformBridge::injectIDBKeyIntoSerializedValue):
* src/WebIDBKey.cpp:
(WebKit::WebIDBKey::injectIDBKeyIntoSerializedValue):
* tests/IDBBindingUtilitiesTest.cpp:
(WebCore::injectKey):
(WebCore::checkInjection):
(WebCore::checkInjectionFails):
(WebCore::TEST):
2011-02-16 Sheriff Bot <webkit.review.bot@gmail.com>
 
Unreviewed, rolling out r78678.
......@@ -49,6 +49,7 @@ public:
WEBKIT_API static WebIDBKey createNumber(double);
WEBKIT_API static WebIDBKey createInvalid();
WEBKIT_API static WebIDBKey createFromValueAndKeyPath(const WebSerializedScriptValue&, const WebIDBKeyPath&);
WEBKIT_API static WebSerializedScriptValue injectIDBKeyIntoSerializedValue(const WebIDBKey&, const WebSerializedScriptValue&, const WebIDBKeyPath&);
WebIDBKey(const WebIDBKey& e) { assign(e); }
WebIDBKey& operator=(const WebIDBKey& e)
......
......@@ -36,6 +36,7 @@
#include "WebCommon.h"
#include "WebData.h"
#include "WebLocalizedString.h"
#include "WebSerializedScriptValue.h"
#include "WebString.h"
#include "WebVector.h"
#include "WebURL.h"
......@@ -62,7 +63,6 @@ class WebMessagePortChannel;
class WebMimeRegistry;
class WebPluginListBuilder;
class WebSandboxSupport;
class WebSerializedScriptValue;
class WebSharedWorkerRepository;
class WebSocketStreamHandle;
class WebStorageNamespace;
......@@ -144,6 +144,7 @@ public:
virtual WebIDBFactory* idbFactory() { return 0; }
virtual void createIDBKeysFromSerializedValuesAndKeyPath(const WebVector<WebSerializedScriptValue>& values, const WebString& keyPath, WebVector<WebIDBKey>& keys) { }
virtual WebSerializedScriptValue injectIDBKeyIntoSerializedValue(const WebIDBKey& key, const WebSerializedScriptValue& value, const WebString& keyPath) { return WebSerializedScriptValue(); }
// Keygen --------------------------------------------------------------
......
......@@ -539,7 +539,7 @@ void PlatformBridge::createIDBKeysFromSerializedValuesAndKeyPath(const Vector<Re
{
WebVector<WebSerializedScriptValue> webValues = values;
WebVector<WebIDBKey> webKeys;
webKitClient()->createIDBKeysFromSerializedValuesAndKeyPath(webValues, WebString(keyPath), webKeys);
webKitClient()->createIDBKeysFromSerializedValuesAndKeyPath(webValues, keyPath, webKeys);
size_t webKeysSize = webKeys.size();
keys.reserveCapacity(webKeysSize);
......@@ -547,6 +547,11 @@ void PlatformBridge::createIDBKeysFromSerializedValuesAndKeyPath(const Vector<Re
keys.append(PassRefPtr<IDBKey>(webKeys[i]));
}
PassRefPtr<SerializedScriptValue> PlatformBridge::injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
{
return webKitClient()->injectIDBKeyIntoSerializedValue(key, value, keyPath);
}
// Keygen ---------------------------------------------------------------------
String PlatformBridge::signedPublicKeyAndChallengeString(
......
......@@ -83,6 +83,11 @@ WebIDBKey WebIDBKey::createFromValueAndKeyPath(const WebSerializedScriptValue& s
return WebCore::createIDBKeyFromSerializedValueAndKeyPath(serializedScriptValue, idbKeyPath);
}
WebSerializedScriptValue WebIDBKey::injectIDBKeyIntoSerializedValue(const WebIDBKey& key, const WebSerializedScriptValue& value, const WebIDBKeyPath& path)
{
return WebCore::injectIDBKeyIntoSerializedValue(key, value, path);
}
void WebIDBKey::assign(const WebIDBKey& value)
{
m_private = value.m_private;
......
......@@ -73,6 +73,29 @@ void checkKeyPathNullValue(SerializedScriptValue* value, const String& keyPath)
ASSERT_FALSE(idbKey.get());
}
PassRefPtr<SerializedScriptValue> injectKey(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
{
Vector<IDBKeyPathElement> idbKeyPath;
IDBKeyPathParseError parseError;
IDBParseKeyPath(keyPath, idbKeyPath, parseError);
EXPECT_EQ(IDBKeyPathParseErrorNone, parseError);
return injectIDBKeyIntoSerializedValue(key, value, idbKeyPath);
}
void checkInjection(PassRefPtr<IDBKey> prpKey, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
{
RefPtr<IDBKey> key = prpKey;
RefPtr<SerializedScriptValue> newValue = injectKey(key, value, keyPath);
ASSERT_TRUE(newValue);
RefPtr<IDBKey> extractedKey = checkKeyFromValueAndKeyPathInternal(newValue.get(), keyPath);
EXPECT_TRUE(key->isEqual(extractedKey.get()));
}
void checkInjectionFails(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
{
EXPECT_FALSE(injectKey(key, value, keyPath));
}
void checkKeyPathStringValue(SerializedScriptValue* value, const String& keyPath, const String& expected)
{
RefPtr<IDBKey> idbKey = checkKeyFromValueAndKeyPathInternal(value, keyPath);
......@@ -160,6 +183,67 @@ TEST(IDBKeyFromValueAndKeyPathTest, Array2D)
checkKeyPathNullValue(serializedScriptValue.get(), "[4]");
}
TEST(InjectIDBKeyTest, TopLevelPropertyStringValue)
{
LocalContext v8context;
v8::Local<v8::Object> object = v8::Object::New();
object->Set(v8::String::New("foo"), v8::String::New("zoo"));
checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(object), "bar");
checkInjection(IDBKey::createNumber(1234), SerializedScriptValue::create(object), "bar");
checkInjectionFails(IDBKey::createString("key"), SerializedScriptValue::create(object), "foo.bar");
checkInjectionFails(IDBKey::createString("key"), SerializedScriptValue::create(object), "[3]");
}
TEST(InjectIDBKeyTest, TopLevelArrayElement)
{
LocalContext v8context;
v8::Local<v8::Array> array = v8::Array::New();
array->Set(3, v8::String::New("zoo"));
checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(array), "[2]");
checkInjection(IDBKey::createNumber(789), SerializedScriptValue::create(array), "[4]");
checkInjection(IDBKey::createDate(4567), SerializedScriptValue::create(array), "[1]");
checkInjectionFails(IDBKey::createString("foo"), SerializedScriptValue::create(array), "[5].bar");
}
TEST(InjectIDBKeyTest, SubProperty)
{
LocalContext v8context;
v8::Local<v8::Object> object = v8::Object::New();
v8::Local<v8::Object> subProperty = v8::Object::New();
subProperty->Set(v8::String::New("bar"), v8::String::New("zee"));
object->Set(v8::String::New("foo"), subProperty);
checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(object), "foo.baz");
checkInjection(IDBKey::createNumber(789), SerializedScriptValue::create(object), "foo.baz");
checkInjection(IDBKey::createDate(4567), SerializedScriptValue::create(object), "foo.baz");
checkInjection(IDBKey::createDate(4567), SerializedScriptValue::create(object), "bar");
checkInjectionFails(IDBKey::createString("zoo"), SerializedScriptValue::create(object), "foo.bar.baz");
checkInjectionFails(IDBKey::createString("zoo"), SerializedScriptValue::create(object), "foo.xyz.foo");
}
TEST(InjectIDBKeyTest, Array2D)
{
LocalContext v8context;
v8::Local<v8::Object> object = v8::Object::New();
v8::Local<v8::Array> array = v8::Array::New();
v8::Local<v8::Array> subArray = v8::Array::New();
subArray->Set(7, v8::String::New("zee"));
array->Set(3, subArray);
object->Set(v8::String::New("foo"), array);
checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(object), "foo[3][8]");
checkInjection(IDBKey::createNumber(789), SerializedScriptValue::create(object), "foo[3][8]");
checkInjection(IDBKey::createDate(4567), SerializedScriptValue::create(object), "foo[3][8]");
checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(object), "bar");
checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(object), "foo[4]");
checkInjectionFails(IDBKey::createString("zoo"), SerializedScriptValue::create(object), "foo[3][7].foo");
}
} // namespace
#endif // ENABLE(INDEXED_DATABASE)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment