Changeset 87370 in webkit


Ignore:
Timestamp:
May 26, 2011 1:48:09 AM (13 years ago)
Author:
hans@chromium.org
Message:

2011-05-25 Hans Wennborg <hans@chromium.org>

Reviewed by Steve Block.

IndexedDB: Support LevelDB transactions.
https://bugs.webkit.org/show_bug.cgi?id=61270

Introduce LevelDBTransaction, which implements in-memory transaction
support on top of LevelDB, and hook this up for IndexedDB to use.

This is all covered by existing tests.

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • WebCore.gypi:
  • WebCore.pro:
  • WebCore.xcodeproj/project.pbxproj:
  • platform/leveldb/LevelDBDatabase.cpp: (WebCore::LevelDBDatabase::open): (WebCore::LevelDBDatabase::put): (WebCore::LevelDBDatabase::remove): (WebCore::LevelDBDatabase::write): (WebCore::IteratorImpl::IteratorImpl): (WebCore::IteratorImpl::isValid): (WebCore::IteratorImpl::seekToLast): (WebCore::IteratorImpl::seek): (WebCore::IteratorImpl::next): (WebCore::IteratorImpl::prev): (WebCore::IteratorImpl::key): (WebCore::IteratorImpl::value): (WebCore::LevelDBDatabase::createIterator): (WebCore::LevelDBDatabase::comparator):
  • platform/leveldb/LevelDBDatabase.h:
  • platform/leveldb/LevelDBIterator.h: (WebCore::LevelDBIterator::~LevelDBIterator):
  • platform/leveldb/LevelDBTransaction.cpp: Added. (WebCore::LevelDBTransaction::create): (WebCore::LevelDBTransaction::LevelDBTransaction): (WebCore::LevelDBTransaction::clearTree): (WebCore::LevelDBTransaction::~LevelDBTransaction): (WebCore::makeVector): (WebCore::LevelDBTransaction::set): (WebCore::LevelDBTransaction::put): (WebCore::LevelDBTransaction::remove): (WebCore::LevelDBTransaction::get): (WebCore::LevelDBTransaction::commit): (WebCore::LevelDBTransaction::rollback): (WebCore::LevelDBTransaction::createIterator): (WebCore::LevelDBTransaction::TreeIterator::create): (WebCore::LevelDBTransaction::TreeIterator::isValid): (WebCore::LevelDBTransaction::TreeIterator::seekToLast): (WebCore::LevelDBTransaction::TreeIterator::seek): (WebCore::LevelDBTransaction::TreeIterator::next): (WebCore::LevelDBTransaction::TreeIterator::prev): (WebCore::LevelDBTransaction::TreeIterator::key): (WebCore::LevelDBTransaction::TreeIterator::value): (WebCore::LevelDBTransaction::TreeIterator::isDeleted): (WebCore::LevelDBTransaction::TreeIterator::reset): (WebCore::LevelDBTransaction::TreeIterator::~TreeIterator): (WebCore::LevelDBTransaction::TreeIterator::TreeIterator): (WebCore::LevelDBTransaction::TransactionIterator::create): (WebCore::LevelDBTransaction::TransactionIterator::TransactionIterator): (WebCore::LevelDBTransaction::TransactionIterator::isValid): (WebCore::LevelDBTransaction::TransactionIterator::seekToLast): (WebCore::LevelDBTransaction::TransactionIterator::seek): (WebCore::LevelDBTransaction::TransactionIterator::next): (WebCore::LevelDBTransaction::TransactionIterator::prev): (WebCore::LevelDBTransaction::TransactionIterator::key): (WebCore::LevelDBTransaction::TransactionIterator::value): (WebCore::LevelDBTransaction::TransactionIterator::handleConflictsAndDeletes): (WebCore::LevelDBTransaction::TransactionIterator::setCurrentIteratorToSmallestKey): (WebCore::LevelDBTransaction::TransactionIterator::setCurrentIteratorToLargestKey): (WebCore::LevelDBTransaction::registerIterator): (WebCore::LevelDBTransaction::unregisterIterator): (WebCore::LevelDBTransaction::resetIterators):
  • platform/leveldb/LevelDBTransaction.h: Added. (WebCore::LevelDBTransaction::AVLTreeAbstractor::get_less): (WebCore::LevelDBTransaction::AVLTreeAbstractor::set_less): (WebCore::LevelDBTransaction::AVLTreeAbstractor::get_greater): (WebCore::LevelDBTransaction::AVLTreeAbstractor::set_greater): (WebCore::LevelDBTransaction::AVLTreeAbstractor::get_balance_factor): (WebCore::LevelDBTransaction::AVLTreeAbstractor::set_balance_factor): (WebCore::LevelDBTransaction::AVLTreeAbstractor::compare_key_key): (WebCore::LevelDBTransaction::AVLTreeAbstractor::compare_key_node): (WebCore::LevelDBTransaction::AVLTreeAbstractor::compare_node_node): (WebCore::LevelDBTransaction::AVLTreeAbstractor::null): (WebCore::LevelDBTransaction::TransactionIterator::~TransactionIterator):
  • platform/leveldb/LevelDBWriteBatch.cpp: (WebCore::LevelDBWriteBatch::create): (WebCore::LevelDBWriteBatch::LevelDBWriteBatch): (WebCore::LevelDBWriteBatch::~LevelDBWriteBatch): (WebCore::makeSlice): (WebCore::LevelDBWriteBatch::put): (WebCore::LevelDBWriteBatch::remove): (WebCore::LevelDBWriteBatch::clear):
  • storage/IDBLevelDBBackingStore.cpp: (WebCore::getInt): (WebCore::putInt): (WebCore::getString): (WebCore::putString): (WebCore::getNewObjectStoreId): (WebCore::IDBLevelDBBackingStore::createObjectStore): (WebCore::deleteRange): (WebCore::IDBLevelDBBackingStore::deleteObjectStore): (WebCore::IDBLevelDBBackingStore::getObjectStoreRecord): (WebCore::getNewVersionNumber): (WebCore::IDBLevelDBBackingStore::putObjectStoreRecord): (WebCore::IDBLevelDBBackingStore::clearObjectStore): (WebCore::IDBLevelDBBackingStore::deleteObjectStoreRecord): (WebCore::IDBLevelDBBackingStore::nextAutoIncrementNumber): (WebCore::IDBLevelDBBackingStore::keyExistsInObjectStore): (WebCore::IDBLevelDBBackingStore::forEachObjectStoreRecord): (WebCore::getNewIndexId): (WebCore::IDBLevelDBBackingStore::createIndex): (WebCore::IDBLevelDBBackingStore::putIndexDataForRecord): (WebCore::findGreatestKeyLessThan): (WebCore::versionExists): (WebCore::IDBLevelDBBackingStore::getPrimaryKeyViaIndex): (WebCore::IDBLevelDBBackingStore::keyExistsInIndex): (WebCore::findLastIndexKeyEqualTo): (WebCore::IDBLevelDBBackingStore::openObjectStoreCursor): (WebCore::IDBLevelDBBackingStore::openIndexKeyCursor): (WebCore::IDBLevelDBBackingStore::openIndexCursor): (WebCore::IDBLevelDBBackingStore::createTransaction): (WebCore::IDBLevelDBBackingStore::Transaction::create): (WebCore::IDBLevelDBBackingStore::Transaction::Transaction): (WebCore::IDBLevelDBBackingStore::Transaction::begin): (WebCore::IDBLevelDBBackingStore::Transaction::commit): (WebCore::IDBLevelDBBackingStore::Transaction::rollback):
  • storage/IDBLevelDBBackingStore.h:
  • storage/IDBTransactionBackendImpl.cpp: (WebCore::IDBTransactionBackendImpl::abort):
Location:
trunk/Source/WebCore
Files:
2 added
12 edited
1 copied
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/CMakeLists.txt

    r87293 r87370  
    14701470    LIST(APPEND WebCore_SOURCES
    14711471        platform/leveldb/LevelDBDatabase.cpp
    1472         platform/leveldb/LevelDBIterator.cpp
     1472        platform/leveldb/LevelDBTransaction.cpp
     1473        platform/leveldb/LevelDBWriteBatch.cpp
    14731474    )
    14741475ENDIF ()
  • trunk/Source/WebCore/ChangeLog

    r87368 r87370  
     12011-05-25  Hans Wennborg  <hans@chromium.org>
     2
     3        Reviewed by Steve Block.
     4
     5        IndexedDB: Support LevelDB transactions.
     6        https://bugs.webkit.org/show_bug.cgi?id=61270
     7
     8        Introduce LevelDBTransaction, which implements in-memory transaction
     9        support on top of LevelDB, and hook this up for IndexedDB to use.
     10
     11        This is all covered by existing tests.
     12
     13        * CMakeLists.txt:
     14        * GNUmakefile.list.am:
     15        * WebCore.gypi:
     16        * WebCore.pro:
     17        * WebCore.xcodeproj/project.pbxproj:
     18        * platform/leveldb/LevelDBDatabase.cpp:
     19        (WebCore::LevelDBDatabase::open):
     20        (WebCore::LevelDBDatabase::put):
     21        (WebCore::LevelDBDatabase::remove):
     22        (WebCore::LevelDBDatabase::write):
     23        (WebCore::IteratorImpl::IteratorImpl):
     24        (WebCore::IteratorImpl::isValid):
     25        (WebCore::IteratorImpl::seekToLast):
     26        (WebCore::IteratorImpl::seek):
     27        (WebCore::IteratorImpl::next):
     28        (WebCore::IteratorImpl::prev):
     29        (WebCore::IteratorImpl::key):
     30        (WebCore::IteratorImpl::value):
     31        (WebCore::LevelDBDatabase::createIterator):
     32        (WebCore::LevelDBDatabase::comparator):
     33        * platform/leveldb/LevelDBDatabase.h:
     34        * platform/leveldb/LevelDBIterator.h:
     35        (WebCore::LevelDBIterator::~LevelDBIterator):
     36        * platform/leveldb/LevelDBTransaction.cpp: Added.
     37        (WebCore::LevelDBTransaction::create):
     38        (WebCore::LevelDBTransaction::LevelDBTransaction):
     39        (WebCore::LevelDBTransaction::clearTree):
     40        (WebCore::LevelDBTransaction::~LevelDBTransaction):
     41        (WebCore::makeVector):
     42        (WebCore::LevelDBTransaction::set):
     43        (WebCore::LevelDBTransaction::put):
     44        (WebCore::LevelDBTransaction::remove):
     45        (WebCore::LevelDBTransaction::get):
     46        (WebCore::LevelDBTransaction::commit):
     47        (WebCore::LevelDBTransaction::rollback):
     48        (WebCore::LevelDBTransaction::createIterator):
     49        (WebCore::LevelDBTransaction::TreeIterator::create):
     50        (WebCore::LevelDBTransaction::TreeIterator::isValid):
     51        (WebCore::LevelDBTransaction::TreeIterator::seekToLast):
     52        (WebCore::LevelDBTransaction::TreeIterator::seek):
     53        (WebCore::LevelDBTransaction::TreeIterator::next):
     54        (WebCore::LevelDBTransaction::TreeIterator::prev):
     55        (WebCore::LevelDBTransaction::TreeIterator::key):
     56        (WebCore::LevelDBTransaction::TreeIterator::value):
     57        (WebCore::LevelDBTransaction::TreeIterator::isDeleted):
     58        (WebCore::LevelDBTransaction::TreeIterator::reset):
     59        (WebCore::LevelDBTransaction::TreeIterator::~TreeIterator):
     60        (WebCore::LevelDBTransaction::TreeIterator::TreeIterator):
     61        (WebCore::LevelDBTransaction::TransactionIterator::create):
     62        (WebCore::LevelDBTransaction::TransactionIterator::TransactionIterator):
     63        (WebCore::LevelDBTransaction::TransactionIterator::isValid):
     64        (WebCore::LevelDBTransaction::TransactionIterator::seekToLast):
     65        (WebCore::LevelDBTransaction::TransactionIterator::seek):
     66        (WebCore::LevelDBTransaction::TransactionIterator::next):
     67        (WebCore::LevelDBTransaction::TransactionIterator::prev):
     68        (WebCore::LevelDBTransaction::TransactionIterator::key):
     69        (WebCore::LevelDBTransaction::TransactionIterator::value):
     70        (WebCore::LevelDBTransaction::TransactionIterator::handleConflictsAndDeletes):
     71        (WebCore::LevelDBTransaction::TransactionIterator::setCurrentIteratorToSmallestKey):
     72        (WebCore::LevelDBTransaction::TransactionIterator::setCurrentIteratorToLargestKey):
     73        (WebCore::LevelDBTransaction::registerIterator):
     74        (WebCore::LevelDBTransaction::unregisterIterator):
     75        (WebCore::LevelDBTransaction::resetIterators):
     76        * platform/leveldb/LevelDBTransaction.h: Added.
     77        (WebCore::LevelDBTransaction::AVLTreeAbstractor::get_less):
     78        (WebCore::LevelDBTransaction::AVLTreeAbstractor::set_less):
     79        (WebCore::LevelDBTransaction::AVLTreeAbstractor::get_greater):
     80        (WebCore::LevelDBTransaction::AVLTreeAbstractor::set_greater):
     81        (WebCore::LevelDBTransaction::AVLTreeAbstractor::get_balance_factor):
     82        (WebCore::LevelDBTransaction::AVLTreeAbstractor::set_balance_factor):
     83        (WebCore::LevelDBTransaction::AVLTreeAbstractor::compare_key_key):
     84        (WebCore::LevelDBTransaction::AVLTreeAbstractor::compare_key_node):
     85        (WebCore::LevelDBTransaction::AVLTreeAbstractor::compare_node_node):
     86        (WebCore::LevelDBTransaction::AVLTreeAbstractor::null):
     87        (WebCore::LevelDBTransaction::TransactionIterator::~TransactionIterator):
     88        * platform/leveldb/LevelDBWriteBatch.cpp:
     89        (WebCore::LevelDBWriteBatch::create):
     90        (WebCore::LevelDBWriteBatch::LevelDBWriteBatch):
     91        (WebCore::LevelDBWriteBatch::~LevelDBWriteBatch):
     92        (WebCore::makeSlice):
     93        (WebCore::LevelDBWriteBatch::put):
     94        (WebCore::LevelDBWriteBatch::remove):
     95        (WebCore::LevelDBWriteBatch::clear):
     96        * storage/IDBLevelDBBackingStore.cpp:
     97        (WebCore::getInt):
     98        (WebCore::putInt):
     99        (WebCore::getString):
     100        (WebCore::putString):
     101        (WebCore::getNewObjectStoreId):
     102        (WebCore::IDBLevelDBBackingStore::createObjectStore):
     103        (WebCore::deleteRange):
     104        (WebCore::IDBLevelDBBackingStore::deleteObjectStore):
     105        (WebCore::IDBLevelDBBackingStore::getObjectStoreRecord):
     106        (WebCore::getNewVersionNumber):
     107        (WebCore::IDBLevelDBBackingStore::putObjectStoreRecord):
     108        (WebCore::IDBLevelDBBackingStore::clearObjectStore):
     109        (WebCore::IDBLevelDBBackingStore::deleteObjectStoreRecord):
     110        (WebCore::IDBLevelDBBackingStore::nextAutoIncrementNumber):
     111        (WebCore::IDBLevelDBBackingStore::keyExistsInObjectStore):
     112        (WebCore::IDBLevelDBBackingStore::forEachObjectStoreRecord):
     113        (WebCore::getNewIndexId):
     114        (WebCore::IDBLevelDBBackingStore::createIndex):
     115        (WebCore::IDBLevelDBBackingStore::putIndexDataForRecord):
     116        (WebCore::findGreatestKeyLessThan):
     117        (WebCore::versionExists):
     118        (WebCore::IDBLevelDBBackingStore::getPrimaryKeyViaIndex):
     119        (WebCore::IDBLevelDBBackingStore::keyExistsInIndex):
     120        (WebCore::findLastIndexKeyEqualTo):
     121        (WebCore::IDBLevelDBBackingStore::openObjectStoreCursor):
     122        (WebCore::IDBLevelDBBackingStore::openIndexKeyCursor):
     123        (WebCore::IDBLevelDBBackingStore::openIndexCursor):
     124        (WebCore::IDBLevelDBBackingStore::createTransaction):
     125        (WebCore::IDBLevelDBBackingStore::Transaction::create):
     126        (WebCore::IDBLevelDBBackingStore::Transaction::Transaction):
     127        (WebCore::IDBLevelDBBackingStore::Transaction::begin):
     128        (WebCore::IDBLevelDBBackingStore::Transaction::commit):
     129        (WebCore::IDBLevelDBBackingStore::Transaction::rollback):
     130        * storage/IDBLevelDBBackingStore.h:
     131        * storage/IDBTransactionBackendImpl.cpp:
     132        (WebCore::IDBTransactionBackendImpl::abort):
     133
    11342011-05-26  Shane Stephens  <shanestephens@google.com>
    2135
  • trunk/Source/WebCore/GNUmakefile.list.am

    r87293 r87370  
    25442544        Source/WebCore/platform/leveldb/LevelDBDatabase.cpp \
    25452545        Source/WebCore/platform/leveldb/LevelDBDatabase.h \
    2546         Source/WebCore/platform/leveldb/LevelDBIterator.cpp \
    25472546        Source/WebCore/platform/leveldb/LevelDBIterator.h \
    25482547        Source/WebCore/platform/leveldb/LevelDBSlice.h \
     2548        Source/WebCore/platform/leveldb/LevelDBTransaction.h \
     2549        Source/WebCore/platform/leveldb/LevelDBTransaction.cpp \
     2550        Source/WebCore/platform/leveldb/LevelDBWriteBatch.h \
     2551        Source/WebCore/platform/leveldb/LevelDBWriteBatch.cpp \
    25492552        Source/WebCore/platform/LinkHash.cpp \
    25502553        Source/WebCore/platform/LinkHash.h \
  • trunk/Source/WebCore/WebCore.gypi

    r87347 r87370  
    875875            'platform/leveldb/LevelDBDatabase.cpp',
    876876            'platform/leveldb/LevelDBDatabase.h',
    877             'platform/leveldb/LevelDBIterator.cpp',
    878877            'platform/leveldb/LevelDBIterator.h',
    879878            'platform/leveldb/LevelDBSlice.h',
     879            'platform/leveldb/LevelDBTransaction.cpp',
     880            'platform/leveldb/LevelDBTransaction.h',
     881            'platform/leveldb/LevelDBWriteBatch.cpp',
     882            'platform/leveldb/LevelDBWriteBatch.h',
    880883            'platform/mac/BlockExceptions.h',
    881884            'platform/mac/ClipboardMac.h',
  • trunk/Source/WebCore/WebCore.pro

    r87312 r87370  
    10181018    platform/Length.cpp \
    10191019    platform/text/LineEnding.cpp \
    1020     platform/leveldb/LevelDBComparator.h \
    10211020    platform/leveldb/LevelDBDatabase.cpp \
    1022     platform/leveldb/LevelDBDatabase.h \
    1023     platform/leveldb/LevelDBIterator.cpp \
    1024     platform/leveldb/LevelDBIterator.h \
    1025     platform/leveldb/LevelDBSlice.h \
     1021    platform/leveldb/LevelDBTransaction.cpp \
     1022    platform/leveldb/LevelDBWriteBatch.cpp \
    10261023    platform/LinkHash.cpp \
    10271024    platform/Logging.cpp \
     
    19991996    platform/KURL.h \
    20001997    platform/Length.h \
     1998    platform/leveldb/LevelDBComparator.h \
     1999    platform/leveldb/LevelDBDatabase.h \
     2000    platform/leveldb/LevelDBIterator.h \
     2001    platform/leveldb/LevelDBSlice.h \
     2002    platform/leveldb/LevelDBTransaction.h \
     2003    platform/leveldb/LevelDBWriteBatch.h \
    20012004    platform/text/BidiRunList.h \
    20022005    platform/text/LineEnding.h \
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r87293 r87370  
    27702770                8AF4E55B11DC5A63000ED3DE /* PerformanceTiming.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8AF4E55811DC5A63000ED3DE /* PerformanceTiming.cpp */; };
    27712771                8AF4E55C11DC5A63000ED3DE /* PerformanceTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AF4E55911DC5A63000ED3DE /* PerformanceTiming.h */; };
     2772                8C0E334C138A92C7008DA94F /* LevelDBTransaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C0E3348138A92C7008DA94F /* LevelDBTransaction.cpp */; };
     2773                8C0E334D138A92C7008DA94F /* LevelDBTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C0E3349138A92C7008DA94F /* LevelDBTransaction.h */; };
     2774                8C0E334E138A92C7008DA94F /* LevelDBWriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C0E334A138A92C7008DA94F /* LevelDBWriteBatch.cpp */; };
     2775                8C0E334F138A92C7008DA94F /* LevelDBWriteBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C0E334B138A92C7008DA94F /* LevelDBWriteBatch.h */; };
    27722776                8C6EA61911EF7E0400FD8EE3 /* RuntimeEnabledFeatures.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C6EA61711EF7E0400FD8EE3 /* RuntimeEnabledFeatures.cpp */; };
    27732777                8C6EA61A11EF7E0400FD8EE3 /* RuntimeEnabledFeatures.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C6EA61811EF7E0400FD8EE3 /* RuntimeEnabledFeatures.h */; };
     
    27752779                8CADF2AA135C7B36009EF43F /* LevelDBDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CADF2A4135C7B36009EF43F /* LevelDBDatabase.cpp */; };
    27762780                8CADF2AB135C7B36009EF43F /* LevelDBDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CADF2A5135C7B36009EF43F /* LevelDBDatabase.h */; };
    2777                 8CADF2AC135C7B36009EF43F /* LevelDBIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CADF2A6135C7B36009EF43F /* LevelDBIterator.cpp */; };
    27782781                8CADF2AD135C7B36009EF43F /* LevelDBIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CADF2A7135C7B36009EF43F /* LevelDBIterator.h */; };
    27792782                8CADF2AE135C7B36009EF43F /* LevelDBSlice.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CADF2A8135C7B36009EF43F /* LevelDBSlice.h */; };
     
    93359338                8AF4E55911DC5A63000ED3DE /* PerformanceTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerformanceTiming.h; sourceTree = "<group>"; };
    93369339                8AF4E55A11DC5A63000ED3DE /* PerformanceTiming.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PerformanceTiming.idl; sourceTree = "<group>"; };
     9340                8C0E3348138A92C7008DA94F /* LevelDBTransaction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LevelDBTransaction.cpp; sourceTree = "<group>"; };
     9341                8C0E3349138A92C7008DA94F /* LevelDBTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LevelDBTransaction.h; sourceTree = "<group>"; };
     9342                8C0E334A138A92C7008DA94F /* LevelDBWriteBatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LevelDBWriteBatch.cpp; sourceTree = "<group>"; };
     9343                8C0E334B138A92C7008DA94F /* LevelDBWriteBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LevelDBWriteBatch.h; sourceTree = "<group>"; };
    93379344                8C6EA61711EF7E0400FD8EE3 /* RuntimeEnabledFeatures.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RuntimeEnabledFeatures.cpp; path = generic/RuntimeEnabledFeatures.cpp; sourceTree = "<group>"; };
    93389345                8C6EA61811EF7E0400FD8EE3 /* RuntimeEnabledFeatures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RuntimeEnabledFeatures.h; path = generic/RuntimeEnabledFeatures.h; sourceTree = "<group>"; };
     
    93409347                8CADF2A4135C7B36009EF43F /* LevelDBDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LevelDBDatabase.cpp; sourceTree = "<group>"; };
    93419348                8CADF2A5135C7B36009EF43F /* LevelDBDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LevelDBDatabase.h; sourceTree = "<group>"; };
    9342                 8CADF2A6135C7B36009EF43F /* LevelDBIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LevelDBIterator.cpp; sourceTree = "<group>"; };
    93439349                8CADF2A7135C7B36009EF43F /* LevelDBIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LevelDBIterator.h; sourceTree = "<group>"; };
    93449350                8CADF2A8135C7B36009EF43F /* LevelDBSlice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LevelDBSlice.h; sourceTree = "<group>"; };
     
    1560515611                                8CADF2A4135C7B36009EF43F /* LevelDBDatabase.cpp */,
    1560615612                                8CADF2A5135C7B36009EF43F /* LevelDBDatabase.h */,
    15607                                 8CADF2A6135C7B36009EF43F /* LevelDBIterator.cpp */,
    1560815613                                8CADF2A7135C7B36009EF43F /* LevelDBIterator.h */,
    1560915614                                8CADF2A8135C7B36009EF43F /* LevelDBSlice.h */,
     15615                                8C0E3348138A92C7008DA94F /* LevelDBTransaction.cpp */,
     15616                                8C0E3349138A92C7008DA94F /* LevelDBTransaction.h */,
     15617                                8C0E334A138A92C7008DA94F /* LevelDBWriteBatch.cpp */,
     15618                                8C0E334B138A92C7008DA94F /* LevelDBWriteBatch.h */,
    1561015619                        );
    1561115620                        path = leveldb;
     
    2299823007                                B12D236A1356033F002A28D4 /* JSExclusiveTrackList.h in Headers */,
    2299923008                                B12D236E1356034D002A28D4 /* JSMultipleTrackList.h in Headers */,
     23009                                8C0E334D138A92C7008DA94F /* LevelDBTransaction.h in Headers */,
     23010                                8C0E334F138A92C7008DA94F /* LevelDBWriteBatch.h in Headers */,
    2300023011                        );
    2300123012                        runOnlyForDeploymentPostprocessing = 0;
     
    2490224913                                BCE65BEA0EACDF16007E4533 /* Length.cpp in Sources */,
    2490324914                                8CADF2AA135C7B36009EF43F /* LevelDBDatabase.cpp in Sources */,
    24904                                 8CADF2AC135C7B36009EF43F /* LevelDBIterator.cpp in Sources */,
    2490524915                                84730D901248F0B300D3A9C9 /* LightSource.cpp in Sources */,
    2490624916                                89B5EAA111E8003D00F2367E /* LineEnding.cpp in Sources */,
     
    2569325703                                B12D23691356033F002A28D4 /* JSExclusiveTrackList.cpp in Sources */,
    2569425704                                B12D236D1356034D002A28D4 /* JSMultipleTrackList.cpp in Sources */,
     25705                                8C0E334C138A92C7008DA94F /* LevelDBTransaction.cpp in Sources */,
     25706                                8C0E334E138A92C7008DA94F /* LevelDBWriteBatch.cpp in Sources */,
    2569525707                        );
    2569625708                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp

    r85716 r87370  
    3232#include "LevelDBIterator.h"
    3333#include "LevelDBSlice.h"
     34#include "LevelDBWriteBatch.h"
    3435#include <leveldb/comparator.h>
    3536#include <leveldb/db.h>
     
    111112    result->m_db = adoptPtr(db);
    112113    result->m_comparatorAdapter = comparatorAdapter.release();
     114    result->m_comparator = comparator;
    113115
    114116    return result.release();
    115117}
    116118
    117 
    118119bool LevelDBDatabase::put(const LevelDBSlice& key, const Vector<char>& value)
    119120{
    120121    leveldb::WriteOptions writeOptions;
    121     writeOptions.sync = false;
     122    writeOptions.sync = true;
    122123
    123124    return m_db->Put(writeOptions, makeSlice(key), makeSlice(value)).ok();
     
    127128{
    128129    leveldb::WriteOptions writeOptions;
    129     writeOptions.sync = false;
     130    writeOptions.sync = true;
    130131
    131132    return m_db->Delete(writeOptions, makeSlice(key)).ok();
     
    142143}
    143144
     145bool LevelDBDatabase::write(LevelDBWriteBatch& writeBatch)
     146{
     147    leveldb::WriteOptions writeOptions;
     148    writeOptions.sync = true;
     149
     150    return m_db->Write(writeOptions, writeBatch.m_writeBatch.get()).ok();
     151}
     152
     153namespace {
     154class IteratorImpl : public LevelDBIterator {
     155public:
     156    ~IteratorImpl() { };
     157
     158    virtual bool isValid() const;
     159    virtual void seekToLast();
     160    virtual void seek(const LevelDBSlice& target);
     161    virtual void next();
     162    virtual void prev();
     163    virtual LevelDBSlice key() const;
     164    virtual LevelDBSlice value() const;
     165
     166private:
     167    friend class WebCore::LevelDBDatabase;
     168    IteratorImpl(PassOwnPtr<leveldb::Iterator>);
     169
     170    OwnPtr<leveldb::Iterator> m_iterator;
     171};
     172}
     173
     174IteratorImpl::IteratorImpl(PassOwnPtr<leveldb::Iterator> it)
     175    : m_iterator(it)
     176{
     177}
     178
     179bool IteratorImpl::isValid() const
     180{
     181    return m_iterator->Valid();
     182}
     183
     184void IteratorImpl::seekToLast()
     185{
     186    m_iterator->SeekToLast();
     187}
     188
     189void IteratorImpl::seek(const LevelDBSlice& target)
     190{
     191    m_iterator->Seek(makeSlice(target));
     192}
     193
     194void IteratorImpl::next()
     195{
     196    ASSERT(isValid());
     197    m_iterator->Next();
     198}
     199
     200void IteratorImpl::prev()
     201{
     202    ASSERT(isValid());
     203    m_iterator->Prev();
     204}
     205
     206LevelDBSlice IteratorImpl::key() const
     207{
     208    ASSERT(isValid());
     209    return makeLevelDBSlice(m_iterator->key());
     210}
     211
     212LevelDBSlice IteratorImpl::value() const
     213{
     214    ASSERT(isValid());
     215    return makeLevelDBSlice(m_iterator->value());
     216}
     217
    144218PassOwnPtr<LevelDBIterator> LevelDBDatabase::createIterator()
    145219{
     
    147221    if (!i) // FIXME: Double check if we actually need to check this.
    148222        return nullptr;
    149     return adoptPtr(new LevelDBIterator(i.release()));
     223    return adoptPtr(new IteratorImpl(i.release()));
     224}
     225
     226const LevelDBComparator* LevelDBDatabase::comparator() const
     227{
     228    return m_comparator;
    150229}
    151230
  • trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.h

    r85122 r87370  
    4444class LevelDBIterator;
    4545class LevelDBSlice;
     46class LevelDBWriteBatch;
    4647
    4748class LevelDBDatabase {
     
    5354    bool remove(const LevelDBSlice& key);
    5455    bool get(const LevelDBSlice& key, Vector<char>& value);
     56    bool write(LevelDBWriteBatch&);
    5557    PassOwnPtr<LevelDBIterator> createIterator();
     58    const LevelDBComparator* comparator() const;
    5659
    5760private:
     
    5962
    6063    OwnPtr<leveldb::DB> m_db;
     64    const LevelDBComparator* m_comparator;
    6165    OwnPtr<leveldb::Comparator> m_comparatorAdapter;
    6266};
  • trunk/Source/WebCore/platform/leveldb/LevelDBIterator.h

    r85122 r87370  
    3030
    3131#include "LevelDBSlice.h"
    32 #include "PlatformString.h"
    33 #include <OwnPtr.h>
    34 #include <Vector.h>
    35 
    36 namespace leveldb {
    37 class Iterator;
    38 }
    3932
    4033namespace WebCore {
     
    4235class LevelDBIterator {
    4336public:
    44     ~LevelDBIterator();
    45 
    46     bool isValid() const;
    47     void seekToLast();
    48     void seek(const Vector<char>& target);
    49     void next();
    50     void prev();
    51     LevelDBSlice key() const;
    52     LevelDBSlice value() const;
    53 
    54 private:
    55     LevelDBIterator(PassOwnPtr<leveldb::Iterator>);
    56     friend class LevelDBDatabase;
    57 
    58     OwnPtr<leveldb::Iterator> m_iterator;
     37    virtual ~LevelDBIterator() { };
     38    virtual bool isValid() const = 0;
     39    virtual void seekToLast() = 0;
     40    virtual void seek(const LevelDBSlice& target) = 0;
     41    virtual void next() = 0;
     42    virtual void prev() = 0;
     43    virtual LevelDBSlice key() const = 0;
     44    virtual LevelDBSlice value() const = 0;
    5945};
    60 
    6146
    6247} // namespace WebCore
  • trunk/Source/WebCore/platform/leveldb/LevelDBWriteBatch.cpp

    r87368 r87370  
    2525
    2626#include "config.h"
    27 #include "LevelDBIterator.h"
     27#include "LevelDBWriteBatch.h"
    2828
    2929#if ENABLE(LEVELDB)
    3030
    31 #include <leveldb/iterator.h>
     31#include "LevelDBSlice.h"
    3232#include <leveldb/slice.h>
    33 #include <wtf/PassOwnPtr.h>
    34 #include <wtf/text/CString.h>
    35 #include <wtf/text/WTFString.h>
     33#include <leveldb/write_batch.h>
    3634
    3735namespace WebCore {
    3836
    39 LevelDBIterator::~LevelDBIterator()
     37PassOwnPtr<LevelDBWriteBatch> LevelDBWriteBatch::create()
     38{
     39    return adoptPtr(new LevelDBWriteBatch);
     40}
     41
     42LevelDBWriteBatch::LevelDBWriteBatch()
     43    : m_writeBatch(adoptPtr(new leveldb::WriteBatch))
    4044{
    4145}
    4246
    43 LevelDBIterator::LevelDBIterator(PassOwnPtr<leveldb::Iterator> it)
    44     : m_iterator(it)
     47LevelDBWriteBatch::~LevelDBWriteBatch()
    4548{
    4649}
    4750
    48 static leveldb::Slice makeSlice(const Vector<char>& value)
     51static leveldb::Slice makeSlice(const LevelDBSlice& s)
    4952{
    50     return leveldb::Slice(value.data(), value.size());
     53    return leveldb::Slice(s.begin(), s.end() - s.begin());
    5154}
    5255
    53 static LevelDBSlice makeLevelDBSlice(leveldb::Slice s)
     56void LevelDBWriteBatch::put(const LevelDBSlice& key, const LevelDBSlice& value)
    5457{
    55     return LevelDBSlice(s.data(), s.data() + s.size());
     58    m_writeBatch->Put(makeSlice(key), makeSlice(value));
    5659}
    5760
    58 bool LevelDBIterator::isValid() const
     61void LevelDBWriteBatch::remove(const LevelDBSlice& key)
    5962{
    60     return m_iterator->Valid();
     63    m_writeBatch->Delete(makeSlice(key));
    6164}
    6265
    63 void LevelDBIterator::seekToLast()
     66void LevelDBWriteBatch::clear()
    6467{
    65     m_iterator->SeekToLast();
     68    m_writeBatch->Clear();
    6669}
    6770
    68 void LevelDBIterator::seek(const Vector<char>& target)
    69 {
    70     m_iterator->Seek(makeSlice(target));
    7171}
    7272
    73 void LevelDBIterator::next()
    74 {
    75     m_iterator->Next();
    76 }
    77 
    78 void LevelDBIterator::prev()
    79 {
    80     m_iterator->Prev();
    81 }
    82 
    83 LevelDBSlice LevelDBIterator::key() const
    84 {
    85     return makeLevelDBSlice(m_iterator->key());
    86 }
    87 
    88 LevelDBSlice LevelDBIterator::value() const
    89 {
    90     return makeLevelDBSlice(m_iterator->value());
    91 }
    92 
    93 } // namespace WebCore
    94 
    95 #endif // ENABLE(LEVELDB)
     73#endif
  • trunk/Source/WebCore/platform/leveldb/LevelDBWriteBatch.h

    r87368 r87370  
    2424 */
    2525
    26 #ifndef LevelDBIterator_h
    27 #define LevelDBIterator_h
     26#ifndef LevelDBWriteBatch_h
     27#define LevelDBWriteBatch_h
    2828
    2929#if ENABLE(LEVELDB)
    3030
    31 #include "LevelDBSlice.h"
    32 #include "PlatformString.h"
    33 #include <OwnPtr.h>
    34 #include <Vector.h>
     31#include <wtf/OwnPtr.h>
     32#include <wtf/PassOwnPtr.h>
    3533
    3634namespace leveldb {
    37 class Iterator;
     35class WriteBatch;
    3836}
    3937
    4038namespace WebCore {
    4139
    42 class LevelDBIterator {
     40class LevelDBSlice;
     41
     42// Wrapper around leveldb::WriteBatch.
     43// This class holds a collection of updates to apply atomically to a database.
     44class LevelDBWriteBatch {
    4345public:
    44     ~LevelDBIterator();
     46    static PassOwnPtr<LevelDBWriteBatch> create();
     47    ~LevelDBWriteBatch();
    4548
    46     bool isValid() const;
    47     void seekToLast();
    48     void seek(const Vector<char>& target);
    49     void next();
    50     void prev();
    51     LevelDBSlice key() const;
    52     LevelDBSlice value() const;
     49    void put(const LevelDBSlice& key, const LevelDBSlice& value);
     50    void remove(const LevelDBSlice& key); // Add remove operation to the batch.
     51    void clear();
    5352
    5453private:
    55     LevelDBIterator(PassOwnPtr<leveldb::Iterator>);
    5654    friend class LevelDBDatabase;
     55    LevelDBWriteBatch();
    5756
    58     OwnPtr<leveldb::Iterator> m_iterator;
     57    OwnPtr<leveldb::WriteBatch> m_writeBatch;
    5958};
    6059
    61 
    62 } // namespace WebCore
     60}
    6361
    6462#endif // ENABLE(LEVELDB)
    65 #endif // LevelDBIterator_h
     63#endif // LevelDBWriteBatch_h
  • trunk/Source/WebCore/storage/IDBLevelDBBackingStore.cpp

    r87313 r87370  
    3939#include "LevelDBIterator.h"
    4040#include "LevelDBSlice.h"
     41#include "LevelDBTransaction.h"
    4142#include "SecurityOrigin.h"
    4243
     
    5051using namespace IDBLevelDBCoding;
    5152
    52 static bool getInt(LevelDBDatabase* db, const Vector<char>& key, int64_t& foundInt)
     53template <typename DBOrTransaction>
     54static bool getInt(DBOrTransaction* db, const Vector<char>& key, int64_t& foundInt)
    5355{
    5456    Vector<char> result;
     
    6062}
    6163
    62 static bool putInt(LevelDBDatabase* db, const Vector<char>& key, int64_t value)
     64template <typename DBOrTransaction>
     65static bool putInt(DBOrTransaction* db, const Vector<char>& key, int64_t value)
    6366{
    6467    return db->put(key, encodeInt(value));
    6568}
    6669
    67 static bool getString(LevelDBDatabase* db, const Vector<char>& key, String& foundString)
     70template <typename DBOrTransaction>
     71static bool getString(DBOrTransaction* db, const Vector<char>& key, String& foundString)
    6872{
    6973    Vector<char> result;
     
    7579}
    7680
    77 static bool putString(LevelDBDatabase* db, const Vector<char> key, const String& value)
     81template <typename DBOrTransaction>
     82static bool putString(DBOrTransaction* db, const Vector<char> key, const String& value)
    7883{
    7984    if (!db->put(key, encodeString(value)))
     
    284289}
    285290
    286 static int64_t getNewObjectStoreId(LevelDBDatabase* db, int64_t databaseId)
     291static int64_t getNewObjectStoreId(LevelDBTransaction* transaction, int64_t databaseId)
    287292{
    288293    const Vector<char> freeListStartKey = ObjectStoreFreeListKey::encode(databaseId, 0);
    289294    const Vector<char> freeListStopKey = ObjectStoreFreeListKey::encode(databaseId, INT64_MAX);
    290295
    291     OwnPtr<LevelDBIterator> it = db->createIterator();
     296    OwnPtr<LevelDBIterator> it = transaction->createIterator();
    292297    for (it->seek(freeListStartKey); it->isValid() && compareKeys(it->key(), freeListStopKey) < 0; it->next()) {
    293298        const char* p = it->key().begin();
     
    298303        ASSERT(p);
    299304
    300         bool ok = db->remove(it->key());
     305        bool ok = transaction->remove(it->key());
    301306        ASSERT_UNUSED(ok, ok);
    302307
     
    306311    int64_t maxObjectStoreId = -1;
    307312    const Vector<char> maxObjectStoreIdKey = DatabaseMetaDataKey::encode(databaseId, DatabaseMetaDataKey::kMaxObjectStoreId);
    308     if (!getInt(db, maxObjectStoreIdKey, maxObjectStoreId))
     313    if (!getInt(transaction, maxObjectStoreIdKey, maxObjectStoreId))
    309314        maxObjectStoreId = 0;
    310315
     
    312317
    313318    int64_t objectStoreId = maxObjectStoreId + 1;
    314     bool ok = putInt(db, maxObjectStoreIdKey, objectStoreId);
     319    bool ok = putInt(transaction, maxObjectStoreIdKey, objectStoreId);
    315320    ASSERT_UNUSED(ok, ok);
    316321
     
    320325bool IDBLevelDBBackingStore::createObjectStore(int64_t databaseId, const String& name, const String& keyPath, bool autoIncrement, int64_t& assignedObjectStoreId)
    321326{
    322     int64_t objectStoreId = getNewObjectStoreId(m_db.get(), databaseId);
     327    ASSERT(m_currentTransaction);
     328    int64_t objectStoreId = getNewObjectStoreId(m_currentTransaction.get(), databaseId);
    323329
    324330    const Vector<char> nameKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0);
     
    330336    const Vector<char> namesKey = ObjectStoreNamesKey::encode(databaseId, name);
    331337
    332     bool ok = putString(m_db.get(), nameKey, name);
     338    bool ok = putString(m_currentTransaction.get(), nameKey, name);
    333339    if (!ok) {
    334340        LOG_ERROR("Internal Indexed DB error.");
     
    336342    }
    337343
    338     ok = putString(m_db.get(), keyPathKey, keyPath);
     344    ok = putString(m_currentTransaction.get(), keyPathKey, keyPath);
    339345    if (!ok) {
    340346        LOG_ERROR("Internal Indexed DB error.");
     
    342348    }
    343349
    344     ok = putInt(m_db.get(), autoIncrementKey, autoIncrement);
     350    ok = putInt(m_currentTransaction.get(), autoIncrementKey, autoIncrement);
    345351    if (!ok) {
    346352        LOG_ERROR("Internal Indexed DB error.");
     
    348354    }
    349355
    350     ok = putInt(m_db.get(), evictableKey, false);
     356    ok = putInt(m_currentTransaction.get(), evictableKey, false);
    351357    if (!ok) {
    352358        LOG_ERROR("Internal Indexed DB error.");
     
    354360    }
    355361
    356     ok = putInt(m_db.get(), lastVersionKey, 1);
     362    ok = putInt(m_currentTransaction.get(), lastVersionKey, 1);
    357363    if (!ok) {
    358364        LOG_ERROR("Internal Indexed DB error.");
     
    360366    }
    361367
    362     ok = putInt(m_db.get(), maxIndexIdKey, kMinimumIndexId);
     368    ok = putInt(m_currentTransaction.get(), maxIndexIdKey, kMinimumIndexId);
    363369    if (!ok) {
    364370        LOG_ERROR("Internal Indexed DB error.");
     
    366372    }
    367373
    368     ok = putInt(m_db.get(), namesKey, objectStoreId);
     374    ok = putInt(m_currentTransaction.get(), namesKey, objectStoreId);
    369375    if (!ok) {
    370376        LOG_ERROR("Internal Indexed DB error.");
     
    377383}
    378384
    379 static bool deleteRange(LevelDBDatabase* db, const Vector<char>& begin, const Vector<char>& end)
    380 {
    381     // FIXME: LevelDB may be able to provide a bulk operation that we can do first.
    382     OwnPtr<LevelDBIterator> it = db->createIterator();
     385static bool deleteRange(LevelDBTransaction* transaction, const Vector<char>& begin, const Vector<char>& end)
     386{
     387    OwnPtr<LevelDBIterator> it = transaction->createIterator();
    383388    for (it->seek(begin); it->isValid() && compareKeys(it->key(), end) < 0; it->next()) {
    384         if (!db->remove(it->key()))
     389        if (!transaction->remove(it->key()))
    385390            return false;
    386391    }
     
    391396void IDBLevelDBBackingStore::deleteObjectStore(int64_t databaseId, int64_t objectStoreId)
    392397{
     398    ASSERT(m_currentTransaction);
     399
    393400    String objectStoreName;
    394     getString(m_db.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), objectStoreName);
    395 
    396     if (!deleteRange(m_db.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 6)))
     401    getString(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), objectStoreName);
     402
     403    if (!deleteRange(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 6)))
    397404        return; // FIXME: Report error.
    398405
    399     putString(m_db.get(), ObjectStoreFreeListKey::encode(databaseId, objectStoreId), "");
    400     m_db->remove(ObjectStoreNamesKey::encode(databaseId, objectStoreName));
    401 
    402     if (!deleteRange(m_db.get(), IndexFreeListKey::encode(databaseId, objectStoreId, 0), IndexFreeListKey::encode(databaseId, objectStoreId, INT64_MAX)))
     406    putString(m_currentTransaction.get(), ObjectStoreFreeListKey::encode(databaseId, objectStoreId), "");
     407    m_currentTransaction->remove(ObjectStoreNamesKey::encode(databaseId, objectStoreName));
     408
     409    if (!deleteRange(m_currentTransaction.get(), IndexFreeListKey::encode(databaseId, objectStoreId, 0), IndexFreeListKey::encode(databaseId, objectStoreId, INT64_MAX)))
    403410        return; // FIXME: Report error.
    404     if (!deleteRange(m_db.get(), IndexMetaDataKey::encode(databaseId, objectStoreId, 0, 0), IndexMetaDataKey::encode(databaseId, objectStoreId, INT64_MAX, 0)))
     411    if (!deleteRange(m_currentTransaction.get(), IndexMetaDataKey::encode(databaseId, objectStoreId, 0, 0), IndexMetaDataKey::encode(databaseId, objectStoreId, INT64_MAX, 0)))
    405412        return; // FIXME: Report error.
    406413
     
    413420    Vector<char> data;
    414421
    415     if (!m_db->get(leveldbKey, data))
     422    ASSERT(m_currentTransaction);
     423    if (!m_currentTransaction->get(leveldbKey, data))
    416424        return String();
    417425
     
    446454}
    447455
    448 static int64_t getNewVersionNumber(LevelDBDatabase* db, int64_t databaseId, int64_t objectStoreId)
     456static int64_t getNewVersionNumber(LevelDBTransaction* transaction, int64_t databaseId, int64_t objectStoreId)
    449457{
    450458    const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 4);
    451459
    452460    int64_t lastVersion = -1;
    453     if (!getInt(db, lastVersionKey, lastVersion))
     461    if (!getInt(transaction, lastVersionKey, lastVersion))
    454462        lastVersion = 0;
    455463
     
    457465
    458466    int64_t version = lastVersion + 1;
    459     bool ok = putInt(db, lastVersionKey, version);
     467    bool ok = putInt(transaction, lastVersionKey, version);
    460468    ASSERT_UNUSED(ok, ok);
    461469
     
    467475bool IDBLevelDBBackingStore::putObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const IDBKey& key, const String& value, ObjectStoreRecordIdentifier* recordIdentifier)
    468476{
    469     int64_t version = getNewVersionNumber(m_db.get(), databaseId, objectStoreId);
     477    ASSERT(m_currentTransaction);
     478    int64_t version = getNewVersionNumber(m_currentTransaction.get(), databaseId, objectStoreId);
    470479    const Vector<char> objectStoredataKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key);
    471480
     
    474483    v.append(encodeString(value));
    475484
    476     if (!m_db->put(objectStoredataKey, v))
     485    if (!m_currentTransaction->put(objectStoredataKey, v))
    477486        return false;
    478487
    479488    const Vector<char> existsEntryKey = ExistsEntryKey::encode(databaseId, objectStoreId, key);
    480     if (!m_db->put(existsEntryKey, encodeInt(version)))
     489    if (!m_currentTransaction->put(existsEntryKey, encodeInt(version)))
    481490        return false;
    482491
     
    489498void IDBLevelDBBackingStore::clearObjectStore(int64_t databaseId, int64_t objectStoreId)
    490499{
     500    ASSERT(m_currentTransaction);
    491501    const Vector<char> startKey = KeyPrefix(databaseId, objectStoreId, 0).encode();
    492502    const Vector<char> stopKey = KeyPrefix(databaseId, objectStoreId + 1, 0).encode();
    493503
    494     deleteRange(m_db.get(), startKey, stopKey);
     504    deleteRange(m_currentTransaction.get(), startKey, stopKey);
    495505}
    496506
     
    502512void IDBLevelDBBackingStore::deleteObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const ObjectStoreRecordIdentifier* recordIdentifier)
    503513{
     514    ASSERT(m_currentTransaction);
    504515    const LevelDBRecordIdentifier* levelDBRecordIdentifier = static_cast<const LevelDBRecordIdentifier*>(recordIdentifier);
    505516    const Vector<char> key = ObjectStoreDataKey::encode(databaseId, objectStoreId, levelDBRecordIdentifier->primaryKey());
    506     m_db->remove(key);
     517    m_currentTransaction->remove(key);
    507518}
    508519
    509520double IDBLevelDBBackingStore::nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId)
    510521{
     522    ASSERT(m_currentTransaction);
    511523    const Vector<char> startKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, minIDBKey());
    512524    const Vector<char> stopKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, maxIDBKey());
    513525
    514     OwnPtr<LevelDBIterator> it = m_db->createIterator();
     526    OwnPtr<LevelDBIterator> it = m_currentTransaction->createIterator();
    515527
    516528    int maxNumericKey = 0;
     
    538550bool IDBLevelDBBackingStore::keyExistsInObjectStore(int64_t databaseId, int64_t objectStoreId, const IDBKey& key, ObjectStoreRecordIdentifier* foundRecordIdentifier)
    539551{
     552    ASSERT(m_currentTransaction);
    540553    const Vector<char> leveldbKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key);
    541554    Vector<char> data;
    542555
    543     if (!m_db->get(leveldbKey, data))
     556    if (!m_currentTransaction->get(leveldbKey, data))
    544557        return false;
    545558
     
    556569bool IDBLevelDBBackingStore::forEachObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, ObjectStoreRecordCallback& callback)
    557570{
     571    ASSERT(m_currentTransaction);
    558572    const Vector<char> startKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, minIDBKey());
    559573    const Vector<char> stopKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, maxIDBKey());
    560574
    561     OwnPtr<LevelDBIterator> it = m_db->createIterator();
     575    OwnPtr<LevelDBIterator> it = m_currentTransaction->createIterator();
    562576    for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) {
    563577        const char *p = it->key().begin();
     
    623637}
    624638
    625 static int64_t getNewIndexId(LevelDBDatabase* db, int64_t databaseId, int64_t objectStoreId)
     639static int64_t getNewIndexId(LevelDBTransaction* transaction, int64_t databaseId, int64_t objectStoreId)
    626640{
    627641    const Vector<char> startKey = IndexFreeListKey::encode(databaseId, objectStoreId, 0);
    628642    const Vector<char> stopKey = IndexFreeListKey::encode(databaseId, objectStoreId, INT64_MAX);
    629643
    630     OwnPtr<LevelDBIterator> it = db->createIterator();
     644    OwnPtr<LevelDBIterator> it = transaction->createIterator();
    631645    for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) {
    632646        const char* p = it->key().begin();
     
    637651        ASSERT(p);
    638652
    639         bool ok = db->remove(it->key());
     653        bool ok = transaction->remove(it->key());
    640654        ASSERT_UNUSED(ok, ok);
    641655
     
    646660    int64_t maxIndexId = -1;
    647661    const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 5);
    648     if (!getInt(db, maxIndexIdKey, maxIndexId))
     662    if (!getInt(transaction, maxIndexIdKey, maxIndexId))
    649663        maxIndexId = kMinimumIndexId;
    650664
     
    652666
    653667    int64_t indexId = maxIndexId + 1;
    654     bool ok = putInt(db, maxIndexIdKey, indexId);
     668    bool ok = putInt(transaction, maxIndexIdKey, indexId);
    655669    if (!ok)
    656670        return false;
     
    661675bool IDBLevelDBBackingStore::createIndex(int64_t databaseId, int64_t objectStoreId, const String& name, const String& keyPath, bool isUnique, int64_t& indexId)
    662676{
    663     indexId = getNewIndexId(m_db.get(), databaseId, objectStoreId);
     677    ASSERT(m_currentTransaction);
     678    indexId = getNewIndexId(m_currentTransaction.get(), databaseId, objectStoreId);
    664679
    665680    const Vector<char> nameKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 0);
     
    667682    const Vector<char> keyPathKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 2);
    668683
    669     bool ok = putString(m_db.get(), nameKey, name);
     684    bool ok = putString(m_currentTransaction.get(), nameKey, name);
    670685    if (!ok) {
    671686        LOG_ERROR("Internal Indexed DB error.");
     
    673688    }
    674689
    675     ok = putInt(m_db.get(), uniqueKey, isUnique);
     690    ok = putInt(m_currentTransaction.get(), uniqueKey, isUnique);
    676691    if (!ok) {
    677692        LOG_ERROR("Internal Indexed DB error.");
     
    679694    }
    680695
    681     ok = putString(m_db.get(), keyPathKey, keyPath);
     696    ok = putString(m_currentTransaction.get(), keyPathKey, keyPath);
    682697    if (!ok) {
    683698        LOG_ERROR("Internal Indexed DB error.");
     
    699714    const LevelDBRecordIdentifier* levelDBRecordIdentifier = static_cast<const LevelDBRecordIdentifier*>(recordIdentifier);
    700715
    701     const int64_t globalSequenceNumber = getNewVersionNumber(m_db.get(), databaseId, objectStoreId);
     716    ASSERT(m_currentTransaction);
     717    const int64_t globalSequenceNumber = getNewVersionNumber(m_currentTransaction.get(), databaseId, objectStoreId);
    702718    const Vector<char> indexDataKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, key, globalSequenceNumber);
    703719
     
    706722    data.append(levelDBRecordIdentifier->primaryKey());
    707723
    708     return m_db->put(indexDataKey, data);
    709 }
    710 
    711 static bool findGreatestKeyLessThan(LevelDBDatabase* db, const Vector<char>& target, Vector<char>& foundKey)
    712 {
    713     OwnPtr<LevelDBIterator> it = db->createIterator();
     724    return m_currentTransaction->put(indexDataKey, data);
     725}
     726
     727static bool findGreatestKeyLessThan(LevelDBTransaction* transaction, const Vector<char>& target, Vector<char>& foundKey)
     728{
     729    OwnPtr<LevelDBIterator> it = transaction->createIterator();
    714730    it->seek(target);
    715731
     
    746762}
    747763
    748 static bool versionExists(LevelDBDatabase* db, int64_t databaseId, int64_t objectStoreId, int64_t version, const Vector<char>& encodedPrimaryKey)
     764static bool versionExists(LevelDBTransaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t version, const Vector<char>& encodedPrimaryKey)
    749765{
    750766    const Vector<char> key = ExistsEntryKey::encode(databaseId, objectStoreId, encodedPrimaryKey);
    751767    Vector<char> data;
    752768
    753     if (!db->get(key, data))
     769    if (!transaction->get(key, data))
    754770        return false;
    755771
     
    759775PassRefPtr<IDBKey> IDBLevelDBBackingStore::getPrimaryKeyViaIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key)
    760776{
     777    ASSERT(m_currentTransaction);
    761778    const Vector<char> leveldbKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, key, 0);
    762     OwnPtr<LevelDBIterator> it = m_db->createIterator();
     779    OwnPtr<LevelDBIterator> it = m_currentTransaction->createIterator();
    763780    it->seek(leveldbKey);
    764781
     
    776793        encodedPrimaryKey.append(p, it->value().end() - p);
    777794
    778         if (!versionExists(m_db.get(), databaseId, objectStoreId, version, encodedPrimaryKey)) {
     795        if (!versionExists(m_currentTransaction.get(), databaseId, objectStoreId, version, encodedPrimaryKey)) {
    779796            // Delete stale index data entry and continue.
    780             m_db->remove(it->key());
     797            m_currentTransaction->remove(it->key());
    781798            it->next();
    782799            continue;
     
    791808bool IDBLevelDBBackingStore::keyExistsInIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key)
    792809{
     810    ASSERT(m_currentTransaction);
    793811    const Vector<char> levelDBKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, key, 0);
    794     OwnPtr<LevelDBIterator> it = m_db->createIterator();
     812    OwnPtr<LevelDBIterator> it = m_currentTransaction->createIterator();
    795813
    796814    bool found = false;
     
    819837
    820838protected:
    821     CursorImplCommon(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
    822         : m_db(db)
     839    CursorImplCommon(LevelDBTransaction* transaction, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
     840        : m_transaction(transaction)
    823841        , m_lowKey(lowKey)
    824842        , m_lowOpen(lowOpen)
     
    830848    virtual ~CursorImplCommon() {}
    831849
    832     LevelDBDatabase* m_db;
     850    LevelDBTransaction* m_transaction;
    833851    OwnPtr<LevelDBIterator> m_iterator;
    834852    Vector<char> m_lowKey;
     
    842860bool CursorImplCommon::firstSeek()
    843861{
    844     m_iterator = m_db->createIterator();
     862    m_iterator = m_transaction->createIterator();
    845863
    846864    if (m_forward)
     
    903921
    904922        Vector<char> trash;
    905         if (!m_db->get(m_iterator->key(), trash))
     923        if (!m_transaction->get(m_iterator->key(), trash))
    906924             continue;
    907925
     
    938956class ObjectStoreCursorImpl : public CursorImplCommon {
    939957public:
    940     static PassRefPtr<ObjectStoreCursorImpl> create(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
     958    static PassRefPtr<ObjectStoreCursorImpl> create(LevelDBTransaction* transaction, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
    941959    {
    942         return adoptRef(new ObjectStoreCursorImpl(db, lowKey, lowOpen, highKey, highOpen, forward));
     960        return adoptRef(new ObjectStoreCursorImpl(transaction, lowKey, lowOpen, highKey, highOpen, forward));
    943961    }
    944962
     
    950968
    951969private:
    952     ObjectStoreCursorImpl(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
    953         : CursorImplCommon(db, lowKey, lowOpen, highKey, highOpen, forward)
     970    ObjectStoreCursorImpl(LevelDBTransaction* transaction, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
     971        : CursorImplCommon(transaction, lowKey, lowOpen, highKey, highOpen, forward)
    954972    {
    955973    }
     
    9851003class IndexKeyCursorImpl : public CursorImplCommon {
    9861004public:
    987     static PassRefPtr<IndexKeyCursorImpl> create(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
     1005    static PassRefPtr<IndexKeyCursorImpl> create(LevelDBTransaction* transaction, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
    9881006    {
    989         return adoptRef(new IndexKeyCursorImpl(db, lowKey, lowOpen, highKey, highOpen, forward));
     1007        return adoptRef(new IndexKeyCursorImpl(transaction, lowKey, lowOpen, highKey, highOpen, forward));
    9901008    }
    9911009
     
    9981016
    9991017private:
    1000     IndexKeyCursorImpl(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
    1001         : CursorImplCommon(db, lowKey, lowOpen, highKey, highOpen, forward)
     1018    IndexKeyCursorImpl(LevelDBTransaction* transaction, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
     1019        : CursorImplCommon(transaction, lowKey, lowOpen, highKey, highOpen, forward)
    10021020    {
    10031021    }
     
    10291047
    10301048    Vector<char> result;
    1031     if (!m_db->get(primaryLevelDBKey, result))
     1049    if (!m_transaction->get(primaryLevelDBKey, result))
    10321050        return false;
    10331051
     
    10391057
    10401058    if (objectStoreDataVersion != indexDataVersion) { // FIXME: This is probably not very well covered by the layout tests.
    1041         m_db->remove(m_iterator->key());
     1059        m_transaction->remove(m_iterator->key());
    10421060        return false;
    10431061    }
     
    10481066class IndexCursorImpl : public CursorImplCommon {
    10491067public:
    1050     static PassRefPtr<IndexCursorImpl> create(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
     1068    static PassRefPtr<IndexCursorImpl> create(LevelDBTransaction* transaction, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
    10511069    {
    1052         return adoptRef(new IndexCursorImpl(db, lowKey, lowOpen, highKey, highOpen, forward));
     1070        return adoptRef(new IndexCursorImpl(transaction, lowKey, lowOpen, highKey, highOpen, forward));
    10531071    }
    10541072
     
    10611079
    10621080private:
    1063     IndexCursorImpl(LevelDBDatabase* db, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
    1064         : CursorImplCommon(db, lowKey, lowOpen, highKey, highOpen, forward)
     1081    IndexCursorImpl(LevelDBTransaction* transaction, const Vector<char>& lowKey, bool lowOpen, const Vector<char>& highKey, bool highOpen, bool forward)
     1082        : CursorImplCommon(transaction, lowKey, lowOpen, highKey, highOpen, forward)
    10651083    {
    10661084    }
     
    10971115
    10981116    Vector<char> result;
    1099     if (!m_db->get(m_primaryLevelDBKey, result))
     1117    if (!m_transaction->get(m_primaryLevelDBKey, result))
    11001118        return false;
    11011119
     
    11071125
    11081126    if (objectStoreDataVersion != indexDataVersion) {
    1109         m_db->remove(m_iterator->key());
     1127        m_transaction->remove(m_iterator->key());
    11101128        return false;
    11111129    }
     
    11171135}
    11181136
    1119 static bool findLastIndexKeyEqualTo(LevelDBDatabase* db, const Vector<char>& target, Vector<char>& foundKey)
    1120 {
    1121     OwnPtr<LevelDBIterator> it = db->createIterator();
     1137static bool findLastIndexKeyEqualTo(LevelDBTransaction* transaction, const Vector<char>& target, Vector<char>& foundKey)
     1138{
     1139    OwnPtr<LevelDBIterator> it = transaction->createIterator();
    11221140    it->seek(target);
    11231141
     
    11361154PassRefPtr<IDBBackingStore::Cursor> IDBLevelDBBackingStore::openObjectStoreCursor(int64_t databaseId, int64_t objectStoreId, const IDBKeyRange* range, IDBCursor::Direction direction)
    11371155{
     1156    ASSERT(m_currentTransaction);
    11381157    bool lowerBound = range && range->lower();
    11391158    bool upperBound = range && range->upper();
     
    11561175
    11571176        if (!forward) { // We need a key that exists.
    1158             if (!findGreatestKeyLessThan(m_db.get(), stopKey, stopKey))
     1177            if (!findGreatestKeyLessThan(m_currentTransaction.get(), stopKey, stopKey))
    11591178                return 0;
    11601179            upperOpen = false;
     
    11651184    }
    11661185
    1167     RefPtr<ObjectStoreCursorImpl> cursor = ObjectStoreCursorImpl::create(m_db.get(), startKey, lowerOpen, stopKey, upperOpen, forward);
     1186    RefPtr<ObjectStoreCursorImpl> cursor = ObjectStoreCursorImpl::create(m_currentTransaction.get(), startKey, lowerOpen, stopKey, upperOpen, forward);
    11681187    if (!cursor->firstSeek())
    11691188        return 0;
     
    11741193PassRefPtr<IDBBackingStore::Cursor> IDBLevelDBBackingStore::openIndexKeyCursor(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKeyRange* range, IDBCursor::Direction direction)
    11751194{
     1195    ASSERT(m_currentTransaction);
    11761196    bool lowerBound = range && range->lower();
    11771197    bool upperBound = range && range->upper();
     
    11941214
    11951215        if (!forward) { // We need a key that exists.
    1196             if (!findGreatestKeyLessThan(m_db.get(), stopKey, stopKey))
     1216            if (!findGreatestKeyLessThan(m_currentTransaction.get(), stopKey, stopKey))
    11971217                return 0;
    11981218            upperOpen = false;
     
    12001220    } else {
    12011221        stopKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, *range->upper(), 0);
    1202         if (!findLastIndexKeyEqualTo(m_db.get(), stopKey, stopKey)) // Seek to the *last* key in the set of non-unique keys.
     1222        if (!findLastIndexKeyEqualTo(m_currentTransaction.get(), stopKey, stopKey)) // Seek to the *last* key in the set of non-unique keys.
    12031223            return 0;
    12041224        upperOpen = range->upperOpen();
    12051225    }
    12061226
    1207     RefPtr<IndexKeyCursorImpl> cursor = IndexKeyCursorImpl::create(m_db.get(), startKey, lowerOpen, stopKey, upperOpen, forward);
     1227    RefPtr<IndexKeyCursorImpl> cursor = IndexKeyCursorImpl::create(m_currentTransaction.get(), startKey, lowerOpen, stopKey, upperOpen, forward);
    12081228    if (!cursor->firstSeek())
    12091229        return 0;
     
    12141234PassRefPtr<IDBBackingStore::Cursor> IDBLevelDBBackingStore::openIndexCursor(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKeyRange* range, IDBCursor::Direction direction)
    12151235{
     1236    ASSERT(m_currentTransaction);
    12161237    bool lowerBound = range && range->lower();
    12171238    bool upperBound = range && range->upper();
     
    12341255
    12351256        if (!forward) { // We need a key that exists.
    1236             if (!findGreatestKeyLessThan(m_db.get(), stopKey, stopKey))
     1257            if (!findGreatestKeyLessThan(m_currentTransaction.get(), stopKey, stopKey))
    12371258                return 0;
    12381259            upperOpen = false;
     
    12401261    } else {
    12411262        stopKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, *range->upper(), 0);
    1242         if (!findLastIndexKeyEqualTo(m_db.get(), stopKey, stopKey)) // Seek to the *last* key in the set of non-unique keys.
     1263        if (!findLastIndexKeyEqualTo(m_currentTransaction.get(), stopKey, stopKey)) // Seek to the *last* key in the set of non-unique keys.
    12431264            return 0;
    12441265        upperOpen = range->upperOpen();
    12451266    }
    12461267
    1247     RefPtr<IndexCursorImpl> cursor = IndexCursorImpl::create(m_db.get(), startKey, lowerOpen, stopKey, upperOpen, forward);
     1268    RefPtr<IndexCursorImpl> cursor = IndexCursorImpl::create(m_currentTransaction.get(), startKey, lowerOpen, stopKey, upperOpen, forward);
    12481269    if (!cursor->firstSeek())
    12491270        return 0;
     
    12521273}
    12531274
    1254 namespace {
    1255 class DummyTransaction : public IDBBackingStore::Transaction {
    1256 public:
    1257     virtual void begin() {}
    1258     virtual void commit() {}
    1259     virtual void rollback() {}
    1260 };
    1261 }
    1262 
    12631275PassRefPtr<IDBBackingStore::Transaction> IDBLevelDBBackingStore::createTransaction()
    12641276{
    1265     // FIXME: We need to implement a transaction abstraction that allows for roll-backs, and write tests for it.
    1266     return adoptRef(new DummyTransaction());
     1277    return Transaction::create(this);
     1278}
     1279
     1280PassRefPtr<IDBLevelDBBackingStore::Transaction> IDBLevelDBBackingStore::Transaction::create(IDBLevelDBBackingStore* backingStore)
     1281{
     1282    return adoptRef(new Transaction(backingStore));
     1283}
     1284
     1285IDBLevelDBBackingStore::Transaction::Transaction(IDBLevelDBBackingStore* backingStore)
     1286    : m_backingStore(backingStore)
     1287{
     1288}
     1289
     1290void IDBLevelDBBackingStore::Transaction::begin()
     1291{
     1292    ASSERT(!m_backingStore->m_currentTransaction);
     1293    m_backingStore->m_currentTransaction = LevelDBTransaction::create(m_backingStore->m_db.get());
     1294}
     1295
     1296void IDBLevelDBBackingStore::Transaction::commit()
     1297{
     1298    ASSERT(m_backingStore->m_currentTransaction);
     1299    m_backingStore->m_currentTransaction->commit();
     1300    m_backingStore->m_currentTransaction.clear();
     1301}
     1302
     1303void IDBLevelDBBackingStore::Transaction::rollback()
     1304{
     1305    ASSERT(m_backingStore->m_currentTransaction);
     1306    m_backingStore->m_currentTransaction->rollback();
     1307    m_backingStore->m_currentTransaction.clear();
    12671308}
    12681309
  • trunk/Source/WebCore/storage/IDBLevelDBBackingStore.h

    r87313 r87370  
    3737class LevelDBComparator;
    3838class LevelDBDatabase;
     39class LevelDBTransaction;
    3940
    4041class IDBLevelDBBackingStore : public IDBBackingStore {
     
    8182    OwnPtr<LevelDBDatabase> m_db;
    8283    OwnPtr<LevelDBComparator> m_comparator;
     84    RefPtr<LevelDBTransaction> m_currentTransaction;
     85
     86    class Transaction : public IDBBackingStore::Transaction {
     87    public:
     88        static PassRefPtr<Transaction> create(IDBLevelDBBackingStore*);
     89        virtual void begin();
     90        virtual void commit();
     91        virtual void rollback();
     92
     93    private:
     94        Transaction(IDBLevelDBBackingStore*);
     95        IDBLevelDBBackingStore* m_backingStore;
     96    };
    8397};
    8498
  • trunk/Source/WebCore/storage/IDBTransactionBackendImpl.cpp

    r86422 r87370  
    107107        return;
    108108
     109    bool wasRunning = m_state == Running;
     110
    109111    // The last reference to this object may be released while performing the
    110112    // abort steps below. We therefore take a self reference to keep ourselves
     
    117119
    118120    closeOpenCursors();
    119     m_transaction->rollback();
     121    if (wasRunning)
     122        m_transaction->rollback();
    120123
    121124    // Run the abort tasks, if any.
Note: See TracChangeset for help on using the changeset viewer.