Changeset 128379 in webkit


Ignore:
Timestamp:
Sep 12, 2012 4:20:22 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

IndexedDB: Use ScriptValue instead of SerializedScriptValue when possible
https://bugs.webkit.org/show_bug.cgi?id=94023

Patch by Alec Flett <alecflett@chromium.org> on 2012-09-12
Reviewed by Kentaro Hara.

Transition the put/add/update methods to accept direct ScriptValue
objects rather than SerializedScriptValues, to eliminate lots of
redundant deserialization/serialization steps while storing
values.

Also see https://bugs.webkit.org/show_bug.cgi?id=95409 for
followup get/openCursor work, following this.

No new tests, this is a performance refactor of core IDB
functionality. Most existing tests cover correctness. Tests that
might fail include:

storage/indexeddb/objectstore-basics.html
storage/indexeddb/keypath-basics.html
storage/indexeddb/index-basics.html

  • Modules/indexeddb/IDBCursor.cpp:

(WebCore::IDBCursor::update):

  • Modules/indexeddb/IDBCursor.h:

(IDBCursor):

  • Modules/indexeddb/IDBCursor.idl:
  • Modules/indexeddb/IDBObjectStore.cpp:

(WebCore::generateIndexKeysForValue):
(WebCore::IDBObjectStore::add):
(WebCore::IDBObjectStore::put):
(WebCore):

  • Modules/indexeddb/IDBObjectStore.h:

(WebCore::IDBObjectStore::add):
(WebCore::IDBObjectStore::put):
(IDBObjectStore):

  • Modules/indexeddb/IDBObjectStore.idl:
  • bindings/v8/IDBBindingUtilities.cpp:

(WebCore):
(WebCore::createIDBKeyFromScriptValueAndKeyPath):
(WebCore::deserializeIDBValue):
(WebCore::canInjectIDBKeyIntoScriptValue):

  • bindings/v8/IDBBindingUtilities.h:

(WebCore):

Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r128376 r128379  
     12012-09-12  Alec Flett  <alecflett@chromium.org>
     2
     3        IndexedDB: Use ScriptValue instead of SerializedScriptValue when possible
     4        https://bugs.webkit.org/show_bug.cgi?id=94023
     5
     6        Reviewed by Kentaro Hara.
     7
     8        Transition the put/add/update methods to accept direct ScriptValue
     9        objects rather than SerializedScriptValues, to eliminate lots of
     10        redundant deserialization/serialization steps while storing
     11        values.
     12
     13        Also see https://bugs.webkit.org/show_bug.cgi?id=95409 for
     14        followup get/openCursor work, following this.
     15
     16        No new tests, this is a performance refactor of core IDB
     17        functionality. Most existing tests cover correctness. Tests that
     18        might fail include:
     19
     20        storage/indexeddb/objectstore-basics.html
     21        storage/indexeddb/keypath-basics.html
     22        storage/indexeddb/index-basics.html
     23
     24        * Modules/indexeddb/IDBCursor.cpp:
     25        (WebCore::IDBCursor::update):
     26        * Modules/indexeddb/IDBCursor.h:
     27        (IDBCursor):
     28        * Modules/indexeddb/IDBCursor.idl:
     29        * Modules/indexeddb/IDBObjectStore.cpp:
     30        (WebCore::generateIndexKeysForValue):
     31        (WebCore::IDBObjectStore::add):
     32        (WebCore::IDBObjectStore::put):
     33        (WebCore):
     34        * Modules/indexeddb/IDBObjectStore.h:
     35        (WebCore::IDBObjectStore::add):
     36        (WebCore::IDBObjectStore::put):
     37        (IDBObjectStore):
     38        * Modules/indexeddb/IDBObjectStore.idl:
     39        * bindings/v8/IDBBindingUtilities.cpp:
     40        (WebCore):
     41        (WebCore::createIDBKeyFromScriptValueAndKeyPath):
     42        (WebCore::deserializeIDBValue):
     43        (WebCore::canInjectIDBKeyIntoScriptValue):
     44        * bindings/v8/IDBBindingUtilities.h:
     45        (WebCore):
     46
    1472012-09-12  Chris Fleizach  <cfleizach@apple.com>
    248
  • trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp

    r126254 r128379  
    126126}
    127127
    128 PassRefPtr<IDBRequest> IDBCursor::update(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> prpValue, ExceptionCode& ec)
     128PassRefPtr<IDBRequest> IDBCursor::update(ScriptExecutionContext* context, ScriptValue& value, ExceptionCode& ec)
    129129{
    130130    IDB_TRACE("IDBCursor::update");
    131     RefPtr<SerializedScriptValue> value = prpValue;
    132131
    133132    if (!m_gotValue || isKeyCursor()) {
     
    141140    if (m_transaction->isReadOnly()) {
    142141        ec = IDBDatabaseException::READ_ONLY_ERR;
    143         return 0;
    144     }
    145     if (value->blobURLs().size() > 0) {
    146         // FIXME: Add Blob/File/FileList support
    147         ec = IDBDatabaseException::IDB_DATA_CLONE_ERR;
    148142        return 0;
    149143    }
     
    153147    const bool usesInLineKeys = !keyPath.isNull();
    154148    if (usesInLineKeys) {
    155         RefPtr<IDBKey> keyPathKey = createIDBKeyFromSerializedValueAndKeyPath(value, keyPath);
     149        RefPtr<IDBKey> keyPathKey = createIDBKeyFromScriptValueAndKeyPath(value, keyPath);
    156150        if (!keyPathKey || !keyPathKey->isEqual(m_currentPrimaryKey.get())) {
    157151            ec = IDBDatabaseException::DATA_ERR;
  • trunk/Source/WebCore/Modules/indexeddb/IDBCursor.h

    r125568 r128379  
    7676    IDBAny* source() const;
    7777
    78     PassRefPtr<IDBRequest> update(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue>, ExceptionCode&);
     78    PassRefPtr<IDBRequest> update(ScriptExecutionContext*, ScriptValue&, ExceptionCode&);
    7979    void advance(unsigned long, ExceptionCode&);
    8080    void continueFunction(PassRefPtr<IDBKey>, ExceptionCode&);
  • trunk/Source/WebCore/Modules/indexeddb/IDBCursor.idl

    r116337 r128379  
    4040        readonly attribute IDBAny source;
    4141
    42         [CallWith=ScriptExecutionContext] IDBRequest update(in SerializedScriptValue value)
     42        [CallWith=ScriptExecutionContext] IDBRequest update(in any value)
    4343            raises (IDBDatabaseException);
    4444        void advance(in unsigned long count)
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp

    r126968 r128379  
    106106
    107107static void generateIndexKeysForValue(const IDBIndexMetadata& indexMetadata,
    108                                       PassRefPtr<SerializedScriptValue> objectValue,
     108                                      const ScriptValue& objectValue,
    109109                                      IDBObjectStore::IndexKeys* indexKeys)
    110110{
    111111    ASSERT(indexKeys);
    112     RefPtr<IDBKey> indexKey = createIDBKeyFromSerializedValueAndKeyPath(objectValue, indexMetadata.keyPath);
     112    RefPtr<IDBKey> indexKey = createIDBKeyFromScriptValueAndKeyPath(objectValue, indexMetadata.keyPath);
    113113
    114114    if (!indexKey)
     
    130130}
    131131
    132 PassRefPtr<IDBRequest> IDBObjectStore::add(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, ExceptionCode& ec)
     132PassRefPtr<IDBRequest> IDBObjectStore::add(ScriptExecutionContext* context, ScriptValue& value, PassRefPtr<IDBKey> key, ExceptionCode& ec)
    133133{
    134134    IDB_TRACE("IDBObjectStore::add");
     
    136136}
    137137
    138 PassRefPtr<IDBRequest> IDBObjectStore::put(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, ExceptionCode& ec)
     138PassRefPtr<IDBRequest> IDBObjectStore::put(ScriptExecutionContext* context, ScriptValue& value, PassRefPtr<IDBKey> key, ExceptionCode& ec)
    139139{
    140140    IDB_TRACE("IDBObjectStore::put");
     
    142142}
    143143
    144 PassRefPtr<IDBRequest> IDBObjectStore::put(IDBObjectStoreBackendInterface::PutMode putMode, PassRefPtr<IDBAny> source, ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, ExceptionCode& ec)
     144PassRefPtr<IDBRequest> IDBObjectStore::put(IDBObjectStoreBackendInterface::PutMode putMode, PassRefPtr<IDBAny> source, ScriptExecutionContext* context, ScriptValue& value, PassRefPtr<IDBKey> prpKey, ExceptionCode& ec)
    145145{
    146146    IDB_TRACE("IDBObjectStore::put");
    147     RefPtr<SerializedScriptValue> value = prpValue;
    148147    RefPtr<IDBKey> key = prpKey;
    149148    if (m_deleted) {
     
    159158        return 0;
    160159    }
    161     if (value->blobURLs().size() > 0) {
     160
     161    ScriptState* state = ScriptState::current();
     162    RefPtr<SerializedScriptValue> serializedValue = value.serialize(state);
     163    if (state->hadException()) {
     164        ec = IDBDatabaseException::IDB_DATA_CLONE_ERR;
     165        return 0;
     166    }
     167
     168    if (serializedValue->blobURLs().size() > 0) {
    162169        // FIXME: Add Blob/File/FileList support
    163170        ec = IDBDatabaseException::IDB_DATA_CLONE_ERR;
     
    178185    }
    179186    if (usesInLineKeys) {
    180         RefPtr<IDBKey> keyPathKey = createIDBKeyFromSerializedValueAndKeyPath(value, keyPath);
     187        RefPtr<IDBKey> keyPathKey = createIDBKeyFromScriptValueAndKeyPath(value, keyPath);
    181188        if (keyPathKey && !keyPathKey->isValid()) {
    182189            ec = IDBDatabaseException::DATA_ERR;
     
    188195        }
    189196        if (hasKeyGenerator && !keyPathKey) {
    190             RefPtr<IDBKey> dummyKey = IDBKey::createNumber(-1);
    191             RefPtr<SerializedScriptValue> valueAfterInjection = injectIDBKeyIntoSerializedValue(dummyKey, value, keyPath);
    192             if (!valueAfterInjection) {
     197            if (!canInjectIDBKeyIntoScriptValue(value, keyPath)) {
    193198                ec = IDBDatabaseException::DATA_ERR;
    194199                return 0;
     
    214219
    215220    RefPtr<IDBRequest> request = IDBRequest::create(context, source, m_transaction.get());
    216     m_backend->putWithIndexKeys(value.release(), key.release(), putMode, request, m_transaction->backend(), indexNames, indexKeys, ec);
     221    m_backend->putWithIndexKeys(serializedValue.release(), key.release(), putMode, request, m_transaction->backend(), indexNames, indexKeys, ec);
    217222    if (ec) {
    218223        request->markEarlyDeath();
     
    314319    }
    315320
    316     virtual void handleEvent(ScriptExecutionContext*, Event* event)
     321    virtual void handleEvent(ScriptExecutionContext* context, Event* event)
    317322    {
    318323        ASSERT(event->type() == eventNames().successEvent);
     
    337342
    338343            ASSERT(valueAny->type() == IDBAny::SerializedScriptValueType);
    339             RefPtr<SerializedScriptValue> value = valueAny->serializedScriptValue();
     344            RefPtr<SerializedScriptValue> serializedValue = valueAny->serializedScriptValue();
     345            ScriptValue value(deserializeIDBValue(context, serializedValue));
    340346
    341347            IDBObjectStore::IndexKeys indexKeys;
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h

    r127757 r128379  
    6565    bool autoIncrement() const { return m_metadata.autoIncrement; }
    6666
    67     PassRefPtr<IDBRequest> add(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, ExceptionCode& ec) { return add(context, value, 0, ec);  }
    68     PassRefPtr<IDBRequest> put(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, ExceptionCode& ec) { return put(context, value, 0, ec);  }
     67    PassRefPtr<IDBRequest> add(ScriptExecutionContext* context, ScriptValue& value, ExceptionCode& ec) { return add(context, value, 0, ec);  }
     68    PassRefPtr<IDBRequest> put(ScriptExecutionContext* context, ScriptValue& value, ExceptionCode& ec) { return put(context, value, 0, ec);  }
    6969    PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext* context, ExceptionCode& ec) { return openCursor(context, static_cast<IDBKeyRange*>(0), ec); }
    7070    PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec) { return openCursor(context, keyRange, IDBCursor::directionNext(), ec); }
     
    7878    PassRefPtr<IDBRequest> get(ScriptExecutionContext*, PassRefPtr<IDBKey>, ExceptionCode&);
    7979    PassRefPtr<IDBRequest> get(ScriptExecutionContext*, PassRefPtr<IDBKeyRange>, ExceptionCode&);
    80     PassRefPtr<IDBRequest> add(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, ExceptionCode&);
    81     PassRefPtr<IDBRequest> put(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, ExceptionCode&);
     80    PassRefPtr<IDBRequest> add(ScriptExecutionContext*, ScriptValue&, PassRefPtr<IDBKey>, ExceptionCode&);
     81    PassRefPtr<IDBRequest> put(ScriptExecutionContext*, ScriptValue&, PassRefPtr<IDBKey>, ExceptionCode&);
    8282    PassRefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, PassRefPtr<IDBKeyRange>, ExceptionCode&);
    8383    PassRefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, PassRefPtr<IDBKey> key, ExceptionCode&);
     
    9898    PassRefPtr<IDBRequest> count(ScriptExecutionContext*, PassRefPtr<IDBKey>, ExceptionCode&);
    9999
    100     PassRefPtr<IDBRequest> put(IDBObjectStoreBackendInterface::PutMode, PassRefPtr<IDBAny> source, ScriptExecutionContext*, PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, ExceptionCode&);
     100    PassRefPtr<IDBRequest> put(IDBObjectStoreBackendInterface::PutMode, PassRefPtr<IDBAny> source, ScriptExecutionContext*, ScriptValue&, PassRefPtr<IDBKey>, ExceptionCode&);
    101101    void markDeleted() { m_deleted = true; }
    102102    void transactionFinished();
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.idl

    r125730 r128379  
    3535        readonly attribute boolean autoIncrement;
    3636
    37         [CallWith=ScriptExecutionContext] IDBRequest put(in SerializedScriptValue value, in [Optional] IDBKey key)
     37        [CallWith=ScriptExecutionContext] IDBRequest put(in any value, in [Optional] IDBKey key)
    3838            raises (IDBDatabaseException);
    39         [CallWith=ScriptExecutionContext] IDBRequest add(in SerializedScriptValue value, in [Optional] IDBKey key)
     39        [CallWith=ScriptExecutionContext] IDBRequest add(in any value, in [Optional] IDBKey key)
    4040            raises (IDBDatabaseException);
    4141        [CallWith=ScriptExecutionContext, ImplementedAs=deleteFunction] IDBRequest delete(in IDBKeyRange? keyRange)
  • trunk/Source/WebCore/bindings/v8/IDBBindingUtilities.cpp

    r128125 r128379  
    3636#include "V8Binding.h"
    3737#include "V8IDBKey.h"
     38#include "WorldContextHandle.h"
    3839#include <wtf/MathExtras.h>
    3940#include <wtf/Vector.h>
     
    8687}
    8788
    88 namespace {
    89 
    9089template<typename T>
    91 bool getValueFrom(T indexOrName, v8::Handle<v8::Value>& v8Value)
     90static bool getValueFrom(T indexOrName, v8::Handle<v8::Value>& v8Value)
    9291{
    9392    v8::Local<v8::Object> object = v8Value->ToObject();
     
    9998
    10099template<typename T>
    101 bool setValue(v8::Handle<v8::Value>& v8Object, T indexOrName, const v8::Handle<v8::Value>& v8Value)
     100static bool setValue(v8::Handle<v8::Value>& v8Object, T indexOrName, const v8::Handle<v8::Value>& v8Value)
    102101{
    103102    v8::Local<v8::Object> object = v8Object->ToObject();
     
    105104}
    106105
    107 bool get(v8::Handle<v8::Value>& object, const String& keyPathElement)
     106static bool get(v8::Handle<v8::Value>& object, const String& keyPathElement, v8::Handle<v8::Value>& result)
    108107{
    109108    if (object->IsString() && keyPathElement == "length") {
    110109        int32_t length = v8::Handle<v8::String>::Cast(object)->Length();
    111         object = v8::Number::New(length);
     110        result = v8::Number::New(length);
    112111        return true;
    113112    }
    114     return object->IsObject() && getValueFrom(v8String(keyPathElement), object);
    115 }
    116 
    117 bool set(v8::Handle<v8::Value>& object, const String& keyPathElement, const v8::Handle<v8::Value>& v8Value)
    118 {
    119     return object->IsObject() && setValue(object, v8String(keyPathElement), v8Value);
    120 }
    121 
    122 v8::Handle<v8::Value> getNthValueOnKeyPath(v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index)
     113    return object->IsObject() && getValueFrom(v8String(keyPathElement), result);
     114}
     115
     116static bool canSet(v8::Handle<v8::Value>& object, const String& keyPathElement)
     117{
     118    return object->IsObject();
     119}
     120
     121static bool set(v8::Handle<v8::Value>& object, const String& keyPathElement, const v8::Handle<v8::Value>& v8Value)
     122{
     123    return canSet(object, keyPathElement) && setValue(object, v8String(keyPathElement), v8Value);
     124}
     125
     126static v8::Handle<v8::Value> getNthValueOnKeyPath(v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index)
    123127{
    124128    v8::Handle<v8::Value> currentValue(rootValue);
    125 
    126129    ASSERT(index <= keyPathElements.size());
    127130    for (size_t i = 0; i < index; ++i) {
    128         if (!get(currentValue, keyPathElements[i]))
     131        v8::Handle<v8::Value> parentValue(currentValue);
     132        if (!get(parentValue, keyPathElements[i], currentValue))
    129133            return v8Undefined();
    130134    }
     
    133137}
    134138
    135 v8::Handle<v8::Value> ensureNthValueOnKeyPath(v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index)
    136 {
     139static bool canInjectNthValueOnKeyPath(v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index)
     140{
     141    if (!rootValue->IsObject())
     142        return false;
     143
    137144    v8::Handle<v8::Value> currentValue(rootValue);
    138145
     
    141148        v8::Handle<v8::Value> parentValue(currentValue);
    142149        const String& keyPathElement = keyPathElements[i];
    143         if (!get(currentValue, keyPathElement)) {
     150        if (!get(parentValue, keyPathElement, currentValue))
     151            return canSet(parentValue, keyPathElement);
     152    }
     153    return true;
     154}
     155
     156
     157static v8::Handle<v8::Value> ensureNthValueOnKeyPath(v8::Handle<v8::Value>& rootValue, const Vector<String>& keyPathElements, size_t index)
     158{
     159    v8::Handle<v8::Value> currentValue(rootValue);
     160
     161    ASSERT(index <= keyPathElements.size());
     162    for (size_t i = 0; i < index; ++i) {
     163        v8::Handle<v8::Value> parentValue(currentValue);
     164        const String& keyPathElement = keyPathElements[i];
     165        if (!get(parentValue, keyPathElement, currentValue)) {
    144166            v8::Handle<v8::Object> object = v8::Object::New();
    145167            if (!set(parentValue, keyPathElement, object))
     
    152174}
    153175
    154 } // anonymous namespace
    155 
    156 static PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> prpValue, const String& keyPath)
     176static PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(const ScriptValue& value, const String& keyPath)
    157177{
    158178    Vector<String> keyPathElements;
     
    161181    ASSERT(error == IDBKeyPathParseErrorNone);
    162182
     183    v8::Handle<v8::Value> v8Value(value.v8Value());
     184    v8::Handle<v8::Value> v8Key(getNthValueOnKeyPath(v8Value, keyPathElements, keyPathElements.size()));
     185    if (v8Key.IsEmpty())
     186        return 0;
     187    return createIDBKeyFromValue(v8Key);
     188}
     189
     190PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(const ScriptValue& value, const IDBKeyPath& keyPath)
     191{
     192    IDB_TRACE("createIDBKeyFromScriptValueAndKeyPath");
     193    ASSERT(!keyPath.isNull());
     194
     195    v8::HandleScope scope;
     196    if (keyPath.type() == IDBKeyPath::ArrayType) {
     197        IDBKey::KeyArray result;
     198        const Vector<String>& array = keyPath.array();
     199        for (size_t i = 0; i < array.size(); ++i) {
     200            RefPtr<IDBKey> key = createIDBKeyFromScriptValueAndKeyPath(value, array[i]);
     201            if (!key)
     202                return 0;
     203            result.append(key);
     204        }
     205        return IDBKey::createArray(result);
     206    }
     207
     208    ASSERT(keyPath.type() == IDBKeyPath::StringType);
     209    return createIDBKeyFromScriptValueAndKeyPath(value, keyPath.string());
     210}
     211
     212static PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> prpValue, const String& keyPath)
     213{
     214    Vector<String> keyPathElements;
     215    IDBKeyPathParseError error;
     216    IDBParseKeyPath(keyPath, keyPathElements, error);
     217    ASSERT(error == IDBKeyPathParseErrorNone);
     218
    163219    RefPtr<SerializedScriptValue> value = prpValue;
    164220
     
    173229}
    174230
     231// FIXME: The only reason this exists is because we need a v8::Context and scope inside a timer. Is there a better / more general way to do this?
     232ScriptValue deserializeIDBValue(ScriptExecutionContext* scriptContext, PassRefPtr<SerializedScriptValue> prpValue)
     233{
     234    v8::HandleScope handleScope;
     235    v8::Context::Scope contextScope(toV8Context(scriptContext, UseCurrentWorld));
     236    return ScriptValue(prpValue->deserialize());
     237}
    175238
    176239PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> prpValue, const IDBKeyPath& keyPath)
     
    224287}
    225288
     289bool canInjectIDBKeyIntoScriptValue(const ScriptValue& scriptValue, const IDBKeyPath& keyPath)
     290{
     291    IDB_TRACE("canInjectIDBKeyIntoScriptValue");
     292    ASSERT(keyPath.type() == IDBKeyPath::StringType);
     293    Vector<String> keyPathElements;
     294    IDBKeyPathParseError error;
     295    IDBParseKeyPath(keyPath.string(), keyPathElements, error);
     296    ASSERT(error == IDBKeyPathParseErrorNone);
     297
     298    if (!keyPathElements.size())
     299        return false;
     300
     301    v8::Handle<v8::Value> v8Value(scriptValue.v8Value());
     302    return canInjectNthValueOnKeyPath(v8Value, keyPathElements, keyPathElements.size() - 1);
     303}
     304
    226305} // namespace WebCore
    227306
  • trunk/Source/WebCore/bindings/v8/IDBBindingUtilities.h

    r117817 r128379  
    2929#if ENABLE(INDEXED_DATABASE)
    3030
     31#include "ScriptValue.h"
    3132#include <v8.h>
    3233#include <wtf/Forward.h>
     
    3940
    4041PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value>);
     42
     43// FIXME: remove the SerializedValue versions when their use is finally removed in https://bugs.webkit.org/show_bug.cgi?id=95409.
    4144PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue>, const IDBKeyPath&);
    4245PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const IDBKeyPath&);
     46
     47PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(const ScriptValue&, const IDBKeyPath&);
     48bool canInjectIDBKeyIntoScriptValue(const ScriptValue&, const IDBKeyPath&);
     49ScriptValue deserializeIDBValue(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue>);
    4350
    4451}
Note: See TracChangeset for help on using the changeset viewer.