Changeset 138900 in webkit


Ignore:
Timestamp:
Jan 5, 2013 12:42:38 PM (11 years ago)
Author:
alecflett@chromium.org
Message:

IndexedDB: Migrate backend ObjectStore calls to use transaction id
https://bugs.webkit.org/show_bug.cgi?id=102741

Reviewed by Tony Chang.

Source/WebCore:

Fully migrate 8 core data calls (get, put, setIndexKeys, setIndexesReady,
openCursor, count, deleteRange, and clear) into IDBDatabaseBackendImpl,
combining common code from IDBObjectStoreBackendImpl and IDBIndexBackendImpl
in order to simplify the backend interface. These calls are now
implemented in terms of an int64_t-based transactionId rather than
an IDBTransactionBackendInterface, which simplifies the ownership model
between the frontend and the backend.

In addition, remove references to IDBObjectStoreBackend* from IDBIndex,
as it is no longer needed.

A few duplicate IDB_TRACE methods have been removed from wrapper methods
that call another method that already have IDB_TRACE's.

Finally, IDBCursorBackendImpl now no longer holds onto an
IDBObjectStoreBackendImpl*, so its destruction and member variables are
simplified, and reordered to match proper destruction order.

  • Modules/indexeddb/IDBCursorBackendImpl.cpp: Reordered to account for proper destruction.

(WebCore::IDBCursorBackendImpl::IDBCursorBackendImpl):
(WebCore::IDBCursorBackendImpl::~IDBCursorBackendImpl):
(WebCore::IDBCursorBackendImpl::deleteFunction):

  • Modules/indexeddb/IDBCursorBackendImpl.h:

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

  • Modules/indexeddb/IDBDatabase.h:

(WebCore::IDBDatabase::backend):
(IDBDatabase):

  • Modules/indexeddb/IDBDatabaseBackendImpl.cpp:

(GetOperation): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::*RetrievalOperation
(WebCore::GetOperation::create):
(WebCore::GetOperation::GetOperation):
(WebCore):
(PutOperation): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::*StorageOperation.
(WebCore::PutOperation::create):
(WebCore::PutOperation::PutOperation):
(SetIndexesReadyOperation): Moved from IDBObjectStoreBackendImpl::IndexesReadyOperation
(WebCore::SetIndexesReadyOperation::create):
(WebCore::SetIndexesReadyOperation::SetIndexesReadyOperation):
(OpenCursorOperation): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::Open*CursorOperation
(WebCore::OpenCursorOperation::create):
(WebCore::OpenCursorOperation::OpenCursorOperation):
(CountOperation): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::CountOperation
(WebCore::CountOperation::create):
(WebCore::CountOperation::CountOperation):
(DeleteRangeOperation): Moved from IDBObjectStoreBackendImpl::DeleteOperation
(WebCore::DeleteRangeOperation::create):
(WebCore::DeleteRangeOperation::DeleteRangeOperation):
(ClearOperation): Moved from IDBObjectStoreBackendImpl::ClearOperation
(WebCore::ClearOperation::create):
(WebCore::ClearOperation::ClearOperation):
(WebCore::IDBDatabaseBackendImpl::get): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::get*
(WebCore::GetOperation::perform):
(WebCore::IDBDatabaseBackendImpl::put): Moved from IDBObjectStoreBackendImpl::put
(WebCore::PutOperation::perform):
(WebCore::IDBDatabaseBackendImpl::setIndexKeys): Moved from IDBObjectStoreBackendImpl::setIndexKeys
(WebCore::IDBDatabaseBackendImpl::setIndexesReady):
(WebCore::SetIndexesReadyOperation::perform):
(WebCore::IDBDatabaseBackendImpl::openCursor):
(WebCore::IDBDatabaseBackendImpl::count):
(WebCore::CountOperation::perform):
(WebCore::IDBDatabaseBackendImpl::deleteRange):
(WebCore::DeleteRangeOperation::perform):
(WebCore::IDBDatabaseBackendImpl::clear):
(WebCore::ClearOperation::perform):
(WebCore::OpenCursorOperation::perform):

  • Modules/indexeddb/IDBIndex.cpp:

(WebCore::IDBIndex::IDBIndex):
(WebCore::IDBIndex::openCursor):
(WebCore::IDBIndex::count):
(WebCore::IDBIndex::openKeyCursor):
(WebCore::IDBIndex::get):
(WebCore::IDBIndex::getKey):
(WebCore::IDBIndex::backendDB):
(WebCore):

  • Modules/indexeddb/IDBIndex.h:

(WebCore::IDBIndex::create):
(IDBIndex):

  • Modules/indexeddb/IDBIndexBackendImpl.cpp:

(WebCore::IDBIndexBackendImpl::IDBIndexBackendImpl):

  • Modules/indexeddb/IDBIndexBackendImpl.h:

(WebCore::IDBIndexBackendImpl::create):
(WebCore::IDBIndexBackendImpl::openCursor):
(WebCore::IDBIndexBackendImpl::count):
(WebCore::IDBIndexBackendImpl::openKeyCursor):
(WebCore::IDBIndexBackendImpl::get):
(WebCore::IDBIndexBackendImpl::getKey):
(IDBIndexBackendImpl):

  • Modules/indexeddb/IDBObjectStore.cpp:

(WebCore::IDBObjectStore::get):
(WebCore::IDBObjectStore::put):
(WebCore::IDBObjectStore::deleteFunction):
(WebCore::IDBObjectStore::clear):
(WebCore):
(WebCore::IDBObjectStore::createIndex):
(WebCore::IDBObjectStore::index):
(WebCore::IDBObjectStore::openCursor):
(WebCore::IDBObjectStore::count):
(WebCore::IDBObjectStore::backendDB):

  • Modules/indexeddb/IDBObjectStore.h:

(WebCore::IDBObjectStore::id):
(IDBObjectStore):

  • Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:

(WebCore::IDBObjectStoreBackendImpl::createIndex):
(WebCore::IDBObjectStoreBackendImpl::loadIndexes):
(WebCore::IDBObjectStoreBackendImpl::generateKey):
(WebCore::IDBObjectStoreBackendImpl::updateKeyGenerator):

  • Modules/indexeddb/IDBObjectStoreBackendImpl.h:

(WebCore::IDBObjectStoreBackendImpl::get):
(WebCore::IDBObjectStoreBackendImpl::put):
(WebCore::IDBObjectStoreBackendImpl::deleteFunction):
(WebCore::IDBObjectStoreBackendImpl::clear):
(WebCore::IDBObjectStoreBackendImpl::setIndexKeys):
(WebCore::IDBObjectStoreBackendImpl::setIndexesReady):
(WebCore::IDBObjectStoreBackendImpl::openCursor):
(WebCore::IDBObjectStoreBackendImpl::count):
(IDBObjectStoreBackendImpl):

  • Modules/indexeddb/IDBTransactionBackendImpl.h:

(WebCore::IDBTransactionBackendImpl::database):
(IDBTransactionBackendImpl):

Source/WebKit/chromium:

Fix a bug where an array was initialized with a large empty buffer,
clean up whitespace, and update to match signatures that changed
in WebCore.

  • public/WebIDBDatabase.h:

(WebKit::WebIDBDatabase::clear):

  • src/WebIDBDatabaseImpl.cpp:

(WebKit::WebIDBDatabaseImpl::put):

  • src/WebIDBIndexImpl.cpp:
  • tests/IDBDatabaseBackendTest.cpp:

LayoutTests:

Add additional count() tests for multi-entry indexes, not previously
covered.

  • storage/indexeddb/index-multientry-expected.txt:
  • storage/indexeddb/resources/index-multientry.js:

(.transaction.oncomplete):
(verifyCount.request.onsuccess.request.onsuccess):
(verifyCount.request.onsuccess):
(verifyCount):

Location:
trunk
Files:
24 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r138899 r138900  
     12013-01-05  Alec Flett  <alecflett@chromium.org>
     2
     3        IndexedDB: Migrate backend ObjectStore calls to use transaction id
     4        https://bugs.webkit.org/show_bug.cgi?id=102741
     5
     6        Reviewed by Tony Chang.
     7
     8        Add additional count() tests for multi-entry indexes, not previously
     9        covered.
     10
     11        * storage/indexeddb/index-multientry-expected.txt:
     12        * storage/indexeddb/resources/index-multientry.js:
     13        (.transaction.oncomplete):
     14        (verifyCount.request.onsuccess.request.onsuccess):
     15        (verifyCount.request.onsuccess):
     16        (verifyCount):
     17
    1182013-01-05  Robert Hogan  <robert@webkit.org>
    219
  • trunk/LayoutTests/storage/indexeddb/index-multientry-expected.txt

    r134661 r138900  
    8383cursor = event.target.result
    8484PASS expected.length is 0
     85transaction = db.transaction(['store'])
     86transaction.objectStore('store').index('index')
     87index.count()
     88PASS event.target.result is 9
     89index.count(7)
     90PASS event.target.result is 1
    8591
    8692Verifying unique constraint on multiEntry index
     
    163169cursor = event.target.result
    164170PASS expected.length is 0
     171transaction = db.transaction(['store'])
     172transaction.objectStore('store').index('index')
     173index.count()
     174PASS event.target.result is 9
     175index.count(7)
     176PASS event.target.result is 1
    165177PASS successfullyParsed is true
    166178
  • trunk/LayoutTests/storage/indexeddb/resources/index-multientry.js

    r134661 r138900  
    4646    transaction = evalAndLog("transaction = db.transaction(['store'], 'readonly')");
    4747    transaction.onabort = unexpectedAbortCallback;
    48     transaction.oncomplete = callback;
     48    transaction.oncomplete = function() { verifyCount(callback); };
    4949
    5050    expected = [
     
    105105}
    106106
     107function verifyCount(callback) {
     108    evalAndLog("transaction = db.transaction(['store'])");
     109
     110    transaction.onabort = unexpectedAbortCallback;
     111    transaction.oncomplete = callback;
     112
     113    index = evalAndLog("transaction.objectStore('store').index('index')");
     114    request = evalAndLog("index.count()");
     115    request.onsuccess = function(event) {
     116
     117        shouldBe("event.target.result", "9");
     118
     119        request = evalAndLog("index.count(7)");
     120        request.onsuccess = function(event) {
     121            shouldBe("event.target.result", "1");
     122        };
     123    };
     124
     125}
     126
    107127function createIndexOnStoreWithData()
    108128{
  • trunk/Source/WebCore/ChangeLog

    r138899 r138900  
     12013-01-05  Alec Flett  <alecflett@chromium.org>
     2
     3        IndexedDB: Migrate backend ObjectStore calls to use transaction id
     4        https://bugs.webkit.org/show_bug.cgi?id=102741
     5
     6        Reviewed by Tony Chang.
     7
     8        Fully migrate 8 core data calls (get, put, setIndexKeys, setIndexesReady,
     9        openCursor, count, deleteRange, and clear) into IDBDatabaseBackendImpl,
     10        combining common code from IDBObjectStoreBackendImpl and IDBIndexBackendImpl
     11        in order to simplify the backend interface. These calls are now
     12        implemented in terms of an int64_t-based transactionId rather than
     13        an IDBTransactionBackendInterface, which simplifies the ownership model
     14        between the frontend and the backend.
     15
     16        In addition, remove references to IDBObjectStoreBackend* from IDBIndex,
     17        as it is no longer needed.
     18
     19        A few duplicate IDB_TRACE methods have been removed from wrapper methods
     20        that call another method that already have IDB_TRACE's.
     21
     22        Finally, IDBCursorBackendImpl now no longer holds onto an
     23        IDBObjectStoreBackendImpl*, so its destruction and member variables are
     24        simplified, and reordered to match proper destruction order.
     25
     26        * Modules/indexeddb/IDBCursorBackendImpl.cpp: Reordered to account for proper destruction.
     27        (WebCore::IDBCursorBackendImpl::IDBCursorBackendImpl):
     28        (WebCore::IDBCursorBackendImpl::~IDBCursorBackendImpl):
     29        (WebCore::IDBCursorBackendImpl::deleteFunction):
     30        * Modules/indexeddb/IDBCursorBackendImpl.h:
     31        (WebCore::IDBCursorBackendImpl::create):
     32        (IDBCursorBackendImpl):
     33        * Modules/indexeddb/IDBDatabase.h:
     34        (WebCore::IDBDatabase::backend):
     35        (IDBDatabase):
     36        * Modules/indexeddb/IDBDatabaseBackendImpl.cpp:
     37        (GetOperation): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::*RetrievalOperation
     38        (WebCore::GetOperation::create):
     39        (WebCore::GetOperation::GetOperation):
     40        (WebCore):
     41        (PutOperation): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::*StorageOperation.
     42        (WebCore::PutOperation::create):
     43        (WebCore::PutOperation::PutOperation):
     44        (SetIndexesReadyOperation): Moved from IDBObjectStoreBackendImpl::IndexesReadyOperation
     45        (WebCore::SetIndexesReadyOperation::create):
     46        (WebCore::SetIndexesReadyOperation::SetIndexesReadyOperation):
     47        (OpenCursorOperation): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::Open*CursorOperation
     48        (WebCore::OpenCursorOperation::create):
     49        (WebCore::OpenCursorOperation::OpenCursorOperation):
     50        (CountOperation): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::CountOperation
     51        (WebCore::CountOperation::create):
     52        (WebCore::CountOperation::CountOperation):
     53        (DeleteRangeOperation): Moved from IDBObjectStoreBackendImpl::DeleteOperation
     54        (WebCore::DeleteRangeOperation::create):
     55        (WebCore::DeleteRangeOperation::DeleteRangeOperation):
     56        (ClearOperation): Moved from IDBObjectStoreBackendImpl::ClearOperation
     57        (WebCore::ClearOperation::create):
     58        (WebCore::ClearOperation::ClearOperation):
     59        (WebCore::IDBDatabaseBackendImpl::get): Combined from IDBObjectStoreBackendImpl/IDBIndexBackendImpl::get*
     60        (WebCore::GetOperation::perform):
     61        (WebCore::IDBDatabaseBackendImpl::put): Moved from IDBObjectStoreBackendImpl::put
     62        (WebCore::PutOperation::perform):
     63        (WebCore::IDBDatabaseBackendImpl::setIndexKeys): Moved from IDBObjectStoreBackendImpl::setIndexKeys
     64        (WebCore::IDBDatabaseBackendImpl::setIndexesReady):
     65        (WebCore::SetIndexesReadyOperation::perform):
     66        (WebCore::IDBDatabaseBackendImpl::openCursor):
     67        (WebCore::IDBDatabaseBackendImpl::count):
     68        (WebCore::CountOperation::perform):
     69        (WebCore::IDBDatabaseBackendImpl::deleteRange):
     70        (WebCore::DeleteRangeOperation::perform):
     71        (WebCore::IDBDatabaseBackendImpl::clear):
     72        (WebCore::ClearOperation::perform):
     73        (WebCore::OpenCursorOperation::perform):
     74        * Modules/indexeddb/IDBIndex.cpp:
     75        (WebCore::IDBIndex::IDBIndex):
     76        (WebCore::IDBIndex::openCursor):
     77        (WebCore::IDBIndex::count):
     78        (WebCore::IDBIndex::openKeyCursor):
     79        (WebCore::IDBIndex::get):
     80        (WebCore::IDBIndex::getKey):
     81        (WebCore::IDBIndex::backendDB):
     82        (WebCore):
     83        * Modules/indexeddb/IDBIndex.h:
     84        (WebCore::IDBIndex::create):
     85        (IDBIndex):
     86        * Modules/indexeddb/IDBIndexBackendImpl.cpp:
     87        (WebCore::IDBIndexBackendImpl::IDBIndexBackendImpl):
     88        * Modules/indexeddb/IDBIndexBackendImpl.h:
     89        (WebCore::IDBIndexBackendImpl::create):
     90        (WebCore::IDBIndexBackendImpl::openCursor):
     91        (WebCore::IDBIndexBackendImpl::count):
     92        (WebCore::IDBIndexBackendImpl::openKeyCursor):
     93        (WebCore::IDBIndexBackendImpl::get):
     94        (WebCore::IDBIndexBackendImpl::getKey):
     95        (IDBIndexBackendImpl):
     96        * Modules/indexeddb/IDBObjectStore.cpp:
     97        (WebCore::IDBObjectStore::get):
     98        (WebCore::IDBObjectStore::put):
     99        (WebCore::IDBObjectStore::deleteFunction):
     100        (WebCore::IDBObjectStore::clear):
     101        (WebCore):
     102        (WebCore::IDBObjectStore::createIndex):
     103        (WebCore::IDBObjectStore::index):
     104        (WebCore::IDBObjectStore::openCursor):
     105        (WebCore::IDBObjectStore::count):
     106        (WebCore::IDBObjectStore::backendDB):
     107        * Modules/indexeddb/IDBObjectStore.h:
     108        (WebCore::IDBObjectStore::id):
     109        (IDBObjectStore):
     110        * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
     111        (WebCore::IDBObjectStoreBackendImpl::createIndex):
     112        (WebCore::IDBObjectStoreBackendImpl::loadIndexes):
     113        (WebCore::IDBObjectStoreBackendImpl::generateKey):
     114        (WebCore::IDBObjectStoreBackendImpl::updateKeyGenerator):
     115        * Modules/indexeddb/IDBObjectStoreBackendImpl.h:
     116        (WebCore::IDBObjectStoreBackendImpl::get):
     117        (WebCore::IDBObjectStoreBackendImpl::put):
     118        (WebCore::IDBObjectStoreBackendImpl::deleteFunction):
     119        (WebCore::IDBObjectStoreBackendImpl::clear):
     120        (WebCore::IDBObjectStoreBackendImpl::setIndexKeys):
     121        (WebCore::IDBObjectStoreBackendImpl::setIndexesReady):
     122        (WebCore::IDBObjectStoreBackendImpl::openCursor):
     123        (WebCore::IDBObjectStoreBackendImpl::count):
     124        (IDBObjectStoreBackendImpl):
     125        * Modules/indexeddb/IDBTransactionBackendImpl.h:
     126        (WebCore::IDBTransactionBackendImpl::database):
     127        (IDBTransactionBackendImpl):
     128
    11292013-01-05  Robert Hogan  <robert@webkit.org>
    2130
  • trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp

    r138716 r138900  
    102102};
    103103
    104 IDBCursorBackendImpl::IDBCursorBackendImpl(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendImpl* transaction, IDBObjectStoreBackendImpl* objectStore)
    105     : m_cursor(cursor)
    106     , m_taskType(taskType)
     104IDBCursorBackendImpl::IDBCursorBackendImpl(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendImpl* transaction, int64_t objectStoreId)
     105    : m_taskType(taskType)
    107106    , m_cursorType(cursorType)
     107    , m_database(transaction->database())
    108108    , m_transaction(transaction)
    109     , m_objectStore(objectStore)
     109    , m_objectStoreId(objectStoreId)
     110    , m_cursor(cursor)
    110111    , m_closed(false)
    111112{
     
    116117{
    117118    m_transaction->unregisterOpenCursor(this);
    118     // Order is important, the cursors have to be destructed before the objectStore.
    119     m_cursor.clear();
    120     m_savedCursor.clear();
    121 
    122     m_objectStore.clear();
    123119}
    124120
     
    171167    ASSERT(!ec);
    172168
    173     m_objectStore->deleteFunction(keyRange.release(), prpCallbacks, m_transaction.get(), ec);
    174     ASSERT(!ec);
     169    m_database->deleteRange(m_transaction->id(), m_objectStoreId, keyRange.release(), prpCallbacks);
    175170}
    176171
  • trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.h

    r138290 r138900  
    4848class IDBCursorBackendImpl : public IDBCursorBackendInterface {
    4949public:
    50     static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendImpl* transaction, IDBObjectStoreBackendImpl* objectStore)
     50    static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendImpl* transaction, int64_t objectStoreId)
    5151    {
    52         return adoptRef(new IDBCursorBackendImpl(cursor, cursorType, IDBTransactionBackendInterface::NormalTask, transaction, objectStore));
     52        return adoptRef(new IDBCursorBackendImpl(cursor, cursorType, IDBTransactionBackendInterface::NormalTask, transaction, objectStoreId));
    5353    }
    54     static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendImpl* transaction, IDBObjectStoreBackendImpl* objectStore)
     54    static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBBackingStore::Cursor> cursor, CursorType cursorType, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendImpl* transaction, int64_t objectStoreId)
    5555    {
    56         return adoptRef(new IDBCursorBackendImpl(cursor, cursorType, taskType, transaction, objectStore));
     56        return adoptRef(new IDBCursorBackendImpl(cursor, cursorType, taskType, transaction, objectStoreId));
    5757    }
    5858    virtual ~IDBCursorBackendImpl();
     
    7272
    7373private:
    74     IDBCursorBackendImpl(PassRefPtr<IDBBackingStore::Cursor>, CursorType, IDBTransactionBackendInterface::TaskType, IDBTransactionBackendImpl*, IDBObjectStoreBackendImpl*);
     74    IDBCursorBackendImpl(PassRefPtr<IDBBackingStore::Cursor>, CursorType, IDBTransactionBackendInterface::TaskType, IDBTransactionBackendImpl*, int64_t objectStoreId);
    7575
    7676    class CursorIterationOperation;
     
    7878    class CursorPrefetchIterationOperation;
    7979
    80     RefPtr<IDBBackingStore::Cursor> m_cursor;
    81     RefPtr<IDBBackingStore::Cursor> m_savedCursor;
    8280    IDBTransactionBackendInterface::TaskType m_taskType;
    8381    CursorType m_cursorType;
    84     RefPtr<IDBTransactionBackendImpl> m_transaction;
    85     RefPtr<IDBObjectStoreBackendImpl> m_objectStore;
     82    const RefPtr<IDBDatabaseBackendImpl> m_database;
     83    const RefPtr<IDBTransactionBackendImpl> m_transaction;
     84    const int64_t m_objectStoreId;
     85
     86    RefPtr<IDBBackingStore::Cursor> m_cursor; // Must be destroyed before m_transaction.
     87    RefPtr<IDBBackingStore::Cursor> m_savedCursor; // Must be destroyed before m_transaction.
    8688
    8789    bool m_closed;
  • trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.h

    r138674 r138900  
    104104    }
    105105
     106    IDBDatabaseBackendInterface* backend() const { return m_backend.get(); }
     107
    106108    static int64_t nextTransactionId();
    107109
  • trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp

    r138666 r138900  
    3030
    3131#include "IDBBackingStore.h"
     32#include "IDBCursorBackendImpl.h"
    3233#include "IDBDatabaseException.h"
    3334#include "IDBFactoryBackendImpl.h"
     35#include "IDBIndexBackendImpl.h"
    3436#include "IDBObjectStoreBackendImpl.h"
    3537#include "IDBTracing.h"
     
    155157};
    156158
     159class GetOperation : public IDBTransactionBackendImpl::Operation {
     160public:
     161    static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, const IDBDatabaseMetadata& metadata, int64 objectStoreId, int64 indexId, PassRefPtr<IDBKeyRange> keyRange, IDBCursorBackendInterface::CursorType cursorType, PassRefPtr<IDBCallbacks> callbacks)
     162    {
     163        return adoptPtr(new GetOperation(backingStore, metadata, objectStoreId, indexId, keyRange, cursorType, callbacks));
     164    }
     165    virtual void perform(IDBTransactionBackendImpl*);
     166private:
     167    GetOperation(PassRefPtr<IDBBackingStore> backingStore, const IDBDatabaseMetadata& metadata, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, IDBCursorBackendInterface::CursorType cursorType, PassRefPtr<IDBCallbacks> callbacks)
     168        : m_backingStore(backingStore)
     169        , m_databaseId(metadata.id)
     170        , m_objectStoreId(objectStoreId)
     171        , m_indexId(indexId)
     172        , m_keyPath(metadata.objectStores.get(objectStoreId).keyPath)
     173        , m_autoIncrement(metadata.objectStores.get(objectStoreId).autoIncrement)
     174        , m_keyRange(keyRange)
     175        , m_cursorType(cursorType)
     176        , m_callbacks(callbacks)
     177    {
     178        ASSERT(metadata.objectStores.get(objectStoreId).id == objectStoreId);
     179    }
     180
     181    const RefPtr<IDBBackingStore> m_backingStore;
     182    const int64_t m_databaseId;
     183    const int64_t m_objectStoreId;
     184    const int64_t m_indexId;
     185    const IDBKeyPath m_keyPath;
     186    const bool m_autoIncrement;
     187    const RefPtr<IDBKeyRange> m_keyRange;
     188    const IDBCursorBackendInterface::CursorType m_cursorType;
     189    const RefPtr<IDBCallbacks> m_callbacks;
     190};
     191
     192class PutOperation : public IDBTransactionBackendImpl::Operation {
     193public:
     194    static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, const IDBObjectStoreMetadata& objectStore, Vector<uint8_t>& value, PassRefPtr<IDBKey> key, IDBDatabaseBackendInterface::PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, const Vector<int64_t>& indexIds, const Vector<IDBDatabaseBackendInterface::IndexKeys>& indexKeys)
     195    {
     196        return adoptPtr(new PutOperation(backingStore, databaseId, objectStore, value, key, putMode, callbacks, indexIds, indexKeys));
     197    }
     198    virtual void perform(IDBTransactionBackendImpl*);
     199private:
     200    PutOperation(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, const IDBObjectStoreMetadata& objectStore, Vector<uint8_t>& value, PassRefPtr<IDBKey> key, IDBDatabaseBackendInterface::PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, const Vector<int64_t>& indexIds, const Vector<IDBDatabaseBackendInterface::IndexKeys>& indexKeys)
     201        : m_backingStore(backingStore)
     202        , m_databaseId(databaseId)
     203        , m_objectStore(objectStore)
     204        , m_key(key)
     205        , m_putMode(putMode)
     206        , m_callbacks(callbacks)
     207        , m_indexIds(indexIds)
     208        , m_indexKeys(indexKeys)
     209    {
     210        m_value.swap(value);
     211    }
     212
     213    const RefPtr<IDBBackingStore> m_backingStore;
     214    const int64_t m_databaseId;
     215    const IDBObjectStoreMetadata m_objectStore;
     216    Vector<uint8_t> m_value;
     217    const RefPtr<IDBKey> m_key;
     218    const IDBDatabaseBackendInterface::PutMode m_putMode;
     219    const RefPtr<IDBCallbacks> m_callbacks;
     220    const Vector<int64_t> m_indexIds;
     221    const Vector<IDBDatabaseBackendInterface::IndexKeys> m_indexKeys;
     222};
     223
     224class SetIndexesReadyOperation : public IDBTransactionBackendImpl::Operation {
     225public:
     226    static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(size_t indexCount)
     227    {
     228        return adoptPtr(new SetIndexesReadyOperation(indexCount));
     229    }
     230    virtual void perform(IDBTransactionBackendImpl*);
     231private:
     232    SetIndexesReadyOperation(size_t indexCount)
     233        : m_indexCount(indexCount)
     234    {
     235    }
     236
     237    const size_t m_indexCount;
     238};
     239
     240class OpenCursorOperation : public IDBTransactionBackendImpl::Operation {
     241public:
     242    static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, IDBCursorBackendInterface::CursorType cursorType, IDBDatabaseBackendInterface::TaskType taskType, PassRefPtr<IDBCallbacks> callbacks)
     243    {
     244        return adoptPtr(new OpenCursorOperation(backingStore, databaseId, objectStoreId, indexId, keyRange, direction, cursorType, taskType, callbacks));
     245    }
     246    virtual void perform(IDBTransactionBackendImpl*);
     247private:
     248    OpenCursorOperation(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, IDBCursorBackendInterface::CursorType cursorType, IDBDatabaseBackendInterface::TaskType taskType, PassRefPtr<IDBCallbacks> callbacks)
     249        : m_backingStore(backingStore)
     250        , m_databaseId(databaseId)
     251        , m_objectStoreId(objectStoreId)
     252        , m_indexId(indexId)
     253        , m_keyRange(keyRange)
     254        , m_direction(direction)
     255        , m_cursorType(cursorType)
     256        , m_taskType(taskType)
     257        , m_callbacks(callbacks)
     258    {
     259    }
     260
     261    const RefPtr<IDBBackingStore> m_backingStore;
     262    const int64_t m_databaseId;
     263    const int64_t m_objectStoreId;
     264    const int64_t m_indexId;
     265    const PassRefPtr<IDBKeyRange> m_keyRange;
     266    const unsigned short m_direction;
     267    const IDBCursorBackendInterface::CursorType m_cursorType;
     268    const IDBDatabaseBackendInterface::TaskType m_taskType;
     269    const RefPtr<IDBCallbacks> m_callbacks;
     270};
     271
     272class CountOperation : public IDBTransactionBackendImpl::Operation {
     273public:
     274    static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
     275    {
     276        return adoptPtr(new CountOperation(backingStore, databaseId, objectStoreId, indexId, keyRange, callbacks));
     277    }
     278    virtual void perform(IDBTransactionBackendImpl*);
     279private:
     280    CountOperation(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
     281        : m_backingStore(backingStore)
     282        , m_databaseId(databaseId)
     283        , m_objectStoreId(objectStoreId)
     284        , m_indexId(indexId)
     285        , m_keyRange(keyRange)
     286        , m_callbacks(callbacks)
     287    {
     288    }
     289
     290    const RefPtr<IDBBackingStore> m_backingStore;
     291    const int64_t m_databaseId;
     292    const int64_t m_objectStoreId;
     293    const int64_t m_indexId;
     294    const RefPtr<IDBKeyRange> m_keyRange;
     295    const RefPtr<IDBCallbacks> m_callbacks;
     296};
     297
     298class DeleteRangeOperation : public IDBTransactionBackendImpl::Operation {
     299public:
     300    static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
     301    {
     302        return adoptPtr(new DeleteRangeOperation(backingStore, databaseId, objectStoreId, keyRange, callbacks));
     303    }
     304    virtual void perform(IDBTransactionBackendImpl*);
     305private:
     306    DeleteRangeOperation(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
     307        : m_backingStore(backingStore)
     308        , m_databaseId(databaseId)
     309        , m_objectStoreId(objectStoreId)
     310        , m_keyRange(keyRange)
     311        , m_callbacks(callbacks)
     312    {
     313    }
     314
     315    const RefPtr<IDBBackingStore> m_backingStore;
     316    const int64_t m_databaseId;
     317    const int64_t m_objectStoreId;
     318    const RefPtr<IDBKeyRange> m_keyRange;
     319    const RefPtr<IDBCallbacks> m_callbacks;
     320};
     321
     322class ClearOperation : public IDBTransactionBackendImpl::Operation {
     323public:
     324    static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks)
     325    {
     326        return adoptPtr(new ClearOperation(backingStore, databaseId, objectStoreId, callbacks));
     327    }
     328    virtual void perform(IDBTransactionBackendImpl*);
     329private:
     330    ClearOperation(PassRefPtr<IDBBackingStore> backingStore, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks)
     331        : m_backingStore(backingStore)
     332        , m_databaseId(databaseId)
     333        , m_objectStoreId(objectStoreId)
     334        , m_callbacks(callbacks)
     335    {
     336    }
     337
     338    const RefPtr<IDBBackingStore> m_backingStore;
     339    const int64_t m_databaseId;
     340    const int64_t m_objectStoreId;
     341    const RefPtr<IDBCallbacks> m_callbacks;
     342};
    157343
    158344class IDBDatabaseBackendImpl::PendingOpenCall {
     
    317503}
    318504
    319 void IDBDatabaseBackendImpl::get(int64_t transactionId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange>, bool keyOnly, PassRefPtr<IDBCallbacks>)
    320 {
    321     ASSERT_NOT_REACHED();
    322 }
    323 
    324 void IDBDatabaseBackendImpl::put(int64_t transactionId, int64_t objectStoreId, Vector<uint8_t>* value, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, const Vector<int64_t>& indexIds, const Vector<IndexKeys>&)
    325 {
    326     ASSERT_NOT_REACHED();
    327 }
    328 
    329 void IDBDatabaseBackendImpl::setIndexKeys(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBKey> prpPrimaryKey, const Vector<int64_t>& indexIds, const Vector<IndexKeys>&)
    330 {
    331     ASSERT_NOT_REACHED();
     505void IDBDatabaseBackendImpl::get(int64_t transactionId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, bool keyOnly, PassRefPtr<IDBCallbacks> callbacks)
     506{
     507    IDB_TRACE("IDBDatabaseBackendImpl::get");
     508    ASSERT(m_transactions.contains(transactionId));
     509    IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId);
     510
     511    transaction->scheduleTask(GetOperation::create(m_backingStore, metadata(), objectStoreId, indexId, keyRange, keyOnly ? IDBCursorBackendInterface::KeyOnly : IDBCursorBackendInterface::KeyAndValue, callbacks));
     512}
     513
     514void GetOperation::perform(IDBTransactionBackendImpl* transaction)
     515{
     516    IDB_TRACE("GetOperation");
     517
     518    RefPtr<IDBKey> key;
     519
     520    if (m_keyRange->isOnlyKey())
     521        key = m_keyRange->lower();
     522    else {
     523        RefPtr<IDBBackingStore::Cursor> backingStoreCursor;
     524        if (m_indexId == IDBIndexMetadata::InvalidId) {
     525            ASSERT(m_cursorType != IDBCursorBackendInterface::KeyOnly);
     526            // ObjectStore Retrieval Operation
     527            backingStoreCursor = m_backingStore->openObjectStoreCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_keyRange.get(), IDBCursor::NEXT);
     528        } else {
     529            if (m_cursorType == IDBCursorBackendInterface::KeyOnly)
     530                // Index Value Retrieval Operation
     531                backingStoreCursor = m_backingStore->openIndexKeyCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), IDBCursor::NEXT);
     532            else
     533                // Index Referenced Value Retrieval Operation
     534                backingStoreCursor = m_backingStore->openIndexCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), IDBCursor::NEXT);
     535        }
     536
     537        if (!backingStoreCursor) {
     538            m_callbacks->onSuccess();
     539            return;
     540        }
     541
     542        key = backingStoreCursor->key();
     543    }
     544
     545    RefPtr<IDBKey> primaryKey;
     546    bool ok;
     547    if (m_indexId == IDBIndexMetadata::InvalidId) {
     548        // Object Store Retrieval Operation
     549        Vector<uint8_t> value;
     550        ok = m_backingStore->getRecord(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, *key, value);
     551        if (!ok) {
     552            m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
     553            return;
     554        }
     555
     556        if (value.isEmpty()) {
     557            m_callbacks->onSuccess();
     558            return;
     559        }
     560
     561        if (m_autoIncrement && !m_keyPath.isNull()) {
     562            m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value), key, m_keyPath);
     563            return;
     564        }
     565
     566        m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value));
     567        return;
     568
     569    }
     570
     571    // From here we are dealing only with indexes.
     572    ok = m_backingStore->getPrimaryKeyViaIndex(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, *key, primaryKey);
     573    if (!ok) {
     574        m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getPrimaryKeyViaIndex."));
     575        return;
     576    }
     577    if (m_cursorType == IDBCursorBackendInterface::KeyOnly) {
     578        // Index Value Retrieval Operation
     579        m_callbacks->onSuccess(primaryKey.get());
     580        return;
     581    }
     582
     583    // Index Referenced Value Retrieval Operation
     584    Vector<uint8_t> value;
     585    ok = m_backingStore->getRecord(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, *primaryKey, value);
     586    if (!ok) {
     587        m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
     588        return;
     589    }
     590
     591    if (value.isEmpty()) {
     592        m_callbacks->onSuccess();
     593        return;
     594    }
     595    if (m_autoIncrement && !m_keyPath.isNull()) {
     596        m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value), primaryKey, m_keyPath);
     597        return;
     598    }
     599    m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value));
     600}
     601
     602void IDBDatabaseBackendImpl::put(int64_t transactionId, int64_t objectStoreId, Vector<uint8_t>* value, PassRefPtr<IDBKey> key, PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys)
     603{
     604    IDB_TRACE("IDBDatabaseBackendImpl::put");
     605
     606    ASSERT(m_transactions.contains(transactionId));
     607    IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId);
     608    ASSERT(transaction->mode() != IDBTransaction::READ_ONLY);
     609
     610    const IDBObjectStoreMetadata objectStoreMetadata = metadata().objectStores.get(objectStoreId);
     611
     612    ASSERT(objectStoreMetadata.autoIncrement || key.get());
     613
     614    transaction->scheduleTask(PutOperation::create(m_backingStore, id(), objectStoreMetadata, *value, key, putMode, callbacks, indexIds, indexKeys));
     615}
     616
     617void PutOperation::perform(IDBTransactionBackendImpl* transaction)
     618{
     619    IDB_TRACE("PutOperation");
     620    ASSERT(transaction->mode() != IDBTransaction::READ_ONLY);
     621    ASSERT(m_indexIds.size() == m_indexKeys.size());
     622    bool keyWasGenerated = false;
     623
     624    RefPtr<IDBKey> key;
     625    if (m_putMode != IDBDatabaseBackendInterface::CursorUpdate && m_objectStore.autoIncrement && !m_key) {
     626        RefPtr<IDBKey> autoIncKey = IDBObjectStoreBackendImpl::generateKey(m_backingStore, transaction, m_databaseId, m_objectStore.id);
     627        keyWasGenerated = true;
     628        if (!autoIncKey->isValid()) {
     629            m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Maximum key generator value reached."));
     630            return;
     631        }
     632        key = autoIncKey;
     633    } else
     634        key = m_key;
     635
     636    ASSERT(key && key->isValid());
     637
     638    IDBBackingStore::RecordIdentifier recordIdentifier;
     639    if (m_putMode == IDBDatabaseBackendInterface::AddOnly) {
     640        bool found = false;
     641        bool ok = m_backingStore->keyExistsInObjectStore(transaction->backingStoreTransaction(), m_databaseId, m_objectStore.id, *key, &recordIdentifier, found);
     642        if (!ok) {
     643            m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error checking key existence."));
     644            return;
     645        }
     646        if (found) {
     647            m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Key already exists in the object store."));
     648            return;
     649        }
     650    }
     651
     652    Vector<OwnPtr<IDBObjectStoreBackendImpl::IndexWriter> > indexWriters;
     653    String errorMessage;
     654    bool obeysConstraints = false;
     655    bool backingStoreSuccess = IDBObjectStoreBackendImpl::makeIndexWriters(transaction, m_backingStore.get(), m_databaseId, m_objectStore, key, keyWasGenerated, m_indexIds, m_indexKeys, &indexWriters, &errorMessage, obeysConstraints);
     656    if (!backingStoreSuccess) {
     657        m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys."));
     658        return;
     659    }
     660    if (!obeysConstraints) {
     661        m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage));
     662        return;
     663    }
     664
     665    // Before this point, don't do any mutation. After this point, rollback the transaction in case of error.
     666    backingStoreSuccess = m_backingStore->putRecord(transaction->backingStoreTransaction(), m_databaseId, m_objectStore.id, *key, m_value, &recordIdentifier);
     667    if (!backingStoreSuccess) {
     668        m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error performing put/add."));
     669        return;
     670    }
     671
     672    for (size_t i = 0; i < indexWriters.size(); ++i) {
     673        IDBObjectStoreBackendImpl::IndexWriter* indexWriter = indexWriters[i].get();
     674        indexWriter->writeIndexKeys(recordIdentifier, *m_backingStore, transaction->backingStoreTransaction(), m_databaseId, m_objectStore.id);
     675    }
     676
     677    if (m_objectStore.autoIncrement && m_putMode != IDBDatabaseBackendInterface::CursorUpdate && key->type() == IDBKey::NumberType) {
     678        bool ok = IDBObjectStoreBackendImpl::updateKeyGenerator(m_backingStore, transaction, m_databaseId, m_objectStore.id, key.get(), !keyWasGenerated);
     679        if (!ok) {
     680            m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error updating key generator."));
     681            return;
     682        }
     683    }
     684
     685    m_callbacks->onSuccess(key.release());
     686}
     687
     688
     689void IDBDatabaseBackendImpl::setIndexKeys(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBKey> prpPrimaryKey, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys)
     690{
     691    IDB_TRACE("IDBDatabaseBackendImpl::setIndexKeys");
     692    if (!m_transactions.contains(transactionId))
     693        return;
     694
     695    IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId);
     696    if (transaction->isFinished())
     697        return;
     698
     699    RefPtr<IDBKey> primaryKey = prpPrimaryKey;
     700    RefPtr<IDBBackingStore> store = backingStore();
     701    // FIXME: This method could be asynchronous, but we need to evaluate if it's worth the extra complexity.
     702    IDBBackingStore::RecordIdentifier recordIdentifier;
     703    bool found = false;
     704    bool ok = store->keyExistsInObjectStore(transaction->backingStoreTransaction(), m_metadata.id, objectStoreId, *primaryKey, &recordIdentifier, found);
     705    if (!ok) {
     706        transaction->abort(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error setting index keys."));
     707        return;
     708    }
     709    if (!found) {
     710        RefPtr<IDBDatabaseError> error = IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error setting index keys for object store."));
     711        transaction->abort(error.release());
     712        return;
     713    }
     714
     715    Vector<OwnPtr<IDBObjectStoreBackendImpl::IndexWriter> > indexWriters;
     716    String errorMessage;
     717    bool obeysConstraints = false;
     718    ASSERT(metadata().objectStores.contains(objectStoreId));
     719    const IDBObjectStoreMetadata& objectStoreMetadata = metadata().objectStores.get(objectStoreId);
     720    bool backingStoreSuccess = IDBObjectStoreBackendImpl::makeIndexWriters(transaction, store.get(), id(), objectStoreMetadata, primaryKey, false, indexIds, indexKeys, &indexWriters, &errorMessage, obeysConstraints);
     721    if (!backingStoreSuccess) {
     722        transaction->abort(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys."));
     723        return;
     724    }
     725    if (!obeysConstraints) {
     726        transaction->abort(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage));
     727        return;
     728    }
     729
     730    for (size_t i = 0; i < indexWriters.size(); ++i) {
     731        IDBObjectStoreBackendImpl::IndexWriter* indexWriter = indexWriters[i].get();
     732        indexWriter->writeIndexKeys(recordIdentifier, *store.get(), transaction->backingStoreTransaction(), id(), objectStoreId);
     733    }
    332734}
    333735
    334736void IDBDatabaseBackendImpl::setIndexesReady(int64_t transactionId, int64_t objectStoreId, const Vector<int64_t>& indexIds)
    335737{
    336     ASSERT_NOT_REACHED();
     738    IDB_TRACE("IDBObjectStoreBackendImpl::setIndexesReady");
     739
     740    if (!m_transactions.contains(transactionId))
     741        return;
     742
     743    IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId);
     744    if (transaction->isFinished())
     745        return;
     746
     747    if (!transaction->scheduleTask(IDBTransactionBackendInterface::PreemptiveTask, SetIndexesReadyOperation::create(indexIds.size())))
     748        ASSERT_NOT_REACHED();
     749}
     750
     751void SetIndexesReadyOperation::perform(IDBTransactionBackendImpl* transaction)
     752{
     753    IDB_TRACE("SetIndexesReadyOperation");
     754    for (size_t i = 0; i < m_indexCount; ++i)
     755        transaction->didCompletePreemptiveEvent();
    337756}
    338757
    339758void IDBDatabaseBackendImpl::openCursor(int64_t transactionId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, bool keyOnly, TaskType taskType, PassRefPtr<IDBCallbacks> callbacks)
    340759{
    341     ASSERT_NOT_REACHED();
    342 }
    343 
    344 void IDBDatabaseBackendImpl::count(int64_t transactionId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>)
    345 {
    346     ASSERT_NOT_REACHED();
    347 }
    348 
    349 void IDBDatabaseBackendImpl::deleteRange(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>)
    350 {
    351     ASSERT_NOT_REACHED();
    352 }
    353 
    354 void IDBDatabaseBackendImpl::clear(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBCallbacks>)
    355 {
    356     ASSERT_NOT_REACHED();
     760    IDB_TRACE("IDBDatabaseBackendImpl::openCursor");
     761    ASSERT(m_transactions.contains(transactionId));
     762    IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId);
     763
     764    transaction->scheduleTask(OpenCursorOperation::create(m_backingStore, id(), objectStoreId, indexId, keyRange, direction, keyOnly ? IDBCursorBackendInterface::KeyOnly : IDBCursorBackendInterface::KeyAndValue, taskType, callbacks));
     765}
     766
     767void OpenCursorOperation::perform(IDBTransactionBackendImpl* transaction)
     768{
     769    IDB_TRACE("OpenCursorOperation");
     770
     771    // The frontend has begun indexing, so this pauses the transaction
     772    // until the indexing is complete. This can't happen any earlier
     773    // because we don't want to switch to early mode in case multiple
     774    // indexes are being created in a row, with put()'s in between.
     775    if (m_taskType == IDBDatabaseBackendInterface::PreemptiveTask)
     776        transaction->addPreemptiveEvent();
     777
     778    IDBCursor::Direction direction = static_cast<IDBCursor::Direction>(m_direction);
     779    RefPtr<IDBBackingStore::Cursor> backingStoreCursor;
     780    if (m_indexId == IDBIndexMetadata::InvalidId) {
     781        ASSERT(m_cursorType != IDBCursorBackendInterface::KeyOnly);
     782        backingStoreCursor = m_backingStore->openObjectStoreCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_keyRange.get(), direction);
     783    } else {
     784        ASSERT(m_taskType == IDBDatabaseBackendInterface::NormalTask);
     785        if (m_cursorType == IDBCursorBackendInterface::KeyOnly)
     786            backingStoreCursor = m_backingStore->openIndexKeyCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), direction);
     787        else
     788            backingStoreCursor = m_backingStore->openIndexCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), direction);
     789    }
     790
     791    if (!backingStoreCursor) {
     792        m_callbacks->onSuccess(static_cast<SerializedScriptValue*>(0));
     793        return;
     794    }
     795
     796    IDBTransactionBackendInterface::TaskType taskType(static_cast<IDBTransactionBackendInterface::TaskType>(m_taskType));
     797    RefPtr<IDBCursorBackendImpl> cursor = IDBCursorBackendImpl::create(backingStoreCursor.get(), m_cursorType, taskType, transaction, m_objectStoreId);
     798    m_callbacks->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value());
     799}
     800
     801void IDBDatabaseBackendImpl::count(int64_t transactionId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
     802{
     803    IDB_TRACE("IDBDatabaseBackendImpl::count");
     804    ASSERT(m_transactions.contains(transactionId));
     805    IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId);
     806    ASSERT(metadata().objectStores.contains(objectStoreId));
     807    transaction->scheduleTask(CountOperation::create(m_backingStore, id(), objectStoreId, indexId, keyRange, callbacks));
     808}
     809
     810void CountOperation::perform(IDBTransactionBackendImpl* transaction)
     811{
     812    IDB_TRACE("CountOperation");
     813    uint32_t count = 0;
     814    RefPtr<IDBBackingStore::Cursor> backingStoreCursor;
     815
     816    if (m_indexId == IDBIndexMetadata::InvalidId)
     817        backingStoreCursor = m_backingStore->openObjectStoreKeyCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_keyRange.get(), IDBCursor::NEXT);
     818    else
     819        backingStoreCursor = m_backingStore->openIndexKeyCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), IDBCursor::NEXT);
     820    if (!backingStoreCursor) {
     821        m_callbacks->onSuccess(count);
     822        return;
     823    }
     824
     825    do {
     826        ++count;
     827    } while (backingStoreCursor->continueFunction(0));
     828
     829    m_callbacks->onSuccess(count);
     830}
     831
     832void IDBDatabaseBackendImpl::deleteRange(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
     833{
     834    IDB_TRACE("IDBDatabaseBackendImpl::deleteRange");
     835
     836    ASSERT(m_transactions.contains(transactionId));
     837    IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId);
     838    ASSERT(transaction->mode() != IDBTransaction::READ_ONLY);
     839
     840    transaction->scheduleTask(DeleteRangeOperation::create(m_backingStore, id(), objectStoreId, keyRange, callbacks));
     841}
     842
     843void DeleteRangeOperation::perform(IDBTransactionBackendImpl* transaction)
     844{
     845    IDB_TRACE("DeleteRangeOperation");
     846
     847    RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_backingStore->openObjectStoreCursor(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, m_keyRange.get(), IDBCursor::NEXT);
     848    if (backingStoreCursor) {
     849        do {
     850            m_backingStore->deleteRecord(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId, backingStoreCursor->recordIdentifier());
     851        } while (backingStoreCursor->continueFunction(0));
     852    }
     853
     854    m_callbacks->onSuccess();
     855}
     856
     857void IDBDatabaseBackendImpl::clear(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks)
     858{
     859    IDB_TRACE("IDBDatabaseBackendImpl::clear");
     860
     861    ASSERT(m_transactions.contains(transactionId));
     862    IDBTransactionBackendImpl* transaction = m_transactions.get(transactionId);
     863    ASSERT(transaction->mode() != IDBTransaction::READ_ONLY);
     864
     865    transaction->scheduleTask(ClearOperation::create(m_backingStore, id(), objectStoreId, callbacks));
     866}
     867
     868void ClearOperation::perform(IDBTransactionBackendImpl* transaction)
     869{
     870    IDB_TRACE("ObjectStoreClearOperation");
     871    m_backingStore->clearObjectStore(transaction->backingStoreTransaction(), m_databaseId, m_objectStoreId);
     872    m_callbacks->onSuccess();
    357873}
    358874
  • trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp

    r138290 r138900  
    4444static const unsigned short defaultDirection = IDBCursor::NEXT;
    4545
    46 IDBIndex::IDBIndex(const IDBIndexMetadata& metadata, PassRefPtr<IDBIndexBackendInterface> backend, IDBObjectStore* objectStore, IDBTransaction* transaction)
     46IDBIndex::IDBIndex(const IDBIndexMetadata& metadata, IDBObjectStore* objectStore, IDBTransaction* transaction)
    4747    : m_metadata(metadata)
    48     , m_backend(backend)
    4948    , m_objectStore(objectStore)
    5049    , m_transaction(transaction)
    5150    , m_deleted(false)
    5251{
    53     ASSERT(m_backend);
    5452    ASSERT(m_objectStore);
    5553    ASSERT(m_transaction);
     54    ASSERT(m_metadata.id != IDBIndexMetadata::InvalidId);
    5655}
    5756
     
    7776    RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
    7877    request->setCursorDetails(IDBCursorBackendInterface::KeyAndValue, direction);
    79     m_backend->openCursor(keyRange, direction, request, m_transaction->backend(), ec);
    80     ASSERT(!ec);
     78    backendDB()->openCursor(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, direction, false, IDBDatabaseBackendInterface::NormalTask, request);
    8179    return request;
    8280}
     
    103101    }
    104102    RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
    105     m_backend->count(keyRange, request, m_transaction->backend(), ec);
    106     ASSERT(!ec);
     103    IDBDatabaseMetadata metadata(m_transaction->db()->metadata());
     104    backendDB()->count(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, request);
    107105    return request;
    108106}
     
    134132    RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
    135133    request->setCursorDetails(IDBCursorBackendInterface::KeyOnly, direction);
    136     m_backend->openKeyCursor(keyRange, direction, request, m_transaction->backend(), ec);
    137     ASSERT(!ec);
     134    backendDB()->openCursor(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, direction, true, IDBDatabaseBackendInterface::NormalTask, request);
    138135    return request;
    139136}
     
    174171
    175172    RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
    176     m_backend->get(keyRange, request, m_transaction->backend(), ec);
    177     ASSERT(!ec);
     173    backendDB()->get(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, false, request);
    178174    return request;
    179175}
     
    206202
    207203    RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
    208     m_backend->getKey(keyRange, request, m_transaction->backend(), ec);
    209     ASSERT(!ec);
    210     return request;
     204    backendDB()->get(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, true, request);
     205    return request;
     206}
     207
     208IDBDatabaseBackendInterface* IDBIndex::backendDB() const
     209{
     210    return m_transaction->backendDB();
    211211}
    212212
  • trunk/Source/WebCore/Modules/indexeddb/IDBIndex.h

    r134040 r138900  
    2828
    2929#include "IDBCursor.h"
    30 #include "IDBIndexBackendInterface.h"
     30#include "IDBDatabase.h"
    3131#include "IDBKeyPath.h"
    3232#include "IDBKeyRange.h"
     
    4646class IDBIndex : public ScriptWrappable, public RefCounted<IDBIndex> {
    4747public:
    48     static PassRefPtr<IDBIndex> create(const IDBIndexMetadata& metadata, PassRefPtr<IDBIndexBackendInterface> backend, IDBObjectStore* objectStore, IDBTransaction* transaction)
     48    static PassRefPtr<IDBIndex> create(const IDBIndexMetadata& metadata, IDBObjectStore* objectStore, IDBTransaction* transaction)
    4949    {
    50         return adoptRef(new IDBIndex(metadata, backend, objectStore, transaction));
     50        return adoptRef(new IDBIndex(metadata, objectStore, transaction));
    5151    }
    5252    ~IDBIndex();
     
    8484    void markDeleted() { m_deleted = true; }
    8585
     86    IDBDatabaseBackendInterface* backendDB() const;
     87
    8688private:
    87     IDBIndex(const IDBIndexMetadata&, PassRefPtr<IDBIndexBackendInterface>, IDBObjectStore*, IDBTransaction*);
     89    IDBIndex(const IDBIndexMetadata&, IDBObjectStore*, IDBTransaction*);
    8890
    8991    IDBIndexMetadata m_metadata;
    90     RefPtr<IDBIndexBackendInterface> m_backend;
    9192    RefPtr<IDBObjectStore> m_objectStore;
    9293    RefPtr<IDBTransaction> m_transaction;
  • trunk/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp

    r138716 r138900  
    4343namespace WebCore {
    4444
    45 class IDBIndexBackendImpl::OpenIndexCursorOperation : public IDBTransactionBackendImpl::Operation {
    46 public:
    47     static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, IDBCursorBackendInterface::CursorType cursorType, PassRefPtr<IDBCallbacks> callbacks)
    48     {
    49         return adoptPtr(new OpenIndexCursorOperation(index, keyRange, direction, cursorType, callbacks));
    50     }
    51     virtual void perform(IDBTransactionBackendImpl*);
    52 private:
    53     OpenIndexCursorOperation(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, IDBCursorBackendInterface::CursorType cursorType, PassRefPtr<IDBCallbacks> callbacks)
    54         : m_index(index)
    55         , m_keyRange(keyRange)
    56         , m_direction(direction)
    57         , m_cursorType(cursorType)
    58         , m_callbacks(callbacks)
    59     {
    60     }
    61 
    62     RefPtr<IDBIndexBackendImpl> m_index;
    63     RefPtr<IDBKeyRange> m_keyRange;
    64     unsigned short m_direction;
    65     IDBCursorBackendInterface::CursorType m_cursorType;
    66     RefPtr<IDBCallbacks> m_callbacks;
    67 };
    68 
    69 class IDBIndexBackendImpl::IndexCountOperation : public IDBTransactionBackendImpl::Operation {
    70 public:
    71     static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
    72     {
    73         return adoptPtr(new IndexCountOperation(index, keyRange, callbacks));
    74     }
    75     virtual void perform(IDBTransactionBackendImpl*);
    76 private:
    77     IndexCountOperation(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
    78         : m_index(index)
    79         , m_keyRange(keyRange)
    80         , m_callbacks(callbacks)
    81     {
    82     }
    83 
    84     RefPtr<IDBIndexBackendImpl> m_index;
    85     RefPtr<IDBKeyRange> m_keyRange;
    86     RefPtr<IDBCallbacks> m_callbacks;
    87 };
    88 
    89 class IDBIndexBackendImpl::IndexReferencedValueRetrievalOperation : public IDBTransactionBackendImpl::Operation {
    90 public:
    91     static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
    92     {
    93         return adoptPtr(new IndexReferencedValueRetrievalOperation(index, keyRange, callbacks));
    94     }
    95     virtual void perform(IDBTransactionBackendImpl*);
    96 private:
    97     IndexReferencedValueRetrievalOperation(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
    98         : m_index(index)
    99         , m_keyRange(keyRange)
    100         , m_callbacks(callbacks)
    101     {
    102     }
    103 
    104     RefPtr<IDBIndexBackendImpl> m_index;
    105     RefPtr<IDBKeyRange> m_keyRange;
    106     RefPtr<IDBCallbacks> m_callbacks;
    107 };
    108 
    109 class IDBIndexBackendImpl::IndexValueRetrievalOperation : public IDBTransactionBackendImpl::Operation {
    110 public:
    111     static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
    112     {
    113         return adoptPtr(new IndexValueRetrievalOperation(index, keyRange, callbacks));
    114     }
    115     virtual void perform(IDBTransactionBackendImpl*);
    116 private:
    117     IndexValueRetrievalOperation(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
    118         : m_index(index)
    119         , m_keyRange(keyRange)
    120         , m_callbacks(callbacks)
    121     {
    122     }
    123 
    124     RefPtr<IDBIndexBackendImpl> m_index;
    125     RefPtr<IDBKeyRange> m_keyRange;
    126     RefPtr<IDBCallbacks> m_callbacks;
    127 };
    128 
    129 
    130 IDBIndexBackendImpl::IDBIndexBackendImpl(const IDBDatabaseBackendImpl* database, IDBObjectStoreBackendImpl* objectStoreBackend, const IDBIndexMetadata& metadata)
     45IDBIndexBackendImpl::IDBIndexBackendImpl(const IDBDatabaseBackendImpl* database, const IDBIndexMetadata& metadata)
    13146    : m_database(database)
    132     , m_objectStoreBackend(objectStoreBackend)
    13347    , m_metadata(metadata)
    13448{
     
    13953}
    14054
    141 void IDBIndexBackendImpl::OpenIndexCursorOperation::perform(IDBTransactionBackendImpl* transaction)
    142 {
    143     IDB_TRACE("OpenIndexCursorOperation");
    144     IDBCursor::Direction direction = static_cast<IDBCursor::Direction>(m_direction);
    145 
    146     RefPtr<IDBBackingStore::Cursor> backingStoreCursor;
    147 
    148     switch (m_cursorType) {
    149     case IDBCursorBackendInterface::KeyOnly:
    150         backingStoreCursor = m_index->backingStore()->openIndexKeyCursor(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), m_keyRange.get(), direction);
    151         break;
    152     case IDBCursorBackendInterface::KeyAndValue:
    153         backingStoreCursor = m_index->backingStore()->openIndexCursor(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), m_keyRange.get(), direction);
    154         break;
    155     default:
    156         ASSERT_NOT_REACHED();
    157     }
    158 
    159     if (!backingStoreCursor) {
    160         m_callbacks->onSuccess(static_cast<SerializedScriptValue*>(0));
    161         return;
    162     }
    163 
    164     RefPtr<IDBCursorBackendImpl> cursor = IDBCursorBackendImpl::create(backingStoreCursor.get(), m_cursorType, transaction, m_index->m_objectStoreBackend);
    165     m_callbacks->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value());
    166 }
    167 
    168 void IDBIndexBackendImpl::openCursor(PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
    169 {
    170     IDB_TRACE("IDBIndexBackendImpl::openCursor");
    171     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
    172     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
    173     transaction->scheduleTask(OpenIndexCursorOperation::create(this, keyRange, direction, IDBCursorBackendInterface::KeyAndValue, callbacks));
    174 }
    175 
    176 void IDBIndexBackendImpl::openKeyCursor(PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
    177 {
    178     IDB_TRACE("IDBIndexBackendImpl::openKeyCursor");
    179     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
    180     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
    181     transaction->scheduleTask(OpenIndexCursorOperation::create(this, keyRange, direction, IDBCursorBackendInterface::KeyOnly, callbacks));
    182 }
    183 
    184 void IDBIndexBackendImpl::IndexCountOperation::perform(IDBTransactionBackendImpl* transaction)
    185 {
    186     IDB_TRACE("IndexCountOperation");
    187     uint32_t count = 0;
    188 
    189     RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_index->backingStore()->openIndexKeyCursor(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), m_keyRange.get(), IDBCursor::NEXT);
    190     if (!backingStoreCursor) {
    191         m_callbacks->onSuccess(count);
    192         return;
    193     }
    194 
    195     do {
    196         ++count;
    197     } while (backingStoreCursor->continueFunction(0));
    198 
    199     m_callbacks->onSuccess(count);
    200 }
    201 
    202 void IDBIndexBackendImpl::count(PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
    203 {
    204     IDB_TRACE("IDBIndexBackendImpl::count");
    205     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
    206     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
    207     transaction->scheduleTask(IndexCountOperation::create(this, range, callbacks));
    208 }
    209 
    210 void IDBIndexBackendImpl::IndexReferencedValueRetrievalOperation::perform(IDBTransactionBackendImpl* transaction)
    211 {
    212     IDB_TRACE("IndexReferencedValueRetrievalOperation");
    213 
    214     RefPtr<IDBKey> key;
    215 
    216     if (m_keyRange->isOnlyKey())
    217         key = m_keyRange->lower();
    218     else {
    219         RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_index->backingStore()->openIndexCursor(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), m_keyRange.get(), IDBCursor::NEXT);
    220 
    221         if (!backingStoreCursor) {
    222             m_callbacks->onSuccess();
    223             return;
    224         }
    225         key = backingStoreCursor->key();
    226     }
    227 
    228     RefPtr<IDBKey> primaryKey;
    229     bool ok = m_index->backingStore()->getPrimaryKeyViaIndex(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), *key, primaryKey);
    230     if (!ok) {
    231         m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getPrimaryKeyViaIndex."));
    232         return;
    233     }
    234 
    235     Vector<uint8_t> value;
    236     ok = m_index->backingStore()->getRecord(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), *primaryKey, value);
    237     if (!ok) {
    238         m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
    239         return;
    240     }
    241 
    242     if (value.isEmpty()) {
    243         m_callbacks->onSuccess();
    244         return;
    245     }
    246     if (m_index->m_objectStoreBackend->autoIncrement() && !m_index->m_objectStoreBackend->keyPath().isNull()) {
    247         m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value), primaryKey, m_index->m_objectStoreBackend->keyPath());
    248         return;
    249     }
    250     m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value));
    251 }
    252 
    253 
    254 void IDBIndexBackendImpl::IndexValueRetrievalOperation::perform(IDBTransactionBackendImpl* transaction)
    255 {
    256     IDB_TRACE("IndexValueRetrievalOperation");
    257 
    258     RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_index->backingStore()->openIndexKeyCursor(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), m_keyRange.get(), IDBCursor::NEXT);
    259 
    260     if (!backingStoreCursor) {
    261         m_callbacks->onSuccess(static_cast<IDBKey*>(0));
    262         return;
    263     }
    264 
    265     RefPtr<IDBKey> keyResult;
    266     bool ok = m_index->backingStore()->getPrimaryKeyViaIndex(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), m_index->id(), *backingStoreCursor->key(), keyResult);
    267     if (!ok) {
    268         m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getPrimaryKeyViaIndex."));
    269         return;
    270     }
    271     if (!keyResult) {
    272         m_callbacks->onSuccess(static_cast<IDBKey*>(0));
    273         return;
    274     }
    275     m_callbacks->onSuccess(keyResult.get());
    276 }
    277 
    278 void IDBIndexBackendImpl::get(PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
    279 {
    280     IDB_TRACE("IDBIndexBackendImpl::get");
    281     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
    282     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
    283     transaction->scheduleTask(IndexReferencedValueRetrievalOperation::create(this, keyRange, callbacks));
    284 }
    285 
    286 void IDBIndexBackendImpl::getKey(PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
    287 {
    288     IDB_TRACE("IDBIndexBackendImpl::getKey");
    289     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
    290     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
    291     transaction->scheduleTask(IndexValueRetrievalOperation::create(this, keyRange, callbacks));
    292 }
    293 
    29455} // namespace WebCore
    29556
  • trunk/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.h

    r136696 r138900  
    4343class IDBIndexBackendImpl : public IDBIndexBackendInterface {
    4444public:
    45     static PassRefPtr<IDBIndexBackendImpl> create(const IDBDatabaseBackendImpl* database, IDBObjectStoreBackendImpl* objectStoreBackend, const IDBIndexMetadata& metadata)
     45    static PassRefPtr<IDBIndexBackendImpl> create(const IDBDatabaseBackendImpl* database, const IDBIndexMetadata& metadata)
    4646    {
    47         return adoptRef(new IDBIndexBackendImpl(database, objectStoreBackend, metadata));
     47        return adoptRef(new IDBIndexBackendImpl(database, metadata));
    4848    }
    4949    virtual ~IDBIndexBackendImpl();
     
    5656
    5757    // IDBIndexBackendInterface
    58     virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
    59     virtual void count(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
    60     virtual void openKeyCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
    61     virtual void get(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
    62     virtual void getKey(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
     58    virtual void openCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); }
     59    virtual void count(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); }
     60    virtual void openKeyCursor(PassRefPtr<IDBKeyRange>, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); }
     61    virtual void get(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); }
     62    virtual void getKey(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); }
    6363
    6464    IDBIndexMetadata metadata() const { return m_metadata; }
     
    6969
    7070private:
    71     IDBIndexBackendImpl(const IDBDatabaseBackendImpl*, IDBObjectStoreBackendImpl*, const IDBIndexMetadata&);
    72 
    73     class OpenIndexCursorOperation;
    74     class IndexCountOperation;
    75     class IndexReferencedValueRetrievalOperation;
    76     class IndexValueRetrievalOperation;
     71    IDBIndexBackendImpl(const IDBDatabaseBackendImpl*, const IDBIndexMetadata&);
    7772
    7873    static const int64_t InvalidId = 0;
     
    8277
    8378    const IDBDatabaseBackendImpl* m_database;
    84 
    85     IDBObjectStoreBackendImpl* m_objectStoreBackend;
    8679
    8780    IDBIndexMetadata m_metadata;
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp

    r138290 r138900  
    8888    }
    8989    RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
    90     m_backend->get(keyRange, request, m_transaction->backend(), ec);
    91     ASSERT(!ec);
     90    backendDB()->get(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, keyRange, false, request);
    9291    return request.release();
    9392}
     
    9594PassRefPtr<IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec)
    9695{
    97     IDB_TRACE("IDBObjectStore::get");
    9896    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec);
    9997    if (ec)
     
    215213
    216214    RefPtr<IDBRequest> request = IDBRequest::create(context, source, m_transaction.get());
    217     m_backend->put(serializedValue.release(), key.release(), putMode, request, m_transaction->backend(), indexIds, indexKeys);
    218     ASSERT(!ec);
     215    Vector<uint8_t> valueBytes = serializedValue->toWireBytes();
     216    backendDB()->put(m_transaction->id(), id(), &valueBytes, key.release(), static_cast<IDBDatabaseBackendInterface::PutMode>(putMode), request, indexIds, indexKeys);
    219217    return request.release();
    220218}
     
    241239
    242240    RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
    243     m_backend->deleteFunction(keyRange, request, m_transaction->backend(), ec);
    244     ASSERT(!ec);
     241    backendDB()->deleteRange(m_transaction->id(), id(), keyRange, request);
    245242    return request.release();
    246243}
     
    248245PassRefPtr<IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec)
    249246{
    250     IDB_TRACE("IDBObjectStore::delete");
    251247    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec);
    252248    if (ec)
     
    272268
    273269    RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
    274     m_backend->clear(request, m_transaction->backend(), ec);
    275     ASSERT(!ec);
     270    backendDB()->clear(m_transaction->id(), id(), request);
    276271    return request.release();
    277272}
     
    285280class IndexPopulator : public EventListener {
    286281public:
    287     static PassRefPtr<IndexPopulator> create(PassRefPtr<IDBObjectStoreBackendInterface> backend, PassRefPtr<IDBTransactionBackendInterface> transaction, PassRefPtr<IDBRequest> request, const IDBIndexMetadata& indexMetadata)
     282    static PassRefPtr<IndexPopulator> create(PassRefPtr<IDBDatabaseBackendInterface> backend, int64_t transactionId, int64_t objectStoreId, const IDBIndexMetadata& indexMetadata)
    288283    {
    289         return adoptRef(new IndexPopulator(backend, transaction, indexMetadata));
     284        return adoptRef(new IndexPopulator(backend, transactionId, objectStoreId, indexMetadata));
    290285    }
    291286
     
    296291
    297292private:
    298     IndexPopulator(PassRefPtr<IDBObjectStoreBackendInterface> backend,
    299                    PassRefPtr<IDBTransactionBackendInterface> transaction,
    300                    const IDBIndexMetadata& indexMetadata)
     293    IndexPopulator(PassRefPtr<IDBDatabaseBackendInterface> backend, int64_t transactionId, int64_t objectStoreId, const IDBIndexMetadata& indexMetadata)
    301294        : EventListener(CPPEventListenerType)
    302         , m_objectStoreBackend(backend)
    303         , m_transaction(transaction)
     295        , m_databaseBackend(backend)
     296        , m_transactionId(transactionId)
     297        , m_objectStoreId(objectStoreId)
    304298        , m_indexMetadata(indexMetadata)
    305299    {
     
    334328            indexKeysList.append(indexKeys);
    335329
    336             m_objectStoreBackend->setIndexKeys(primaryKey, indexIds, indexKeysList, m_transaction.get());
    337 
     330            m_databaseBackend->setIndexKeys(m_transactionId, m_objectStoreId, primaryKey, indexIds, indexKeysList);
    338331        } else {
    339332            // Now that we are done indexing, tell the backend to go
    340333            // back to processing tasks of type NormalTask.
    341             m_objectStoreBackend->setIndexesReady(indexIds, m_transaction.get());
    342             m_objectStoreBackend.clear();
    343             m_transaction.clear();
    344         }
    345 
    346     }
    347 
    348     RefPtr<IDBObjectStoreBackendInterface> m_objectStoreBackend;
    349     RefPtr<IDBTransactionBackendInterface> m_transaction;
    350     IDBIndexMetadata m_indexMetadata;
     334            m_databaseBackend->setIndexesReady(m_transactionId, m_objectStoreId, indexIds);
     335            m_databaseBackend.clear();
     336        }
     337
     338    }
     339
     340    RefPtr<IDBDatabaseBackendInterface> m_databaseBackend;
     341    const int64_t m_transactionId;
     342    const int64_t m_objectStoreId;
     343    const IDBIndexMetadata m_indexMetadata;
    351344};
    352345}
     
    393386
    394387    int64_t indexId = m_metadata.maxIndexId + 1;
    395     RefPtr<IDBIndexBackendInterface> indexBackend = m_backend->createIndex(indexId, name, keyPath, unique, multiEntry, m_transaction->backend(), ec);
    396     ASSERT(!indexBackend != !ec); // If we didn't get an index, we should have gotten an exception code. And vice versa.
     388    m_backend->createIndex(indexId, name, keyPath, unique, multiEntry, m_transaction->backend(), ec);
    397389    if (ec)
    398390        return 0;
     
    401393
    402394    IDBIndexMetadata metadata(name, indexId, keyPath, unique, multiEntry);
    403     RefPtr<IDBIndex> index = IDBIndex::create(metadata, indexBackend.release(), this, m_transaction.get());
     395    RefPtr<IDBIndex> index = IDBIndex::create(metadata, this, m_transaction.get());
    404396    m_indexMap.set(name, index);
    405397    m_metadata.indexes.set(indexId, metadata);
     
    416408
    417409    // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction.
    418     RefPtr<IndexPopulator> indexPopulator = IndexPopulator::create(m_backend, m_transaction->backend(), indexRequest, metadata);
     410    RefPtr<IndexPopulator> indexPopulator = IndexPopulator::create(backendDB(), m_transaction->id(), id(), metadata);
    419411    indexRequest->setOnsuccess(indexPopulator);
    420412
     
    443435        return 0;
    444436    }
    445 
    446     RefPtr<IDBIndexBackendInterface> indexBackend = m_backend->index(indexId);
    447     ASSERT(!ec && indexBackend);
    448437
    449438    const IDBIndexMetadata* indexMetadata(0);
     
    455444    }
    456445    ASSERT(indexMetadata);
    457 
    458     RefPtr<IDBIndex> index = IDBIndex::create(*indexMetadata, indexBackend.release(), this, m_transaction.get());
     446    ASSERT(indexMetadata->id != IDBIndexMetadata::InvalidId);
     447
     448    RefPtr<IDBIndex> index = IDBIndex::create(*indexMetadata, this, m_transaction.get());
    459449    m_indexMap.set(name, index);
    460450    return index.release();
     
    505495    RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
    506496    request->setCursorDetails(IDBCursorBackendInterface::KeyAndValue, direction);
    507     m_backend->openCursor(range, direction, request, taskType, m_transaction->backend(), ec);
    508     ASSERT(!ec);
     497
     498    backendDB()->openCursor(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, range, direction, false, static_cast<IDBDatabaseBackendInterface::TaskType>(taskType), request);
    509499    return request.release();
    510500}
     
    512502PassRefPtr<IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, const String& direction, ExceptionCode& ec)
    513503{
    514     IDB_TRACE("IDBObjectStore::openCursor");
    515504    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec);
    516505    if (ec)
     
    531520    }
    532521    RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
    533     m_backend->count(range, request, m_transaction->backend(), ec);
    534     ASSERT(!ec);
     522    backendDB()->count(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, range, request);
    535523    return request.release();
    536524}
     
    538526PassRefPtr<IDBRequest> IDBObjectStore::count(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec)
    539527{
    540     IDB_TRACE("IDBObjectStore::count");
    541528    RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec);
    542529    if (ec)
     
    564551}
    565552
     553IDBDatabaseBackendInterface* IDBObjectStore::backendDB() const
     554{
     555    return m_transaction->backendDB();
     556}
     557
    566558} // namespace WebCore
    567559
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h

    r138081 r138900  
    3030#include "IDBCursor.h"
    3131#include "IDBIndex.h"
     32#include "IDBIndexBackendInterface.h"
    3233#include "IDBKey.h"
    3334#include "IDBKeyRange.h"
     
    5960
    6061    // Implement the IDBObjectStore IDL
     62    int64_t id() const { return m_metadata.id; }
    6163    const String name() const { return m_metadata.name; }
    6264    PassRefPtr<IDBAny> keyPathAny() const { return IDBAny::create(m_metadata.keyPath); }
     
    105107    typedef HashMap<String, IndexKeys> IndexKeyMap;
    106108
     109    IDBDatabaseBackendInterface* backendDB() const;
     110
    107111private:
    108112    IDBObjectStore(const IDBObjectStoreMetadata&, PassRefPtr<IDBObjectStoreBackendInterface>, IDBTransaction*);
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp

    r138716 r138900  
    4545namespace WebCore {
    4646
    47 class IDBObjectStoreBackendImpl::ObjectStoreRetrievalOperation : public IDBTransactionBackendImpl::Operation {
    48 public:
    49     static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
    50     {
    51         return adoptPtr(new ObjectStoreRetrievalOperation(objectStore, keyRange, callbacks));
    52     }
    53     virtual void perform(IDBTransactionBackendImpl*);
    54 private:
    55     ObjectStoreRetrievalOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
    56         : m_objectStore(objectStore)
    57         , m_keyRange(keyRange)
    58         , m_callbacks(callbacks)
    59     {
    60     }
    61 
    62     RefPtr<IDBObjectStoreBackendImpl> m_objectStore;
    63     RefPtr<IDBKeyRange> m_keyRange;
    64     RefPtr<IDBCallbacks> m_callbacks;
    65 };
    66 
    67 class IDBObjectStoreBackendImpl::ObjectStoreStorageOperation : public IDBTransactionBackendImpl::Operation {
    68 public:
    69     static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, PassOwnPtr<Vector<int64_t> > popIndexIds, PassOwnPtr<Vector<IndexKeys> > popIndexKeys)
    70     {
    71         return adoptPtr(new ObjectStoreStorageOperation(objectStore, value, key, putMode, callbacks, popIndexIds, popIndexKeys));
    72     }
    73     virtual void perform(IDBTransactionBackendImpl*);
    74 private:
    75     ObjectStoreStorageOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, PassOwnPtr<Vector<int64_t> > popIndexIds, PassOwnPtr<Vector<IndexKeys> > popIndexKeys)
    76         : m_objectStore(objectStore)
    77         , m_value(value)
    78         , m_key(key)
    79         , m_putMode(putMode)
    80         , m_callbacks(callbacks)
    81         , m_popIndexIds(popIndexIds)
    82         , m_popIndexKeys(popIndexKeys)
    83     {
    84     }
    85 
    86     RefPtr<IDBObjectStoreBackendImpl> m_objectStore;
    87     RefPtr<SerializedScriptValue> m_value;
    88     RefPtr<IDBKey> m_key;
    89     PutMode m_putMode;
    90     RefPtr<IDBCallbacks> m_callbacks;
    91     OwnPtr<Vector<int64_t> > m_popIndexIds;
    92     OwnPtr<Vector<IndexKeys> > m_popIndexKeys;
    93 };
    94 
    95 class IDBObjectStoreBackendImpl::ObjectStoreIndexesReadyOperation : public IDBTransactionBackendImpl::Operation {
    96 public:
    97     static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassOwnPtr<Vector<int64_t> > popIndexIds)
    98     {
    99         return adoptPtr(new ObjectStoreIndexesReadyOperation(objectStore, popIndexIds));
    100     }
    101     virtual void perform(IDBTransactionBackendImpl*);
    102 private:
    103     ObjectStoreIndexesReadyOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassOwnPtr<Vector<int64_t> > popIndexIds)
    104         : m_objectStore(objectStore)
    105         , m_popIndexIds(popIndexIds)
    106     {
    107     }
    108 
    109     RefPtr<IDBObjectStoreBackendImpl> m_objectStore;
    110     OwnPtr<Vector<int64_t> > m_popIndexIds;
    111 };
    112 
    113 class IDBObjectStoreBackendImpl::ObjectStoreDeletionOperation : public IDBTransactionBackendImpl::Operation {
    114 public:
    115     static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
    116     {
    117         return adoptPtr(new ObjectStoreDeletionOperation(objectStore, keyRange, callbacks));
    118     }
    119     virtual void perform(IDBTransactionBackendImpl*);
    120 private:
    121     ObjectStoreDeletionOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
    122         : m_objectStore(objectStore)
    123         , m_keyRange(keyRange)
    124         , m_callbacks(callbacks)
    125     {
    126     }
    127 
    128     RefPtr<IDBObjectStoreBackendImpl> m_objectStore;
    129     RefPtr<IDBKeyRange> m_keyRange;
    130     RefPtr<IDBCallbacks> m_callbacks;
    131 };
    132 
    133 class IDBObjectStoreBackendImpl::ObjectStoreClearOperation : public IDBTransactionBackendImpl::Operation {
    134 public:
    135     static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBCallbacks> callbacks)
    136     {
    137         return adoptPtr(new ObjectStoreClearOperation(objectStore, callbacks));
    138     }
    139     virtual void perform(IDBTransactionBackendImpl*);
    140 private:
    141     ObjectStoreClearOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBCallbacks> callbacks)
    142         : m_objectStore(objectStore)
    143         , m_callbacks(callbacks)
    144     {
    145     }
    146 
    147     RefPtr<IDBObjectStoreBackendImpl> m_objectStore;
    148     RefPtr<IDBCallbacks> m_callbacks;
    149 };
    150 
    15147class IDBObjectStoreBackendImpl::CreateIndexOperation : public IDBTransactionBackendImpl::Operation {
    15248public:
     
    18581};
    18682
    187 class IDBObjectStoreBackendImpl::OpenObjectStoreCursorOperation : public IDBTransactionBackendImpl::Operation {
    188 public:
    189     static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, IDBCursor::Direction direction, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface::TaskType taskType)
    190     {
    191         return adoptPtr(new OpenObjectStoreCursorOperation(objectStore, range, direction, callbacks, taskType));
    192     }
    193     virtual void perform(IDBTransactionBackendImpl*);
    194 private:
    195     OpenObjectStoreCursorOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, IDBCursor::Direction direction, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface::TaskType taskType)
    196         : m_objectStore(objectStore)
    197         , m_range(range)
    198         , m_direction(direction)
    199         , m_callbacks(callbacks)
    200         , m_taskType(taskType)
    201     {
    202     }
    203 
    204     RefPtr<IDBObjectStoreBackendImpl> m_objectStore;
    205     RefPtr<IDBKeyRange> m_range;
    206     IDBCursor::Direction m_direction;
    207     RefPtr<IDBCallbacks> m_callbacks;
    208     IDBTransactionBackendInterface::TaskType m_taskType;
    209 };
    210 
    211 class IDBObjectStoreBackendImpl::ObjectStoreCountOperation : public IDBTransactionBackendImpl::Operation {
    212 public:
    213     static PassOwnPtr<IDBTransactionBackendImpl::Operation> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks)
    214     {
    215         return adoptPtr(new ObjectStoreCountOperation(objectStore, range, callbacks));
    216     }
    217     virtual void perform(IDBTransactionBackendImpl*);
    218 private:
    219     ObjectStoreCountOperation(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks)
    220         : m_objectStore(objectStore)
    221         , m_range(range)
    222         , m_callbacks(callbacks)
    223     {
    224     }
    225 
    226     RefPtr<IDBObjectStoreBackendImpl> m_objectStore;
    227     RefPtr<IDBKeyRange> m_range;
    228     RefPtr<IDBCallbacks> m_callbacks;
    229 };
    230 
    23183class IDBObjectStoreBackendImpl::CreateIndexAbortOperation : public IDBTransactionBackendImpl::Operation {
    23284public:
     
    283135        metadata.indexes.set(it->key, it->value->metadata());
    284136    return metadata;
    285 }
    286 
    287 void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
    288 {
    289     IDB_TRACE("IDBObjectStoreBackendImpl::get");
    290     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
    291     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
    292     transaction->scheduleTask(ObjectStoreRetrievalOperation::create(this, keyRange, callbacks));
    293 }
    294 
    295 void IDBObjectStoreBackendImpl::ObjectStoreRetrievalOperation::perform(IDBTransactionBackendImpl* transaction)
    296 {
    297     IDB_TRACE("ObjectStoreRetrievalOperation");
    298     RefPtr<IDBKey> key;
    299     if (m_keyRange->isOnlyKey())
    300         key = m_keyRange->lower();
    301     else {
    302         RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_objectStore->backingStore()->openObjectStoreCursor(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), m_keyRange.get(), IDBCursor::NEXT);
    303         if (!backingStoreCursor) {
    304             m_callbacks->onSuccess();
    305             return;
    306         }
    307         key = backingStoreCursor->key();
    308     }
    309 
    310     Vector<uint8_t> wireData;
    311     bool ok = m_objectStore->backingStore()->getRecord(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), *key, wireData);
    312     if (!ok) {
    313         m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
    314         return;
    315     }
    316     if (wireData.isEmpty()) {
    317         m_callbacks->onSuccess();
    318         return;
    319     }
    320 
    321     if (m_objectStore->autoIncrement() && !m_objectStore->keyPath().isNull()) {
    322         m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(wireData), key, m_objectStore->keyPath());
    323         return;
    324     }
    325     m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(wireData));
    326 }
    327 
    328 void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, PutMode putMode, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys)
    329 {
    330     IDB_TRACE("IDBObjectStoreBackendImpl::put");
    331 
    332     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
    333     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
    334     ASSERT(transaction->mode() != IDBTransaction::READ_ONLY);
    335 
    336     OwnPtr<Vector<int64_t> > newIndexIds = adoptPtr(new Vector<int64_t>(indexIds));
    337     OwnPtr<Vector<IndexKeys> > newIndexKeys = adoptPtr(new Vector<IndexKeys>(indexKeys));
    338 
    339     ASSERT(autoIncrement() || key.get());
    340 
    341     transaction->scheduleTask(ObjectStoreStorageOperation::create(this, value, key, putMode, callbacks, newIndexIds.release(), newIndexKeys.release()));
    342137}
    343138
     
    418213}
    419214
    420 void IDBObjectStoreBackendImpl::setIndexKeys(PassRefPtr<IDBKey> prpPrimaryKey, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys, IDBTransactionBackendInterface* transactionPtr)
    421 {
    422     IDB_TRACE("IDBObjectStoreBackendImpl::setIndexKeys");
    423     RefPtr<IDBKey> primaryKey = prpPrimaryKey;
    424     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
    425     if (transaction->isFinished())
    426         return;
    427 
    428     // FIXME: This method could be asynchronous, but we need to evaluate if it's worth the extra complexity.
    429     IDBBackingStore::RecordIdentifier recordIdentifier;
    430     bool found = false;
    431     bool ok = backingStore()->keyExistsInObjectStore(transaction->backingStoreTransaction(), databaseId(), id(), *primaryKey, &recordIdentifier, found);
    432     if (!ok) {
    433         LOG_ERROR("keyExistsInObjectStore reported an error");
    434         transaction->abort(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error setting index keys."));
    435         return;
    436     }
    437     if (!found) {
    438         RefPtr<IDBDatabaseError> error = IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error setting index keys for object store '%s'.", name().utf8().data()));
    439         transaction->abort(error.release());
    440         return;
    441     }
    442 
    443     Vector<OwnPtr<IndexWriter> > indexWriters;
    444     String errorMessage;
    445     bool obeysConstraints = false;
    446     RefPtr<IDBBackingStore> store = backingStore();
    447     bool backingStoreSuccess = makeIndexWriters(transaction, store.get(), databaseId(), metadata(), primaryKey, false, indexIds, indexKeys, &indexWriters, &errorMessage, obeysConstraints);
    448     if (!backingStoreSuccess) {
    449         transaction->abort(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys."));
    450         return;
    451     }
    452     if (!obeysConstraints) {
    453         transaction->abort(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage));
    454         return;
    455     }
    456 
    457     for (size_t i = 0; i < indexWriters.size(); ++i) {
    458         IndexWriter* indexWriter = indexWriters[i].get();
    459         indexWriter->writeIndexKeys(recordIdentifier, *backingStore(), transaction->backingStoreTransaction(), databaseId(), m_metadata.id);
    460     }
    461 }
    462 
    463 void IDBObjectStoreBackendImpl::setIndexesReady(const Vector<int64_t>& indexIds, IDBTransactionBackendInterface* transactionInterface)
    464 {
    465     IDB_TRACE("IDBObjectStoreBackendImpl::setIndexesReady");
    466 
    467     OwnPtr<Vector<int64_t> > newIndexIds = adoptPtr(new Vector<int64_t>(indexIds));
    468     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionInterface);
    469     if (transaction->isFinished())
    470         return;
    471 
    472     if (!transaction->scheduleTask(IDBTransactionBackendInterface::PreemptiveTask, ObjectStoreIndexesReadyOperation::create(this, newIndexIds.release())))
    473         ASSERT_NOT_REACHED();
    474 }
    475 
    476 void IDBObjectStoreBackendImpl::ObjectStoreIndexesReadyOperation::perform(IDBTransactionBackendImpl* transaction)
    477 {
    478     IDB_TRACE("ObjectStoreIndexesReadyOperation");
    479     for (size_t i = 0; i < m_popIndexIds->size(); ++i)
    480         transaction->didCompletePreemptiveEvent();
    481 }
    482 
    483 void IDBObjectStoreBackendImpl::ObjectStoreStorageOperation::perform(IDBTransactionBackendImpl* transaction)
    484 {
    485     IDB_TRACE("ObjectStoreStorageOperation");
    486     ASSERT(transaction->mode() != IDBTransaction::READ_ONLY);
    487     ASSERT(m_popIndexIds && m_popIndexKeys && m_popIndexIds->size() == m_popIndexKeys->size());
    488     const bool autoIncrement = m_objectStore->autoIncrement();
    489     bool keyWasGenerated = false;
    490 
    491     if (m_putMode != CursorUpdate && autoIncrement && !m_key) {
    492         RefPtr<IDBKey> autoIncKey = m_objectStore->generateKey(transaction);
    493         keyWasGenerated = true;
    494         if (!autoIncKey->isValid()) {
    495             m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Maximum key generator value reached."));
    496             return;
    497         }
    498         m_key = autoIncKey;
    499     }
    500 
    501     ASSERT(m_key && m_key->isValid());
    502 
    503     IDBObjectStoreMetadata objectStoreMetadata = m_objectStore->metadata();
    504     IDBBackingStore::RecordIdentifier recordIdentifier;
    505     RefPtr<IDBBackingStore> backingStore = m_objectStore->backingStore();
    506     if (m_putMode == AddOnly) {
    507         bool found = false;
    508         bool ok = backingStore->keyExistsInObjectStore(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), *m_key, &recordIdentifier, found);
    509         if (!ok) {
    510             m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error checking key existence."));
    511             return;
    512         }
    513         if (found) {
    514             m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Key already exists in the object store."));
    515             return;
    516         }
    517     }
    518 
    519     Vector<OwnPtr<IndexWriter> > indexWriters;
    520     String errorMessage;
    521     bool obeysConstraints = false;
    522     bool backingStoreSuccess = makeIndexWriters(transaction, backingStore.get(), m_objectStore->databaseId(), objectStoreMetadata, m_key, keyWasGenerated, *m_popIndexIds, *m_popIndexKeys, &indexWriters, &errorMessage, obeysConstraints);
    523     if (!backingStoreSuccess) {
    524         m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys."));
    525         return;
    526     }
    527     if (!obeysConstraints) {
    528         m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage));
    529         return;
    530     }
    531 
    532     // Before this point, don't do any mutation.  After this point, rollback the transaction in case of error.
    533 
    534     backingStoreSuccess = m_objectStore->backingStore()->putRecord(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), *m_key, m_value->toWireBytes(), &recordIdentifier);
    535     if (!backingStoreSuccess) {
    536         m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error performing put/add."));
    537         return;
    538     }
    539 
    540     for (size_t i = 0; i < indexWriters.size(); ++i) {
    541         IndexWriter* indexWriter = indexWriters[i].get();
    542         indexWriter->writeIndexKeys(recordIdentifier, *m_objectStore->backingStore(), transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->m_metadata.id);
    543     }
    544 
    545     if (autoIncrement && m_putMode != CursorUpdate && m_key->type() == IDBKey::NumberType) {
    546         bool ok = m_objectStore->updateKeyGenerator(transaction, m_key.get(), !keyWasGenerated);
    547         if (!ok) {
    548             m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error updating key generator."));
    549             return;
    550         }
    551     }
    552 
    553     m_callbacks->onSuccess(m_key.release());
    554 }
    555 
    556 void IDBObjectStoreBackendImpl::deleteFunction(PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
    557 {
    558     IDB_TRACE("IDBObjectStoreBackendImpl::delete");
    559 
    560     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
    561     ASSERT(transaction->mode() != IDBTransaction::READ_ONLY);
    562     transaction->scheduleTask(ObjectStoreDeletionOperation::create(this, keyRange, callbacks));
    563 }
    564 
    565 void IDBObjectStoreBackendImpl::ObjectStoreDeletionOperation::perform(IDBTransactionBackendImpl* transaction)
    566 {
    567     IDB_TRACE("ObjectStoreDeletionOperation");
    568 
    569     RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_objectStore->backingStore()->openObjectStoreCursor(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), m_keyRange.get(), IDBCursor::NEXT);
    570     if (backingStoreCursor) {
    571 
    572         do {
    573             m_objectStore->backingStore()->deleteRecord(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), backingStoreCursor->recordIdentifier());
    574 
    575         } while (backingStoreCursor->continueFunction(0));
    576     }
    577 
    578     m_callbacks->onSuccess();
    579 }
    580 
    581 void IDBObjectStoreBackendImpl::clear(PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
    582 {
    583     IDB_TRACE("IDBObjectStoreBackendImpl::clear");
    584 
    585     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
    586     ASSERT(transaction->mode() != IDBTransaction::READ_ONLY);
    587     transaction->scheduleTask(ObjectStoreClearOperation::create(this, callbacks));
    588 }
    589 
    590 void IDBObjectStoreBackendImpl::ObjectStoreClearOperation::perform(IDBTransactionBackendImpl* transaction)
    591 {
    592     IDB_TRACE("ObjectStoreClearOperation");
    593     m_objectStore->backingStore()->clearObjectStore(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id());
    594     m_callbacks->onSuccess();
    595 }
    596 
    597215PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::createIndex(int64_t id, const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
    598216{
    599217    ASSERT_WITH_MESSAGE(!m_indexes.contains(id), "Indexes already contain '%s'", name.utf8().data());
    600218
    601     RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(m_database, this, IDBIndexMetadata(name, id, keyPath, unique, multiEntry));
     219    RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(m_database, IDBIndexMetadata(name, id, keyPath, unique, multiEntry));
    602220    ASSERT(index->name() == name);
    603221
     
    653271}
    654272
    655 void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> range, IDBCursor::Direction direction, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface::TaskType taskType, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
    656 {
    657     IDB_TRACE("IDBObjectStoreBackendImpl::openCursor");
    658     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
    659     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
    660     transaction->scheduleTask(OpenObjectStoreCursorOperation::create(this, range, direction, callbacks, taskType));
    661 }
    662 
    663 void IDBObjectStoreBackendImpl::OpenObjectStoreCursorOperation::perform(IDBTransactionBackendImpl* transaction)
    664 {
    665     IDB_TRACE("OpenObjectStoreCursor");
    666 
    667     RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_objectStore->backingStore()->openObjectStoreCursor(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), m_range.get(), m_direction);
    668     // The frontend has begun indexing, so this pauses the transaction
    669     // until the indexing is complete. This can't happen any earlier
    670     // because we don't want to switch to early mode in case multiple
    671     // indexes are being created in a row, with put()'s in between.
    672     if (m_taskType == IDBTransactionBackendInterface::PreemptiveTask)
    673         transaction->addPreemptiveEvent();
    674     if (!backingStoreCursor) {
    675         m_callbacks->onSuccess(static_cast<SerializedScriptValue*>(0));
    676         return;
    677     }
    678 
    679     RefPtr<IDBCursorBackendImpl> cursor = IDBCursorBackendImpl::create(backingStoreCursor.release(), IDBCursorBackendInterface::KeyAndValue, m_taskType, transaction, m_objectStore.get());
    680     m_callbacks->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value());
    681 }
    682 
    683 void IDBObjectStoreBackendImpl::count(PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode&)
    684 {
    685     IDB_TRACE("IDBObjectStoreBackendImpl::count");
    686     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
    687     RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionPtr);
    688     transaction->scheduleTask(ObjectStoreCountOperation::create(this, range, callbacks));
    689 }
    690 
    691 void IDBObjectStoreBackendImpl::ObjectStoreCountOperation::perform(IDBTransactionBackendImpl* transaction)
    692 {
    693     IDB_TRACE("ObjectStoreCountOperation");
    694     uint32_t count = 0;
    695     RefPtr<IDBBackingStore::Cursor> backingStoreCursor = m_objectStore->backingStore()->openObjectStoreKeyCursor(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), m_range.get(), IDBCursor::NEXT);
    696     if (!backingStoreCursor) {
    697         m_callbacks->onSuccess(count);
    698         return;
    699     }
    700 
    701     do {
    702         ++count;
    703     } while (backingStoreCursor->continueFunction(0));
    704 
    705     m_callbacks->onSuccess(count);
    706 }
    707 
    708273void IDBObjectStoreBackendImpl::loadIndexes()
    709274{
     
    711276
    712277    for (size_t i = 0; i < indexes.size(); ++i)
    713         m_indexes.set(indexes[i].id, IDBIndexBackendImpl::create(m_database, this, indexes[i]));
     278        m_indexes.set(indexes[i].id, IDBIndexBackendImpl::create(m_database, indexes[i]));
    714279}
    715280
     
    728293}
    729294
    730 PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::generateKey(PassRefPtr<IDBTransactionBackendImpl> transaction)
     295PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::generateKey(PassRefPtr<IDBBackingStore> backingStore, PassRefPtr<IDBTransactionBackendImpl> transaction, int64_t databaseId, int64_t objectStoreId)
    731296{
    732297    const int64_t maxGeneratorValue = 9007199254740992LL; // Maximum integer storable as ECMAScript number.
    733298    int64_t currentNumber;
    734     bool ok = backingStore()->getKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId(), id(), currentNumber);
     299    bool ok = backingStore->getKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId, objectStoreId, currentNumber);
    735300    if (!ok) {
    736301        LOG_ERROR("Failed to getKeyGeneratorCurrentNumber");
     
    743308}
    744309
    745 bool IDBObjectStoreBackendImpl::updateKeyGenerator(PassRefPtr<IDBTransactionBackendImpl> transaction, const IDBKey* key, bool checkCurrent)
     310bool IDBObjectStoreBackendImpl::updateKeyGenerator(PassRefPtr<IDBBackingStore> backingStore, PassRefPtr<IDBTransactionBackendImpl> transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey* key, bool checkCurrent)
    746311{
    747312    ASSERT(key && key->type() == IDBKey::NumberType);
    748     return backingStore()->maybeUpdateKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId(), id(), static_cast<int64_t>(floor(key->number())) + 1, checkCurrent);
     313    return backingStore->maybeUpdateKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId, objectStoreId, static_cast<int64_t>(floor(key->number())) + 1, checkCurrent);
    749314}
    750315
  • trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.h

    r138290 r138900  
    6363
    6464    // IDBObjectStoreBackendInterface
    65     virtual void get(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
    66     virtual void put(PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, const Vector<int64_t>&, const Vector<IndexKeys>&);
     65    virtual void get(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); }
     66    virtual void put(PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, const Vector<int64_t>&, const Vector<IndexKeys>&) { ASSERT_NOT_REACHED(); }
    6767
    68     virtual void deleteFunction(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
    69     virtual void clear(PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
     68    virtual void deleteFunction(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); }
     69    virtual void clear(PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); }
    7070
    7171    virtual PassRefPtr<IDBIndexBackendInterface> createIndex(int64_t, const String& name, const IDBKeyPath&, bool unique, bool multiEntry, IDBTransactionBackendInterface*, ExceptionCode&);
    72     virtual void setIndexKeys(PassRefPtr<IDBKey> prpPrimaryKey, const Vector<int64_t>&, const Vector<IndexKeys>&, IDBTransactionBackendInterface*);
    73     virtual void setIndexesReady(const Vector<int64_t>&, IDBTransactionBackendInterface*);
     72    virtual void setIndexKeys(PassRefPtr<IDBKey> prpPrimaryKey, const Vector<int64_t>&, const Vector<IndexKeys>&, IDBTransactionBackendInterface*) { ASSERT_NOT_REACHED(); }
     73    virtual void setIndexesReady(const Vector<int64_t>&, IDBTransactionBackendInterface*) { ASSERT_NOT_REACHED(); }
    7474    virtual PassRefPtr<IDBIndexBackendInterface> index(int64_t);
    7575    virtual void deleteIndex(int64_t, IDBTransactionBackendInterface*, ExceptionCode&);
    7676
    77     virtual void openCursor(PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface::TaskType, IDBTransactionBackendInterface*, ExceptionCode&);
    78     virtual void count(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
     77    virtual void openCursor(PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface::TaskType, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); }
     78    virtual void count(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) { ASSERT_NOT_REACHED(); }
    7979
    8080    static bool populateIndex(IDBBackingStore&, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBIndexBackendImpl>);
    81 
    82     const IndexMap::iterator iterIndexesBegin() { return m_indexes.begin(); };
    83     const IndexMap::iterator iterIndexesEnd() { return m_indexes.end(); };
    8481
    8582    IDBObjectStoreMetadata metadata() const;
     
    115112    static bool makeIndexWriters(PassRefPtr<IDBTransactionBackendImpl>, IDBBackingStore*, int64_t databaseId, const IDBObjectStoreMetadata&, PassRefPtr<IDBKey> primaryKey, bool keyWasGenerated, const Vector<int64_t>& indexIds, const Vector<IDBObjectStoreBackendInterface::IndexKeys>&, Vector<OwnPtr<IndexWriter> >* indexWriters, String* errorMessage, bool& completed) WARN_UNUSED_RETURN;
    116113
     114    static PassRefPtr<IDBKey> generateKey(PassRefPtr<IDBBackingStore>, PassRefPtr<IDBTransactionBackendImpl>, int64_t databaseId, int64_t objectStoreId);
     115    static bool updateKeyGenerator(PassRefPtr<IDBBackingStore>, PassRefPtr<IDBTransactionBackendImpl>, int64_t databaseId, int64_t objectStoreId, const IDBKey*, bool checkCurrent);
     116
    117117private:
    118118    IDBObjectStoreBackendImpl(const IDBDatabaseBackendImpl*, const IDBObjectStoreMetadata&);
    119119
    120120    void loadIndexes();
    121     PassRefPtr<IDBKey> generateKey(PassRefPtr<IDBTransactionBackendImpl>);
    122     bool updateKeyGenerator(PassRefPtr<IDBTransactionBackendImpl>, const IDBKey*, bool checkCurrent);
    123121
    124     class ObjectStoreRetrievalOperation;
    125     class ObjectStoreStorageOperation;
    126     class ObjectStoreIndexesReadyOperation;
    127     class ObjectStoreDeletionOperation;
    128     class ObjectStoreClearOperation;
    129122    class CreateIndexOperation;
    130123    class DeleteIndexOperation;
    131     class OpenObjectStoreCursorOperation;
    132     class ObjectStoreCountOperation;
    133124
    134125    // When a "versionchange" transaction aborts, these restore the back-end object hierarchy.
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp

    r136894 r138900  
    464464}
    465465
     466IDBDatabaseBackendInterface* IDBTransaction::backendDB() const
     467{
     468    return db()->backend();
     469}
     470
    466471}
    467472
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h

    r138674 r138900  
    4848class IDBOpenDBRequest;
    4949class IDBTransactionBackendInterface;
     50class IDBDatabaseBackendInterface;
    5051struct IDBObjectStoreMetadata;
    5152
     
    7273
    7374    IDBTransactionBackendInterface* backend() const;
     75    IDBDatabaseBackendInterface* backendDB() const;
     76
    7477    int64_t id() const { return m_id; }
    7578    bool isActive() const { return m_state == Active; }
  • trunk/Source/WebCore/Modules/indexeddb/IDBTransactionBackendImpl.h

    r136992 r138900  
    7878    int64_t id() const { return m_id; }
    7979
     80    IDBDatabaseBackendImpl* database() const { return m_database.get(); }
     81
    8082private:
    8183    IDBTransactionBackendImpl(int64_t id, const HashSet<int64_t>& objectStoreIds, IDBTransaction::Mode, IDBDatabaseBackendImpl*);
  • trunk/Source/WebKit/chromium/ChangeLog

    r138898 r138900  
     12013-01-05  Alec Flett  <alecflett@chromium.org>
     2
     3        IndexedDB: Migrate backend ObjectStore calls to use transaction id
     4        https://bugs.webkit.org/show_bug.cgi?id=102741
     5
     6        Reviewed by Tony Chang.
     7
     8        Fix a bug where an array was initialized with a large empty buffer,
     9        clean up whitespace, and update to match signatures that changed
     10        in WebCore.
     11
     12        * public/WebIDBDatabase.h:
     13        (WebKit::WebIDBDatabase::clear):
     14        * src/WebIDBDatabaseImpl.cpp:
     15        (WebKit::WebIDBDatabaseImpl::put):
     16        * src/WebIDBIndexImpl.cpp:
     17        * tests/IDBDatabaseBackendTest.cpp:
     18
    1192013-01-05  Alec Flett  <alecflett@chromium.org>
    220
  • trunk/Source/WebKit/chromium/public/WebIDBDatabase.h

    r138898 r138900  
    9393    virtual void count(long long transactionId, long long objectStoreId, long long indexId, const WebIDBKeyRange&, WebIDBCallbacks*) { WEBKIT_ASSERT_NOT_REACHED(); }
    9494    virtual void deleteRange(long long transactionId, long long objectStoreId, const WebIDBKeyRange&, WebIDBCallbacks*) { WEBKIT_ASSERT_NOT_REACHED(); }
    95     virtual void clear(long long transactionId, long long objectStoreId, WebIDBCallbacks*)  { WEBKIT_ASSERT_NOT_REACHED(); }
     95    virtual void clear(long long transactionId, long long objectStoreId, WebIDBCallbacks*) { WEBKIT_ASSERT_NOT_REACHED(); }
    9696
    9797protected:
  • trunk/Source/WebKit/chromium/src/WebIDBDatabaseImpl.cpp

    r138898 r138900  
    165165    }
    166166
    167     Vector<uint8_t> valueBuffer(value->size());
     167    Vector<uint8_t> valueBuffer;
    168168    valueBuffer.append(value->data(), value->size());
    169169    m_databaseBackend->put(transactionId, objectStoreId, &valueBuffer, key, static_cast<IDBDatabaseBackendInterface::PutMode>(putMode), IDBCallbacksProxy::create(adoptPtr(callbacks)), indexIds, indexKeys);
  • trunk/Source/WebKit/chromium/src/WebIDBIndexImpl.cpp

    r121183 r138900  
    3131#include "IDBCallbacksProxy.h"
    3232#include "IDBIndex.h"
     33#include "IDBIndexBackendInterface.h"
    3334#include "IDBKeyRange.h"
    3435#include "WebIDBCallbacks.h"
  • trunk/Source/WebKit/chromium/tests/IDBDatabaseBackendTest.cpp

    r138898 r138900  
    6363    const bool unique = false;
    6464    const bool multiEntry = false;
    65     RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(db.get(), store.get(), IDBIndexMetadata("index", -1, IDBKeyPath("keyPath"), unique, multiEntry));
     65    RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(db.get(), IDBIndexMetadata("index", -1, IDBKeyPath("keyPath"), unique, multiEntry));
    6666    EXPECT_GT(backingStore->refCount(), 1);
    6767
Note: See TracChangeset for help on using the changeset viewer.