summaryrefslogtreecommitdiff
path: root/Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp')
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp626
1 files changed, 0 insertions, 626 deletions
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp b/Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp
deleted file mode 100644
index b7333f965..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "IDBServerConnectionLevelDB.h"
-
-#if ENABLE(INDEXED_DATABASE)
-#if USE(LEVELDB)
-
-#include "IDBBackingStoreCursorLevelDB.h"
-#include "IDBBackingStoreLevelDB.h"
-#include "IDBBackingStoreTransactionLevelDB.h"
-#include "IDBCursorBackend.h"
-#include "IDBFactoryBackendLevelDB.h"
-#include "IDBIndexWriterLevelDB.h"
-#include <wtf/MainThread.h>
-
-#define ASYNC_COMPLETION_CALLBACK_WITH_ARG(callback, arg) \
- callOnMainThread([callback, arg]() { \
- callback(arg); \
- });
-
-#define ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(callback, arg1, arg2) \
- callOnMainThread([callback]() { \
- callback(arg1, arg2); \
- });
-
-#define ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(callback) \
- callOnMainThread([callback]() { \
- callback(0); \
- });
-
-#define EMPTY_ASYNC_COMPLETION_CALLBACK(callback) \
- callOnMainThread([callback]() { \
- callback(); \
- });
-
-
-namespace WebCore {
-
-IDBServerConnectionLevelDB::IDBServerConnectionLevelDB(const String& databaseName, IDBBackingStoreLevelDB* backingStore)
- : m_backingStore(backingStore)
- , m_nextCursorID(1)
- , m_closed(false)
- , m_databaseName(databaseName)
-{
-}
-
-IDBServerConnectionLevelDB::~IDBServerConnectionLevelDB()
-{
-}
-
-bool IDBServerConnectionLevelDB::isClosed()
-{
- return m_closed;
-}
-
-void IDBServerConnectionLevelDB::getOrEstablishIDBDatabaseMetadata(GetIDBDatabaseMetadataFunction callback)
-{
- RefPtr<IDBServerConnection> self(this);
- m_backingStore->getOrEstablishIDBDatabaseMetadata(m_databaseName, [self, this, callback](const IDBDatabaseMetadata& metadata, bool success) {
- callback(metadata, success);
- });
-}
-
-void IDBServerConnectionLevelDB::deleteDatabase(const String& name, BoolCallbackFunction successCallback)
-{
- RefPtr<IDBServerConnection> self(this);
- m_backingStore->deleteDatabase(name, [self, this, successCallback](bool success) {
- successCallback(success);
- });
-}
-
-void IDBServerConnectionLevelDB::close()
-{
- m_backingStore.clear();
- m_closed = true;
-}
-
-void IDBServerConnectionLevelDB::openTransaction(int64_t transactionID, const HashSet<int64_t>&, IndexedDB::TransactionMode, BoolCallbackFunction successCallback)
-{
- if (!m_backingStore) {
- callOnMainThread([successCallback]() {
- successCallback(false);
- });
- return;
- }
-
- m_backingStore->establishBackingStoreTransaction(transactionID);
- callOnMainThread([successCallback]() {
- successCallback(true);
- });
-}
-
-void IDBServerConnectionLevelDB::beginTransaction(int64_t transactionID, std::function<void()> completionCallback)
-{
- RefPtr<IDBBackingStoreTransactionLevelDB> transaction = m_backingStoreTransactions.get(transactionID);
- ASSERT(transaction);
-
- transaction->begin();
- callOnMainThread(completionCallback);
-}
-
-void IDBServerConnectionLevelDB::commitTransaction(int64_t transactionID, BoolCallbackFunction successCallback)
-{
- RefPtr<IDBBackingStoreTransactionLevelDB> transaction = m_backingStoreTransactions.get(transactionID);
- ASSERT(transaction);
-
- bool result = transaction->commit();
- callOnMainThread([successCallback, result]() {
- successCallback(result);
- });
-}
-
-void IDBServerConnectionLevelDB::resetTransaction(int64_t transactionID, std::function<void()> completionCallback)
-{
- RefPtr<IDBBackingStoreTransactionLevelDB> transaction = m_backingStoreTransactions.get(transactionID);
- ASSERT(transaction);
-
- transaction->resetTransaction();
- callOnMainThread(completionCallback);
-}
-
-void IDBServerConnectionLevelDB::rollbackTransaction(int64_t transactionID, std::function<void()> completionCallback)
-{
- RefPtr<IDBBackingStoreTransactionLevelDB> transaction = m_backingStoreTransactions.get(transactionID);
- ASSERT(transaction);
-
- transaction->rollback();
- callOnMainThread(completionCallback);
-}
-
-void IDBServerConnectionLevelDB::setIndexKeys(int64_t transactionID, int64_t databaseID, int64_t objectStoreID, const IDBObjectStoreMetadata& objectStoreMetadata, IDBKey& primaryKey, const Vector<int64_t>& indexIDs, const Vector<Vector<RefPtr<IDBKey>>>& indexKeys, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- RefPtr<IDBBackingStoreTransactionLevelDB> backingStoreTransaction = m_backingStoreTransactions.get(transactionID);
- ASSERT(backingStoreTransaction);
-
- RefPtr<IDBRecordIdentifier> recordIdentifier;
- bool ok = m_backingStore->keyExistsInObjectStore(*backingStoreTransaction, databaseID, objectStoreID, primaryKey, recordIdentifier);
- if (!ok) {
- callOnMainThread([completionCallback]() {
- completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: setting index keys."));
- });
- return;
- }
- if (!recordIdentifier) {
- callOnMainThread([completionCallback]() {
- completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: setting index keys for object store."));
- });
- return;
- }
-
- Vector<RefPtr<IDBIndexWriterLevelDB>> indexWriters;
- String errorMessage;
- bool obeysConstraints = false;
-
- bool backingStoreSuccess = m_backingStore->makeIndexWriters(transactionID, databaseID, objectStoreMetadata, primaryKey, false, indexIDs, indexKeys, indexWriters, &errorMessage, obeysConstraints);
- if (!backingStoreSuccess) {
- callOnMainThread([completionCallback]() {
- completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys."));
- });
- return;
- }
- if (!obeysConstraints) {
- callOnMainThread([completionCallback, errorMessage]() {
- completionCallback(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage));
- });
- return;
- }
-
- for (size_t i = 0; i < indexWriters.size(); ++i) {
- IDBIndexWriterLevelDB* indexWriter = indexWriters[i].get();
- indexWriter->writeIndexKeys(recordIdentifier.get(), *m_backingStore, *backingStoreTransaction, databaseID, objectStoreID);
- }
-
- ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
-}
-
-void IDBServerConnectionLevelDB::createObjectStore(IDBTransactionBackend& transaction, const CreateObjectStoreOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
- ASSERT(backingStoreTransaction);
-
- String objectStoreName = operation.objectStoreMetadata().name;
-
- if (!m_backingStore->createObjectStore(*backingStoreTransaction, transaction.database().id(), operation.objectStoreMetadata().id, objectStoreName, operation.objectStoreMetadata().keyPath, operation.objectStoreMetadata().autoIncrement)) {
- callOnMainThread([completionCallback, objectStoreName]() {
- completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error creating object store '%s'.", objectStoreName.utf8().data())));
- });
- return;
- }
- ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
-}
-
-void IDBServerConnectionLevelDB::createIndex(IDBTransactionBackend& transaction, const CreateIndexOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
- ASSERT(backingStoreTransaction);
-
- const IDBIndexMetadata& indexMetadata = operation.idbIndexMetadata();
- if (!m_backingStore->createIndex(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), indexMetadata.id, indexMetadata.name, indexMetadata.keyPath, indexMetadata.unique, indexMetadata.multiEntry)) {
- callOnMainThread([completionCallback, indexMetadata]() {
- completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error when trying to create index '%s'.", indexMetadata.name.utf8().data())));
- });
- return;
- }
- ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
-}
-
-void IDBServerConnectionLevelDB::deleteIndex(IDBTransactionBackend& transaction, const DeleteIndexOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
- ASSERT(backingStoreTransaction);
-
- const IDBIndexMetadata& indexMetadata = operation.idbIndexMetadata();
- if (!m_backingStore->deleteIndex(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), indexMetadata.id)) {
- callOnMainThread([completionCallback, indexMetadata]() {
- completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error deleting index '%s'.", indexMetadata.name.utf8().data())));
- });
- return;
- }
- ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
-}
-
-void IDBServerConnectionLevelDB::get(IDBTransactionBackend& transaction, const GetOperation& operation, std::function<void(const IDBGetResult&, PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
- ASSERT(backingStoreTransaction);
-
- RefPtr<IDBKey> key;
-
- if (operation.keyRange()->isOnlyKey())
- key = operation.keyRange()->lower();
- else {
- RefPtr<IDBBackingStoreCursorLevelDB> backingStoreCursor;
- int64_t cursorID = m_nextCursorID++;
-
- if (operation.indexID() == IDBIndexMetadata::InvalidId) {
- ASSERT(operation.cursorType() != IndexedDB::CursorType::KeyOnly);
- // ObjectStore Retrieval Operation
- backingStoreCursor = m_backingStore->openObjectStoreCursor(cursorID, *backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.keyRange(), IndexedDB::CursorDirection::Next);
- } else {
- if (operation.cursorType() == IndexedDB::CursorType::KeyOnly) {
- // Index Value Retrieval Operation
- backingStoreCursor = m_backingStore->openIndexKeyCursor(cursorID, *backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.indexID(), operation.keyRange(), IndexedDB::CursorDirection::Next);
- } else {
- // Index Referenced Value Retrieval Operation
- backingStoreCursor = m_backingStore->openIndexCursor(cursorID, *backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.indexID(), operation.keyRange(), IndexedDB::CursorDirection::Next);
- }
- }
-
- if (!backingStoreCursor) {
- ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, IDBGetResult(), nullptr);
- return;
- }
-
- key = backingStoreCursor->key();
- }
-
- RefPtr<IDBKey> primaryKey;
- bool ok;
- if (operation.indexID() == IDBIndexMetadata::InvalidId) {
- // Object Store Retrieval Operation
- Vector<char> value;
- ok = m_backingStore->getRecord(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), *key, value);
- if (!ok) {
- ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, IDBGetResult(), IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
- return;
- }
-
- if (value.isEmpty()) {
- ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, IDBGetResult(), nullptr);
- return;
- }
-
- IDBGetResult result;
-
- if (operation.autoIncrement() && !operation.keyPath().isNull())
- result = IDBGetResult(SharedBuffer::adoptVector(value), key, operation.keyPath());
- else
- result = IDBGetResult(SharedBuffer::adoptVector(value));
-
- callOnMainThread([completionCallback, result]() {
- completionCallback(result, nullptr);
- });
- return;
- }
-
- // From here we are dealing only with indexes.
- ok = m_backingStore->getPrimaryKeyViaIndex(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.indexID(), *key, primaryKey);
- if (!ok) {
- ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, IDBGetResult(), IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getPrimaryKeyViaIndex."));
- return;
- }
- if (!primaryKey) {
- ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, IDBGetResult(), nullptr);
- return;
- }
- if (operation.cursorType() == IndexedDB::CursorType::KeyOnly) {
- // Index Value Retrieval Operation
- IDBGetResult result(primaryKey.release());
- callOnMainThread([completionCallback, result]() {
- completionCallback(result, nullptr);
- });
- return;
- }
-
- // Index Referenced Value Retrieval Operation
- Vector<char> value;
- ok = m_backingStore->getRecord(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), *primaryKey, value);
- if (!ok) {
- ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, IDBGetResult(), IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
- return;
- }
-
- if (value.isEmpty()) {
- ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, IDBGetResult(), nullptr);
- return;
- }
- if (operation.autoIncrement() && !operation.keyPath().isNull()) {
- IDBGetResult result(SharedBuffer::adoptVector(value), key, operation.keyPath());
- callOnMainThread([completionCallback, result]() {
- completionCallback(result, nullptr);
- });
-
- return;
- }
-
- IDBGetResult result(SharedBuffer::adoptVector(value));
- callOnMainThread([completionCallback, result]() {
- completionCallback(result, nullptr);
- });
-}
-
-void IDBServerConnectionLevelDB::put(IDBTransactionBackend& transaction, const PutOperation& operation, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
- ASSERT(backingStoreTransaction);
-
- bool keyWasGenerated = false;
-
- RefPtr<IDBKey> key;
- if (operation.putMode() != IDBDatabaseBackend::CursorUpdate && operation.objectStore().autoIncrement && !operation.key()) {
- RefPtr<IDBKey> autoIncKey = m_backingStore->generateKey(transaction, transaction.database().id(), operation.objectStore().id);
- keyWasGenerated = true;
- if (!autoIncKey->isValid()) {
- ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, nullptr, IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Maximum key generator value reached."));
- return;
- }
- key = autoIncKey;
- } else
- key = operation.key();
-
- ASSERT(key);
- ASSERT(key->isValid());
-
- RefPtr<IDBRecordIdentifier> recordIdentifier;
- if (operation.putMode() == IDBDatabaseBackend::AddOnly) {
- bool ok = m_backingStore->keyExistsInObjectStore(*backingStoreTransaction, transaction.database().id(), operation.objectStore().id, *key, recordIdentifier);
- if (!ok) {
- ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error checking key existence."));
- return;
- }
- if (recordIdentifier) {
- ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, nullptr, IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Key already exists in the object store."));
- return;
- }
- }
-
- Vector<RefPtr<IDBIndexWriterLevelDB>> indexWriters;
- String errorMessage;
- bool obeysConstraints = false;
- bool backingStoreSuccess = m_backingStore->makeIndexWriters(transaction.id(), transaction.database().id(), operation.objectStore(), *key, keyWasGenerated, operation.indexIDs(), operation.indexKeys(), indexWriters, &errorMessage, obeysConstraints);
- if (!backingStoreSuccess) {
- ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys."));
- return;
- }
- if (!obeysConstraints) {
- callOnMainThread([completionCallback, errorMessage]() { \
- completionCallback(nullptr, IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage)); \
- });
- return;
- }
-
- // Before this point, don't do any mutation. After this point, rollback the transaction in case of error.
- backingStoreSuccess = m_backingStore->putRecord(*backingStoreTransaction, transaction.database().id(), operation.objectStore().id, *key, operation.value(), recordIdentifier.get());
- if (!backingStoreSuccess) {
- ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error performing put/add."));
- return;
- }
-
- for (size_t i = 0; i < indexWriters.size(); ++i) {
- IDBIndexWriterLevelDB* indexWriter = indexWriters[i].get();
- indexWriter->writeIndexKeys(recordIdentifier.get(), *m_backingStore, *backingStoreTransaction, transaction.database().id(), operation.objectStore().id);
- }
-
- if (operation.objectStore().autoIncrement && operation.putMode() != IDBDatabaseBackend::CursorUpdate && key->type() == IDBKey::NumberType) {
- bool ok = m_backingStore->updateKeyGenerator(transaction, transaction.database().id(), operation.objectStore().id, *key, !keyWasGenerated);
- if (!ok) {
- ASYNC_COMPLETION_CALLBACK_WITH_TWO_ARGS(completionCallback, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error updating key generator."));
- return;
- }
- }
-
- callOnMainThread([completionCallback, key]() { \
- completionCallback(key.get(), nullptr); \
- });
-}
-
-void IDBServerConnectionLevelDB::openCursor(IDBTransactionBackend& transaction, const OpenCursorOperation& operation, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
- ASSERT(backingStoreTransaction);
-
- // The frontend has begun indexing, so this pauses the transaction
- // until the indexing is complete. This can't happen any earlier
- // because we don't want to switch to early mode in case multiple
- // indexes are being created in a row, with put()'s in between.
- if (operation.taskType() == IDBDatabaseBackend::PreemptiveTask)
- transaction.addPreemptiveEvent();
-
- int64_t cursorID = m_nextCursorID++;
-
- RefPtr<IDBBackingStoreCursorLevelDB> backingStoreCursor;
- if (operation.indexID() == IDBIndexMetadata::InvalidId) {
- ASSERT(operation.cursorType() != IndexedDB::CursorType::KeyOnly);
- backingStoreCursor = m_backingStore->openObjectStoreCursor(cursorID, *backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.keyRange(), operation.direction());
- } else {
- ASSERT(operation.taskType() == IDBDatabaseBackend::NormalTask);
- if (operation.cursorType() == IndexedDB::CursorType::KeyOnly)
- backingStoreCursor = m_backingStore->openIndexKeyCursor(cursorID, *backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.indexID(), operation.keyRange(), operation.direction());
- else
- backingStoreCursor = m_backingStore->openIndexCursor(cursorID, *backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.indexID(), operation.keyRange(), operation.direction());
- }
-
- if (!backingStoreCursor) {
- // FIXME: Should it be an error to not have a backing store cursor?
- cursorID = 0;
- }
-
- callOnMainThread([completionCallback, cursorID]() {
- completionCallback(cursorID, nullptr);
- });
-}
-
-void IDBServerConnectionLevelDB::count(IDBTransactionBackend& transaction, const CountOperation& operation, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
- ASSERT(backingStoreTransaction);
-
- uint32_t count = 0;
- RefPtr<IDBBackingStoreCursorLevelDB> backingStoreCursor;
-
- int64_t cursorID = m_nextCursorID++;
-
- if (operation.indexID() == IDBIndexMetadata::InvalidId)
- backingStoreCursor = m_backingStore->openObjectStoreKeyCursor(cursorID, *backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.keyRange(), IndexedDB::CursorDirection::Next);
- else
- backingStoreCursor = m_backingStore->openIndexKeyCursor(cursorID, *backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.indexID(), operation.keyRange(), IndexedDB::CursorDirection::Next);
- if (!backingStoreCursor) {
- // FIXME: Is this an error case?
- callOnMainThread([completionCallback, count]() {
- completionCallback(count, nullptr);
- });
- return;
- }
-
- do {
- ++count;
- } while (backingStoreCursor->continueFunction(0));
-
- callOnMainThread([completionCallback, count]() {
- completionCallback(count, nullptr);
- });
-}
-
-void IDBServerConnectionLevelDB::deleteRange(IDBTransactionBackend& transaction, const DeleteRangeOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
- ASSERT(backingStoreTransaction);
-
- int64_t cursorID = m_nextCursorID++;
-
- RefPtr<IDBBackingStoreCursorLevelDB> backingStoreCursor = m_backingStore->openObjectStoreCursor(cursorID, *backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.keyRange(), IndexedDB::CursorDirection::Next);
- if (backingStoreCursor) {
- do {
- if (!m_backingStore->deleteRecord(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), backingStoreCursor->recordIdentifier())) {
- callOnMainThread([completionCallback]() {
- completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Error deleting data in range"));
- });
- return;
- }
- } while (backingStoreCursor->continueFunction(0));
- }
-
- callOnMainThread([completionCallback]() {
- completionCallback(nullptr);
- });
-}
-
-void IDBServerConnectionLevelDB::clearObjectStore(IDBTransactionBackend& transaction, const ClearObjectStoreOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
- ASSERT(backingStoreTransaction);
-
- if (!m_backingStore->clearObjectStore(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID())) {
- callOnMainThread([completionCallback]() {
- completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Error clearing object store"));
- });
- return;
- }
-
- ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
-}
-
-void IDBServerConnectionLevelDB::deleteObjectStore(IDBTransactionBackend& transaction, const DeleteObjectStoreOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
- ASSERT(backingStoreTransaction);
-
- const IDBObjectStoreMetadata& objectStoreMetadata = operation.objectStoreMetadata();
-
- if (!m_backingStore->deleteObjectStore(*backingStoreTransaction, transaction.database().id(), objectStoreMetadata.id)) {
- callOnMainThread([completionCallback, objectStoreMetadata]() {
- completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error deleting object store '%s'.", objectStoreMetadata.name.utf8().data())));
- });
- return;
- }
- ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
-}
-
-void IDBServerConnectionLevelDB::changeDatabaseVersion(IDBTransactionBackend& transaction, const IDBDatabaseBackend::VersionChangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
- ASSERT(backingStoreTransaction);
-
- IDBDatabaseBackend& database = transaction.database();
- int64_t databaseId = database.id();
-
- if (!m_backingStore->updateIDBDatabaseVersion(*backingStoreTransaction, databaseId, database.metadata().version)) {
- RefPtr<IDBDatabaseError> error = IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Error writing data to stable storage when updating version.");
- ASYNC_COMPLETION_CALLBACK_WITH_ARG(completionCallback, error);
- return;
- }
-
- ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
-}
-
-void IDBServerConnectionLevelDB::cursorAdvance(IDBCursorBackend& cursor, const CursorAdvanceOperation& operation, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- IDBBackingStoreCursorLevelDB* backingStoreCursor = cursor.id() ? m_backingStoreCursors.get(cursor.id()) : 0;
-#ifndef NDEBUG
- if (cursor.id())
- ASSERT(backingStoreCursor);
-#endif
-
- if (!backingStoreCursor || !backingStoreCursor->advance(operation.count())) {
- m_backingStoreCursors.remove(cursor.id());
-
- callOnMainThread([completionCallback]() {
- completionCallback(nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error advancing cursor"));
- });
-
- return;
- }
-
- RefPtr<IDBKey> key = backingStoreCursor->key(), primaryKey = backingStoreCursor->primaryKey();
- RefPtr<SharedBuffer> value = backingStoreCursor->value();
-
- callOnMainThread([completionCallback, key, primaryKey, value]() {
- completionCallback(key, primaryKey, value, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error advancing cursor"));
- });
-}
-
-void IDBServerConnectionLevelDB::cursorIterate(IDBCursorBackend& cursor, const CursorIterationOperation& operation, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
-{
- IDBBackingStoreCursorLevelDB* backingStoreCursor = cursor.id() ? m_backingStoreCursors.get(cursor.id()) : 0;
-#ifndef NDEBUG
- if (cursor.id())
- ASSERT(backingStoreCursor);
-#endif
-
- if (!backingStoreCursor || !backingStoreCursor->continueFunction(operation.key())) {
- m_backingStoreCursors.remove(cursor.id());
-
- callOnMainThread([completionCallback]() {
- completionCallback(nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error advancing cursor"));
- });
-
- return;
- }
-
- RefPtr<IDBKey> key = backingStoreCursor->key(), primaryKey = backingStoreCursor->primaryKey();
- RefPtr<SharedBuffer> value = backingStoreCursor->value();
-
- callOnMainThread([completionCallback, key, primaryKey, value]() {
- completionCallback(key, primaryKey, value, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error advancing cursor"));
- });
-}
-
-} // namespace WebCore
-
-#endif // USE(LEVELDB)
-#endif // ENABLE(INDEXED_DATABASE)