Exemple #1
0
bool UniqueIDBDatabaseBackingStoreSQLite::putRecord(const IDBTransactionIdentifier& identifier, int64_t objectStoreID, const IDBKey& key, const uint8_t* valueBuffer, size_t valueSize)
{
    ASSERT(!isMainThread());
    ASSERT(m_sqliteDB);
    ASSERT(m_sqliteDB->isOpen());

    SQLiteIDBTransaction* transaction = m_transactions.get(identifier);
    if (!transaction || !transaction->inProgress()) {
        LOG_ERROR("Attempt to put a record into database without an established, in-progress transaction");
        return false;
    }
    if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
        LOG_ERROR("Attempt to put a record into database during read-only transaction");
        return false;
    }

    RefPtr<SharedBuffer> keyBuffer = serializeIDBKey(key);
    if (!keyBuffer) {
        LOG_ERROR("Unable to serialize IDBKey to be stored in the database");
        return false;
    }
    {
        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO Records VALUES (?, ?, ?);"));
        if (sql.prepare() != SQLResultOk
            || sql.bindInt64(1, objectStoreID) != SQLResultOk
            || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLResultOk
            || sql.bindBlob(3, valueBuffer, valueSize) != SQLResultOk
            || sql.step() != SQLResultDone) {
            LOG_ERROR("Could not put record for object store %lli in Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
            return false;
        }
    }

    return true;
}
bool UniqueIDBDatabaseBackingStoreSQLite::changeDatabaseVersion(const IDBTransactionIdentifier& identifier, uint64_t newVersion)
{
    ASSERT(!isMainThread());
    ASSERT(m_sqliteDB);
    ASSERT(m_sqliteDB->isOpen());

    SQLiteIDBTransaction* transaction = m_transactions.get(identifier);
    if (!transaction || !transaction->inProgress()) {
        LOG_ERROR("Attempt to change database version with an establish, in-progress transaction");
        return false;
    }
    if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
        LOG_ERROR("Attempt to change database version during a non version-change transaction");
        return false;
    }

    {
        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("UPDATE IDBDatabaseInfo SET value = ? where key = 'DatabaseVersion';"));
        if (sql.prepare() != SQLResultOk
            || sql.bindText(1, String::number(newVersion)) != SQLResultOk
            || sql.step() != SQLResultDone) {
            LOG_ERROR("Could not update database version in IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
            return false;
        }
    }

    return true;
}
Exemple #3
0
bool UniqueIDBDatabaseBackingStoreSQLite::deleteIndex(const IDBTransactionIdentifier& identifier, int64_t objectStoreID, int64_t indexID)
{
    ASSERT(!isMainThread());
    ASSERT(m_sqliteDB);
    ASSERT(m_sqliteDB->isOpen());

    SQLiteIDBTransaction* transaction = m_transactions.get(identifier);
    if (!transaction || !transaction->inProgress()) {
        LOG_ERROR("Attempt to delete index without an established, in-progress transaction");
        return false;
    }
    if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
        LOG_ERROR("Attempt to delete index during a non-version-change transaction");
        return false;
    }

    {
        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE id = ? AND objectStoreID = ?;"));
        if (sql.prepare() != SQLResultOk
            || sql.bindInt64(1, indexID) != SQLResultOk
            || sql.bindInt64(2, objectStoreID) != SQLResultOk
            || sql.step() != SQLResultDone) {
            LOG_ERROR("Could not delete index id %lli from IndexInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
            return false;
        }
    }

    // FIXME (<rdar://problem/15905293>) - Once we store records against indexes, delete them here.
    return true;
}
Exemple #4
0
bool UniqueIDBDatabaseBackingStoreSQLite::clearObjectStore(const IDBTransactionIdentifier& identifier, int64_t objectStoreID)
{
    ASSERT(!isMainThread());
    ASSERT(m_sqliteDB);
    ASSERT(m_sqliteDB->isOpen());

    SQLiteIDBTransaction* transaction = m_transactions.get(identifier);
    if (!transaction || !transaction->inProgress()) {
        LOG_ERROR("Attempt to change database version with an establish, in-progress transaction");
        return false;
    }
    if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
        LOG_ERROR("Attempt to change database version during a read-only transaction");
        return false;
    }

    {
        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ?;"));
        if (sql.prepare() != SQLResultOk
            || sql.bindInt64(1, objectStoreID) != SQLResultOk
            || sql.step() != SQLResultDone) {
            LOG_ERROR("Could not delete records from object store id %lli (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
            return false;
        }
    }

    // FIXME <rdar://problem/15779642>: Once indexes are implemented, drop index records.
    return true;
}
Exemple #5
0
bool UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore(const IDBTransactionIdentifier& identifier, int64_t objectStoreID)
{
    ASSERT(!isMainThread());
    ASSERT(m_sqliteDB);
    ASSERT(m_sqliteDB->isOpen());

    SQLiteIDBTransaction* transaction = m_transactions.get(identifier);
    if (!transaction || !transaction->inProgress()) {
        LOG_ERROR("Attempt to change database version with an established, in-progress transaction");
        return false;
    }
    if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
        LOG_ERROR("Attempt to change database version during a non version-change transaction");
        return false;
    }

    // Delete the ObjectStore record
    {
        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM ObjectStoreInfo WHERE id = ?;"));
        if (sql.prepare() != SQLResultOk
            || sql.bindInt64(1, objectStoreID) != SQLResultOk
            || sql.step() != SQLResultDone) {
            LOG_ERROR("Could not delete object store id %lli from ObjectStoreInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
            return false;
        }
    }

    // Delete all associated Index records
    {
        Vector<int64_t> indexIDs;
        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id FROM IndexInfo WHERE objectStoreID = ?;"));
        if (sql.prepare() != SQLResultOk
            || sql.bindInt64(1, objectStoreID) != SQLResultOk) {
            LOG_ERROR("Error fetching index ID records for object store id %lli from IndexInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
            return false;
        }

        int resultCode;
        while ((resultCode = sql.step()) == SQLResultRow)
            indexIDs.append(sql.getColumnInt64(0));

        if (resultCode != SQLResultDone) {
            LOG_ERROR("Error fetching index ID records for object store id %lli from IndexInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
            return false;
        }

        for (auto indexID : indexIDs) {
            if (!deleteIndex(identifier, objectStoreID, indexID))
                return false;
        }
    }

    {
        // FIXME: Execute SQL here to drop all records related to this object store.
    }

    return true;
}
bool UniqueIDBDatabaseBackingStoreSQLite::rollbackTransaction(const IDBTransactionIdentifier& identifier)
{
    ASSERT(!isMainThread());

    SQLiteIDBTransaction* transaction = m_transactions.get(identifier);
    if (!transaction) {
        LOG_ERROR("Attempt to rollback a transaction that hasn't been established");
        return false;
    }

    return transaction->rollback();
}
Exemple #7
0
bool UniqueIDBDatabaseBackingStoreSQLite::getKeyRangeRecordFromObjectStore(const IDBTransactionIdentifier& identifier, int64_t objectStoreID, const WebCore::IDBKeyRange& keyRange, RefPtr<WebCore::SharedBuffer>& result, RefPtr<WebCore::IDBKey>& resultKey)
{
    ASSERT(!isMainThread());
    ASSERT(m_sqliteDB);
    ASSERT(m_sqliteDB->isOpen());

    SQLiteIDBTransaction* transaction = m_transactions.get(identifier);
    if (!transaction || !transaction->inProgress()) {
        LOG_ERROR("Attempt to put a record into database without an established, in-progress transaction");
        return false;
    }

    RefPtr<SharedBuffer> lowerBuffer = serializeIDBKey(*keyRange.lower());
    if (!lowerBuffer) {
        LOG_ERROR("Unable to serialize IDBKey to be stored in the database");
        return false;
    }

    RefPtr<SharedBuffer> upperBuffer = serializeIDBKey(*keyRange.upper());
    if (!upperBuffer) {
        LOG_ERROR("Unable to serialize IDBKey to be stored in the database");
        return false;
    }

    {
        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT value FROM Records WHERE objectStoreID = ? AND key >= ? AND key <= ? ORDER BY key;"));
        if (sql.prepare() != SQLResultOk
            || sql.bindInt64(1, objectStoreID) != SQLResultOk
            || sql.bindBlob(2, lowerBuffer->data(), lowerBuffer->size()) != SQLResultOk
            || sql.bindBlob(3, upperBuffer->data(), upperBuffer->size()) != SQLResultOk) {
            LOG_ERROR("Could not get key range record from object store %lli from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
            return false;
        }

        int sqlResult = sql.step();

        if (sqlResult == SQLResultOk || sqlResult == SQLResultDone) {
            // There was no record for the key in the database.
            return true;
        }
        if (sqlResult != SQLResultRow) {
            // There was an error fetching the record from the database.
            LOG_ERROR("Could not get record from object store %lli from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
            return false;
        }

        Vector<char> buffer;
        sql.getColumnBlobAsVector(0, buffer);
        result = SharedBuffer::create(static_cast<const char*>(buffer.data()), buffer.size());
    }

    return true;
}
SQLiteIDBCursor::SQLiteIDBCursor(SQLiteIDBTransaction& transaction, const uint64_t objectStoreID, const uint64_t indexID, const IDBKeyRangeData& range)
    : m_transaction(&transaction)
    , m_cursorIdentifier(transaction.transactionIdentifier())
    , m_objectStoreID(objectStoreID)
    , m_indexID(indexID ? indexID : IDBIndexMetadata::InvalidId)
    , m_cursorDirection(IndexedDB::CursorDirection::Next)
    , m_keyRange(range)
    , m_backingStoreCursor(true)
{
    ASSERT(m_objectStoreID);
}
Exemple #9
0
bool UniqueIDBDatabaseBackingStoreSQLite::createIndex(const IDBTransactionIdentifier& identifier, int64_t objectStoreID, const WebCore::IDBIndexMetadata& metadata)
{
    ASSERT(!isMainThread());
    ASSERT(m_sqliteDB);
    ASSERT(m_sqliteDB->isOpen());

    SQLiteIDBTransaction* transaction = m_transactions.get(identifier);
    if (!transaction || !transaction->inProgress()) {
        LOG_ERROR("Attempt to create index without an established, in-progress transaction");
        return false;
    }
    if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
        LOG_ERROR("Attempt to create index during a non-version-change transaction");
        return false;
    }

    RefPtr<SharedBuffer> keyPathBlob = serializeIDBKeyPath(metadata.keyPath);
    if (!keyPathBlob) {
        LOG_ERROR("Unable to serialize IDBKeyPath to save in database");
        return false;
    }

    SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexInfo VALUES (?, ?, ?, ?, ?, ?);"));
    if (sql.prepare() != SQLResultOk
        || sql.bindInt64(1, metadata.id) != SQLResultOk
        || sql.bindText(2, metadata.name) != SQLResultOk
        || sql.bindInt64(3, objectStoreID) != SQLResultOk
        || sql.bindBlob(4, keyPathBlob->data(), keyPathBlob->size()) != SQLResultOk
        || sql.bindInt(5, metadata.unique) != SQLResultOk
        || sql.bindInt(6, metadata.multiEntry) != SQLResultOk
        || sql.step() != SQLResultDone) {
        LOG_ERROR("Could not add index '%s' to IndexInfo table (%i) - %s", metadata.name.utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
        return false;
    }

    return true;
}