summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/storage/IDBCursorBackendImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/storage/IDBCursorBackendImpl.cpp')
-rw-r--r--Source/WebCore/storage/IDBCursorBackendImpl.cpp59
1 files changed, 24 insertions, 35 deletions
diff --git a/Source/WebCore/storage/IDBCursorBackendImpl.cpp b/Source/WebCore/storage/IDBCursorBackendImpl.cpp
index d75e28d..089bb67 100644
--- a/Source/WebCore/storage/IDBCursorBackendImpl.cpp
+++ b/Source/WebCore/storage/IDBCursorBackendImpl.cpp
@@ -68,7 +68,6 @@ unsigned short IDBCursorBackendImpl::direction() const
PassRefPtr<IDBKey> IDBCursorBackendImpl::key() const
{
-
return m_currentKey;
}
@@ -79,43 +78,15 @@ PassRefPtr<IDBAny> IDBCursorBackendImpl::value() const
return IDBAny::create(m_currentIDBKeyValue.get());
}
-void IDBCursorBackendImpl::update(PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode& ec)
+void IDBCursorBackendImpl::update(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBCallbacks> callbacks, ExceptionCode& ec)
{
- RefPtr<IDBCursorBackendImpl> cursor = this;
- RefPtr<SerializedScriptValue> value = prpValue;
- RefPtr<IDBCallbacks> callbacks = prpCallbacks;
- // FIXME: Throw DATA_ERR and SERIAL_ERR when appropriate.
- if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::updateInternal, cursor, value, callbacks)))
+ if (!m_query || m_currentId == InvalidId || !m_isSerializedScriptValueCursor) {
ec = IDBDatabaseException::NOT_ALLOWED_ERR;
-}
-
-void IDBCursorBackendImpl::updateInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl> cursor, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBCallbacks> callbacks)
-{
- // FIXME: This method doesn't update indexes. It's dangerous to call in its current state.
- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Not implemented."));
- return;
-
- RefPtr<SerializedScriptValue> value = prpValue;
-
- if (!cursor->m_query || cursor->m_currentId == InvalidId) {
- // FIXME: Use the proper error code when it's specced.
- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Operation not possible."));
return;
}
- String sql = "UPDATE ObjectStoreData SET value = ? WHERE id = ?";
- SQLiteStatement updateQuery(cursor->database(), sql);
-
- bool ok = updateQuery.prepare() == SQLResultOk;
- ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
- updateQuery.bindText(1, value->toWireString());
- updateQuery.bindInt64(2, cursor->m_currentId);
- ok = updateQuery.step() == SQLResultDone;
- ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
-
- if (cursor->m_isSerializedScriptValueCursor)
- cursor->m_currentSerializedScriptValue = value.release();
- callbacks->onSuccess();
+ RefPtr<IDBKey> key = m_currentIDBKeyValue ? m_currentIDBKeyValue : m_currentKey;
+ m_objectStore->put(value, key.release(), IDBObjectStoreBackendInterface::CursorUpdate, callbacks, m_transaction.get(), ec);
}
void IDBCursorBackendImpl::continueFunction(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode& ec)
@@ -127,6 +98,20 @@ void IDBCursorBackendImpl::continueFunction(PassRefPtr<IDBKey> prpKey, PassRefPt
ec = IDBDatabaseException::NOT_ALLOWED_ERR;
}
+bool IDBCursorBackendImpl::currentRowExists()
+{
+ String sql = m_currentIDBKeyValue ? "SELECT id FROM IndexData WHERE id = ?" : "SELECT id FROM ObjectStoreData WHERE id = ?";
+ SQLiteStatement statement(m_database->db(), sql);
+
+ bool ok = statement.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok);
+
+ statement.bindInt64(1, m_currentId);
+ return statement.step() == SQLResultRow;
+}
+
+// IMPORTANT: If this ever 1) fires an 'error' event and 2) it's possible to fire another event afterwards,
+// IDBRequest::hasPendingActivity() will need to be modified to handle this!!!
void IDBCursorBackendImpl::continueFunctionInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl> prpCursor, PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> callbacks)
{
RefPtr<IDBCursorBackendImpl> cursor = prpCursor;
@@ -138,13 +123,17 @@ void IDBCursorBackendImpl::continueFunctionInternal(ScriptExecutionContext*, Pas
cursor->m_currentKey = 0;
cursor->m_currentSerializedScriptValue = 0;
cursor->m_currentIDBKeyValue = 0;
- callbacks->onSuccess();
+ callbacks->onSuccess(SerializedScriptValue::nullValue());
return;
}
RefPtr<IDBKey> oldKey = cursor->m_currentKey;
cursor->loadCurrentRow();
+ // Skip if this entry has been deleted from the object store.
+ if (!cursor->currentRowExists())
+ continue;
+
// If a key was supplied, we must loop until we find that key (or hit the end).
if (key && !key->isEqual(cursor->m_currentKey.get()))
continue;
@@ -178,7 +167,7 @@ void IDBCursorBackendImpl::loadCurrentRow()
m_currentId = m_query->getColumnInt64(0);
m_currentKey = IDBKey::fromQuery(*m_query, 1);
if (m_isSerializedScriptValueCursor)
- m_currentSerializedScriptValue = SerializedScriptValue::createFromWire(m_query->getColumnText(4));
+ m_currentSerializedScriptValue = SerializedScriptValue::createFromWire(m_query->getColumnBlobAsString(4));
m_currentIDBKeyValue = IDBKey::fromQuery(*m_query, 5);
}