Exemplo n.º 1
0
void IDBConnectionProxy::putOrAdd(TransactionOperation& operation, IDBKey* key, const IDBValue& value, const IndexedDB::ObjectStoreOverwriteMode mode)
{
    const IDBRequestData requestData(operation);
    saveOperation(operation);

    callConnectionOnMainThread(&IDBConnectionToServer::putOrAdd, requestData, IDBKeyData(key), value, mode);
}
Exemplo n.º 2
0
void IDBCursor::advance(unsigned long count, ExceptionCode& ec)
{
    LOG(IndexedDB, "IDBCursor::advance");

    if (!m_request) {
        ec = IDBDatabaseException::InvalidStateError;
        return;
    }
    
    if (!count) {
        ec = TypeError;
        return;
    }

    if (sourcesDeleted()) {
        ec = IDBDatabaseException::InvalidStateError;
        return;
    }

    if (!transaction().isActive()) {
        ec = IDBDatabaseException::TransactionInactiveError;
        return;
    }

    if (!m_gotValue) {
        ec = IDBDatabaseException::InvalidStateError;
        return;
    }

    m_gotValue = false;

    uncheckedIteratorCursor(IDBKeyData(), count);
}
Exemplo n.º 3
0
IDBKeyData::IDBKeyData(const IDBKey* key)
    : m_type(KeyType::Invalid)
{
    if (!key) {
        m_isNull = true;
        return;
    }

    m_type = key->type();

    switch (m_type) {
    case KeyType::Invalid:
        break;
    case KeyType::Array:
        for (auto& key2 : key->array())
            m_arrayValue.append(IDBKeyData(key2.get()));
        break;
    case KeyType::String:
        m_stringValue = key->string();
        break;
    case KeyType::Date:
        m_numberValue = key->date();
        break;
    case KeyType::Number:
        m_numberValue = key->number();
        break;
    case KeyType::Max:
    case KeyType::Min:
        break;
    }
}
Exemplo n.º 4
0
void IDBKeyData::setNumberValue(double value)
{
    *this = IDBKeyData();
    m_numberValue = value;
    m_type = KeyType::Number;
    m_isNull = false;
}
Exemplo n.º 5
0
void IDBKeyData::setStringValue(const String& value)
{
    *this = IDBKeyData();
    m_stringValue = value;
    m_type = KeyType::String;
    m_isNull = false;
}
Exemplo n.º 6
0
void IDBKeyData::setArrayValue(const Vector<IDBKeyData>& value)
{
    *this = IDBKeyData();
    m_arrayValue = value;
    m_type = KeyType::Array;
    m_isNull = false;
}
Exemplo n.º 7
0
void IDBCursor::continueFunction(ScriptExecutionContext* context, ExceptionCode& ec)
{
    if (!context) {
        ec = IDBDatabaseException::InvalidStateError;
        return;
    }

    continueFunction(IDBKeyData(), ec);
}
Exemplo n.º 8
0
IDBKeyData IndexValueStore::lowestKeyWithRecordInRange(const IDBKeyRangeData& range) const
{
    LOG(IndexedDB, "IndexValueStore::lowestKeyWithRecordInRange - %s", range.loggingString().utf8().data());

    if (range.isExactlyOneKey())
        return m_records.contains(range.lowerKey) ? range.lowerKey : IDBKeyData();

    auto iterator = lowestIteratorInRange(range);
    if (iterator == m_orderedKeys.end())
        return { };

    return *iterator;
}
void generateIndexKeysForValue(ExecState* exec, const IDBIndexMetadata& indexMetadata, const Deprecated::ScriptValue& objectValue, Vector<IDBKeyData>& indexKeys)
{
    RefPtr<IDBKey> indexKey = createIDBKeyFromScriptValueAndKeyPath(exec, objectValue, indexMetadata.keyPath);

    if (!indexKey)
        return;

    if (!indexMetadata.multiEntry || indexKey->type() != KeyType::Array) {
        if (!indexKey->isValid())
            return;

        indexKeys.append(IDBKeyData(indexKey.get()));
    } else {
        ASSERT(indexMetadata.multiEntry);
        ASSERT(indexKey->type() == KeyType::Array);
        indexKey = IDBKey::createMultiEntryArray(indexKey->array());

        if (!indexKey->isValid())
            return;

        for (auto& i : indexKey->array())
            indexKeys.append(IDBKeyData(i.get()));
    }
}
Exemplo n.º 10
0
void IDBCursor::advance(unsigned long count, ExceptionCodeWithMessage& ec)
{
    LOG(IndexedDB, "IDBCursor::advance");

    if (!m_request) {
        ec.code = IDBDatabaseException::InvalidStateError;
        return;
    }
    
    if (!count) {
        ec.code = TypeError;
        ec.message = ASCIILiteral("Failed to execute 'advance' on 'IDBCursor': A count argument with value 0 (zero) was supplied, must be greater than 0.");
        return;
    }

    if (sourcesDeleted()) {
        ec.code = IDBDatabaseException::InvalidStateError;
        return;
    }

    if (!transaction().isActive()) {
        ec.code = IDBDatabaseException::TransactionInactiveError;
        ec.message = ASCIILiteral("Failed to execute 'advance' on 'IDBCursor': The transaction is inactive or finished.");
        return;
    }

    if (!m_gotValue) {
        ec.code = IDBDatabaseException::InvalidStateError;
        ec.message = ASCIILiteral("Failed to execute 'advance' on 'IDBCursor': The cursor is being iterated or has iterated past its end.");
        return;
    }

    m_gotValue = false;

    uncheckedIteratorCursor(IDBKeyData(), count);
}
SQLiteIDBCursor::AdvanceResult SQLiteIDBCursor::internalAdvanceOnce()
{
    ASSERT(m_transaction->sqliteTransaction());
    ASSERT(m_statement);

    if (m_completed) {
        LOG_ERROR("Attempt to advance a completed cursor");
        return AdvanceResult::Failure;
    }

    int result = m_statement->step();
    if (result == SQLITE_DONE) {
        m_completed = true;

        // When a cursor reaches its end, that is indicated by having undefined keys/values
        m_currentKey = IDBKeyData();
        m_currentPrimaryKey = IDBKeyData();
        m_currentValueBuffer.clear();

        return AdvanceResult::Success;
    }

    if (result != SQLITE_ROW) {
        LOG_ERROR("Error advancing cursor - (%i) %s", result, m_transaction->sqliteTransaction()->database().lastErrorMsg());
        m_completed = true;
        m_errored = true;
        return AdvanceResult::Failure;
    }

    int64_t recordID = m_statement->getColumnInt64(0);

    // If the recordID of the record just fetched is the same as the current record ID
    // then this statement must have been re-prepared in response to an object store change.
    // We don't want to re-use the current record so we'll move on to the next one.
    if (recordID == m_currentRecordID)
        return AdvanceResult::ShouldAdvanceAgain;

    m_currentRecordID = recordID;

    Vector<uint8_t> keyData;
    m_statement->getColumnBlobAsVector(1, keyData);

    if (!deserializeIDBKeyData(keyData.data(), keyData.size(), m_currentKey)) {
        LOG_ERROR("Unable to deserialize key data from database while advancing cursor");
        m_completed = true;
        m_errored = true;
        return AdvanceResult::Failure;
    }

    m_statement->getColumnBlobAsVector(2, keyData);
    m_currentValueBuffer = keyData;

    // The primaryKey of an ObjectStore cursor is the same as its key.
    if (m_indexID == IDBIndexMetadata::InvalidId)
        m_currentPrimaryKey = m_currentKey;
    else {
        if (!deserializeIDBKeyData(keyData.data(), keyData.size(), m_currentPrimaryKey)) {
            LOG_ERROR("Unable to deserialize value data from database while advancing index cursor");
            m_completed = true;
            m_errored = true;
            return AdvanceResult::Failure;
        }

        SQLiteStatement objectStoreStatement(m_statement->database(), "SELECT value FROM Records WHERE key = CAST(? AS TEXT) and objectStoreID = ?;");

        if (objectStoreStatement.prepare() != SQLITE_OK
            || objectStoreStatement.bindBlob(1, m_currentValueBuffer.data(), m_currentValueBuffer.size()) != SQLITE_OK
            || objectStoreStatement.bindInt64(2, m_objectStoreID) != SQLITE_OK) {
            LOG_ERROR("Could not create index cursor statement into object store records (%i) '%s'", m_statement->database().lastError(), m_statement->database().lastErrorMsg());
            m_completed = true;
            m_errored = true;
            return AdvanceResult::Failure;
        }

        int result = objectStoreStatement.step();

        if (result == SQLITE_ROW)
            objectStoreStatement.getColumnBlobAsVector(0, m_currentValueBuffer);
        else if (result == SQLITE_DONE) {
            // This indicates that the record we're trying to retrieve has been removed from the object store.
            // Skip over it.
            return AdvanceResult::ShouldAdvanceAgain;
        } else {
            LOG_ERROR("Could not step index cursor statement into object store records (%i) '%s'", m_statement->database().lastError(), m_statement->database().lastErrorMsg());
            m_completed = true;
            m_errored = true;
            return AdvanceResult::Failure;

        }
    }

    return AdvanceResult::Success;
}
Exemplo n.º 12
0
String IDBKey::loggingString() const
{
    return IDBKeyData(this).loggingString();
}