Changeset 125728 in webkit


Ignore:
Timestamp:
Aug 15, 2012 5:50:52 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

IndexedDB: generate index keys for existing data in createIndex in front end
https://bugs.webkit.org/show_bug.cgi?id=91125

Patch by Alec Flett <alecflett@chromium.org> on 2012-08-15
Reviewed by Tony Chang.

Source/WebCore:

Make createIndex() do index key generation in the frontend, rather
than the backend. When an index is created, the frontend uses the
cursor API to iterate through the values in the backend to
generate keys, sending them back to the backend using
IDBObjectStore::setIndexKeys()

This confines all key injection/extraction to the frontend.

The new test verifies the implemented behavior with respect to
error handling in degenerate uses of put(), though that behavior
is still in discussion as the spec is vague on the proper error
behavior.

Test: storage/indexeddb/lazy-index-population.html

  • Modules/indexeddb/IDBCursorBackendImpl.cpp: Make sure that the

TaskType propagates throught the cursor and all subsequent
continue() calls.
(WebCore::IDBCursorBackendImpl::IDBCursorBackendImpl):
(WebCore::IDBCursorBackendImpl::continueFunction):
(WebCore::IDBCursorBackendImpl::prefetchContinue):

  • Modules/indexeddb/IDBCursorBackendImpl.h:

(WebCore::IDBCursorBackendImpl::create):
(IDBCursorBackendImpl):

  • Modules/indexeddb/IDBObjectStore.cpp: Add an IndexPopulator

class to run a cursor from the frontend.
(WebCore):
(WebCore::IDBObjectStore::createIndex):
(WebCore::IDBObjectStore::openCursor):

  • Modules/indexeddb/IDBObjectStore.h:

(WebCore::IDBObjectStore::openCursor):
(IDBObjectStore):
(WebCore::IDBObjectStore::createIndex):

  • Modules/indexeddb/IDBObjectStore.idl: Pass along ScriptContext

so that openCursor can be called from createIndex.

  • Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:

(WebCore):
(WebCore::makeIndexWriters):
(WebCore::IDBObjectStoreBackendImpl::setIndexKeys):
(WebCore::IDBObjectStoreBackendImpl::setIndexesReady):
(WebCore::IDBObjectStoreBackendImpl::setIndexesReadyInternal):
(WebCore::IDBObjectStoreBackendImpl::putInternal):
(WebCore::IDBObjectStoreBackendImpl::deleteInternal):
(WebCore::IDBObjectStoreBackendImpl::createIndexInternal):
(WebCore::IDBObjectStoreBackendImpl::openCursor):
(WebCore::IDBObjectStoreBackendImpl::openCursorInternal):

  • Modules/indexeddb/IDBObjectStoreBackendImpl.h:

(IDBObjectStoreBackendImpl):
(WebCore::IDBObjectStoreBackendImpl::iterIndexesBegin):
(WebCore::IDBObjectStoreBackendImpl::iterIndexesEnd):
(WebCore::IDBObjectStoreBackendImpl::backingStore):
(WebCore::IDBObjectStoreBackendImpl::databaseId):

  • Modules/indexeddb/IDBObjectStoreBackendInterface.h:
  • Modules/indexeddb/IDBRequest.cpp:

Allow requests to keep their own TaskType, to give certain
requests priority over others.
(WebCore::IDBRequest::create):
(WebCore):
(WebCore::IDBRequest::IDBRequest):
(WebCore::IDBRequest::abort):

  • Modules/indexeddb/IDBRequest.h:

(IDBRequest):
(WebCore::IDBRequest::taskType):

  • Modules/indexeddb/IDBTransactionBackendImpl.cpp:

Introduce a second, higher priority event queue, m_preemptiveTaskQueue,
which takes priority over the regular task queue.
(WebCore::IDBTransactionBackendImpl::IDBTransactionBackendImpl):
(WebCore::IDBTransactionBackendImpl::scheduleTask):
(WebCore::IDBTransactionBackendImpl::isTaskQueueEmpty):
(WebCore):
(WebCore::IDBTransactionBackendImpl::commit):
(WebCore::IDBTransactionBackendImpl::taskTimerFired):
(WebCore::IDBTransactionBackendImpl::taskEventTimerFired):

  • Modules/indexeddb/IDBTransactionBackendImpl.h:

(WebCore::IDBTransactionBackendImpl::scheduleTask):
(IDBTransactionBackendImpl):
(WebCore::IDBTransactionBackendImpl::addEarlyEvent):
(WebCore::IDBTransactionBackendImpl::didCompleteEarlyEvent):

  • Modules/indexeddb/IDBVersionChangeRequest.cpp:

(WebCore::IDBVersionChangeRequest::IDBVersionChangeRequest):

Source/WebKit/chromium:

Add Chromium API methods to let the renderer process tell the
browser process about indexing progress.

  • public/WebIDBObjectStore.h:

(WebKit::WebIDBObjectStore::openCursor):

  • src/IDBObjectStoreBackendProxy.cpp:

(WebKit::IDBObjectStoreBackendProxy::setIndexKeys):
(WebKit):
(WebKit::IDBObjectStoreBackendProxy::setIndexesReady):
(WebKit::IDBObjectStoreBackendProxy::openCursor):

  • src/IDBObjectStoreBackendProxy.h:

(IDBObjectStoreBackendProxy):

  • src/WebIDBObjectStoreImpl.cpp:

(WebKit::WebIDBObjectStoreImpl::setIndexKeys):
(WebKit):
(WebKit::WebIDBObjectStoreImpl::setIndexesReady):
(WebKit::WebIDBObjectStoreImpl::openCursor):

  • src/WebIDBObjectStoreImpl.h:

(WebIDBObjectStoreImpl):

LayoutTests:

The transaction should be aborted when existing data in an
objectStore causes uniqueness errors during index creation.

  • storage/indexeddb/lazy-index-population-expected.txt: Added.
  • storage/indexeddb/lazy-index-population.html: Added.
Location:
trunk
Files:
2 added
27 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r125727 r125728  
     12012-08-15  Alec Flett  <alecflett@chromium.org>
     2
     3        IndexedDB: generate index keys for existing data in createIndex in front end
     4        https://bugs.webkit.org/show_bug.cgi?id=91125
     5
     6        Reviewed by Tony Chang.
     7
     8        The transaction should be aborted when existing data in an
     9        objectStore causes uniqueness errors during index creation.
     10
     11        * storage/indexeddb/lazy-index-population-expected.txt: Added.
     12        * storage/indexeddb/lazy-index-population.html: Added.
     13
    1142012-08-15  Hayato Ito  <hayato@chromium.org>
    215
  • trunk/LayoutTests/storage/indexeddb/index-multientry-expected.txt

    r120967 r125728  
    9898This should fail the uniqueness constraint on the index, and fail:
    9999transaction.objectStore('store-unique').put({x: [5, 2], y: 'c'}, 'should fail')
    100 Request failed, as expected (DataError)
     100Request failed, as expected (ConstraintError)
    101101Transaction aborted as expected
    102102
  • trunk/LayoutTests/storage/indexeddb/index-unique-expected.txt

    r120114 r125728  
    2222addMoreDataFailed():
    2323event.preventDefault()
    24 PASS event.target.errorCode is IDBDatabaseException.DATA_ERR
    25 PASS event.target.error.name is 'DataError'
     24PASS event.target.errorCode is IDBDatabaseException.CONSTRAINT_ERR
     25PASS event.target.error.name is 'ConstraintError'
    2626transaction.objectStore('store').put({x: 0}, 'foo')
    2727changeDataSuccess():
  • trunk/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt

    r124859 r125728  
    9797event.target.source.add({x: 'foo'}, 'zzz')
    9898addAgainFailure():
    99 PASS event.target.errorCode is IDBDatabaseException.DATA_ERR
    100 PASS event.target.error.name is 'DataError'
     99PASS event.target.errorCode is IDBDatabaseException.CONSTRAINT_ERR
     100PASS event.target.error.name is 'ConstraintError'
    101101event.preventDefault()
    102102db.transaction(['storeName'], 'readwrite')
  • trunk/LayoutTests/storage/indexeddb/objectstore-basics-workers-expected.txt

    r124859 r125728  
    9898[Worker] event.target.source.add({x: 'foo'}, 'zzz')
    9999[Worker] addAgainFailure():
    100 PASS [Worker] event.target.errorCode is IDBDatabaseException.DATA_ERR
    101 PASS [Worker] event.target.error.name is 'DataError'
     100PASS [Worker] event.target.errorCode is IDBDatabaseException.CONSTRAINT_ERR
     101PASS [Worker] event.target.error.name is 'ConstraintError'
    102102[Worker] event.preventDefault()
    103103[Worker] db.transaction(['storeName'], 'readwrite')
  • trunk/LayoutTests/storage/indexeddb/resources/index-unique.js

    r120114 r125728  
    6666    evalAndLog("event.preventDefault()");
    6767
    68     shouldBe("event.target.errorCode", "IDBDatabaseException.DATA_ERR");
    69     shouldBe("event.target.error.name", "'DataError'");
     68    shouldBe("event.target.errorCode", "IDBDatabaseException.CONSTRAINT_ERR");
     69    shouldBe("event.target.error.name", "'ConstraintError'");
    7070
    7171    // Update the 'foo' entry in object store, changing the value of x.
  • trunk/LayoutTests/storage/indexeddb/resources/objectstore-basics.js

    r124859 r125728  
    176176    event = evt;
    177177    debug("addAgainFailure():");
    178     shouldBe("event.target.errorCode", "IDBDatabaseException.DATA_ERR");
    179     shouldBe("event.target.error.name", "'DataError'");
     178    shouldBe("event.target.errorCode", "IDBDatabaseException.CONSTRAINT_ERR");
     179    shouldBe("event.target.error.name", "'ConstraintError'");
    180180
    181181    evalAndLog("event.preventDefault()");
  • trunk/Source/WebCore/ChangeLog

    r125727 r125728  
     12012-08-15  Alec Flett  <alecflett@chromium.org>
     2
     3        IndexedDB: generate index keys for existing data in createIndex in front end
     4        https://bugs.webkit.org/show_bug.cgi?id=91125
     5
     6        Reviewed by Tony Chang.
     7
     8        Make createIndex() do index key generation in the frontend, rather
     9        than the backend. When an index is created, the frontend uses the
     10        cursor API to iterate through the values in the backend to
     11        generate keys, sending them back to the backend using
     12        IDBObjectStore::setIndexKeys()
     13
     14        This confines all key injection/extraction to the frontend.
     15
     16        The new test verifies the implemented behavior with respect to
     17        error handling in degenerate uses of put(), though that behavior
     18        is still in discussion as the spec is vague on the proper error
     19        behavior.
     20
     21        Test: storage/indexeddb/lazy-index-population.html
     22
     23        * Modules/indexeddb/IDBCursorBackendImpl.cpp: Make sure that the
     24        TaskType propagates throught the cursor and all subsequent
     25        continue() calls.
     26        (WebCore::IDBCursorBackendImpl::IDBCursorBackendImpl):
     27        (WebCore::IDBCursorBackendImpl::continueFunction):
     28        (WebCore::IDBCursorBackendImpl::prefetchContinue):
     29        * Modules/indexeddb/IDBCursorBackendImpl.h:
     30        (WebCore::IDBCursorBackendImpl::create):
     31        (IDBCursorBackendImpl):
     32        * Modules/indexeddb/IDBObjectStore.cpp: Add an IndexPopulator
     33        class to run a cursor from the frontend.
     34        (WebCore):
     35        (WebCore::IDBObjectStore::createIndex):
     36        (WebCore::IDBObjectStore::openCursor):
     37        * Modules/indexeddb/IDBObjectStore.h:
     38        (WebCore::IDBObjectStore::openCursor):
     39        (IDBObjectStore):
     40        (WebCore::IDBObjectStore::createIndex):
     41        * Modules/indexeddb/IDBObjectStore.idl: Pass along ScriptContext
     42        so that openCursor can be called from createIndex.
     43        * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
     44        (WebCore):
     45        (WebCore::makeIndexWriters):
     46        (WebCore::IDBObjectStoreBackendImpl::setIndexKeys):
     47        (WebCore::IDBObjectStoreBackendImpl::setIndexesReady):
     48        (WebCore::IDBObjectStoreBackendImpl::setIndexesReadyInternal):
     49        (WebCore::IDBObjectStoreBackendImpl::putInternal):
     50        (WebCore::IDBObjectStoreBackendImpl::deleteInternal):
     51        (WebCore::IDBObjectStoreBackendImpl::createIndexInternal):
     52        (WebCore::IDBObjectStoreBackendImpl::openCursor):
     53        (WebCore::IDBObjectStoreBackendImpl::openCursorInternal):
     54        * Modules/indexeddb/IDBObjectStoreBackendImpl.h:
     55        (IDBObjectStoreBackendImpl):
     56        (WebCore::IDBObjectStoreBackendImpl::iterIndexesBegin):
     57        (WebCore::IDBObjectStoreBackendImpl::iterIndexesEnd):
     58        (WebCore::IDBObjectStoreBackendImpl::backingStore):
     59        (WebCore::IDBObjectStoreBackendImpl::databaseId):
     60        * Modules/indexeddb/IDBObjectStoreBackendInterface.h:
     61        * Modules/indexeddb/IDBRequest.cpp:
     62        Allow requests to keep their own TaskType, to give certain
     63        requests priority over others.
     64        (WebCore::IDBRequest::create):
     65        (WebCore):
     66        (WebCore::IDBRequest::IDBRequest):
     67        (WebCore::IDBRequest::abort):
     68        * Modules/indexeddb/IDBRequest.h:
     69        (IDBRequest):
     70        (WebCore::IDBRequest::taskType):
     71        * Modules/indexeddb/IDBTransactionBackendImpl.cpp:
     72        Introduce a second, higher priority event queue, m_preemptiveTaskQueue,
     73        which takes priority over the regular task queue.
     74        (WebCore::IDBTransactionBackendImpl::IDBTransactionBackendImpl):
     75        (WebCore::IDBTransactionBackendImpl::scheduleTask):
     76        (WebCore::IDBTransactionBackendImpl::isTaskQueueEmpty):
     77        (WebCore):
     78        (WebCore::IDBTransactionBackendImpl::commit):
     79        (WebCore::IDBTransactionBackendImpl::taskTimerFired):
     80        (WebCore::IDBTransactionBackendImpl::taskEventTimerFired):
     81        * Modules/indexeddb/IDBTransactionBackendImpl.h:
     82        (WebCore::IDBTransactionBackendImpl::scheduleTask):
     83        (IDBTransactionBackendImpl):
     84        (WebCore::IDBTransactionBackendImpl::addEarlyEvent):
     85        (WebCore::IDBTransactionBackendImpl::didCompleteEarlyEvent):
     86        * Modules/indexeddb/IDBVersionChangeRequest.cpp:
     87        (WebCore::IDBVersionChangeRequest::IDBVersionChangeRequest):
     88
    1892012-08-15  Hayato Ito  <hayato@chromium.org>
    290
  • trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp

    r125568 r125728  
    4343namespace WebCore {
    4444
    45 IDBCursorBackendImpl::IDBCursorBackendImpl(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendImpl* transaction, IDBObjectStoreBackendImpl* objectStore)
     45IDBCursorBackendImpl::IDBCursorBackendImpl(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendImpl* transaction, IDBObjectStoreBackendImpl* objectStore)
    4646    : m_cursor(cursor)
     47    , m_taskType(taskType)
    4748    , m_cursorType(cursorType)
    4849    , m_transaction(transaction)
     
    6667{
    6768    IDB_TRACE("IDBCursorBackendImpl::continue");
    68     RefPtr<IDBKey> key = prpKey;
    69 
    70     if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::continueFunctionInternal, this, key, prpCallbacks)))
     69
     70    if (!m_transaction->scheduleTask(m_taskType, createCallbackTask(&IDBCursorBackendImpl::continueFunctionInternal, this, prpKey, prpCallbacks)))
    7171        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
    7272}
     
    127127{
    128128    IDB_TRACE("IDBCursorBackendImpl::prefetchContinue");
    129     if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::prefetchContinueInternal, this, numberToFetch, prpCallbacks)))
     129    if (!m_transaction->scheduleTask(m_taskType, createCallbackTask(&IDBCursorBackendImpl::prefetchContinueInternal, this, numberToFetch, prpCallbacks)))
    130130        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
    131131}
  • trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.h

    r125568 r125728  
    5050    static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendImpl* transaction, IDBObjectStoreBackendImpl* objectStore)
    5151    {
    52         return adoptRef(new IDBCursorBackendImpl(cursor, cursorType, transaction, objectStore));
     52        return adoptRef(new IDBCursorBackendImpl(cursor, cursorType, IDBTransactionBackendInterface::NormalTask, transaction, objectStore));
     53    }
     54    static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendImpl* transaction, IDBObjectStoreBackendImpl* objectStore)
     55    {
     56        return adoptRef(new IDBCursorBackendImpl(cursor, cursorType, taskType, transaction, objectStore));
    5357    }
    5458    virtual ~IDBCursorBackendImpl();
     
    6872
    6973private:
    70     IDBCursorBackendImpl(PassRefPtr<IDBBackingStore::Cursor>, CursorType, IDBTransactionBackendImpl*, IDBObjectStoreBackendImpl*);
     74    IDBCursorBackendImpl(PassRefPtr<IDBBackingStore::Cursor>, CursorType, IDBTransactionBackendInterface::TaskType, IDBTransactionBackendImpl*, IDBObjectStoreBackendImpl*);
    7175
    7276    static void advanceInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl>, unsigned long, PassRefPtr<IDBCallbacks>);
     
    7680    RefPtr<IDBBackingStore::Cursor> m_cursor;
    7781    RefPtr<IDBBackingStore::Cursor> m_savedCursor;
     82    IDBTransactionBackendInterface::TaskType m_taskType;
    7883    CursorType m_cursorType;
    7984    RefPtr<IDBTransactionBackendImpl> m_transaction;
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp

    r123843 r125728  
    3333#include "IDBBindingUtilities.h"
    3434#include "IDBCursorBackendInterface.h"
     35#include "IDBCursorWithValue.h"
    3536#include "IDBDatabase.h"
    3637#include "IDBDatabaseException.h"
     
    283284}
    284285
    285 PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const String& keyPath, const Dictionary& options, ExceptionCode& ec)
    286 {
    287     return createIndex(name, IDBKeyPath(keyPath), options, ec);
    288 }
    289 
    290 PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, PassRefPtr<DOMStringList> keyPath, const Dictionary& options, ExceptionCode& ec)
    291 {
    292     return createIndex(name, IDBKeyPath(*keyPath), options, ec);
    293 }
    294 
    295 
    296 PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const IDBKeyPath& keyPath, const Dictionary& options, ExceptionCode& ec)
     286namespace {
     287// This class creates the index keys for a given index by extracting
     288// them from the SerializedScriptValue, for all the existing values in
     289// the objectStore. It only needs to be kept alive by virtue of being
     290// a listener on an IDBRequest object, in the same way that JavaScript
     291// cursor success handlers are kept alive.
     292class IndexPopulator : public EventListener {
     293public:
     294    static PassRefPtr<IndexPopulator> create(PassRefPtr<IDBObjectStoreBackendInterface> backend, PassRefPtr<IDBTransactionBackendInterface> transaction, PassRefPtr<IDBRequest> request, const IDBIndexMetadata& indexMetadata)
     295    {
     296        return adoptRef(new IndexPopulator(backend, transaction, indexMetadata));
     297    }
     298
     299    virtual bool operator==(const EventListener& other)
     300    {
     301        return this == &other;
     302    }
     303
     304private:
     305    IndexPopulator(PassRefPtr<IDBObjectStoreBackendInterface> backend,
     306                   PassRefPtr<IDBTransactionBackendInterface> transaction,
     307                   const IDBIndexMetadata& indexMetadata)
     308        : EventListener(CPPEventListenerType)
     309        , m_objectStoreBackend(backend)
     310        , m_transaction(transaction)
     311        , m_indexMetadata(indexMetadata)
     312    {
     313    }
     314
     315    virtual void handleEvent(ScriptExecutionContext*, Event* event)
     316    {
     317        ASSERT(event->type() == eventNames().successEvent);
     318        EventTarget* target = event->target();
     319        IDBRequest* request = static_cast<IDBRequest*>(target);
     320
     321        ExceptionCode ec = 0;
     322        RefPtr<IDBAny> cursorAny = request->result(ec);
     323        ASSERT(!ec);
     324        RefPtr<IDBCursorWithValue> cursor;
     325        if (cursorAny->type() == IDBAny::IDBCursorWithValueType)
     326            cursor = cursorAny->idbCursorWithValue();
     327
     328        Vector<String, 1> indexNames;
     329        indexNames.append(m_indexMetadata.name);
     330        if (cursor) {
     331            cursor->continueFunction(ec);
     332            ASSERT(!ec);
     333
     334            RefPtr<IDBKey> primaryKey = cursor->primaryKey();
     335            RefPtr<IDBAny> valueAny = cursor->value();
     336
     337            ASSERT(valueAny->type() == IDBAny::SerializedScriptValueType);
     338            RefPtr<SerializedScriptValue> value = valueAny->serializedScriptValue();
     339
     340            IDBObjectStore::IndexKeys indexKeys;
     341            generateIndexKeysForValue(m_indexMetadata, value, &indexKeys);
     342
     343            Vector<IDBObjectStore::IndexKeys, 1> indexKeysList;
     344            indexKeysList.append(indexKeys);
     345
     346            m_objectStoreBackend->setIndexKeys(primaryKey, indexNames, indexKeysList, m_transaction.get());
     347
     348        } else {
     349            // Now that we are done indexing, tell the backend to go
     350            // back to processing tasks of type NormalTask.
     351            m_objectStoreBackend->setIndexesReady(indexNames, m_transaction.get());
     352            m_objectStoreBackend.clear();
     353            m_transaction.clear();
     354        }
     355
     356    }
     357
     358    RefPtr<IDBObjectStoreBackendInterface> m_objectStoreBackend;
     359    RefPtr<IDBTransactionBackendInterface> m_transaction;
     360    IDBIndexMetadata m_indexMetadata;
     361};
     362}
     363
     364PassRefPtr<IDBIndex> IDBObjectStore::createIndex(ScriptExecutionContext* context, const String& name, const String& keyPath, const Dictionary& options, ExceptionCode& ec)
     365{
     366    return createIndex(context, name, IDBKeyPath(keyPath), options, ec);
     367}
     368
     369PassRefPtr<IDBIndex> IDBObjectStore::createIndex(ScriptExecutionContext* context, const String& name, PassRefPtr<DOMStringList> keyPath, const Dictionary& options, ExceptionCode& ec)
     370{
     371    return createIndex(context, name, IDBKeyPath(*keyPath), options, ec);
     372}
     373
     374
     375PassRefPtr<IDBIndex> IDBObjectStore::createIndex(ScriptExecutionContext* context, const String& name, const IDBKeyPath& keyPath, const Dictionary& options, ExceptionCode& ec)
    297376{
    298377    IDB_TRACE("IDBObjectStore::createIndex");
     
    338417    m_indexMap.set(name, index);
    339418    m_metadata.indexes.set(name, metadata);
     419
     420    ASSERT(!ec);
     421    if (ec)
     422        return 0;
     423
     424    RefPtr<IDBRequest> indexRequest = openCursor(context, static_cast<IDBKeyRange*>(0), IDBCursor::directionNext(), IDBTransactionBackendInterface::PreemptiveTask, ec);
     425    ASSERT(!ec);
     426    if (ec)
     427        return 0;
     428
     429    // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction.
     430    RefPtr<IndexPopulator> indexPopulator = IndexPopulator::create(m_backend, m_transaction->backend(), indexRequest, metadata);
     431    indexRequest->setOnsuccess(indexPopulator);
    340432
    341433    return index.release();
     
    399491}
    400492
    401 PassRefPtr<IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> range, const String& directionString, ExceptionCode& ec)
     493PassRefPtr<IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> range, const String& directionString, IDBTransactionBackendInterface::TaskType taskType, ExceptionCode& ec)
    402494{
    403495    IDB_TRACE("IDBObjectStore::openCursor");
     
    416508    RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
    417509    request->setCursorDetails(IDBCursorBackendInterface::ObjectStoreCursor, direction);
    418     m_backend->openCursor(range, direction, request, m_transaction->backend(), ec);
     510    m_backend->openCursor(range, direction, request, taskType, m_transaction->backend(), ec);
    419511    if (ec) {
    420512        request->markEarlyDeath();
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h

    r123843 r125728  
    6969    PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec) { return openCursor(context, keyRange, IDBCursor::directionNext(), ec); }
    7070    PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec) { return openCursor(context, key, IDBCursor::directionNext(), ec); }
     71    PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> range, const String& direction, ExceptionCode& ec) { return openCursor(context, range, direction, IDBTransactionBackendInterface::NormalTask, ec); }
     72    PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext*, PassRefPtr<IDBKeyRange>, const String& direction, IDBTransactionBackendInterface::TaskType, ExceptionCode&);
     73    PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext*, PassRefPtr<IDBKey>, const String& direction, ExceptionCode&);
     74    PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext*, PassRefPtr<IDBKeyRange>, unsigned short direction, ExceptionCode&);
     75    PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext*, PassRefPtr<IDBKey>, unsigned short direction, ExceptionCode&);
    7176
    7277    PassRefPtr<IDBRequest> get(ScriptExecutionContext*, PassRefPtr<IDBKey>, ExceptionCode&);
     
    7984
    8085    // FIXME: Try to modify the code generator so this duplication is unneeded.
    81     PassRefPtr<IDBIndex> createIndex(const String& name, const String& keyPath, const Dictionary&, ExceptionCode&);
    82     PassRefPtr<IDBIndex> createIndex(const String& name, const String& keyPath, ExceptionCode& ec) { return createIndex(name, keyPath, Dictionary(), ec); }
    83     PassRefPtr<IDBIndex> createIndex(const String& name, PassRefPtr<DOMStringList> keyPath, const Dictionary&, ExceptionCode&);
    84     PassRefPtr<IDBIndex> createIndex(const String& name, PassRefPtr<DOMStringList> keyPath, ExceptionCode& ec) { return createIndex(name, keyPath, Dictionary(), ec); }
    85     PassRefPtr<IDBIndex> createIndex(const String&, const IDBKeyPath&, const Dictionary&, ExceptionCode&);
     86    PassRefPtr<IDBIndex> createIndex(ScriptExecutionContext*, const String& name, const String& keyPath, const Dictionary&, ExceptionCode&);
     87    PassRefPtr<IDBIndex> createIndex(ScriptExecutionContext* context, const String& name, const String& keyPath, ExceptionCode& ec) { return createIndex(context, name, keyPath, Dictionary(), ec); }
     88    PassRefPtr<IDBIndex> createIndex(ScriptExecutionContext*, const String& name, PassRefPtr<DOMStringList> keyPath, const Dictionary&, ExceptionCode&);
     89    PassRefPtr<IDBIndex> createIndex(ScriptExecutionContext* context, const String& name, PassRefPtr<DOMStringList> keyPath, ExceptionCode& ec) { return createIndex(context, name, keyPath, Dictionary(), ec); }
     90    PassRefPtr<IDBIndex> createIndex(ScriptExecutionContext*, const String&, const IDBKeyPath&, const Dictionary&, ExceptionCode&);
    8691
    8792    PassRefPtr<IDBIndex> index(const String& name, ExceptionCode&);
    8893    void deleteIndex(const String& name, ExceptionCode&);
    8994
    90     PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext*, PassRefPtr<IDBKeyRange>, const String& direction, ExceptionCode&);
    91     PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext*, PassRefPtr<IDBKey>, const String& direction, ExceptionCode&);
    92     PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext*, PassRefPtr<IDBKeyRange>, unsigned short direction, ExceptionCode&);
    93     PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext*, PassRefPtr<IDBKey>, unsigned short direction, ExceptionCode&);
    9495    PassRefPtr<IDBRequest> count(ScriptExecutionContext* context, ExceptionCode& ec) { return count(context, static_cast<IDBKeyRange*>(0), ec); }
    9596    PassRefPtr<IDBRequest> count(ScriptExecutionContext*, PassRefPtr<IDBKeyRange>, ExceptionCode&);
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.idl

    r122775 r125728  
    6060            raises (IDBDatabaseException);
    6161
    62         IDBIndex createIndex(in DOMString name, in DOMString[] keyPath, in [Optional] Dictionary options)
     62        [CallWith=ScriptExecutionContext] IDBIndex createIndex(in DOMString name, in DOMString[] keyPath, in [Optional] Dictionary options)
    6363            raises (IDBDatabaseException);
    64         IDBIndex createIndex(in DOMString name, in DOMString keyPath, in [Optional] Dictionary options)
     64        [CallWith=ScriptExecutionContext] IDBIndex createIndex(in DOMString name, in DOMString keyPath, in [Optional] Dictionary options)
    6565            raises (IDBDatabaseException);
    6666        IDBIndex index(in DOMString name)
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp

    r125627 r125728  
    155155    { }
    156156
    157     // FIXME: remove this once createIndex() generates these in the renderer.
    158     void generateIndexKeysForValue(SerializedScriptValue* objectValue)
    159     {
    160         m_indexKeys.clear();
    161 
    162         RefPtr<IDBKey> indexKey = fetchKeyFromKeyPath(objectValue);
    163 
    164         if (!indexKey)
    165             return;
    166 
    167         if (!m_indexMetadata.multiEntry || indexKey->type() != IDBKey::ArrayType) {
    168             if (!indexKey->isValid())
    169                 return;
    170 
    171             m_indexKeys.append(indexKey);
    172         } else {
    173             ASSERT(m_indexMetadata.multiEntry);
    174             ASSERT(indexKey->type() == IDBKey::ArrayType);
    175             indexKey = IDBKey::createMultiEntryArray(indexKey->array());
    176 
    177             for (size_t i = 0; i < indexKey->array().size(); ++i)
    178                 m_indexKeys.append(indexKey->array()[i]);
    179         }
    180     }
    181 
    182157    bool verifyIndexKeys(IDBBackingStore& backingStore,
    183158                         int64_t databaseId, int64_t objectStoreId, int64_t indexId,
     
    246221}
    247222
     223static bool makeIndexWriters(IDBObjectStoreBackendImpl* objectStore, PassRefPtr<IDBKey> primaryKey, bool keyWasGenerated, const Vector<String> indexNames, const Vector<IDBObjectStoreBackendInterface::IndexKeys>& indexKeys, Vector<OwnPtr<IndexWriter> >* indexWriters, String* errorMessage)
     224{
     225    ASSERT(indexNames.size() == indexKeys.size());
     226
     227    HashMap<String, IDBObjectStoreBackendInterface::IndexKeys> indexKeyMap;
     228    for (size_t i = 0; i < indexNames.size(); i++)
     229        indexKeyMap.add(indexNames[i], indexKeys[i]);
     230
     231    for (IDBObjectStoreBackendImpl::IndexMap::iterator it = objectStore->iterIndexesBegin(); it != objectStore->iterIndexesEnd(); ++it) {
     232
     233        const RefPtr<IDBIndexBackendImpl>& index = it->second;
     234        if (!index->hasValidId())
     235            continue; // The index object has been created, but does not exist in the database yet.
     236
     237        IDBObjectStoreBackendInterface::IndexKeys keys = indexKeyMap.get(it->first);
     238        // If the objectStore is using autoIncrement, then any indexes with an identical keyPath need to also use the primary (generated) key as a key.
     239        if (keyWasGenerated) {
     240            const IDBKeyPath& indexKeyPath = index->keyPath();
     241            if (indexKeyPath == objectStore->keyPath())
     242                keys.append(primaryKey);
     243        }
     244
     245        OwnPtr<IndexWriter> indexWriter(adoptPtr(new IndexWriter(index->metadata(), keys)));
     246        if (!indexWriter->verifyIndexKeys(*objectStore->backingStore(),
     247                                          objectStore->databaseId(),
     248                                          objectStore->id(),
     249                                          index->id(), primaryKey.get(), errorMessage)) {
     250            return false;
     251        }
     252
     253        indexWriters->append(indexWriter.release());
     254    }
     255
     256    return true;
     257}
     258
     259void IDBObjectStoreBackendImpl::setIndexKeys(PassRefPtr<IDBKey> prpPrimaryKey, const Vector<String>& indexNames, const Vector<IndexKeys>& indexKeys, IDBTransactionBackendInterface* transaction)
     260{
     261    IDB_TRACE("IDBObjectStoreBackendImpl::setIndexKeys");
     262    RefPtr<IDBKey> primaryKey = prpPrimaryKey;
     263
     264    // FIXME: This method could be asynchronous, but we need to evaluate if it's worth the extra complexity.
     265    RefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> recordIdentifier = backingStore()->createInvalidRecordIdentifier();
     266    if (!backingStore()->keyExistsInObjectStore(databaseId(), id(), *primaryKey, recordIdentifier.get())) {
     267        transaction->abort();
     268        return;
     269    }
     270
     271    Vector<OwnPtr<IndexWriter> > indexWriters;
     272    String errorMessage;
     273    if (!makeIndexWriters(this, primaryKey, false, indexNames, indexKeys, &indexWriters, &errorMessage)) {
     274        // FIXME: Need to deal with errorMessage here. makeIndexWriters only fails on uniqueness constraint errors.
     275        transaction->abort();
     276        return;
     277    }
     278
     279    for (size_t i = 0; i < indexWriters.size(); ++i) {
     280        IndexWriter* indexWriter = indexWriters[i].get();
     281        if (!indexWriter->writeIndexKeys(recordIdentifier.get(),
     282                                         *backingStore(),
     283                                         databaseId(),
     284                                         m_id,
     285                                         m_indexes.get(indexWriter->indexName())->id())) {
     286            transaction->abort();
     287            return;
     288        }
     289    }
     290}
     291
     292void IDBObjectStoreBackendImpl::setIndexesReady(const Vector<String>& indexNames, IDBTransactionBackendInterface* transactionInterface)
     293{
     294    IDB_TRACE("IDBObjectStoreBackendImpl::setIndexesReady");
     295    RefPtr<IDBObjectStoreBackendImpl> objectStore = this;
     296
     297    OwnPtr<Vector<String> > names = adoptPtr(new Vector<String>(indexNames));
     298    RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionInterface);
     299
     300    if (!transaction->scheduleTask(
     301            IDBTransactionBackendInterface::PreemptiveTask,
     302            createCallbackTask(&IDBObjectStoreBackendImpl::setIndexesReadyInternal, objectStore, names.release(), transaction)))
     303        ASSERT_NOT_REACHED();
     304}
     305
     306void IDBObjectStoreBackendImpl::setIndexesReadyInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassOwnPtr<Vector<String> > popIndexNames, PassRefPtr<IDBTransactionBackendImpl> transaction)
     307{
     308    IDB_TRACE("IDBObjectStoreBackendImpl::setIndexesReadyInternal");
     309    OwnPtr<Vector<String> > indexNames = popIndexNames;
     310    for (size_t i = 0; i < indexNames->size(); ++i)
     311        transaction->didCompletePreemptiveEvent();
     312    transaction->didCompleteTaskEvents();
     313}
     314
    248315void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendImpl> transaction, PassOwnPtr<Vector<String> > popIndexNames, PassOwnPtr<Vector<IndexKeys> > popIndexKeys)
    249316{
     
    277344
    278345    Vector<OwnPtr<IndexWriter> > indexWriters;
    279     HashMap<String, IndexKeys> indexKeyMap;
    280     for (size_t i = 0; i < indexNames->size(); ++i) {
    281         IndexKeys keys = indexKeys->at(i);
    282 
    283         // If the objectStore is using autoIncrement, then any indexes with an identical keyPath need to also use the primary (generated) key as a key.
    284         if (keyWasGenerated) {
    285             const IDBKeyPath& indexKeyPath = objectStore->m_indexes.get(indexNames->at(i))->keyPath();
    286             if (indexKeyPath == objectStore->keyPath())
    287                 keys.append(key);
    288         }
    289 
    290         indexKeyMap.add(indexNames->at(i), keys);
    291     }
    292 
    293     for (IndexMap::iterator it = objectStore->m_indexes.begin(); it != objectStore->m_indexes.end(); ++it) {
    294 
    295         const RefPtr<IDBIndexBackendImpl>& index = it->second;
    296         if (!index->hasValidId())
    297             continue; // The index object has been created, but does not exist in the database yet.
    298 
    299         OwnPtr<IndexWriter> indexWriter;
    300         indexWriter = adoptPtr(new IndexWriter(index->metadata(), indexKeyMap.get(it->first)));
    301 
    302         String errorMessage;
    303         if (!indexWriter->verifyIndexKeys(*objectStore->backingStore(),
    304                                           objectStore->databaseId(),
    305                                           objectStore->id(),
    306                                           index->id(), key.get(), &errorMessage)) {
    307             callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, errorMessage));
    308             return;
    309         }
    310 
    311         indexWriters.append(indexWriter.release());
     346    String errorMessage;
     347    if (!makeIndexWriters(objectStore.get(), key, keyWasGenerated, *indexNames, *indexKeys, &indexWriters, &errorMessage)) {
     348        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, errorMessage));
     349        return;
    312350    }
    313351
     
    366404            recordIdentifier = backingStoreCursor->objectStoreRecordIdentifier();
    367405
    368             for (IndexMap::iterator it = objectStore->m_indexes.begin(); it != objectStore->m_indexes.end(); ++it) {
     406            for (IDBObjectStoreBackendImpl::IndexMap::iterator it = objectStore->m_indexes.begin(); it != objectStore->m_indexes.end(); ++it) {
    369407                if (!it->second->hasValidId())
    370408                    continue; // The index object has been created, but does not exist in the database yet.
     
    404442}
    405443
    406 namespace {
    407 class PopulateIndexCallback : public IDBBackingStore::ObjectStoreRecordCallback {
    408 public:
    409     PopulateIndexCallback(IDBBackingStore& backingStore, const IDBIndexMetadata& indexMetadata, int64_t databaseId, int64_t objectStoreId, int64_t indexId)
    410         : m_backingStore(backingStore)
    411         , m_databaseId(databaseId)
    412         , m_objectStoreId(objectStoreId)
    413         , m_indexId(indexId)
    414         , m_writer(indexMetadata)
    415     {
    416     }
    417 
    418     virtual bool callback(const IDBBackingStore::ObjectStoreRecordIdentifier* recordIdentifier, const String& value)
    419     {
    420         RefPtr<SerializedScriptValue> objectValue = SerializedScriptValue::createFromWire(value);
    421         m_writer.generateIndexKeysForValue(objectValue.get());
    422         if (!m_writer.verifyIndexKeys(m_backingStore, m_databaseId, m_objectStoreId, m_indexId))
    423             return false;
    424         return m_writer.writeIndexKeys(recordIdentifier, m_backingStore, m_databaseId, m_objectStoreId, m_indexId);
    425     }
    426 
    427 private:
    428     IDBBackingStore& m_backingStore;
    429     int64_t m_databaseId;
    430     int64_t m_objectStoreId;
    431     int64_t m_indexId;
    432     IndexWriter m_writer;
    433 };
    434 }
    435 
    436 bool IDBObjectStoreBackendImpl::populateIndex(IDBBackingStore& backingStore, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBIndexBackendImpl> index)
    437 {
    438     PopulateIndexCallback callback(backingStore, index->metadata(), databaseId, objectStoreId, index->id());
    439     if (!backingStore.forEachObjectStoreRecord(databaseId, objectStoreId, callback))
    440         return false;
    441     return true;
    442 }
    443 
    444444PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::createIndex(const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
    445445{
     
    473473
    474474    index->setId(id);
    475 
    476     if (!populateIndex(*objectStore->backingStore(), objectStore->databaseId(), objectStore->m_id, index)) {
    477         transaction->abort();
    478         return;
    479     }
    480475
    481476    transaction->didCompleteTaskEvents();
     
    516511}
    517512
    518 void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
     513void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpRange, unsigned short tmpDirection, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
     514{
     515    IDBCursor::Direction direction = static_cast<IDBCursor::Direction>(tmpDirection);
     516    openCursor(prpRange, direction, prpCallbacks, IDBTransactionBackendInterface::NormalTask, transactionPtr, ec);
     517}
     518
     519void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpRange, IDBCursor::Direction direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
    519520{
    520521    IDB_TRACE("IDBObjectStoreBackendImpl::openCursor");
     
    524525    RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
    525526    if (!transaction->scheduleTask(
    526             createCallbackTask(&IDBObjectStoreBackendImpl::openCursorInternal, objectStore, range, direction, callbacks, transaction))) {
    527         ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
    528     }
    529 }
    530 
    531 void IDBObjectStoreBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, unsigned short tmpDirection, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendImpl> transaction)
     527            createCallbackTask(&IDBObjectStoreBackendImpl::openCursorInternal, objectStore, range, direction, callbacks, taskType, transaction))) {
     528        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
     529    }
     530}
     531
     532void IDBObjectStoreBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, IDBCursor::Direction direction, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface::TaskType taskType, PassRefPtr<IDBTransactionBackendImpl> transaction)
    532533{
    533534    IDB_TRACE("IDBObjectStoreBackendImpl::openCursorInternal");
    534     IDBCursor::Direction direction = static_cast<IDBCursor::Direction>(tmpDirection);
    535535
    536536    RefPtr<IDBBackingStore::Cursor> backingStoreCursor = objectStore->backingStore()->openObjectStoreCursor(objectStore->databaseId(), objectStore->id(), range.get(), direction);
     537    // The frontend has begun indexing, so this pauses the transaction
     538    // until the indexing is complete. This can't happen any earlier
     539    // because we don't want to switch to early mode in case multiple
     540    // indexes are being created in a row, with put()'s in between.
     541    if (taskType == IDBTransactionBackendInterface::PreemptiveTask)
     542        transaction->addPreemptiveEvent();
    537543    if (!backingStoreCursor) {
    538544        callbacks->onSuccess(SerializedScriptValue::nullValue());
     
    540546    }
    541547
    542     RefPtr<IDBCursorBackendImpl> cursor = IDBCursorBackendImpl::create(backingStoreCursor.release(), IDBCursorBackendInterface::ObjectStoreCursor, transaction.get(), objectStore.get());
     548    RefPtr<IDBCursorBackendImpl> cursor = IDBCursorBackendImpl::create(backingStoreCursor.release(), IDBCursorBackendInterface::ObjectStoreCursor, taskType, transaction.get(), objectStore.get());
    543549    callbacks->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value());
    544550}
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.h

    r123843 r125728  
    2727#define IDBObjectStoreBackendImpl_h
    2828
     29#include "IDBBackingStore.h"
    2930#include "IDBDatabaseBackendImpl.h"
    3031#include "IDBKeyPath.h"
     
    5758    virtual ~IDBObjectStoreBackendImpl();
    5859
     60    typedef HashMap<String, RefPtr<IDBIndexBackendImpl> > IndexMap;
     61   
    5962    static const int64_t InvalidId = 0;
    6063    int64_t id() const
     
    7275
    7376    virtual PassRefPtr<IDBIndexBackendInterface> createIndex(const String& name, const IDBKeyPath&, bool unique, bool multiEntry, IDBTransactionBackendInterface*, ExceptionCode&);
     77    virtual void setIndexKeys(PassRefPtr<IDBKey> prpPrimaryKey, const Vector<String>&, const Vector<IndexKeys>& , IDBTransactionBackendInterface*);
     78    virtual void setIndexesReady(const Vector<String>&, IDBTransactionBackendInterface*);
    7479    virtual PassRefPtr<IDBIndexBackendInterface> index(const String& name, ExceptionCode&);
    7580    virtual void deleteIndex(const String& name, IDBTransactionBackendInterface*, ExceptionCode&);
    7681
     82    // FIXME: Remove this version of openCursor when TaskType is plumbed through chromium.
    7783    virtual void openCursor(PassRefPtr<IDBKeyRange> range, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
     84    virtual void openCursor(PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface::TaskType, IDBTransactionBackendInterface*, ExceptionCode&);
    7885    virtual void count(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
    7986
    8087    static bool populateIndex(IDBBackingStore&, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBIndexBackendImpl>);
     88
     89    const IndexMap::iterator iterIndexesBegin() { return m_indexes.begin(); };
     90    const IndexMap::iterator iterIndexesEnd() { return m_indexes.end(); };
    8191
    8292    IDBObjectStoreMetadata metadata() const;
     
    8494    const IDBKeyPath& keyPath() const { return m_keyPath; }
    8595    const bool& autoIncrement() const { return m_autoIncrement; }
    86 
     96   
     97    PassRefPtr<IDBBackingStore> backingStore() const { return m_database->backingStore(); }
     98    int64_t databaseId() const { return m_database->id(); }
     99   
    87100private:
    88101    IDBObjectStoreBackendImpl(const IDBDatabaseBackendImpl*, int64_t databaseId, const String& name, const IDBKeyPath&, bool autoIncrement);
     
    96109    static void putInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBTransactionBackendImpl>, PassOwnPtr<Vector<String> > popIndexNames, PassOwnPtr<Vector<IndexKeys> >);
    97110    static void deleteInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>);
     111    static void setIndexesReadyInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassOwnPtr<Vector<String> > popIndexNames, PassRefPtr<IDBTransactionBackendImpl>);
    98112    static void clearInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBCallbacks>);
    99113    static void createIndexInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBIndexBackendImpl>, PassRefPtr<IDBTransactionBackendImpl>);
    100114    static void deleteIndexInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBIndexBackendImpl>, PassRefPtr<IDBTransactionBackendImpl>);
    101     static void openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBTransactionBackendImpl>);
     115    static void openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface::TaskType, PassRefPtr<IDBTransactionBackendImpl>);
    102116    static void countInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>);
    103117
     
    105119    static void removeIndexFromMap(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBIndexBackendImpl>);
    106120    static void addIndexToMap(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBIndexBackendImpl>);
    107 
    108     PassRefPtr<IDBBackingStore> backingStore() const { return m_database->backingStore(); }
    109     int64_t databaseId() const { return m_database->id(); }
    110121
    111122    const IDBDatabaseBackendImpl* m_database;
     
    115126    bool m_autoIncrement;
    116127
    117     typedef HashMap<String, RefPtr<IDBIndexBackendImpl> > IndexMap;
    118128    IndexMap m_indexes;
    119129};
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendInterface.h

    r123843 r125728  
    2727#define IDBObjectStoreBackendInterface_h
    2828
     29#include "IDBCursor.h"
    2930#include "PlatformString.h"
    3031#include <wtf/Threading.h>
     
    6465
    6566    virtual PassRefPtr<IDBIndexBackendInterface> createIndex(const String& name, const IDBKeyPath&, bool unique, bool multiEntry, IDBTransactionBackendInterface*, ExceptionCode&) = 0;
     67    virtual void setIndexKeys(PassRefPtr<IDBKey> prpPrimaryKey, const Vector<String>&, const Vector<IndexKeys>&, IDBTransactionBackendInterface*) = 0;
     68    virtual void setIndexesReady(const Vector<String>&, IDBTransactionBackendInterface*) = 0;
    6669    virtual PassRefPtr<IDBIndexBackendInterface> index(const String& name, ExceptionCode&) = 0;
    6770    virtual void deleteIndex(const String& name, IDBTransactionBackendInterface*, ExceptionCode&) = 0;
    6871
     72    // FIXME: Remove this version of openCursor when TaskType is plumbed through chromium.
    6973    virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) = 0;
     74    virtual void openCursor(PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface::TaskType, IDBTransactionBackendInterface*, ExceptionCode&) = 0;
    7075    virtual void count(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) = 0;
    7176};
  • trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp

    r125713 r125728  
    4747PassRefPtr<IDBRequest> IDBRequest::create(ScriptExecutionContext* context, PassRefPtr<IDBAny> source, IDBTransaction* transaction)
    4848{
    49     RefPtr<IDBRequest> request(adoptRef(new IDBRequest(context, source, transaction)));
     49    RefPtr<IDBRequest> request(adoptRef(new IDBRequest(context, source, IDBTransactionBackendInterface::NormalTask, transaction)));
    5050    request->suspendIfNeeded();
    5151    return request.release();
    5252}
    5353
    54 IDBRequest::IDBRequest(ScriptExecutionContext* context, PassRefPtr<IDBAny> source, IDBTransaction* transaction)
     54PassRefPtr<IDBRequest> IDBRequest::create(ScriptExecutionContext* context, PassRefPtr<IDBAny> source, IDBTransactionBackendInterface::TaskType taskType, IDBTransaction* transaction)
     55{
     56    RefPtr<IDBRequest> request(adoptRef(new IDBRequest(context, source, taskType, transaction)));
     57    request->suspendIfNeeded();
     58    return request.release();
     59}
     60
     61IDBRequest::IDBRequest(ScriptExecutionContext* context, PassRefPtr<IDBAny> source, IDBTransactionBackendInterface::TaskType taskType, IDBTransaction* transaction)
    5562    : ActiveDOMObject(context, this)
    5663    , m_errorCode(0)
    5764    , m_source(source)
     65    , m_taskType(taskType)
    5866    , m_transaction(transaction)
    5967    , m_readyState(PENDING)
  • trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h

    r125568 r125728  
    5353public:
    5454    static PassRefPtr<IDBRequest> create(ScriptExecutionContext*, PassRefPtr<IDBAny> source, IDBTransaction*);
     55    static PassRefPtr<IDBRequest> create(ScriptExecutionContext*, PassRefPtr<IDBAny> source, IDBTransactionBackendInterface::TaskType, IDBTransaction*);
    5556    virtual ~IDBRequest();
    5657
     
    106107    using ThreadSafeRefCounted<IDBCallbacks>::deref;
    107108
     109    IDBTransactionBackendInterface::TaskType taskType() { return m_taskType; }
     110
    108111protected:
    109     IDBRequest(ScriptExecutionContext*, PassRefPtr<IDBAny> source, IDBTransaction*);
     112    IDBRequest(ScriptExecutionContext*, PassRefPtr<IDBAny> source, IDBTransactionBackendInterface::TaskType, IDBTransaction*);
    110113    void enqueueEvent(PassRefPtr<Event>);
    111114    bool shouldEnqueueEvent() const;
     
    127130
    128131    RefPtr<IDBAny> m_source;
     132    const IDBTransactionBackendInterface::TaskType m_taskType;
    129133    RefPtr<IDBTransaction> m_transaction;
    130134
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransactionBackendImpl.cpp

    r124675 r125728  
    5252    , m_taskTimer(this, &IDBTransactionBackendImpl::taskTimerFired)
    5353    , m_taskEventTimer(this, &IDBTransactionBackendImpl::taskEventTimerFired)
     54    , m_pendingPreemptiveEvents(0)
    5455    , m_pendingEvents(0)
    5556{
     
    9091}
    9192
    92 bool IDBTransactionBackendImpl::scheduleTask(PassOwnPtr<ScriptExecutionContext::Task> task, PassOwnPtr<ScriptExecutionContext::Task> abortTask)
     93bool IDBTransactionBackendImpl::scheduleTask(TaskType type, PassOwnPtr<ScriptExecutionContext::Task> task, PassOwnPtr<ScriptExecutionContext::Task> abortTask)
    9394{
    9495    if (m_state == Finished)
    9596        return false;
    9697
    97     m_taskQueue.append(task);
     98    if (type == NormalTask)
     99        m_taskQueue.append(task);
     100    else
     101        m_preemptiveTaskQueue.append(task);
     102   
    98103    if (abortTask)
    99104        m_abortTaskQueue.prepend(abortTask);
     
    148153
    149154    m_database = 0;
     155}
     156
     157bool IDBTransactionBackendImpl::isTaskQueueEmpty() const
     158{
     159    return m_preemptiveTaskQueue.isEmpty() && m_taskQueue.isEmpty();
    150160}
    151161
     
    204214    RefPtr<IDBTransactionBackendImpl> self(this);
    205215    ASSERT(m_state == Unused || m_state == Running);
    206     ASSERT(m_taskQueue.isEmpty());
     216    ASSERT(isTaskQueueEmpty());
    207217
    208218    bool unused = m_state == Unused;
     
    236246{
    237247    IDB_TRACE("IDBTransactionBackendImpl::taskTimerFired");
    238     ASSERT(!m_taskQueue.isEmpty());
     248    ASSERT(!isTaskQueueEmpty());
    239249
    240250    if (m_state == StartPending) {
     
    243253    }
    244254
    245     TaskQueue queue;
    246     queue.swap(m_taskQueue);
    247     while (!queue.isEmpty() && m_state != Finished) {
     255    // Just process a single event here, in case the event itself
     256    // changes which queue should be processed next.
     257    TaskQueue& taskQueue = m_pendingPreemptiveEvents ? m_preemptiveTaskQueue : m_taskQueue;
     258    if (!taskQueue.isEmpty() && m_state != Finished) {
    248259        ASSERT(m_state == Running);
    249         OwnPtr<ScriptExecutionContext::Task> task(queue.first().release());
    250         queue.removeFirst();
     260        OwnPtr<ScriptExecutionContext::Task> task(taskQueue.first().release());
     261        taskQueue.removeFirst();
    251262        m_pendingEvents++;
    252263        task->performTask(0);
     
    259270    ASSERT(m_state == Running);
    260271
    261     if (!m_pendingEvents && m_taskQueue.isEmpty()) {
     272    if (!m_pendingEvents && isTaskQueueEmpty()) {
    262273        // The last task event has completed and the task
    263274        // queue is empty. Commit the transaction.
     
    269280    // the task queue is non-empty and the timer is inactive.
    270281    // We can therfore schedule the timer again.
    271     if (!m_taskQueue.isEmpty() && !m_taskTimer.isActive())
     282    if (!isTaskQueueEmpty() && !m_taskTimer.isActive())
    272283        m_taskTimer.startOneShot(0);
    273284}
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransactionBackendImpl.h

    r123276 r125728  
    5959    void run();
    6060    unsigned short mode() const { return m_mode; }
    61     bool scheduleTask(PassOwnPtr<ScriptExecutionContext::Task>, PassOwnPtr<ScriptExecutionContext::Task> abortTask = nullptr);
     61    bool scheduleTask(PassOwnPtr<ScriptExecutionContext::Task> task, PassOwnPtr<ScriptExecutionContext::Task> abortTask = nullptr) { return scheduleTask(NormalTask, task, abortTask); }
     62    bool scheduleTask(TaskType, PassOwnPtr<ScriptExecutionContext::Task>, PassOwnPtr<ScriptExecutionContext::Task> abortTask = nullptr);
    6263    void registerOpenCursor(IDBCursorBackendImpl*);
    6364    void unregisterOpenCursor(IDBCursorBackendImpl*);
    6465    void addPendingEvents(int);
     66    void addPreemptiveEvent() { m_pendingPreemptiveEvents++; }
     67    void didCompletePreemptiveEvent() { m_pendingPreemptiveEvents--; ASSERT(m_pendingPreemptiveEvents >= 0); }
    6568
    6669private:
     
    7780    void commit();
    7881
     82    bool isTaskQueueEmpty() const;
     83
    7984    void taskTimerFired(Timer<IDBTransactionBackendImpl>*);
    8085    void taskEventTimerFired(Timer<IDBTransactionBackendImpl>*);
     
    9095    typedef Deque<OwnPtr<ScriptExecutionContext::Task> > TaskQueue;
    9196    TaskQueue m_taskQueue;
     97    TaskQueue m_preemptiveTaskQueue;
    9298    TaskQueue m_abortTaskQueue;
    9399
     
    97103    Timer<IDBTransactionBackendImpl> m_taskTimer;
    98104    Timer<IDBTransactionBackendImpl> m_taskEventTimer;
     105    int m_pendingPreemptiveEvents;
    99106    int m_pendingEvents;
    100107
  • trunk/Source/WebCore/Modules/indexeddb/IDBVersionChangeRequest.cpp

    r125231 r125728  
    4343
    4444IDBVersionChangeRequest::IDBVersionChangeRequest(ScriptExecutionContext* context, PassRefPtr<IDBAny> source, const String& version)
    45     : IDBRequest(context, source, 0)
     45    : IDBRequest(context, source, IDBTransactionBackendInterface::NormalTask, 0)
    4646    , m_version(version)
    4747{
  • trunk/Source/WebKit/chromium/ChangeLog

    r125716 r125728  
     12012-08-15  Alec Flett  <alecflett@chromium.org>
     2
     3        IndexedDB: generate index keys for existing data in createIndex in front end
     4        https://bugs.webkit.org/show_bug.cgi?id=91125
     5
     6        Reviewed by Tony Chang.
     7
     8        Add Chromium API methods to let the renderer process tell the
     9        browser process about indexing progress.
     10
     11        * public/WebIDBObjectStore.h:
     12        (WebKit::WebIDBObjectStore::openCursor):
     13        * src/IDBObjectStoreBackendProxy.cpp:
     14        (WebKit::IDBObjectStoreBackendProxy::setIndexKeys):
     15        (WebKit):
     16        (WebKit::IDBObjectStoreBackendProxy::setIndexesReady):
     17        (WebKit::IDBObjectStoreBackendProxy::openCursor):
     18        * src/IDBObjectStoreBackendProxy.h:
     19        (IDBObjectStoreBackendProxy):
     20        * src/WebIDBObjectStoreImpl.cpp:
     21        (WebKit::WebIDBObjectStoreImpl::setIndexKeys):
     22        (WebKit):
     23        (WebKit::WebIDBObjectStoreImpl::setIndexesReady):
     24        (WebKit::WebIDBObjectStoreImpl::openCursor):
     25        * src/WebIDBObjectStoreImpl.h:
     26        (WebIDBObjectStoreImpl):
     27
    1282012-08-15  Bruno de Oliveira Abinader  <bruno.abinader@basyskom.com>
    229
  • trunk/Source/WebKit/chromium/public/WebIDBObjectStore.h

    r125084 r125728  
    7474    virtual void deleteIndex(const WebString& name, const WebIDBTransaction&, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); }
    7575    // FIXME: Remove this version of openCursor when TaskType is plumbed through chromium.
    76     virtual void openCursor(const WebIDBKeyRange&, unsigned short direction, WebIDBCallbacks*, const WebIDBTransaction&, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); }
     76    virtual void openCursor(const WebIDBKeyRange& range, unsigned short direction, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction, WebExceptionCode& ec)
     77    {
     78        openCursor(range, static_cast<WebIDBCursor::Direction>(direction), callbacks, WebIDBTransaction::NormalTask, transaction, ec);
     79    }
    7780    virtual void openCursor(const WebIDBKeyRange&, WebIDBCursor::Direction direction, WebIDBCallbacks*, WebIDBTransaction::TaskType, const WebIDBTransaction&, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); }
    7881    virtual void count(const WebIDBKeyRange&, WebIDBCallbacks*, const WebIDBTransaction&, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); }
  • trunk/Source/WebKit/chromium/src/IDBObjectStoreBackendProxy.cpp

    r123843 r125728  
    7878}
    7979
     80void IDBObjectStoreBackendProxy::setIndexKeys(PassRefPtr<IDBKey> prpPrimaryKey, const Vector<String>& indexNames, const Vector<IndexKeys>& indexKeys, IDBTransactionBackendInterface* transaction)
     81{
     82    // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer,
     83    // all implementations of IDB interfaces are proxy objects.
     84    IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction);
     85    WebVector<WebString> webIndexNames(indexNames);
     86    WebVector<IndexKeys> webIndexKeys(indexKeys);
     87    m_webIDBObjectStore->setIndexKeys(prpPrimaryKey, webIndexNames, webIndexKeys, *transactionProxy->getWebIDBTransaction());
     88}
     89
    8090void IDBObjectStoreBackendProxy::deleteFunction(PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
    8191{
     
    105115}
    106116
     117void IDBObjectStoreBackendProxy::setIndexesReady(const Vector<String>& indexNames, IDBTransactionBackendInterface* transaction)
     118{
     119    // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer,
     120    // all implementations of IDB interfaces are proxy objects.
     121    IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction);
     122    m_webIDBObjectStore->setIndexesReady(indexNames, *transactionProxy->getWebIDBTransaction());
     123}
     124
    107125PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendProxy::index(const String& name, ExceptionCode& ec)
    108126{
     
    126144    // all implementations of IDB interfaces are proxy objects.
    127145    IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction);
    128     m_webIDBObjectStore->openCursor(range, direction, new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction(), ec);
     146    m_webIDBObjectStore->openCursor(range, static_cast<WebIDBCursor::Direction>(direction), new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction(), ec);
     147}
     148
     149void IDBObjectStoreBackendProxy::openCursor(PassRefPtr<IDBKeyRange> range, IDBCursor::Direction direction, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
     150{
     151    // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer,
     152    // all implementations of IDB interfaces are proxy objects.
     153    IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction);
     154    m_webIDBObjectStore->openCursor(range, static_cast<WebIDBCursor::Direction>(direction), new WebIDBCallbacksImpl(callbacks), static_cast<WebIDBTransaction::TaskType>(taskType), *transactionProxy->getWebIDBTransaction(), ec);
    129155}
    130156
  • trunk/Source/WebKit/chromium/src/IDBObjectStoreBackendProxy.h

    r123843 r125728  
    5050
    5151    PassRefPtr<WebCore::IDBIndexBackendInterface> createIndex(const String& name, const WebCore::IDBKeyPath&, bool unique, bool multiEntry, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&);
     52    virtual void setIndexKeys(PassRefPtr<WebCore::IDBKey> prpPrimaryKey, const WTF::Vector<WTF::String>&, const WTF::Vector<IndexKeys>&, WebCore::IDBTransactionBackendInterface*);
     53    virtual void setIndexesReady(const Vector<String>&, WebCore::IDBTransactionBackendInterface*);
     54   
    5255    PassRefPtr<WebCore::IDBIndexBackendInterface> index(const String& name, WebCore::ExceptionCode&);
    5356    void deleteIndex(const String& name, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&);
    5457
     58    // FIXME: Remove this version of openCursor when TaskType is plumbed through chromium.
    5559    virtual void openCursor(PassRefPtr<WebCore::IDBKeyRange>, unsigned short direction, PassRefPtr<WebCore::IDBCallbacks>, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&);
     60    virtual void openCursor(PassRefPtr<WebCore::IDBKeyRange>, WebCore::IDBCursor::Direction, PassRefPtr<WebCore::IDBCallbacks>, WebCore::IDBTransactionBackendInterface::TaskType, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&);
    5661    virtual void count(PassRefPtr<WebCore::IDBKeyRange>, PassRefPtr<WebCore::IDBCallbacks>, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&);
    5762
  • trunk/Source/WebKit/chromium/src/WebIDBObjectStoreImpl.cpp

    r125211 r125728  
    7676}
    7777
     78void WebIDBObjectStoreImpl::setIndexKeys(const WebIDBKey& primaryKey, const WebVector<WebString>& webIndexNames, const WebVector<WebIndexKeys>& webIndexKeys, const WebIDBTransaction& transaction)
     79{
     80    ASSERT(webIndexNames.size() == webIndexKeys.size());
     81    Vector<String> indexNames(webIndexNames.size());
     82    Vector<IDBObjectStoreBackendInterface::IndexKeys> indexKeys(webIndexKeys.size());
     83
     84    for (size_t i = 0; i < webIndexNames.size(); ++i) {
     85        indexNames[i] = webIndexNames[i];
     86        Vector<RefPtr<IDBKey> > indexKeyList(webIndexKeys[i].size());
     87        for (size_t j = 0; j < webIndexKeys[i].size(); ++j)
     88            indexKeyList[j] = webIndexKeys[i][j];
     89        indexKeys[i] = indexKeyList;
     90    }
     91    m_objectStore->setIndexKeys(primaryKey, indexNames, indexKeys, transaction.getIDBTransactionBackendInterface());
     92}
     93
     94void WebIDBObjectStoreImpl::setIndexesReady(const WebVector<WebString>& webIndexNames, const WebIDBTransaction& transaction)
     95{
     96    Vector<String> indexNames(webIndexNames.size());
     97    for (size_t i = 0; i < webIndexNames.size(); ++i)
     98        indexNames[i] = webIndexNames[i];
     99    m_objectStore->setIndexesReady(indexNames, transaction.getIDBTransactionBackendInterface());
     100}
     101
    78102void WebIDBObjectStoreImpl::deleteFunction(const WebIDBKeyRange& keyRange, WebIDBCallbacks* callbacks, const WebIDBTransaction& transaction, WebExceptionCode& ec)
    79103{
     
    107131}
    108132
    109 void WebIDBObjectStoreImpl::openCursor(const WebIDBKeyRange& keyRange, WebIDBCursor::Direction direction, WebIDBCallbacks* callbacks, WebIDBTransaction::TaskType, const WebIDBTransaction& transaction, WebExceptionCode& ec)
     133void WebIDBObjectStoreImpl::openCursor(const WebIDBKeyRange& keyRange, WebIDBCursor::Direction direction, WebIDBCallbacks* callbacks, WebIDBTransaction::TaskType taskType, const WebIDBTransaction& transaction, WebExceptionCode& ec)
    110134{
    111     // FIXME: Pass along TaskType when the API becomes available.
    112     m_objectStore->openCursor(keyRange, direction, IDBCallbacksProxy::create(adoptPtr(callbacks)), transaction.getIDBTransactionBackendInterface(), ec);
     135    m_objectStore->openCursor(keyRange, static_cast<IDBCursor::Direction>(direction), IDBCallbacksProxy::create(adoptPtr(callbacks)), static_cast<IDBTransactionBackendInterface::TaskType>(taskType), transaction.getIDBTransactionBackendInterface(), ec);
    113136}
    114137
  • trunk/Source/WebKit/chromium/src/WebIDBObjectStoreImpl.h

    r125211 r125728  
    4747
    4848    void get(const WebIDBKeyRange&, WebIDBCallbacks*, const WebIDBTransaction&, WebExceptionCode&);
    49     void putWithIndexKeys(const WebSerializedScriptValue&, const WebIDBKey&, PutMode, WebIDBCallbacks*, const WebIDBTransaction&, const WebVector<WebString>& indexNames, const WebVector<WebIndexKeys>&, WebExceptionCode&);
     49    void putWithIndexKeys(const WebSerializedScriptValue&, const WebIDBKey&, PutMode, WebIDBCallbacks*, const WebIDBTransaction&, const WebVector<WebString>&, const WebVector<WebIndexKeys>&, WebExceptionCode&);
     50    void setIndexKeys(const WebIDBKey&, const WebVector<WebString>& indexNames, const WebVector<WebIndexKeys>&, const WebIDBTransaction&);
     51    void setIndexesReady(const WebVector<WebString>&, const WebIDBTransaction&);
    5052    void deleteFunction(const WebIDBKeyRange&, WebIDBCallbacks*, const WebIDBTransaction&, WebExceptionCode&);
    5153    void clear(WebIDBCallbacks*, const WebIDBTransaction&, WebExceptionCode&);
Note: See TracChangeset for help on using the changeset viewer.