Changeset 163076 in webkit


Ignore:
Timestamp:
Jan 30, 2014 12:19:40 AM (10 years ago)
Author:
beidson@apple.com
Message:

IDB: Key generator support
https://bugs.webkit.org/show_bug.cgi?id=127871

Reviewed by Tim Horton.

  • DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:

(WebKit::UniqueIDBDatabase::putRecordInBackingStore): Update for storing/retrieving integers instead of IDBKeys.

  • DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
  • DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:

(WebKit::UniqueIDBDatabaseBackingStoreSQLite::createAndPopulateInitialMetadata): Create a keygen table.
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::createObjectStore): Put a record in the keygen table for

this object store if necessary.

(WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore): Delete the entry in the keygen table.
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::generateKeyNumber): Pull the current number from the table.
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::updateKeyGeneratorNumber): Update the number in the table.

  • DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:
  • WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:

(WebKit::WebIDBServerConnection::put): Null keys are acceptable for autoIncrement object stores.

Location:
trunk/Source/WebKit2
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r163075 r163076  
     12014-01-30  Brady Eidson  <beidson@apple.com>
     2
     3        IDB: Key generator support
     4        https://bugs.webkit.org/show_bug.cgi?id=127871
     5
     6        Reviewed by Tim Horton.
     7
     8        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
     9        (WebKit::UniqueIDBDatabase::putRecordInBackingStore): Update for storing/retrieving integers instead of IDBKeys.
     10        * DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
     11
     12        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
     13        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::createAndPopulateInitialMetadata): Create a keygen table.
     14        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::createObjectStore): Put a record in the keygen table for
     15          this object store if necessary.
     16        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore): Delete the entry in the keygen table.
     17        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::generateKeyNumber): Pull the current number from the table.
     18        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::updateKeyGeneratorNumber): Update the number in the table.
     19        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:
     20
     21        * WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:
     22        (WebKit::WebIDBServerConnection::put): Null keys are acceptable for autoIncrement object stores.
     23
    1242014-01-30  Brady Eidson  <beidson@apple.com>
    225
  • trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp

    r163075 r163076  
    754754    bool keyWasGenerated = false;
    755755    RefPtr<IDBKey> key;
     756    int64_t keyNumber = 0;
    756757
    757758    if (putMode != IDBDatabaseBackend::CursorUpdate && objectStoreMetadata.autoIncrement && keyData.isNull) {
    758         key = m_backingStore->generateKey(transaction, objectStoreMetadata.id);
     759        if (!m_backingStore->generateKeyNumber(transaction, objectStoreMetadata.id, keyNumber)) {
     760            postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didPutRecordInBackingStore, requestID, IDBKeyData(), IDBDatabaseException::UnknownError, ASCIILiteral("Internal backing store error checking for key existence")));
     761            return;
     762        }
     763        key = IDBKey::createNumber(keyNumber);
    759764        keyWasGenerated = true;
    760765    } else
     
    786791
    787792    if (putMode != IDBDatabaseBackend::CursorUpdate && objectStoreMetadata.autoIncrement && key->type() == IDBKey::NumberType) {
    788         if (!m_backingStore->updateKeyGenerator(transaction, objectStoreMetadata.id, *key, keyWasGenerated)) {
     793        if (!m_backingStore->updateKeyGeneratorNumber(transaction, objectStoreMetadata.id, keyNumber, keyWasGenerated)) {
    789794            postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didPutRecordInBackingStore, requestID, IDBKeyData(), IDBDatabaseException::UnknownError, ASCIILiteral("Internal backing store error updating key generator")));
    790795            return;
  • trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h

    r162891 r163076  
    6464    virtual bool deleteIndex(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID) = 0;
    6565
    66     virtual PassRefPtr<WebCore::IDBKey> generateKey(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID) = 0;
     66    virtual bool generateKeyNumber(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t& generatedKey) = 0;
     67    virtual bool updateKeyGeneratorNumber(const IDBIdentifier& transactionIdentifier, int64_t objectStoreId, int64_t keyNumber, bool checkCurrent) = 0;
     68
    6769    virtual bool keyExistsInObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, bool& keyExists) = 0;
    6870    virtual bool putRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, const uint8_t* valueBuffer, size_t valueSize) = 0;
    69     virtual bool updateKeyGenerator(const IDBIdentifier& transactionIdentifier, int64_t objectStoreId, const WebCore::IDBKey&, bool checkCurrent) = 0;
    7071
    7172    virtual bool getKeyRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, RefPtr<WebCore::SharedBuffer>& result) = 0;
  • trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp

    r163038 r163076  
    9999    }
    100100
     101    if (!m_sqliteDB->executeCommand("CREATE TABLE KeyGenerators (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, currentKey INTEGER NOT NULL ON CONFLICT FAIL);")) {
     102        LOG_ERROR("Could not create KeyGenerators table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     103        m_sqliteDB = nullptr;
     104        return nullptr;
     105    }
     106
    101107    {
    102108        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('MetadataVersion', ?);"));
     
    382388    }
    383389
    384     SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO ObjectStoreInfo VALUES (?, ?, ?, ?, ?);"));
    385     if (sql.prepare() != SQLResultOk
    386         || sql.bindInt64(1, metadata.id) != SQLResultOk
    387         || sql.bindText(2, metadata.name) != SQLResultOk
    388         || sql.bindBlob(3, keyPathBlob->data(), keyPathBlob->size()) != SQLResultOk
    389         || sql.bindInt(4, metadata.autoIncrement) != SQLResultOk
    390         || sql.bindInt64(5, metadata.maxIndexId) != SQLResultOk
    391         || sql.step() != SQLResultDone) {
    392         LOG_ERROR("Could not add object store '%s' to ObjectStoreInfo table (%i) - %s", metadata.name.utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
    393         return false;
     390    {
     391        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO ObjectStoreInfo VALUES (?, ?, ?, ?, ?);"));
     392        if (sql.prepare() != SQLResultOk
     393            || sql.bindInt64(1, metadata.id) != SQLResultOk
     394            || sql.bindText(2, metadata.name) != SQLResultOk
     395            || sql.bindBlob(3, keyPathBlob->data(), keyPathBlob->size()) != SQLResultOk
     396            || sql.bindInt(4, metadata.autoIncrement) != SQLResultOk
     397            || sql.bindInt64(5, metadata.maxIndexId) != SQLResultOk
     398            || sql.step() != SQLResultDone) {
     399            LOG_ERROR("Could not add object store '%s' to ObjectStoreInfo table (%i) - %s", metadata.name.utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     400            return false;
     401        }
     402    }
     403
     404    {
     405        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO KeyGenerators VALUES (?, 0);"));
     406        if (sql.prepare() != SQLResultOk
     407            || sql.bindInt64(1, metadata.id) != SQLResultOk
     408            || sql.step() != SQLResultDone) {
     409            LOG_ERROR("Could not seed initial key generator value for ObjectStoreInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     410            return false;
     411        }
    394412    }
    395413
     
    420438            || sql.step() != SQLResultDone) {
    421439            LOG_ERROR("Could not delete object store id %lli from ObjectStoreInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     440            return false;
     441        }
     442    }
     443
     444    // Delete the ObjectStore's key generator record if there is one.
     445    {
     446        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM KeyGenerators WHERE objectStoreID = ?;"));
     447        if (sql.prepare() != SQLResultOk
     448            || sql.bindInt64(1, objectStoreID) != SQLResultOk
     449            || sql.step() != SQLResultDone) {
     450            LOG_ERROR("Could not delete object store from KeyGenerators table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
    422451            return false;
    423452        }
     
    555584}
    556585
    557 PassRefPtr<IDBKey> UniqueIDBDatabaseBackingStoreSQLite::generateKey(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID)
    558 {
    559     // FIXME (<rdar://problem/15877909>): Implement
    560     return nullptr;
     586bool UniqueIDBDatabaseBackingStoreSQLite::generateKeyNumber(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t& generatedKey)
     587{
     588    ASSERT(!isMainThread());
     589    ASSERT(m_sqliteDB);
     590    ASSERT(m_sqliteDB->isOpen());
     591
     592    // The IndexedDatabase spec defines the max key generator value as 2^53;
     593    static const int64_t maxGeneratorValue = 9007199254740992LL;
     594
     595    SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
     596    if (!transaction || !transaction->inProgress()) {
     597        LOG_ERROR("Attempt to generate key in database without an established, in-progress transaction");
     598        return false;
     599    }
     600    if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
     601        LOG_ERROR("Attempt to generate key in database during read-only transaction");
     602        return false;
     603    }
     604
     605    int64_t currentValue;
     606    {
     607        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT currentKey FROM KeyGenerators WHERE objectStoreID = ?;"));
     608        if (sql.prepare() != SQLResultOk
     609            || sql.bindInt64(1, objectStoreID) != SQLResultOk) {
     610            LOG_ERROR("Could not delete index id %lli from IndexInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     611            return false;
     612        }
     613        int result = sql.step();
     614        if (result != SQLResultRow) {
     615            LOG_ERROR("Could not retreive key generator value for object store, but it should be there.");
     616            return false;
     617        }
     618
     619        currentValue = sql.getColumnInt64(0);
     620    }
     621
     622    if (currentValue < 0 || currentValue > maxGeneratorValue)
     623        return false;
     624
     625    generatedKey = currentValue + 1;
     626    return true;
     627}
     628
     629bool UniqueIDBDatabaseBackingStoreSQLite::updateKeyGeneratorNumber(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t keyNumber, bool)
     630{
     631    ASSERT(!isMainThread());
     632    ASSERT(m_sqliteDB);
     633    ASSERT(m_sqliteDB->isOpen());
     634
     635    SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
     636    if (!transaction || !transaction->inProgress()) {
     637        LOG_ERROR("Attempt to update key generator in database without an established, in-progress transaction");
     638        return false;
     639    }
     640    if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
     641        LOG_ERROR("Attempt to update key generator in database during read-only transaction");
     642        return false;
     643    }
     644
     645    {
     646        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO KeyGenerators VALUES (?, ?);"));
     647        if (sql.prepare() != SQLResultOk
     648            || sql.bindInt64(1, objectStoreID) != SQLResultOk
     649            || sql.bindInt64(2, keyNumber) != SQLResultOk
     650            || sql.step() != SQLResultDone) {
     651            LOG_ERROR("Could not update key generator value (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     652            return false;
     653        }
     654    }
     655
     656    return true;
    561657}
    562658
     
    601697
    602698    return true;
    603 }
    604 
    605 bool UniqueIDBDatabaseBackingStoreSQLite::updateKeyGenerator(const IDBIdentifier& transactionIdentifier, int64_t objectStoreId, const IDBKey&, bool checkCurrent)
    606 {
    607     // FIXME (<rdar://problem/15877909>): Implement
    608     return false;
    609699}
    610700
  • trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h

    r162891 r163076  
    6868    virtual bool deleteIndex(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID) override;
    6969
    70     virtual PassRefPtr<WebCore::IDBKey> generateKey(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID) override;
     70    virtual bool generateKeyNumber(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t& generatedKey) override;
     71    virtual bool updateKeyGeneratorNumber(const IDBIdentifier& transactionIdentifier, int64_t objectStoreId, int64_t keyNumber, bool checkCurrent) override;
     72
    7173    virtual bool keyExistsInObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, bool& keyExists) override;
    7274    virtual bool putRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, const uint8_t* valueBuffer, size_t valueSize) override;
    73     virtual bool updateKeyGenerator(const IDBIdentifier& transactionIdentifier, int64_t objectStoreId, const WebCore::IDBKey&, bool checkCurrent) override;
    7475
    7576    virtual bool getKeyRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, RefPtr<WebCore::SharedBuffer>& result) override;
  • trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp

    r163075 r163076  
    382382    LOG(IDB, "WebProcess put request ID %llu", requestID);
    383383
    384     ASSERT(operation.key());
    385384    ASSERT(operation.value());
    386385
Note: See TracChangeset for help on using the changeset viewer.