Changeset 89948 in webkit


Ignore:
Timestamp:
Jun 28, 2011 12:19:33 PM (13 years ago)
Author:
commit-queue@webkit.org
Message:

2011-06-28 Greg Simon <gregsimon@chromium.org>

Reviewed by Dimitri Glazkov.

Update migration LayoutTest to include indexes and successful migration.
https://bugs.webkit.org/show_bug.cgi?id=62780

  • storage/indexeddb/migrate-basics-expected.txt:
  • storage/indexeddb/migrate-basics.html:

2011-06-28 Greg Simon <gregsimon@chromium.org>

Reviewed by Dimitri Glazkov.

Migrate SQLite backing store to LevelDB backing store for Indexeddb.
https://bugs.webkit.org/show_bug.cgi?id=62780

  • storage/IDBFactoryBackendImpl.cpp: (WebCore::computeFileIdentifier): (WebCore::computeUniqueIdentifier): (WebCore::IDBFactoryBackendImpl::open): (WebCore::migrateObjectStores): (WebCore::IDBFactoryBackendImpl::migrateFromSQLiteToLevelDB):
  • storage/IDBLevelDBBackingStore.cpp: (WebCore::IDBLevelDBBackingStore::backingStoreExists):
  • storage/IDBLevelDBBackingStore.h:
  • storage/IDBObjectStoreBackendImpl.cpp: (WebCore::IDBObjectStoreBackendImpl::populateIndex):
  • storage/IDBObjectStoreBackendImpl.h:
  • storage/IDBSQLiteBackingStore.cpp: (WebCore::IDBSQLiteBackingStore::backingStoreExists):
  • storage/IDBSQLiteBackingStore.h:
Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r89946 r89948  
     12011-06-28  Greg Simon  <gregsimon@chromium.org>
     2
     3        Reviewed by Dimitri Glazkov.
     4
     5        Update migration LayoutTest to include indexes and successful migration.
     6        https://bugs.webkit.org/show_bug.cgi?id=62780
     7
     8        * storage/indexeddb/migrate-basics-expected.txt:
     9        * storage/indexeddb/migrate-basics.html:
     10
    1112011-06-28  Gavin Barraclough  <barraclough@apple.com>
    212
  • trunk/LayoutTests/storage/indexeddb/migrate-basics-expected.txt

    r88358 r89948  
    2828leveldbCheckPlainOldStore():
    2929store = trans.objectStore('MigrationPlainOldStore')
    30 FAIL store = trans.objectStore('MigrationPlainOldStore') threw exception Error: NOT_FOUND_ERR: DOM IDBDatabase Exception 3
    3130request = store.openCursor(keyRange)
    32 FAIL request = store.openCursor(keyRange) threw exception TypeError: Cannot call method 'openCursor' of undefined
     31leveldbCheckPlainOldStoreCursorNext():
     32PASS cursor.value.name == 'George' is true
     33leveldbCheckPlainOldStoreCursorNext():
     34leveldbCheckStoreWithKeyPath():
     35store = trans.objectStore('MigrationStoreWithKeyPath')
     36leveldbCheckStoreWithKeyPathCursorNext():
     37PASS ((window.index = window.store.index('ExampleIndex')) != undefined) is true
     38PASS (window.keyIndexCursor.key == 3) is true
     39PASS cursor.value.name == 'Thomas' is true
     40PASS cursor.value.id == '3' is true
     41leveldbCheckStoreWithKeyPathCursorNext():
     42leveldbCheckStoreWithAutoIncrement():
     43store = trans.objectStore('MigrationStoreWithAutoIncrement')
     44leveldbCheckStoreWithAutoIncrementCursorNext():
     45PASS cursor.value.name == 'Lincoln' is true
     46PASS cursor.value.number == '7012' is true
     47leveldbCheckStoreWithAutoIncrementCursorNext():
    3348PASS successfullyParsed is true
    3449
  • trunk/LayoutTests/storage/indexeddb/migrate-basics.html

    r88358 r89948  
    4646    window.index = evalAndLog("index = store.createIndex('ExampleIndex','id', false)");
    4747
    48 
    4948    sqliteTestAddRecords1();
    5049}
     
    152151    }
    153152
     153    shouldBeTrue("((window.index = window.store.index('ExampleIndex')) != undefined)");
     154    openKeyCursor = window.index.openKeyCursor();
     155    openKeyCursor.onsuccess = leveldbCheckStoreWithKeyPathCursorNext2;
     156    openKeyCursor.onerror = unexpectedErrorCallback;
     157}
     158
     159function leveldbCheckStoreWithKeyPathCursorNext2()
     160{
     161    window.keyIndexCursor = event.target.result;
     162    shouldBeTrue("(window.keyIndexCursor.key == 3)");
    154163    shouldBeTrue("cursor.value.name == 'Thomas'");
    155164    shouldBeTrue("cursor.value.id == '3'");
  • trunk/Source/WebCore/ChangeLog

    r89945 r89948  
     12011-06-28  Greg Simon  <gregsimon@chromium.org>
     2
     3        Reviewed by Dimitri Glazkov.
     4
     5        Migrate SQLite backing store to LevelDB backing store for Indexeddb.
     6        https://bugs.webkit.org/show_bug.cgi?id=62780
     7
     8        * storage/IDBFactoryBackendImpl.cpp:
     9        (WebCore::computeFileIdentifier):
     10        (WebCore::computeUniqueIdentifier):
     11        (WebCore::IDBFactoryBackendImpl::open):
     12        (WebCore::migrateObjectStores):
     13        (WebCore::IDBFactoryBackendImpl::migrateFromSQLiteToLevelDB):
     14        * storage/IDBLevelDBBackingStore.cpp:
     15        (WebCore::IDBLevelDBBackingStore::backingStoreExists):
     16        * storage/IDBLevelDBBackingStore.h:
     17        * storage/IDBObjectStoreBackendImpl.cpp:
     18        (WebCore::IDBObjectStoreBackendImpl::populateIndex):
     19        * storage/IDBObjectStoreBackendImpl.h:
     20        * storage/IDBSQLiteBackingStore.cpp:
     21        (WebCore::IDBSQLiteBackingStore::backingStoreExists):
     22        * storage/IDBSQLiteBackingStore.h:
     23
    1242011-06-28  Levi Weintraub  <leviw@chromium.org>
    225
  • trunk/Source/WebCore/storage/IDBFactoryBackendImpl.cpp

    r89130 r89948  
    3434#include "IDBDatabaseException.h"
    3535#include "IDBLevelDBBackingStore.h"
     36#include "IDBObjectStoreBackendImpl.h"
    3637#include "IDBSQLiteBackingStore.h"
    3738#include "IDBTransactionCoordinator.h"
     
    4445namespace WebCore {
    4546
     47static String computeFileIdentifier(SecurityOrigin* securityOrigin, IDBFactoryBackendInterface::BackingStoreType type)
     48{
     49    return securityOrigin->databaseIdentifier() + String::format("@%d", type);
     50}
     51
     52static String computeUniqueIdentifier(const String& name, SecurityOrigin* securityOrigin, IDBFactoryBackendInterface::BackingStoreType type)
     53{
     54    return computeFileIdentifier(securityOrigin, type) + name;
     55}
     56
    4657IDBFactoryBackendImpl::IDBFactoryBackendImpl()
    4758    : m_transactionCoordinator(IDBTransactionCoordinator::create())
     
    7687        backingStoreType = SQLiteBackingStore; // FIXME: DefaultBackingStore is confusing; get rid of it.
    7788
    78     const String fileIdentifier = securityOrigin->databaseIdentifier() + String::format("@%d", static_cast<int>(backingStoreType));
    79     const String uniqueIdentifier = fileIdentifier + "@" + name;
     89    const String fileIdentifier = computeFileIdentifier(securityOrigin.get(), backingStoreType);
     90    const String uniqueIdentifier = computeUniqueIdentifier(name, securityOrigin.get(), backingStoreType);
    8091
    8192    IDBDatabaseBackendMap::iterator it = m_databaseBackendMap.find(uniqueIdentifier);
     
    95106#if ENABLE(LEVELDB)
    96107        if (backingStoreType == LevelDBBackingStore) {
    97             const bool hasSQLBackingStore = IDBSQLiteBackingStore::backingStoreExists(securityOrigin.get(), dataDir);
     108            bool hasSQLBackingStore = IDBSQLiteBackingStore::backingStoreExists(securityOrigin.get(), name, dataDir);
     109
     110            // LayoutTests: SQLite backing store may not exist on disk but may exist in cache.
     111            String cachedSqliteBackingStoreIdentifier = computeFileIdentifier(securityOrigin.get(), SQLiteBackingStore);
     112            if (!hasSQLBackingStore && (m_backingStoreMap.end() != m_backingStoreMap.find(cachedSqliteBackingStoreIdentifier)))
     113                hasSQLBackingStore = true;
    98114
    99115            if (hasSQLBackingStore) {
     
    121137}
    122138
     139#if ENABLE(LEVELDB)
     140
     141static bool migrateObjectStores(PassRefPtr<IDBBackingStore> fromBackingStore, int64_t fromDatabaseId, PassRefPtr<IDBBackingStore> toBackingStore, int64_t toDatabaseId)
     142{
     143    Vector<int64_t> fromObjStoreIds, toObjStoreIds;
     144    Vector<String> fromObjStoreNames, toObjStoreNames;
     145    Vector<String> fromKeyPaths, toKeyPaths;
     146    Vector<bool> fromAutoIncrement, toAutoIncrement;
     147
     148    // Migrate objectStores. Check to see if the object store already exists in the target.
     149    fromBackingStore->getObjectStores(fromDatabaseId, fromObjStoreIds, fromObjStoreNames, fromKeyPaths, fromAutoIncrement);
     150
     151    toBackingStore->getObjectStores(toDatabaseId, toObjStoreIds, toObjStoreNames, toKeyPaths, toAutoIncrement);
     152
     153    for (unsigned i = 0; i < fromObjStoreIds.size(); i++) {
     154        if (toObjStoreNames.contains(fromObjStoreNames[i]))
     155            continue;
     156
     157        int64_t assignedObjectStoreId = -1;
     158
     159        RefPtr<IDBBackingStore::Transaction> trans = toBackingStore->createTransaction();
     160        trans->begin();
     161
     162        if (!toBackingStore->createObjectStore(toDatabaseId, fromObjStoreNames[i], fromKeyPaths[i], fromAutoIncrement[i], assignedObjectStoreId))
     163            return false;
     164
     165        RefPtr<IDBBackingStore::Cursor> cursor = fromBackingStore->openObjectStoreCursor(fromDatabaseId, fromObjStoreIds[i], 0, IDBCursor::NEXT);
     166        if (cursor) {
     167            do {
     168                RefPtr<IDBKey> key = cursor->key();
     169                RefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> recordIdentifier = toBackingStore->createInvalidRecordIdentifier();
     170
     171                if (!toBackingStore->putObjectStoreRecord(toDatabaseId, assignedObjectStoreId, *(key.get()), cursor->value(), recordIdentifier.get()))
     172                    return false;
     173
     174            } while (cursor->continueFunction());
     175        }
     176
     177        // Populate any/all indexes for this objectstore.
     178        Vector<int64_t> idxIds;
     179        Vector<String> idxNames;
     180        Vector<String> idxKeyPaths;
     181        Vector<bool> idxUnique;
     182        fromBackingStore->getIndexes(fromDatabaseId, fromObjStoreIds[i], idxIds, idxNames, idxKeyPaths, idxUnique);
     183        for (unsigned j = 0; j < idxIds.size(); j++) {
     184            int64_t indexId = -1;
     185
     186            if (!toBackingStore->createIndex(toDatabaseId, assignedObjectStoreId, idxNames[j], idxKeyPaths[j], idxUnique[j], indexId))
     187                return false;
     188
     189            if (!IDBObjectStoreBackendImpl::populateIndex(*toBackingStore, toDatabaseId, assignedObjectStoreId, indexId, fromKeyPaths[i]))
     190                return false;
     191        }
     192
     193        trans->commit();
     194    }
     195
     196    return true;
     197}
     198#endif // #if ENABLE(LEVELDB)
     199
    123200bool IDBFactoryBackendImpl::migrateFromSQLiteToLevelDB(const String& name, SecurityOrigin* securityOrigin, const String& dataDir, int64_t maximumSize)
    124201{
    125     return false; // FIXME: To be implemented.
     202#if ENABLE(LEVELDB)
     203    String fromUniqueIdentifier = computeUniqueIdentifier(name, securityOrigin, SQLiteBackingStore);
     204    String fromFileIdentifier = computeFileIdentifier(securityOrigin, SQLiteBackingStore);
     205    String toUniqueIdentifier = computeUniqueIdentifier(name, securityOrigin, LevelDBBackingStore);
     206    String toFileIdentifier = computeFileIdentifier(securityOrigin, LevelDBBackingStore);
     207    RefPtr<IDBTransactionCoordinator> transactionCoordinator = IDBTransactionCoordinator::create();
     208    RefPtr<IDBBackingStore> fromBackingStore;
     209    RefPtr<IDBDatabaseBackendImpl> fromDatabaseBackend;
     210    RefPtr<IDBBackingStore> toBackingStore;
     211
     212
     213    // Open "From" backing store and backend. When running LayoutTests, the
     214    // "from" database may be cached in this class instance, so look for it there first.
     215    IDBBackingStoreMap::iterator it = m_backingStoreMap.find(fromFileIdentifier);
     216    if (it != m_backingStoreMap.end())
     217        fromBackingStore = it->second;
     218    else
     219        fromBackingStore = IDBSQLiteBackingStore::open(securityOrigin, dataDir, maximumSize, fromFileIdentifier, this);
     220
     221    if (!fromBackingStore)
     222        return false;
     223
     224    IDBDatabaseBackendMap::iterator it2 = m_databaseBackendMap.find(fromUniqueIdentifier);
     225    if (it2 != m_databaseBackendMap.end())
     226        fromDatabaseBackend = it2->second;
     227    else {
     228        fromDatabaseBackend = IDBDatabaseBackendImpl::create(name, fromBackingStore.get(), transactionCoordinator.get(), this, fromUniqueIdentifier);
     229        m_databaseBackendMap.set(fromUniqueIdentifier, fromDatabaseBackend.get());
     230    }
     231
     232    if (!fromDatabaseBackend)
     233        return false;
     234
     235    // Open "To" database. First find out if it already exists -- this will determine if
     236    // it is safe to call IDBLevelDBBackingStore::extractIDBDatabaseMetaData.
     237    it = m_backingStoreMap.find(toFileIdentifier);
     238    if (it != m_backingStoreMap.end())
     239        toBackingStore = it->second;
     240    else
     241        toBackingStore = IDBLevelDBBackingStore::open(securityOrigin, dataDir, maximumSize, toFileIdentifier, this);
     242
     243    if (!toBackingStore)
     244        return false;
     245
     246
     247    String toDatabaseName = fromDatabaseBackend->name();
     248    String toDatabaseVersion = fromDatabaseBackend->version();
     249    int64_t toDatabaseId = -1;
     250
     251    if (!toBackingStore->extractIDBDatabaseMetaData(toDatabaseName, toDatabaseVersion, toDatabaseId)) {
     252        if (!toBackingStore->setIDBDatabaseMetaData(toDatabaseName, toDatabaseVersion, toDatabaseId, true))
     253            return false;
     254    }
     255
     256    return migrateObjectStores(fromBackingStore, fromDatabaseBackend->id(), toBackingStore, toDatabaseId);
     257
     258#endif // ENABLE(LEVELDB)
     259    return false;
    126260}
    127261
  • trunk/Source/WebCore/storage/IDBLevelDBBackingStore.cpp

    r89707 r89948  
    13051305}
    13061306
    1307 bool IDBLevelDBBackingStore::backingStoreExists(SecurityOrigin* securityOrigin, const String& pathBaseArg)
     1307bool IDBLevelDBBackingStore::backingStoreExists(SecurityOrigin* securityOrigin, const String&, const String& pathBaseArg)
    13081308{
    13091309    String pathBase = pathBaseArg;
     
    13151315    String path = pathByAppendingComponent(pathBase, securityOrigin->databaseIdentifier() + ".indexeddb.leveldb");
    13161316
    1317     // FIXME: It would be more thorough to open the database here but also more expensive.
    1318     if (fileExists(path+"/CURRENT"))
    1319         return true;
    1320 
    1321     return false;
     1317    // FIXME: this is checking for presence of the domain, not the database itself
     1318    return fileExists(path+"/CURRENT");
    13221319}
    13231320
  • trunk/Source/WebCore/storage/IDBLevelDBBackingStore.h

    r89707 r89948  
    7777    virtual IDBFactoryBackendInterface::BackingStoreType backingStoreType() const { return IDBFactoryBackendInterface::LevelDBBackingStore; }
    7878
    79     static bool backingStoreExists(SecurityOrigin*, const String& pathBase);
     79    static bool backingStoreExists(SecurityOrigin*, const String& name, const String& pathBase);
    8080
    8181private:
  • trunk/Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp

    r86804 r89948  
    376376}
    377377
    378 static bool populateIndex(IDBBackingStore& backingStore, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const String& indexKeyPath)
     378bool IDBObjectStoreBackendImpl::populateIndex(IDBBackingStore& backingStore, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const String& indexKeyPath)
    379379{
    380380    PopulateIndexCallback callback(backingStore, indexKeyPath, databaseId, objectStoreId, indexId);
  • trunk/Source/WebCore/storage/IDBObjectStoreBackendImpl.h

    r83443 r89948  
    7878    virtual void openCursor(PassRefPtr<IDBKeyRange> range, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
    7979
     80    static bool populateIndex(IDBBackingStore&, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const String& indexKeyPath);
     81
    8082private:
    8183    IDBObjectStoreBackendImpl(IDBBackingStore*, int64_t databaseId, int64_t id, const String& name, const String& keyPath, bool autoIncrement);
  • trunk/Source/WebCore/storage/IDBSQLiteBackingStore.cpp

    r89707 r89948  
    992992}
    993993
    994 bool IDBSQLiteBackingStore::backingStoreExists(SecurityOrigin* securityOrigin, const String& pathBase)
     994bool IDBSQLiteBackingStore::backingStoreExists(SecurityOrigin* securityOrigin, const String& name, const String& pathBase)
    995995{
    996996    String path = pathByAppendingComponent(pathBase, securityOrigin->databaseIdentifier() + ".indexeddb");
    997     if (!fileExists(path))
    998         return false;
    999 
    1000997    SQLiteDatabase db;
    1001998    if (!db.open(path))
    1002999        return false;
    10031000
    1004     db.close();
    1005     return true;
     1001    SQLiteStatement databaseQuery(db, "SELECT id, version FROM Databases WHERE name = ?");
     1002    if (databaseQuery.prepare() != SQLResultOk)
     1003        return false;
     1004
     1005    databaseQuery.bindText(1, name);
     1006    return (databaseQuery.step() == SQLResultRow);
    10061007}
    10071008
  • trunk/Source/WebCore/storage/IDBSQLiteBackingStore.h

    r89707 r89948  
    7272    virtual IDBFactoryBackendInterface::BackingStoreType backingStoreType() const { return IDBFactoryBackendInterface::SQLiteBackingStore; }
    7373
    74     static bool backingStoreExists(SecurityOrigin*, const String& pathBase);
     74    static bool backingStoreExists(SecurityOrigin*, const String& name, const String& pathBase);
    7575
    7676private:
Note: See TracChangeset for help on using the changeset viewer.