Ejemplo n.º 1
0
EncodedJSValue JSC_HOST_CALL jsIDBCursorPrototypeFunctionContinue(ExecState* exec)
{
    JSValue thisValue = exec->hostThisValue();
    if (!thisValue.inherits(&JSIDBCursor::s_info))
        return throwVMTypeError(exec);
    JSIDBCursor* castedThis = static_cast<JSIDBCursor*>(asObject(thisValue));
    ASSERT_GC_OBJECT_INHERITS(castedThis, &JSIDBCursor::s_info);
    IDBCursor* imp = static_cast<IDBCursor*>(castedThis->impl());
    ExceptionCode ec = 0;

    size_t argsCount = exec->argumentCount();
    if (argsCount <= 0) {
        imp->continueFunction(ec);
        setDOMException(exec, ec);
        return JSValue::encode(jsUndefined());
    }

    RefPtr<IDBKey> key(createIDBKeyFromValue(exec, exec->argument(0)));
    if (exec->hadException())
        return JSValue::encode(jsUndefined());

    imp->continueFunction(key, ec);
    setDOMException(exec, ec);
    return JSValue::encode(jsUndefined());
}
Ejemplo n.º 2
0
JSValue jsIDBCursorSource(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSIDBCursor* castedThis = static_cast<JSIDBCursor*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    IDBCursor* imp = static_cast<IDBCursor*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->source()));
    return result;
}
Ejemplo n.º 3
0
JSValue jsIDBCursorDirection(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSIDBCursor* castedThis = static_cast<JSIDBCursor*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    IDBCursor* imp = static_cast<IDBCursor*>(castedThis->impl());
    JSValue result = jsNumber(imp->direction());
    return result;
}
Ejemplo n.º 4
0
void IDBTransaction::iterateCursor(IDBCursor& cursor, const IDBKeyData& key, unsigned long count)
{
    LOG(IndexedDB, "IDBTransaction::iterateCursor");
    ASSERT(isActive());
    ASSERT(cursor.request());

    addRequest(*cursor.request());

    auto operation = createTransactionOperation(*this, *cursor.request(), &IDBTransaction::didIterateCursorOnServer, &IDBTransaction::iterateCursorOnServer, key, count);
    scheduleOperation(WTFMove(operation));
}
Ejemplo n.º 5
0
IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBCursor& cursor, IDBTransaction& transaction)
    : IDBOpenDBRequest(&context)
    , m_transaction(&transaction)
    , m_connection(transaction.serverConnection())
    , m_resourceIdentifier(transaction.serverConnection())
    , m_source(cursor.source())
    , m_pendingCursor(&cursor)
{
    suspendIfNeeded();

    cursor.setRequest(*this);
}
Ejemplo n.º 6
0
void IDBRequest::checkForReferenceCycle()
{
    // If this request and its cursor have the only references
    // to each other, then explicitly break the cycle.
    IDBCursor* cursor = getResultCursor();
    if (!cursor || cursor->request() != this)
        return;

    if (!hasOneRef() || !cursor->hasOneRef())
        return;

    m_result.clear();
}
Ejemplo n.º 7
0
IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBCursor& cursor, IDBTransaction& transaction)
    : IDBOpenDBRequest(&context)
    , m_transaction(&transaction)
    , m_connection(transaction.serverConnection())
    , m_resourceIdentifier(transaction.serverConnection())
    , m_pendingCursor(&cursor)
{
    suspendIfNeeded();

    cursor.setRequest(*this);

    auto* cursorSource = cursor.source();
    ASSERT(cursorSource);
    ASSERT(cursorSource->type() == IDBAny::Type::IDBObjectStore || cursorSource->type() == IDBAny::Type::IDBIndex);
    m_source = cursorSource;
}
Ejemplo n.º 8
0
IDBRequest::IDBRequest(ScriptExecutionContext& context, IDBCursor& cursor, IDBTransaction& transaction)
    : IDBActiveDOMObject(&context)
    , m_transaction(&transaction)
    , m_resourceIdentifier(transaction.connectionProxy())
    , m_pendingCursor(&cursor)
    , m_connectionProxy(transaction.database().connectionProxy())
{
    suspendIfNeeded();

    WTF::switchOn(cursor.source(),
        [this] (const auto& value) { this->m_source = IDBRequest::Source { value }; }
    );

    m_result = NullResultType::Empty;
    cursor.setRequest(*this);
}
Ejemplo n.º 9
0
EncodedJSValue JSC_HOST_CALL jsIDBCursorPrototypeFunctionDelete(ExecState* exec)
{
    JSValue thisValue = exec->hostThisValue();
    if (!thisValue.inherits(&JSIDBCursor::s_info))
        return throwVMTypeError(exec);
    JSIDBCursor* castedThis = static_cast<JSIDBCursor*>(asObject(thisValue));
    ASSERT_GC_OBJECT_INHERITS(castedThis, &JSIDBCursor::s_info);
    IDBCursor* imp = static_cast<IDBCursor*>(castedThis->impl());
    ExceptionCode ec = 0;
    ScriptExecutionContext* scriptContext = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext();
    if (!scriptContext)
        return JSValue::encode(jsUndefined());


    JSC::JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->deleteFunction(scriptContext, ec)));
    setDOMException(exec, ec);
    return JSValue::encode(result);
}
Ejemplo n.º 10
0
EncodedJSValue JSC_HOST_CALL jsIDBCursorPrototypeFunctionUpdate(ExecState* exec)
{
    JSValue thisValue = exec->hostThisValue();
    if (!thisValue.inherits(&JSIDBCursor::s_info))
        return throwVMTypeError(exec);
    JSIDBCursor* castedThis = static_cast<JSIDBCursor*>(asObject(thisValue));
    ASSERT_GC_OBJECT_INHERITS(castedThis, &JSIDBCursor::s_info);
    IDBCursor* imp = static_cast<IDBCursor*>(castedThis->impl());
    if (exec->argumentCount() < 1)
        return throwVMError(exec, createTypeError(exec, "Not enough arguments"));
    ExceptionCode ec = 0;
    ScriptExecutionContext* scriptContext = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext();
    if (!scriptContext)
        return JSValue::encode(jsUndefined());
    RefPtr<SerializedScriptValue> value(SerializedScriptValue::create(exec, exec->argument(0)));
    if (exec->hadException())
        return JSValue::encode(jsUndefined());


    JSC::JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->update(scriptContext, value, ec)));
    setDOMException(exec, ec);
    return JSValue::encode(result);
}
Ejemplo n.º 11
0
bool IDBRequest::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
{
    IDB_TRACE("IDBRequest::dispatchEvent");
    if (m_contextStopped || !executionContext())
        return false;
    ASSERT(m_readyState == PENDING);
    ASSERT(m_hasPendingActivity);
    ASSERT(m_enqueuedEvents.size());
    ASSERT(event->target() == this);

    ScriptState::Scope scope(m_scriptState.get());

    if (event->type() != EventTypeNames::blocked)
        m_readyState = DONE;
    dequeueEvent(event.get());

    WillBeHeapVector<RefPtrWillBeMember<EventTarget> > targets;
    targets.append(this);
    if (m_transaction && !m_preventPropagation) {
        targets.append(m_transaction);
        // If there ever are events that are associated with a database but
        // that do not have a transaction, then this will not work and we need
        // this object to actually hold a reference to the database (to ensure
        // it stays alive).
        targets.append(m_transaction->db());
    }

    // Cursor properties should not be updated until the success event is being dispatched.
    IDBCursor* cursorToNotify = 0;
    if (event->type() == EventTypeNames::success) {
        cursorToNotify = getResultCursor();
        if (cursorToNotify) {
            if (m_blobInfo && m_blobInfo->size() > 0)
                V8PerIsolateData::from(scriptState()->isolate())->ensureIDBPendingTransactionMonitor()->unregisterRequest(*this);
            cursorToNotify->setValueReady(m_cursorKey.release(), m_cursorPrimaryKey.release(), m_cursorValue.release(), m_blobInfo.release());
        }
    }

    if (event->type() == EventTypeNames::upgradeneeded) {
        ASSERT(!m_didFireUpgradeNeededEvent);
        m_didFireUpgradeNeededEvent = true;
    }

    // FIXME: When we allow custom event dispatching, this will probably need to change.
    ASSERT_WITH_MESSAGE(event->type() == EventTypeNames::success || event->type() == EventTypeNames::error || event->type() == EventTypeNames::blocked || event->type() == EventTypeNames::upgradeneeded, "event type was %s", event->type().utf8().data());
    const bool setTransactionActive = m_transaction && (event->type() == EventTypeNames::success || event->type() == EventTypeNames::upgradeneeded || (event->type() == EventTypeNames::error && !m_requestAborted));

    if (setTransactionActive)
        m_transaction->setActive(true);

    bool dontPreventDefault = IDBEventDispatcher::dispatch(event.get(), targets);

    if (m_transaction) {
        if (m_readyState == DONE)
            m_transaction->unregisterRequest(this);

        // Possibly abort the transaction. This must occur after unregistering (so this request
        // doesn't receive a second error) and before deactivating (which might trigger commit).
        if (event->type() == EventTypeNames::error && dontPreventDefault && !m_requestAborted) {
            m_transaction->setError(m_error);
            m_transaction->abort(IGNORE_EXCEPTION);
        }

        // If this was the last request in the transaction's list, it may commit here.
        if (setTransactionActive)
            m_transaction->setActive(false);
    }

    if (cursorToNotify)
        cursorToNotify->postSuccessHandlerCallback();

    // An upgradeneeded event will always be followed by a success or error event, so must
    // be kept alive.
    if (m_readyState == DONE && event->type() != EventTypeNames::upgradeneeded)
        m_hasPendingActivity = false;

    return dontPreventDefault;
}