summaryrefslogtreecommitdiff
path: root/Source/WebCore/Modules/indexeddb/leveldb
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/Modules/indexeddb/leveldb')
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreCursorLevelDB.cpp202
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreCursorLevelDB.h100
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreLevelDB.cpp1931
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreLevelDB.h143
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreTransactionLevelDB.cpp86
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreTransactionLevelDB.h71
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.cpp197
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.h87
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBIndexWriterLevelDB.cpp94
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBIndexWriterLevelDB.h66
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBLevelDBCoding.cpp1807
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBLevelDBCoding.h367
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp626
-rw-r--r--Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h100
14 files changed, 0 insertions, 5877 deletions
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreCursorLevelDB.cpp b/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreCursorLevelDB.cpp
deleted file mode 100644
index b3c5f6113..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreCursorLevelDB.cpp
+++ /dev/null
@@ -1,202 +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 "IDBBackingStoreCursorLevelDB.h"
-
-#if ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
-
-#include "IDBBackingStoreLevelDB.h"
-#include "LevelDBTransaction.h"
-
-namespace WebCore {
-
-IDBBackingStoreCursorLevelDB::IDBBackingStoreCursorLevelDB(const IDBBackingStoreCursorLevelDB* other)
- : m_transaction(other->m_transaction)
- , m_cursorOptions(other->m_cursorOptions)
- , m_currentKey(other->m_currentKey)
- , m_recordIdentifier(IDBRecordIdentifier::create())
-{
- if (other->m_iterator) {
- m_iterator = m_transaction->createIterator();
-
- if (other->m_iterator->isValid()) {
- m_iterator->seek(other->m_iterator->key());
- ASSERT(m_iterator->isValid());
- }
- }
-
- m_recordIdentifier->reset(other->m_recordIdentifier->encodedPrimaryKey(), other->m_recordIdentifier->version());
-}
-
-bool IDBBackingStoreCursorLevelDB::firstSeek()
-{
- m_iterator = m_transaction->createIterator();
- if (m_cursorOptions.forward)
- m_iterator->seek(m_cursorOptions.lowKey);
- else
- m_iterator->seek(m_cursorOptions.highKey);
-
- return continueFunction(0, Ready);
-}
-
-bool IDBBackingStoreCursorLevelDB::advance(unsigned long count)
-{
- while (count--) {
- if (!continueFunction())
- return false;
- }
- return true;
-}
-
-bool IDBBackingStoreCursorLevelDB::continueFunction(const IDBKey* key, IteratorState nextState)
-{
- RefPtr<IDBKey> previousKey = m_currentKey;
-
- bool firstIteration = true;
-
- // When iterating with PrevNoDuplicate, spec requires that the
- // value we yield for each key is the first duplicate in forwards
- // order.
- RefPtr<IDBKey> lastDuplicateKey;
-
- bool forward = m_cursorOptions.forward;
-
- for (;;) {
- if (nextState == Seek) {
- // FIXME: Optimize seeking for reverse cursors as well.
- if (firstIteration && key && forward) {
- m_iterator->seek(encodeKey(*key));
- firstIteration = false;
- } else if (forward)
- m_iterator->next();
- else
- m_iterator->prev();
- } else
- nextState = Seek; // for subsequent iterations
-
- if (!m_iterator->isValid()) {
- if (!forward && lastDuplicateKey.get()) {
- // We need to walk forward because we hit the end of
- // the data.
- forward = true;
- continue;
- }
-
- return false;
- }
-
- if (isPastBounds()) {
- if (!forward && lastDuplicateKey.get()) {
- // We need to walk forward because now we're beyond the
- // bounds defined by the cursor.
- forward = true;
- continue;
- }
-
- return false;
- }
-
- if (!haveEnteredRange())
- continue;
-
- // The row may not load because there's a stale entry in the
- // index. This is not fatal.
- if (!loadCurrentRow())
- continue;
-
- if (key) {
- if (forward) {
- if (m_currentKey->isLessThan(key))
- continue;
- } else {
- if (key->isLessThan(m_currentKey.get()))
- continue;
- }
- }
-
- if (m_cursorOptions.unique) {
-
- if (m_currentKey->isEqual(previousKey.get())) {
- // We should never be able to walk forward all the way
- // to the previous key.
- ASSERT(!lastDuplicateKey.get());
- continue;
- }
-
- if (!forward) {
- if (!lastDuplicateKey.get()) {
- lastDuplicateKey = m_currentKey;
- continue;
- }
-
- // We need to walk forward because we hit the boundary
- // between key ranges.
- if (!lastDuplicateKey->isEqual(m_currentKey.get())) {
- forward = true;
- continue;
- }
-
- continue;
- }
- }
- break;
- }
-
- ASSERT(!lastDuplicateKey.get() || (forward && lastDuplicateKey->isEqual(m_currentKey.get())));
- return true;
-}
-
-bool IDBBackingStoreCursorLevelDB::haveEnteredRange() const
-{
- if (m_cursorOptions.forward) {
- if (m_cursorOptions.lowOpen)
- return IDBBackingStoreLevelDB::compareIndexKeys(m_iterator->key(), m_cursorOptions.lowKey) > 0;
-
- return IDBBackingStoreLevelDB::compareIndexKeys(m_iterator->key(), m_cursorOptions.lowKey) >= 0;
- }
- if (m_cursorOptions.highOpen)
- return IDBBackingStoreLevelDB::compareIndexKeys(m_iterator->key(), m_cursorOptions.highKey) < 0;
-
- return IDBBackingStoreLevelDB::compareIndexKeys(m_iterator->key(), m_cursorOptions.highKey) <= 0;
-}
-
-bool IDBBackingStoreCursorLevelDB::isPastBounds() const
-{
- if (m_cursorOptions.forward) {
- if (m_cursorOptions.highOpen)
- return IDBBackingStoreLevelDB::compareIndexKeys(m_iterator->key(), m_cursorOptions.highKey) >= 0;
- return IDBBackingStoreLevelDB::compareIndexKeys(m_iterator->key(), m_cursorOptions.highKey) > 0;
- }
-
- if (m_cursorOptions.lowOpen)
- return IDBBackingStoreLevelDB::compareIndexKeys(m_iterator->key(), m_cursorOptions.lowKey) <= 0;
- return IDBBackingStoreLevelDB::compareIndexKeys(m_iterator->key(), m_cursorOptions.lowKey) < 0;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
-
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreCursorLevelDB.h b/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreCursorLevelDB.h
deleted file mode 100644
index 972088478..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreCursorLevelDB.h
+++ /dev/null
@@ -1,100 +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.
- */
-
-#ifndef IDBBackingStoreCursorLevelDB_h
-#define IDBBackingStoreCursorLevelDB_h
-
-#include "IDBKey.h"
-#include "IDBRecordIdentifier.h"
-#include "LevelDBIterator.h"
-
-#if ENABLE(INDEXED_DATABASE)
-#if USE(LEVELDB)
-
-namespace WebCore {
-
-class LevelDBTransaction;
-class SharedBuffer;
-
-class IDBBackingStoreCursorLevelDB : public RefCounted<IDBBackingStoreCursorLevelDB> {
-public:
- enum IteratorState {
- Ready = 0,
- Seek
- };
-
- struct CursorOptions {
- int64_t databaseId;
- int64_t objectStoreId;
- int64_t indexId;
- Vector<char> lowKey;
- bool lowOpen;
- Vector<char> highKey;
- bool highOpen;
- bool forward;
- bool unique;
- };
-
- virtual PassRefPtr<IDBKey> key() const { return m_currentKey; }
- virtual bool continueFunction(const IDBKey* = 0, IteratorState = Seek);
- virtual bool advance(unsigned long);
- bool firstSeek();
-
- virtual PassRefPtr<IDBBackingStoreCursorLevelDB> clone() = 0;
-
- virtual PassRefPtr<IDBKey> primaryKey() const { return m_currentKey; }
- virtual PassRefPtr<SharedBuffer> value() const = 0;
- virtual const IDBRecordIdentifier& recordIdentifier() const { return *m_recordIdentifier; }
- virtual ~IDBBackingStoreCursorLevelDB() { }
- virtual bool loadCurrentRow() = 0;
-
-protected:
- IDBBackingStoreCursorLevelDB(int64_t cursorID, LevelDBTransaction* transaction, const CursorOptions& cursorOptions)
- : m_cursorID(cursorID)
- , m_transaction(transaction)
- , m_cursorOptions(cursorOptions)
- , m_recordIdentifier(IDBRecordIdentifier::create())
- {
- }
- explicit IDBBackingStoreCursorLevelDB(const IDBBackingStoreCursorLevelDB* other);
-
- virtual Vector<char> encodeKey(const IDBKey&) = 0;
-
- bool isPastBounds() const;
- bool haveEnteredRange() const;
-
- int64_t m_cursorID;
- LevelDBTransaction* m_transaction;
- const CursorOptions m_cursorOptions;
- OwnPtr<LevelDBIterator> m_iterator;
- RefPtr<IDBKey> m_currentKey;
- RefPtr<IDBRecordIdentifier> m_recordIdentifier;
-};
-
-} // namespace WebCore
-
-#endif // USE(LEVELDB)
-#endif // ENABLE(INDEXED_DATABASE)
-#endif // IDBBackingStoreCursorLevelDB_h
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreLevelDB.cpp b/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreLevelDB.cpp
deleted file mode 100644
index 0712bdf38..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreLevelDB.cpp
+++ /dev/null
@@ -1,1931 +0,0 @@
-/*
- * Copyright (C) 2011 Google 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 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 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 "IDBBackingStoreLevelDB.h"
-
-#if ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
-
-#include "FileSystem.h"
-#include "HistogramSupport.h"
-#include "IDBDatabaseMetadata.h"
-#include "IDBIndexWriterLevelDB.h"
-#include "IDBKey.h"
-#include "IDBKeyPath.h"
-#include "IDBKeyRange.h"
-#include "IDBLevelDBCoding.h"
-#include "IDBTransactionBackend.h"
-#include "LevelDBComparator.h"
-#include "LevelDBDatabase.h"
-#include "LevelDBIterator.h"
-#include "LevelDBSlice.h"
-#include "LevelDBTransaction.h"
-#include "Logging.h"
-#include "SecurityOrigin.h"
-#include "SharedBuffer.h"
-#include <wtf/Assertions.h>
-
-namespace WebCore {
-
-using namespace IDBLevelDBCoding;
-
-const int64_t KeyGeneratorInitialNumber = 1; // From the IndexedDB specification.
-
-enum IDBBackingStoreLevelDBErrorSource {
- // 0 - 2 are no longer used.
- FindKeyInIndex = 3,
- GetIDBDatabaseMetaData,
- GetIndexes,
- GetKeyGeneratorCurrentNumber,
- GetObjectStores,
- GetRecord,
- KeyExistsInObjectStore,
- LoadCurrentRow,
- SetupMetadata,
- GetPrimaryKeyViaIndex,
- KeyExistsInIndex,
- VersionExists,
- DeleteObjectStore,
- SetMaxObjectStoreId,
- SetMaxIndexId,
- GetNewDatabaseId,
- GetNewVersionNumber,
- CreateIDBDatabaseMetaData,
- DeleteDatabase,
- IDBLevelDBBackingStoreInternalErrorMax,
-};
-
-static void recordInternalError(const char* type, IDBBackingStoreLevelDBErrorSource location)
-{
- String name = String::format("WebCore.IndexedDB.BackingStore.%sError", type);
- HistogramSupport::histogramEnumeration(name.utf8().data(), location, IDBLevelDBBackingStoreInternalErrorMax);
-}
-
-// Use to signal conditions that usually indicate developer error, but could be caused by data corruption.
-// A macro is used instead of an inline function so that the assert and log report the line number.
-#define REPORT_ERROR(type, location) \
- do { \
- LOG_ERROR("IndexedDB %s Error: %s", type, #location); \
- ASSERT_NOT_REACHED(); \
- recordInternalError(type, location); \
- } while (0)
-
-#define INTERNAL_READ_ERROR(location) REPORT_ERROR("Read", location)
-#define INTERNAL_CONSISTENCY_ERROR(location) REPORT_ERROR("Consistency", location)
-#define INTERNAL_WRITE_ERROR(location) REPORT_ERROR("Write", location)
-
-static void putBool(LevelDBTransaction* transaction, const LevelDBSlice& key, bool value)
-{
- transaction->put(key, encodeBool(value));
-}
-
-template <typename DBOrTransaction>
-static bool getInt(DBOrTransaction* db, const LevelDBSlice& key, int64_t& foundInt, bool& found)
-{
- Vector<char> result;
- bool ok = db->safeGet(key, result, found);
- if (!ok)
- return false;
- if (!found)
- return true;
-
- foundInt = decodeInt(result.begin(), result.end());
- return true;
-}
-
-static void putInt(LevelDBTransaction* transaction, const LevelDBSlice& key, int64_t value)
-{
- ASSERT(value >= 0);
- transaction->put(key, encodeInt(value));
-}
-
-template <typename DBOrTransaction>
-WARN_UNUSED_RETURN static bool getVarInt(DBOrTransaction* db, const LevelDBSlice& key, int64_t& foundInt, bool& found)
-{
- Vector<char> result;
- bool ok = db->safeGet(key, result, found);
- if (!ok)
- return false;
- if (!found)
- return true;
-
- found = decodeVarInt(result.begin(), result.end(), foundInt) == result.end();
- return true;
-}
-
-static void putVarInt(LevelDBTransaction* transaction, const LevelDBSlice& key, int64_t value)
-{
- transaction->put(key, encodeVarInt(value));
-}
-
-template <typename DBOrTransaction>
-WARN_UNUSED_RETURN static bool getString(DBOrTransaction* db, const LevelDBSlice& key, String& foundString, bool& found)
-{
- Vector<char> result;
- found = false;
- bool ok = db->safeGet(key, result, found);
- if (!ok)
- return false;
- if (!found)
- return true;
-
- foundString = decodeString(result.begin(), result.end());
- return true;
-}
-
-static void putString(LevelDBTransaction* transaction, const LevelDBSlice& key, const String& value)
-{
- transaction->put(key, encodeString(value));
-}
-
-static void putIDBKeyPath(LevelDBTransaction* transaction, const LevelDBSlice& key, const IDBKeyPath& value)
-{
- transaction->put(key, encodeIDBKeyPath(value));
-}
-
-static int compareKeys(const LevelDBSlice& a, const LevelDBSlice& b)
-{
- return compare(a, b);
-}
-
-int IDBBackingStoreLevelDB::compareIndexKeys(const LevelDBSlice& a, const LevelDBSlice& b)
-{
- return compare(a, b, true);
-}
-
-class Comparator : public LevelDBComparator {
-public:
- virtual int compare(const LevelDBSlice& a, const LevelDBSlice& b) const { return IDBLevelDBCoding::compare(a, b); }
- virtual const char* name() const { return "idb_cmp1"; }
-};
-
-// 0 - Initial version.
-// 1 - Adds UserIntVersion to DatabaseMetaData.
-// 2 - Adds DataVersion to to global metadata.
-const int64_t latestKnownSchemaVersion = 2;
-WARN_UNUSED_RETURN static bool isSchemaKnown(LevelDBDatabase* db, bool& known)
-{
- int64_t dbSchemaVersion = 0;
- bool found = false;
- bool ok = getInt(db, SchemaVersionKey::encode(), dbSchemaVersion, found);
- if (!ok)
- return false;
- if (!found) {
- known = true;
- return true;
- }
- if (dbSchemaVersion > latestKnownSchemaVersion) {
- known = false;
- return true;
- }
-
- const uint32_t latestKnownDataVersion = SerializedScriptValue::wireFormatVersion();
- int64_t dbDataVersion = 0;
- ok = getInt(db, DataVersionKey::encode(), dbDataVersion, found);
- if (!ok)
- return false;
- if (!found) {
- known = true;
- return true;
- }
-
- if (dbDataVersion > latestKnownDataVersion) {
- known = false;
- return true;
- }
-
- known = true;
- return true;
-}
-
-WARN_UNUSED_RETURN static bool setUpMetadata(LevelDBDatabase* db, const String& origin)
-{
- const uint32_t latestKnownDataVersion = SerializedScriptValue::wireFormatVersion();
- const Vector<char> schemaVersionKey = SchemaVersionKey::encode();
- const Vector<char> dataVersionKey = DataVersionKey::encode();
-
- RefPtr<LevelDBTransaction> transaction = LevelDBTransaction::create(db);
-
- int64_t dbSchemaVersion = 0;
- int64_t dbDataVersion = 0;
- bool found = false;
- bool ok = getInt(transaction.get(), schemaVersionKey, dbSchemaVersion, found);
- if (!ok) {
- INTERNAL_READ_ERROR(SetupMetadata);
- return false;
- }
- if (!found) {
- // Initialize new backing store.
- dbSchemaVersion = latestKnownSchemaVersion;
- putInt(transaction.get(), schemaVersionKey, dbSchemaVersion);
- dbDataVersion = latestKnownDataVersion;
- putInt(transaction.get(), dataVersionKey, dbDataVersion);
- } else {
- // Upgrade old backing store.
- ASSERT(dbSchemaVersion <= latestKnownSchemaVersion);
- if (dbSchemaVersion < 1) {
- dbSchemaVersion = 1;
- putInt(transaction.get(), schemaVersionKey, dbSchemaVersion);
- const Vector<char> startKey = DatabaseNameKey::encodeMinKeyForOrigin(origin);
- const Vector<char> stopKey = DatabaseNameKey::encodeStopKeyForOrigin(origin);
- OwnPtr<LevelDBIterator> it = db->createIterator();
- for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) {
- int64_t databaseId = 0;
- found = false;
- bool ok = getInt(transaction.get(), it->key(), databaseId, found);
- if (!ok) {
- INTERNAL_READ_ERROR(SetupMetadata);
- return false;
- }
- if (!found) {
- INTERNAL_CONSISTENCY_ERROR(SetupMetadata);
- return false;
- }
- Vector<char> intVersionKey = DatabaseMetaDataKey::encode(databaseId, DatabaseMetaDataKey::UserIntVersion);
- putVarInt(transaction.get(), intVersionKey, IDBDatabaseMetadata::DefaultIntVersion);
- }
- }
- if (dbSchemaVersion < 2) {
- dbSchemaVersion = 2;
- putInt(transaction.get(), schemaVersionKey, dbSchemaVersion);
- dbDataVersion = SerializedScriptValue::wireFormatVersion();
- putInt(transaction.get(), dataVersionKey, dbDataVersion);
- }
- }
-
- // All new values will be written using this serialization version.
- found = false;
- ok = getInt(transaction.get(), dataVersionKey, dbDataVersion, found);
- if (!ok) {
- INTERNAL_READ_ERROR(SetupMetadata);
- return false;
- }
- if (!found) {
- INTERNAL_CONSISTENCY_ERROR(SetupMetadata);
- return false;
- }
- if (dbDataVersion < latestKnownDataVersion) {
- dbDataVersion = latestKnownDataVersion;
- putInt(transaction.get(), dataVersionKey, dbDataVersion);
- }
-
- ASSERT(dbSchemaVersion == latestKnownSchemaVersion);
- ASSERT(dbDataVersion == latestKnownDataVersion);
-
- if (!transaction->commit()) {
- INTERNAL_WRITE_ERROR(SetupMetadata);
- return false;
- }
- return true;
-}
-
-template <typename DBOrTransaction>
-WARN_UNUSED_RETURN static bool getMaxObjectStoreId(DBOrTransaction* db, int64_t databaseId, int64_t& maxObjectStoreId)
-{
- const Vector<char> maxObjectStoreIdKey = DatabaseMetaDataKey::encode(databaseId, DatabaseMetaDataKey::MaxObjectStoreId);
- bool ok = getMaxObjectStoreId(db, maxObjectStoreIdKey, maxObjectStoreId);
- return ok;
-}
-
-template <typename DBOrTransaction>
-WARN_UNUSED_RETURN static bool getMaxObjectStoreId(DBOrTransaction* db, const Vector<char>& maxObjectStoreIdKey, int64_t& maxObjectStoreId)
-{
- maxObjectStoreId = -1;
- bool found = false;
- bool ok = getInt(db, maxObjectStoreIdKey, maxObjectStoreId, found);
- if (!ok)
- return false;
- if (!found)
- maxObjectStoreId = 0;
-
- ASSERT(maxObjectStoreId >= 0);
- return true;
-}
-
-class DefaultLevelDBFactory : public LevelDBFactory {
-public:
- virtual PassOwnPtr<LevelDBDatabase> openLevelDB(const String& fileName, const LevelDBComparator* comparator)
- {
- return LevelDBDatabase::open(fileName, comparator);
- }
- virtual bool destroyLevelDB(const String& fileName)
- {
- return LevelDBDatabase::destroy(fileName);
- }
-};
-
-IDBBackingStoreLevelDB::IDBBackingStoreLevelDB(const String& identifier, PassOwnPtr<LevelDBDatabase> db, PassOwnPtr<LevelDBComparator> comparator)
- : m_identifier(identifier)
- , m_db(db)
- , m_comparator(comparator)
- , m_weakFactory(this)
-{
-}
-
-IDBBackingStoreLevelDB::~IDBBackingStoreLevelDB()
-{
- // m_db's destructor uses m_comparator. The order of destruction is important.
- m_db.clear();
- m_comparator.clear();
-}
-
-enum IDBLevelDBBackingStoreOpenResult {
- IDBLevelDBBackingStoreOpenMemorySuccess,
- IDBLevelDBBackingStoreOpenSuccess,
- IDBLevelDBBackingStoreOpenFailedDirectory,
- IDBLevelDBBackingStoreOpenFailedUnknownSchema,
- IDBLevelDBBackingStoreOpenCleanupDestroyFailed,
- IDBLevelDBBackingStoreOpenCleanupReopenFailed,
- IDBLevelDBBackingStoreOpenCleanupReopenSuccess,
- IDBLevelDBBackingStoreOpenFailedIOErrCheckingSchema,
- IDBLevelDBBackingStoreOpenFailedUnknownErr,
- IDBLevelDBBackingStoreOpenMemoryFailed,
- IDBLevelDBBackingStoreOpenAttemptNonASCII,
- IDBLevelDBBackingStoreOpenMax,
-};
-
-PassRefPtr<IDBBackingStoreLevelDB> IDBBackingStoreLevelDB::open(const SecurityOrigin& securityOrigin, const String& pathBaseArg, const String& fileIdentifier)
-{
- DefaultLevelDBFactory levelDBFactory;
- return IDBBackingStoreLevelDB::open(securityOrigin, pathBaseArg, fileIdentifier, &levelDBFactory);
-}
-
-PassRefPtr<IDBBackingStoreLevelDB> IDBBackingStoreLevelDB::open(const SecurityOrigin& securityOrigin, const String& pathBaseArg, const String& fileIdentifier, LevelDBFactory* levelDBFactory)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::open");
- ASSERT(!pathBaseArg.isEmpty());
- String pathBase = pathBaseArg;
-
- OwnPtr<LevelDBComparator> comparator = adoptPtr(new Comparator());
- OwnPtr<LevelDBDatabase> db;
-
- if (!pathBase.containsOnlyASCII())
- HistogramSupport::histogramEnumeration("WebCore.IndexedDB.BackingStore.OpenStatus", IDBLevelDBBackingStoreOpenAttemptNonASCII, IDBLevelDBBackingStoreOpenMax);
- if (!makeAllDirectories(pathBase)) {
- LOG_ERROR("Unable to create IndexedDB database path %s", pathBase.utf8().data());
- HistogramSupport::histogramEnumeration("WebCore.IndexedDB.BackingStore.OpenStatus", IDBLevelDBBackingStoreOpenFailedDirectory, IDBLevelDBBackingStoreOpenMax);
- return PassRefPtr<IDBBackingStoreLevelDB>();
- }
-
- String path = pathByAppendingComponent(pathBase, securityOrigin.databaseIdentifier() + ".indexeddb.leveldb");
-
- db = levelDBFactory->openLevelDB(path, comparator.get());
- if (db) {
- bool known = false;
- bool ok = isSchemaKnown(db.get(), known);
- if (!ok) {
- LOG_ERROR("IndexedDB had IO error checking schema, treating it as failure to open");
- HistogramSupport::histogramEnumeration("WebCore.IndexedDB.BackingStore.OpenStatus", IDBLevelDBBackingStoreOpenFailedIOErrCheckingSchema, IDBLevelDBBackingStoreOpenMax);
- db.clear();
- } else if (!known) {
- LOG_ERROR("IndexedDB backing store had unknown schema, treating it as failure to open");
- HistogramSupport::histogramEnumeration("WebCore.IndexedDB.BackingStore.OpenStatus", IDBLevelDBBackingStoreOpenFailedUnknownSchema, IDBLevelDBBackingStoreOpenMax);
- db.clear();
- }
- }
-
- if (db)
- HistogramSupport::histogramEnumeration("WebCore.IndexedDB.BackingStore.OpenStatus", IDBLevelDBBackingStoreOpenSuccess, IDBLevelDBBackingStoreOpenMax);
- else {
- LOG_ERROR("IndexedDB backing store open failed, attempting cleanup");
- bool success = levelDBFactory->destroyLevelDB(path);
- if (!success) {
- LOG_ERROR("IndexedDB backing store cleanup failed");
- HistogramSupport::histogramEnumeration("WebCore.IndexedDB.BackingStore.OpenStatus", IDBLevelDBBackingStoreOpenCleanupDestroyFailed, IDBLevelDBBackingStoreOpenMax);
- return PassRefPtr<IDBBackingStoreLevelDB>();
- }
-
- LOG_ERROR("IndexedDB backing store cleanup succeeded, reopening");
- db = levelDBFactory->openLevelDB(path, comparator.get());
- if (!db) {
- LOG_ERROR("IndexedDB backing store reopen after recovery failed");
- HistogramSupport::histogramEnumeration("WebCore.IndexedDB.BackingStore.OpenStatus", IDBLevelDBBackingStoreOpenCleanupReopenFailed, IDBLevelDBBackingStoreOpenMax);
- return PassRefPtr<IDBBackingStoreLevelDB>();
- }
- HistogramSupport::histogramEnumeration("WebCore.IndexedDB.BackingStore.OpenStatus", IDBLevelDBBackingStoreOpenCleanupReopenSuccess, IDBLevelDBBackingStoreOpenMax);
- }
-
- if (!db) {
- ASSERT_NOT_REACHED();
- HistogramSupport::histogramEnumeration("WebCore.IndexedDB.BackingStore.OpenStatus", IDBLevelDBBackingStoreOpenFailedUnknownErr, IDBLevelDBBackingStoreOpenMax);
- return PassRefPtr<IDBBackingStoreLevelDB>();
- }
-
- return create(fileIdentifier, db.release(), comparator.release());
-}
-
-PassRefPtr<IDBBackingStoreLevelDB> IDBBackingStoreLevelDB::openInMemory(const String& identifier)
-{
- DefaultLevelDBFactory levelDBFactory;
- return IDBBackingStoreLevelDB::openInMemory(identifier, &levelDBFactory);
-}
-
-PassRefPtr<IDBBackingStoreLevelDB> IDBBackingStoreLevelDB::openInMemory(const String& identifier, LevelDBFactory*)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::openInMemory");
-
- OwnPtr<LevelDBComparator> comparator = adoptPtr(new Comparator());
- OwnPtr<LevelDBDatabase> db = LevelDBDatabase::openInMemory(comparator.get());
- if (!db) {
- LOG_ERROR("LevelDBDatabase::openInMemory failed.");
- HistogramSupport::histogramEnumeration("WebCore.IndexedDB.BackingStore.OpenStatus", IDBLevelDBBackingStoreOpenMemoryFailed, IDBLevelDBBackingStoreOpenMax);
- return PassRefPtr<IDBBackingStoreLevelDB>();
- }
- HistogramSupport::histogramEnumeration("WebCore.IndexedDB.BackingStore.OpenStatus", IDBLevelDBBackingStoreOpenMemorySuccess, IDBLevelDBBackingStoreOpenMax);
-
- return create(identifier, db.release(), comparator.release());
-}
-
-PassRefPtr<IDBBackingStoreLevelDB> IDBBackingStoreLevelDB::create(const String& identifier, PassOwnPtr<LevelDBDatabase> db, PassOwnPtr<LevelDBComparator> comparator)
-{
- // FIXME: Handle comparator name changes.
- RefPtr<IDBBackingStoreLevelDB> backingStore(adoptRef(new IDBBackingStoreLevelDB(identifier, db, comparator)));
-
- if (!setUpMetadata(backingStore->m_db.get(), identifier))
- return PassRefPtr<IDBBackingStoreLevelDB>();
-
- return backingStore.release();
-}
-
-Vector<String> IDBBackingStoreLevelDB::getDatabaseNames()
-{
- Vector<String> foundNames;
- const Vector<char> startKey = DatabaseNameKey::encodeMinKeyForOrigin(m_identifier);
- const Vector<char> stopKey = DatabaseNameKey::encodeStopKeyForOrigin(m_identifier);
-
- ASSERT(foundNames.isEmpty());
-
- OwnPtr<LevelDBIterator> it = m_db->createIterator();
- for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) {
- const char* p = it->key().begin();
- const char* limit = it->key().end();
-
- DatabaseNameKey databaseNameKey;
- p = DatabaseNameKey::decode(p, limit, &databaseNameKey);
- ASSERT(p);
-
- foundNames.append(databaseNameKey.databaseName());
- }
- return foundNames;
-}
-
-bool IDBBackingStoreLevelDB::getIDBDatabaseMetaData(const String& name, IDBDatabaseMetadata* metadata, bool& found)
-{
- const Vector<char> key = DatabaseNameKey::encode(m_identifier, name);
- found = false;
-
- bool ok = getInt(m_db.get(), key, metadata->id, found);
- if (!ok) {
- INTERNAL_READ_ERROR(GetIDBDatabaseMetaData);
- return false;
- }
- if (!found)
- return true;
-
- // FIXME: The string version is no longer supported, so the levelDB ports should consider refactoring off of it.
- String stringVersion;
- ok = getString(m_db.get(), DatabaseMetaDataKey::encode(metadata->id, DatabaseMetaDataKey::UserVersion), stringVersion, found);
- if (!ok) {
- INTERNAL_READ_ERROR(GetIDBDatabaseMetaData);
- return false;
- }
- if (!found) {
- INTERNAL_CONSISTENCY_ERROR(GetIDBDatabaseMetaData);
- return false;
- }
-
- int64_t version;
- ok = getVarInt(m_db.get(), DatabaseMetaDataKey::encode(metadata->id, DatabaseMetaDataKey::UserIntVersion), version, found);
- if (!ok) {
- INTERNAL_READ_ERROR(GetIDBDatabaseMetaData);
- return false;
- }
- if (!found) {
- INTERNAL_CONSISTENCY_ERROR(GetIDBDatabaseMetaData);
- return false;
- }
-
- // FIXME: The versioning semantics have changed since this original code was written, and what was once a negative number
- // stored in the database is no longer a valid version.
- if (version < 0)
- version = 0;
- metadata->version = version;
-
- ok = getMaxObjectStoreId(m_db.get(), metadata->id, metadata->maxObjectStoreId);
- if (!ok) {
- INTERNAL_READ_ERROR(GetIDBDatabaseMetaData);
- return false;
- }
-
- return true;
-}
-
-void IDBBackingStoreLevelDB::getOrEstablishIDBDatabaseMetadata(const String& name, std::function<void (const IDBDatabaseMetadata&, bool success)> metadataFunction)
-{
- const Vector<char> key = DatabaseNameKey::encode(m_identifier, name);
- bool found = false;
-
- IDBDatabaseMetadata resultMetadata;
-
- bool ok = getInt(m_db.get(), key, resultMetadata.id, found);
- if (!ok) {
- INTERNAL_READ_ERROR(GetIDBDatabaseMetaData);
- metadataFunction(resultMetadata, false);
- return;
- }
-
- if (!found) {
- resultMetadata.name = name;
- resultMetadata.version = IDBDatabaseMetadata::DefaultIntVersion;
-
- metadataFunction(resultMetadata, createIDBDatabaseMetaData(resultMetadata));
- return;
- }
-
- int64_t version;
- ok = getVarInt(m_db.get(), DatabaseMetaDataKey::encode(resultMetadata.id, DatabaseMetaDataKey::UserIntVersion), version, found);
- if (!ok) {
- INTERNAL_READ_ERROR(GetIDBDatabaseMetaData);
- metadataFunction(resultMetadata, false);
- return;
- }
- if (!found) {
- INTERNAL_CONSISTENCY_ERROR(GetIDBDatabaseMetaData);
- metadataFunction(resultMetadata, false);
- return;
- }
-
- // FIXME: The versioning semantics have changed since this original code was written, and what was once a negative number
- // stored in the database is no longer a valid version.
- if (version < 0)
- version = 0;
- resultMetadata.version = version;
-
- ok = getMaxObjectStoreId(m_db.get(), resultMetadata.id, resultMetadata.maxObjectStoreId);
- if (!ok) {
- INTERNAL_READ_ERROR(GetIDBDatabaseMetaData);
- metadataFunction(resultMetadata, false);
- return;
- }
-
- ok = getObjectStores(resultMetadata.id, &resultMetadata.objectStores);
- if (!ok) {
- INTERNAL_READ_ERROR(GetIDBDatabaseMetaData);
- metadataFunction(resultMetadata, false);
- return;
- }
-
- metadataFunction(resultMetadata, true);
-}
-
-WARN_UNUSED_RETURN static bool getNewDatabaseId(LevelDBDatabase* db, int64_t& newId)
-{
- RefPtr<LevelDBTransaction> transaction = LevelDBTransaction::create(db);
-
- newId = -1;
- int64_t maxDatabaseId = -1;
- bool found = false;
- bool ok = getInt(transaction.get(), MaxDatabaseIdKey::encode(), maxDatabaseId, found);
- if (!ok) {
- INTERNAL_READ_ERROR(GetNewDatabaseId);
- return false;
- }
- if (!found)
- maxDatabaseId = 0;
-
- ASSERT(maxDatabaseId >= 0);
-
- int64_t databaseId = maxDatabaseId + 1;
- putInt(transaction.get(), MaxDatabaseIdKey::encode(), databaseId);
- if (!transaction->commit()) {
- INTERNAL_WRITE_ERROR(GetNewDatabaseId);
- return false;
- }
- newId = databaseId;
- return true;
-}
-
-// FIXME: LevelDB needs to support uint64_t as the version type.
-bool IDBBackingStoreLevelDB::createIDBDatabaseMetaData(IDBDatabaseMetadata& metadata)
-{
- bool ok = getNewDatabaseId(m_db.get(), metadata.id);
- if (!ok)
- return false;
- ASSERT(metadata.id >= 0);
-
- RefPtr<LevelDBTransaction> transaction = LevelDBTransaction::create(m_db.get());
- putInt(transaction.get(), DatabaseNameKey::encode(m_identifier, metadata.name), metadata.id);
- putVarInt(transaction.get(), DatabaseMetaDataKey::encode(metadata.id, DatabaseMetaDataKey::UserIntVersion), metadata.version);
- if (!transaction->commit()) {
- INTERNAL_WRITE_ERROR(CreateIDBDatabaseMetaData);
- return false;
- }
- return true;
-}
-
-bool IDBBackingStoreLevelDB::updateIDBDatabaseVersion(IDBBackingStoreTransactionLevelDB& transaction, int64_t rowId, uint64_t version)
-{
- if (version == IDBDatabaseMetadata::NoIntVersion)
- version = IDBDatabaseMetadata::DefaultIntVersion;
- putVarInt(IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction), DatabaseMetaDataKey::encode(rowId, DatabaseMetaDataKey::UserIntVersion), version);
- return true;
-}
-
-static void deleteRange(LevelDBTransaction* transaction, const Vector<char>& begin, const Vector<char>& end)
-{
- OwnPtr<LevelDBIterator> it = transaction->createIterator();
- for (it->seek(begin); it->isValid() && compareKeys(it->key(), end) < 0; it->next())
- transaction->remove(it->key());
-}
-
-void IDBBackingStoreLevelDB::deleteDatabase(const String& name, std::function<void (bool success)> boolCallbackFunction)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::deleteDatabase");
- OwnPtr<LevelDBWriteOnlyTransaction> transaction = LevelDBWriteOnlyTransaction::create(m_db.get());
-
- IDBDatabaseMetadata metadata;
- bool success = false;
- bool ok = getIDBDatabaseMetaData(name, &metadata, success);
- if (!ok) {
- boolCallbackFunction(false);
- return;
- }
-
- if (!success) {
- boolCallbackFunction(true);
- return;
- }
-
- const Vector<char> startKey = DatabaseMetaDataKey::encode(metadata.id, DatabaseMetaDataKey::OriginName);
- const Vector<char> stopKey = DatabaseMetaDataKey::encode(metadata.id + 1, DatabaseMetaDataKey::OriginName);
- OwnPtr<LevelDBIterator> it = m_db->createIterator();
- for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next())
- transaction->remove(it->key());
-
- const Vector<char> key = DatabaseNameKey::encode(m_identifier, name);
- transaction->remove(key);
-
- if (!transaction->commit()) {
- INTERNAL_WRITE_ERROR(DeleteDatabase);
- boolCallbackFunction(false);
- return;
- }
- boolCallbackFunction(true);
-}
-
-static bool checkObjectStoreAndMetaDataType(const LevelDBIterator* it, const Vector<char>& stopKey, int64_t objectStoreId, int64_t metaDataType)
-{
- if (!it->isValid() || compareKeys(it->key(), stopKey) >= 0)
- return false;
-
- ObjectStoreMetaDataKey metaDataKey;
- const char* p = ObjectStoreMetaDataKey::decode(it->key().begin(), it->key().end(), &metaDataKey);
- ASSERT_UNUSED(p, p);
- if (metaDataKey.objectStoreId() != objectStoreId)
- return false;
- if (metaDataKey.metaDataType() != metaDataType)
- return false;
- return true;
-}
-
-// FIXME: This should do some error handling rather than plowing ahead when bad data is encountered.
-bool IDBBackingStoreLevelDB::getObjectStores(int64_t databaseId, IDBDatabaseMetadata::ObjectStoreMap* objectStores)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::getObjectStores");
- if (!KeyPrefix::isValidDatabaseId(databaseId))
- return false;
- const Vector<char> startKey = ObjectStoreMetaDataKey::encode(databaseId, 1, 0);
- const Vector<char> stopKey = ObjectStoreMetaDataKey::encodeMaxKey(databaseId);
-
- ASSERT(objectStores->isEmpty());
-
- OwnPtr<LevelDBIterator> it = m_db->createIterator();
- it->seek(startKey);
- while (it->isValid() && compareKeys(it->key(), stopKey) < 0) {
- const char* p = it->key().begin();
- const char* limit = it->key().end();
-
- ObjectStoreMetaDataKey metaDataKey;
- p = ObjectStoreMetaDataKey::decode(p, limit, &metaDataKey);
- ASSERT(p);
- if (metaDataKey.metaDataType() != ObjectStoreMetaDataKey::Name) {
- INTERNAL_CONSISTENCY_ERROR(GetObjectStores);
- // Possible stale metadata, but don't fail the load.
- it->next();
- continue;
- }
-
- int64_t objectStoreId = metaDataKey.objectStoreId();
-
- // FIXME: Do this by direct key lookup rather than iteration, to simplify.
- String objectStoreName = decodeString(it->value().begin(), it->value().end());
-
- it->next();
- if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::KeyPath)) {
- INTERNAL_CONSISTENCY_ERROR(GetObjectStores);
- break;
- }
- IDBKeyPath keyPath = decodeIDBKeyPath(it->value().begin(), it->value().end());
-
- it->next();
- if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::AutoIncrement)) {
- INTERNAL_CONSISTENCY_ERROR(GetObjectStores);
- break;
- }
- bool autoIncrement = decodeBool(it->value().begin(), it->value().end());
-
- it->next(); // Is evicatble.
- if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::Evictable)) {
- INTERNAL_CONSISTENCY_ERROR(GetObjectStores);
- break;
- }
-
- it->next(); // Last version.
- if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::LastVersion)) {
- INTERNAL_CONSISTENCY_ERROR(GetObjectStores);
- break;
- }
-
- it->next(); // Maximum index id allocated.
- if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::MaxIndexId)) {
- INTERNAL_CONSISTENCY_ERROR(GetObjectStores);
- break;
- }
- int64_t maxIndexId = decodeInt(it->value().begin(), it->value().end());
-
- it->next(); // [optional] has key path (is not null)
- if (checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::HasKeyPath)) {
- bool hasKeyPath = decodeBool(it->value().begin(), it->value().end());
- // This check accounts for two layers of legacy coding:
- // (1) Initially, hasKeyPath was added to distinguish null vs. string.
- // (2) Later, null vs. string vs. array was stored in the keyPath itself.
- // So this check is only relevant for string-type keyPaths.
- if (!hasKeyPath && (keyPath.type() == IDBKeyPath::StringType && !keyPath.string().isEmpty())) {
- INTERNAL_CONSISTENCY_ERROR(GetObjectStores);
- break;
- }
- if (!hasKeyPath)
- keyPath = IDBKeyPath();
- it->next();
- }
-
- int64_t keyGeneratorCurrentNumber = -1;
- if (checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::KeyGeneratorCurrentNumber)) {
- keyGeneratorCurrentNumber = decodeInt(it->value().begin(), it->value().end());
- // FIXME: Return keyGeneratorCurrentNumber, cache in object store, and write lazily to backing store.
- // For now, just assert that if it was written it was valid.
- ASSERT_UNUSED(keyGeneratorCurrentNumber, keyGeneratorCurrentNumber >= KeyGeneratorInitialNumber);
- it->next();
- }
-
- IDBObjectStoreMetadata metadata(objectStoreName, objectStoreId, keyPath, autoIncrement, maxIndexId);
- if (!getIndexes(databaseId, objectStoreId, &metadata.indexes))
- return false;
- objectStores->set(objectStoreId, metadata);
- }
- return true;
-}
-
-WARN_UNUSED_RETURN static bool setMaxObjectStoreId(LevelDBTransaction* transaction, int64_t databaseId, int64_t objectStoreId)
-{
- const Vector<char> maxObjectStoreIdKey = DatabaseMetaDataKey::encode(databaseId, DatabaseMetaDataKey::MaxObjectStoreId);
- int64_t maxObjectStoreId = -1;
- bool ok = getMaxObjectStoreId(transaction, maxObjectStoreIdKey, maxObjectStoreId);
- if (!ok) {
- INTERNAL_READ_ERROR(SetMaxObjectStoreId);
- return false;
- }
-
- if (objectStoreId <= maxObjectStoreId) {
- INTERNAL_CONSISTENCY_ERROR(SetMaxObjectStoreId);
- return false;
- }
- putInt(transaction, maxObjectStoreIdKey, objectStoreId);
- return true;
-}
-
-bool IDBBackingStoreLevelDB::createObjectStore(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, const String& name, const IDBKeyPath& keyPath, bool autoIncrement)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::createObjectStore");
- if (!KeyPrefix::validIds(databaseId, objectStoreId))
- return false;
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
- if (!setMaxObjectStoreId(levelDBTransaction, databaseId, objectStoreId))
- return false;
-
- const Vector<char> nameKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::Name);
- const Vector<char> keyPathKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::KeyPath);
- const Vector<char> autoIncrementKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::AutoIncrement);
- const Vector<char> evictableKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::Evictable);
- const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::LastVersion);
- const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::MaxIndexId);
- const Vector<char> hasKeyPathKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::HasKeyPath);
- const Vector<char> keyGeneratorCurrentNumberKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::KeyGeneratorCurrentNumber);
- const Vector<char> namesKey = ObjectStoreNamesKey::encode(databaseId, name);
-
- putString(levelDBTransaction, nameKey, name);
- putIDBKeyPath(levelDBTransaction, keyPathKey, keyPath);
- putInt(levelDBTransaction, autoIncrementKey, autoIncrement);
- putInt(levelDBTransaction, evictableKey, false);
- putInt(levelDBTransaction, lastVersionKey, 1);
- putInt(levelDBTransaction, maxIndexIdKey, MinimumIndexId);
- putBool(levelDBTransaction, hasKeyPathKey, !keyPath.isNull());
- putInt(levelDBTransaction, keyGeneratorCurrentNumberKey, KeyGeneratorInitialNumber);
- putInt(levelDBTransaction, namesKey, objectStoreId);
- return true;
-}
-
-bool IDBBackingStoreLevelDB::deleteObjectStore(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::deleteObjectStore");
- if (!KeyPrefix::validIds(databaseId, objectStoreId))
- return false;
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
-
- String objectStoreName;
- bool found = false;
- bool ok = getString(levelDBTransaction, ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::Name), objectStoreName, found);
- if (!ok) {
- INTERNAL_READ_ERROR(DeleteObjectStore);
- return false;
- }
- if (!found) {
- INTERNAL_CONSISTENCY_ERROR(DeleteObjectStore);
- return false;
- }
-
- deleteRange(levelDBTransaction, ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), ObjectStoreMetaDataKey::encodeMaxKey(databaseId, objectStoreId));
-
- levelDBTransaction->remove(ObjectStoreNamesKey::encode(databaseId, objectStoreName));
-
- deleteRange(levelDBTransaction, IndexFreeListKey::encode(databaseId, objectStoreId, 0), IndexFreeListKey::encodeMaxKey(databaseId, objectStoreId));
- deleteRange(levelDBTransaction, IndexMetaDataKey::encode(databaseId, objectStoreId, 0, 0), IndexMetaDataKey::encodeMaxKey(databaseId, objectStoreId));
-
- return clearObjectStore(transaction, databaseId, objectStoreId);
-}
-
-bool IDBBackingStoreLevelDB::getRecord(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey& key, Vector<char>& record)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::getRecord");
- if (!KeyPrefix::validIds(databaseId, objectStoreId))
- return false;
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
-
- const Vector<char> leveldbKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key);
- Vector<char> data;
-
- record.clear();
-
- bool found = false;
- bool ok = levelDBTransaction->safeGet(leveldbKey, data, found);
- if (!ok) {
- INTERNAL_READ_ERROR(GetRecord);
- return false;
- }
- if (!found)
- return true;
-
- int64_t version;
- const char* p = decodeVarInt(data.begin(), data.end(), version);
- if (!p) {
- INTERNAL_READ_ERROR(GetRecord);
- return false;
- }
-
- record.appendRange(p, static_cast<const char*>(data.end()));
- return true;
-}
-
-WARN_UNUSED_RETURN static bool getNewVersionNumber(LevelDBTransaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t& newVersionNumber)
-{
- const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::LastVersion);
-
- newVersionNumber = -1;
- int64_t lastVersion = -1;
- bool found = false;
- bool ok = getInt(transaction, lastVersionKey, lastVersion, found);
- if (!ok) {
- INTERNAL_READ_ERROR(GetNewVersionNumber);
- return false;
- }
- if (!found)
- lastVersion = 0;
-
- ASSERT(lastVersion >= 0);
-
- int64_t version = lastVersion + 1;
- putInt(transaction, lastVersionKey, version);
-
- ASSERT(version > lastVersion); // FIXME: Think about how we want to handle the overflow scenario.
-
- newVersionNumber = version;
- return true;
-}
-
-bool IDBBackingStoreLevelDB::putRecord(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey& key, PassRefPtr<SharedBuffer> prpValue, IDBRecordIdentifier* recordIdentifier)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::putRecord");
- if (!KeyPrefix::validIds(databaseId, objectStoreId))
- return false;
- ASSERT(key.isValid());
-
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
- int64_t version = -1;
- bool ok = getNewVersionNumber(levelDBTransaction, databaseId, objectStoreId, version);
- if (!ok)
- return false;
- ASSERT(version >= 0);
- const Vector<char> objectStoredataKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key);
-
- Vector<char> v;
- v.appendVector(encodeVarInt(version));
- RefPtr<SharedBuffer> value = prpValue;
- ASSERT(value);
- v.append(value->data(), value->size());
-
- levelDBTransaction->put(objectStoredataKey, v);
-
- const Vector<char> existsEntryKey = ExistsEntryKey::encode(databaseId, objectStoreId, key);
- levelDBTransaction->put(existsEntryKey, encodeInt(version));
-
- recordIdentifier->reset(encodeIDBKey(key), version);
- return true;
-}
-
-bool IDBBackingStoreLevelDB::clearObjectStore(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::clearObjectStore");
- if (!KeyPrefix::validIds(databaseId, objectStoreId))
- return false;
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
- const Vector<char> startKey = KeyPrefix(databaseId, objectStoreId).encode();
- const Vector<char> stopKey = KeyPrefix(databaseId, objectStoreId + 1).encode();
-
- deleteRange(levelDBTransaction, startKey, stopKey);
- return true;
-}
-
-bool IDBBackingStoreLevelDB::deleteRecord(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, const IDBRecordIdentifier& recordIdentifier)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::deleteRecord");
-
- if (!KeyPrefix::validIds(databaseId, objectStoreId))
- return false;
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
-
- const Vector<char> objectStoreDataKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, recordIdentifier.encodedPrimaryKey());
- levelDBTransaction->remove(objectStoreDataKey);
-
- const Vector<char> existsEntryKey = ExistsEntryKey::encode(databaseId, objectStoreId, recordIdentifier.encodedPrimaryKey());
- levelDBTransaction->remove(existsEntryKey);
- return true;
-}
-
-
-bool IDBBackingStoreLevelDB::getKeyGeneratorCurrentNumber(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, int64_t& keyGeneratorCurrentNumber)
-{
- if (!KeyPrefix::validIds(databaseId, objectStoreId))
- return false;
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
-
- const Vector<char> keyGeneratorCurrentNumberKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::KeyGeneratorCurrentNumber);
-
- keyGeneratorCurrentNumber = -1;
- Vector<char> data;
-
- bool found = false;
- bool ok = levelDBTransaction->safeGet(keyGeneratorCurrentNumberKey, data, found);
- if (!ok) {
- INTERNAL_READ_ERROR(GetKeyGeneratorCurrentNumber);
- return false;
- }
- if (found)
- keyGeneratorCurrentNumber = decodeInt(data.begin(), data.end());
- else {
- // Previously, the key generator state was not stored explicitly but derived from the
- // maximum numeric key present in existing data. This violates the spec as the data may
- // be cleared but the key generator state must be preserved.
- const Vector<char> startKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, minIDBKey());
- const Vector<char> stopKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, maxIDBKey());
-
- OwnPtr<LevelDBIterator> it = levelDBTransaction->createIterator();
- int64_t maxNumericKey = 0;
-
- for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) {
- const char* p = it->key().begin();
- const char* limit = it->key().end();
-
- ObjectStoreDataKey dataKey;
- p = ObjectStoreDataKey::decode(p, limit, &dataKey);
- ASSERT(p);
-
- if (dataKey.userKey()->type() == IDBKey::NumberType) {
- int64_t n = static_cast<int64_t>(dataKey.userKey()->number());
- if (n > maxNumericKey)
- maxNumericKey = n;
- }
- }
-
- keyGeneratorCurrentNumber = maxNumericKey + 1;
- }
-
- return keyGeneratorCurrentNumber;
-}
-
-bool IDBBackingStoreLevelDB::maybeUpdateKeyGeneratorCurrentNumber(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, int64_t newNumber, bool checkCurrent)
-{
- if (!KeyPrefix::validIds(databaseId, objectStoreId))
- return false;
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
-
- if (checkCurrent) {
- int64_t currentNumber;
- bool ok = getKeyGeneratorCurrentNumber(transaction, databaseId, objectStoreId, currentNumber);
- if (!ok)
- return false;
- if (newNumber <= currentNumber)
- return true;
- }
-
- const Vector<char> keyGeneratorCurrentNumberKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::KeyGeneratorCurrentNumber);
- putInt(levelDBTransaction, keyGeneratorCurrentNumberKey, newNumber);
- return true;
-}
-
-bool IDBBackingStoreLevelDB::keyExistsInObjectStore(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey& key, RefPtr<IDBRecordIdentifier>& foundIDBRecordIdentifier)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::keyExistsInObjectStore");
- if (!KeyPrefix::validIds(databaseId, objectStoreId))
- return false;
- bool found = false;
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
- const Vector<char> leveldbKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key);
- Vector<char> data;
-
- bool ok = levelDBTransaction->safeGet(leveldbKey, data, found);
- if (!ok) {
- INTERNAL_READ_ERROR(KeyExistsInObjectStore);
- return false;
- }
- if (!found)
- return true;
-
- int64_t version;
- if (!decodeVarInt(data.begin(), data.end(), version))
- return false;
-
- foundIDBRecordIdentifier = IDBRecordIdentifier::create(encodeIDBKey(key), version);
- return true;
-}
-
-static bool checkIndexAndMetaDataKey(const LevelDBIterator* it, const Vector<char>& stopKey, int64_t indexId, unsigned char metaDataType)
-{
- if (!it->isValid() || compareKeys(it->key(), stopKey) >= 0)
- return false;
-
- IndexMetaDataKey metaDataKey;
- const char* p = IndexMetaDataKey::decode(it->key().begin(), it->key().end(), &metaDataKey);
- ASSERT_UNUSED(p, p);
- if (metaDataKey.indexId() != indexId)
- return false;
- if (metaDataKey.metaDataType() != metaDataType)
- return false;
- return true;
-}
-
-
-// FIXME: This should do some error handling rather than plowing ahead when bad data is encountered.
-bool IDBBackingStoreLevelDB::getIndexes(int64_t databaseId, int64_t objectStoreId, IDBObjectStoreMetadata::IndexMap* indexes)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::getIndexes");
- if (!KeyPrefix::validIds(databaseId, objectStoreId))
- return false;
- const Vector<char> startKey = IndexMetaDataKey::encode(databaseId, objectStoreId, 0, 0);
- const Vector<char> stopKey = IndexMetaDataKey::encode(databaseId, objectStoreId + 1, 0, 0);
-
- ASSERT(indexes->isEmpty());
-
- OwnPtr<LevelDBIterator> it = m_db->createIterator();
- it->seek(startKey);
- while (it->isValid() && compareKeys(it->key(), stopKey) < 0) {
- const char* p = it->key().begin();
- const char* limit = it->key().end();
-
- IndexMetaDataKey metaDataKey;
- p = IndexMetaDataKey::decode(p, limit, &metaDataKey);
- ASSERT(p);
- if (metaDataKey.metaDataType() != IndexMetaDataKey::Name) {
- INTERNAL_CONSISTENCY_ERROR(GetIndexes);
- // Possible stale metadata due to http://webkit.org/b/85557 but don't fail the load.
- it->next();
- continue;
- }
-
- // FIXME: Do this by direct key lookup rather than iteration, to simplify.
- int64_t indexId = metaDataKey.indexId();
- String indexName = decodeString(it->value().begin(), it->value().end());
-
- it->next(); // unique flag
- if (!checkIndexAndMetaDataKey(it.get(), stopKey, indexId, IndexMetaDataKey::Unique)) {
- INTERNAL_CONSISTENCY_ERROR(GetIndexes);
- break;
- }
- bool indexUnique = decodeBool(it->value().begin(), it->value().end());
-
- it->next(); // keyPath
- if (!checkIndexAndMetaDataKey(it.get(), stopKey, indexId, IndexMetaDataKey::KeyPath)) {
- INTERNAL_CONSISTENCY_ERROR(GetIndexes);
- break;
- }
- IDBKeyPath keyPath = decodeIDBKeyPath(it->value().begin(), it->value().end());
-
- it->next(); // [optional] multiEntry flag
- bool indexMultiEntry = false;
- if (checkIndexAndMetaDataKey(it.get(), stopKey, indexId, IndexMetaDataKey::MultiEntry)) {
- indexMultiEntry = decodeBool(it->value().begin(), it->value().end());
- it->next();
- }
-
- indexes->set(indexId, IDBIndexMetadata(indexName, indexId, keyPath, indexUnique, indexMultiEntry));
- }
- return true;
-}
-
-WARN_UNUSED_RETURN static bool setMaxIndexId(LevelDBTransaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId)
-{
- int64_t maxIndexId = -1;
- const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::MaxIndexId);
- bool found = false;
- bool ok = getInt(transaction, maxIndexIdKey, maxIndexId, found);
- if (!ok) {
- INTERNAL_READ_ERROR(SetMaxIndexId);
- return false;
- }
- if (!found)
- maxIndexId = MinimumIndexId;
-
- if (indexId <= maxIndexId) {
- INTERNAL_CONSISTENCY_ERROR(SetMaxIndexId);
- return false;
- }
-
- putInt(transaction, maxIndexIdKey, indexId);
- return true;
-}
-
-bool IDBBackingStoreLevelDB::createIndex(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const String& name, const IDBKeyPath& keyPath, bool isUnique, bool isMultiEntry)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::createIndex");
- if (!KeyPrefix::validIds(databaseId, objectStoreId, indexId))
- return false;
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
- if (!setMaxIndexId(levelDBTransaction, databaseId, objectStoreId, indexId))
- return false;
-
- const Vector<char> nameKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, IndexMetaDataKey::Name);
- const Vector<char> uniqueKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, IndexMetaDataKey::Unique);
- const Vector<char> keyPathKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, IndexMetaDataKey::KeyPath);
- const Vector<char> multiEntryKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, IndexMetaDataKey::MultiEntry);
-
- putString(levelDBTransaction, nameKey, name);
- putBool(levelDBTransaction, uniqueKey, isUnique);
- putIDBKeyPath(levelDBTransaction, keyPathKey, keyPath);
- putBool(levelDBTransaction, multiEntryKey, isMultiEntry);
- return true;
-}
-
-bool IDBBackingStoreLevelDB::deleteIndex(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::deleteIndex");
- if (!KeyPrefix::validIds(databaseId, objectStoreId, indexId))
- return false;
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
-
- const Vector<char> indexMetaDataStart = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 0);
- const Vector<char> indexMetaDataEnd = IndexMetaDataKey::encodeMaxKey(databaseId, objectStoreId, indexId);
- deleteRange(levelDBTransaction, indexMetaDataStart, indexMetaDataEnd);
-
- const Vector<char> indexDataStart = IndexDataKey::encodeMinKey(databaseId, objectStoreId, indexId);
- const Vector<char> indexDataEnd = IndexDataKey::encodeMaxKey(databaseId, objectStoreId, indexId);
- deleteRange(levelDBTransaction, indexDataStart, indexDataEnd);
- return true;
-}
-
-bool IDBBackingStoreLevelDB::putIndexDataForRecord(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key, const IDBRecordIdentifier* recordIdentifier)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::putIndexDataForRecord");
- ASSERT(key.isValid());
- ASSERT(recordIdentifier);
- if (!KeyPrefix::validIds(databaseId, objectStoreId, indexId))
- return false;
-
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
- const Vector<char> indexDataKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, encodeIDBKey(key), recordIdentifier->encodedPrimaryKey());
-
- Vector<char> data;
- data.appendVector(encodeVarInt(recordIdentifier->version()));
- data.appendVector(recordIdentifier->encodedPrimaryKey());
-
- levelDBTransaction->put(indexDataKey, data);
- return true;
-}
-
-static bool findGreatestKeyLessThanOrEqual(LevelDBTransaction* transaction, const Vector<char>& target, Vector<char>& foundKey)
-{
- OwnPtr<LevelDBIterator> it = transaction->createIterator();
- it->seek(target);
-
- if (!it->isValid()) {
- it->seekToLast();
- if (!it->isValid())
- return false;
- }
-
- while (IDBBackingStoreLevelDB::compareIndexKeys(it->key(), target) > 0) {
- it->prev();
- if (!it->isValid())
- return false;
- }
-
- do {
- foundKey.clear();
- foundKey.append(it->key().begin(), it->key().end() - it->key().begin());
-
- // There can be several index keys that compare equal. We want the last one.
- it->next();
- } while (it->isValid() && !IDBBackingStoreLevelDB::compareIndexKeys(it->key(), target));
-
- return true;
-}
-
-static bool versionExists(LevelDBTransaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t version, const Vector<char>& encodedPrimaryKey, bool& exists)
-{
- const Vector<char> key = ExistsEntryKey::encode(databaseId, objectStoreId, encodedPrimaryKey);
- Vector<char> data;
-
- bool ok = transaction->safeGet(key, data, exists);
- if (!ok) {
- INTERNAL_READ_ERROR(VersionExists);
- return false;
- }
- if (!exists)
- return true;
-
- exists = (decodeInt(data.begin(), data.end()) == version);
- return true;
-}
-
-bool IDBBackingStoreLevelDB::findKeyInIndex(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key, Vector<char>& foundEncodedPrimaryKey, bool& found)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::findKeyInIndex");
- ASSERT(KeyPrefix::validIds(databaseId, objectStoreId, indexId));
-
- ASSERT(foundEncodedPrimaryKey.isEmpty());
- found = false;
-
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
- const Vector<char> leveldbKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, key);
- OwnPtr<LevelDBIterator> it = levelDBTransaction->createIterator();
- it->seek(leveldbKey);
-
- for (;;) {
- if (!it->isValid())
- return true;
- if (compareIndexKeys(it->key(), leveldbKey) > 0)
- return true;
-
- int64_t version;
- const char* p = decodeVarInt(it->value().begin(), it->value().end(), version);
- if (!p) {
- INTERNAL_READ_ERROR(FindKeyInIndex);
- return false;
- }
- foundEncodedPrimaryKey.append(p, it->value().end() - p);
-
- bool exists = false;
- bool ok = versionExists(levelDBTransaction, databaseId, objectStoreId, version, foundEncodedPrimaryKey, exists);
- if (!ok)
- return false;
- if (!exists) {
- // Delete stale index data entry and continue.
- levelDBTransaction->remove(it->key());
- it->next();
- continue;
- }
- found = true;
- return true;
- }
-}
-
-bool IDBBackingStoreLevelDB::getPrimaryKeyViaIndex(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key, RefPtr<IDBKey>& primaryKey)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::getPrimaryKeyViaIndex");
- if (!KeyPrefix::validIds(databaseId, objectStoreId, indexId))
- return false;
-
- bool found = false;
- Vector<char> foundEncodedPrimaryKey;
- bool ok = findKeyInIndex(transaction, databaseId, objectStoreId, indexId, key, foundEncodedPrimaryKey, found);
- if (!ok) {
- INTERNAL_READ_ERROR(GetPrimaryKeyViaIndex);
- return false;
- }
- if (found) {
- decodeIDBKey(foundEncodedPrimaryKey.begin(), foundEncodedPrimaryKey.end(), primaryKey);
- return true;
- }
-
- return true;
-}
-
-bool IDBBackingStoreLevelDB::keyExistsInIndex(IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey, bool& exists)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::keyExistsInIndex");
- if (!KeyPrefix::validIds(databaseId, objectStoreId, indexId))
- return false;
-
- exists = false;
- Vector<char> foundEncodedPrimaryKey;
- bool ok = findKeyInIndex(transaction, databaseId, objectStoreId, indexId, indexKey, foundEncodedPrimaryKey, exists);
- if (!ok) {
- INTERNAL_READ_ERROR(KeyExistsInIndex);
- return false;
- }
- if (!exists)
- return true;
-
- decodeIDBKey(foundEncodedPrimaryKey.begin(), foundEncodedPrimaryKey.end(), foundPrimaryKey);
- return true;
-}
-
-
-bool IDBBackingStoreLevelDB::makeIndexWriters(int64_t transactionID, int64_t databaseID, const IDBObjectStoreMetadata& objectStore, IDBKey& primaryKey, bool keyWasGenerated, const Vector<int64_t>& indexIDs, const Vector<Vector<RefPtr<IDBKey>>>& indexKeys, Vector<RefPtr<IDBIndexWriterLevelDB>>& indexWriters, String* errorMessage, bool& completed)
-{
- ASSERT(indexIDs.size() == indexKeys.size());
- completed = false;
-
- HashMap<int64_t, IndexKeys> indexKeyMap;
- for (size_t i = 0; i < indexIDs.size(); ++i)
- indexKeyMap.add(indexIDs[i], indexKeys[i]);
-
- for (IDBObjectStoreMetadata::IndexMap::const_iterator it = objectStore.indexes.begin(); it != objectStore.indexes.end(); ++it) {
- const IDBIndexMetadata& index = it->value;
-
- IndexKeys keys = indexKeyMap.get(it->key);
- // If the objectStore is using autoIncrement, then any indexes with an identical keyPath need to also use the primary (generated) key as a key.
- if (keyWasGenerated && (index.keyPath == objectStore.keyPath))
- keys.append(&primaryKey);
-
- RefPtr<IDBIndexWriterLevelDB> indexWriter = IDBIndexWriterLevelDB::create(index, keys);
- bool canAddKeys = false;
- ASSERT(m_backingStoreTransactions.contains(transactionID));
- bool backingStoreSuccess = indexWriter->verifyIndexKeys(*this, *m_backingStoreTransactions.get(transactionID), databaseID, objectStore.id, index.id, canAddKeys, &primaryKey, errorMessage);
- if (!backingStoreSuccess)
- return false;
- if (!canAddKeys)
- return true;
-
- indexWriters.append(indexWriter.release());
- }
-
- completed = true;
- return true;
-}
-
-PassRefPtr<IDBKey> IDBBackingStoreLevelDB::generateKey(IDBTransactionBackend& transaction, int64_t databaseId, int64_t objectStoreId)
-{
- const int64_t maxGeneratorValue = 9007199254740992LL; // Maximum integer storable as ECMAScript number.
- int64_t currentNumber;
- ASSERT(m_backingStoreTransactions.contains(transaction.id()));
- bool ok = getKeyGeneratorCurrentNumber(*m_backingStoreTransactions.get(transaction.id()), databaseId, objectStoreId, currentNumber);
- if (!ok) {
- LOG_ERROR("Failed to getKeyGeneratorCurrentNumber");
- return IDBKey::createInvalid();
- }
- if (currentNumber < 0 || currentNumber > maxGeneratorValue)
- return IDBKey::createInvalid();
-
- return IDBKey::createNumber(currentNumber);
-}
-
-
-bool IDBBackingStoreLevelDB::updateKeyGenerator(IDBTransactionBackend& transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey& key, bool checkCurrent)
-{
- ASSERT(key.type() == IDBKey::NumberType);
- ASSERT(m_backingStoreTransactions.contains(transaction.id()));
-
- return maybeUpdateKeyGeneratorCurrentNumber(*m_backingStoreTransactions.get(transaction.id()), databaseId, objectStoreId, static_cast<int64_t>(floor(key.number())) + 1, checkCurrent);
-}
-
-class ObjectStoreKeyCursorImpl : public IDBBackingStoreCursorLevelDB {
-public:
- static PassRefPtr<ObjectStoreKeyCursorImpl> create(int64_t cursorID, LevelDBTransaction* transaction, const IDBBackingStoreCursorLevelDB::CursorOptions& cursorOptions)
- {
- return adoptRef(new ObjectStoreKeyCursorImpl(cursorID, transaction, cursorOptions));
- }
-
- virtual PassRefPtr<IDBBackingStoreCursorLevelDB> clone()
- {
- return adoptRef(new ObjectStoreKeyCursorImpl(this));
- }
-
- // IDBBackingStoreCursorLevelDB
- virtual PassRefPtr<SharedBuffer> value() const override { ASSERT_NOT_REACHED(); return 0; }
- virtual bool loadCurrentRow() override;
-
-protected:
- virtual Vector<char> encodeKey(const IDBKey &key)
- {
- return ObjectStoreDataKey::encode(m_cursorOptions.databaseId, m_cursorOptions.objectStoreId, key);
- }
-
-private:
- ObjectStoreKeyCursorImpl(int64_t cursorID, LevelDBTransaction* transaction, const IDBBackingStoreCursorLevelDB::CursorOptions& cursorOptions)
- : IDBBackingStoreCursorLevelDB(cursorID, transaction, cursorOptions)
- {
- }
-
- ObjectStoreKeyCursorImpl(const ObjectStoreKeyCursorImpl* other)
- : IDBBackingStoreCursorLevelDB(other)
- {
- }
-};
-
-bool ObjectStoreKeyCursorImpl::loadCurrentRow()
-{
- const char* keyPosition = m_iterator->key().begin();
- const char* keyLimit = m_iterator->key().end();
-
- ObjectStoreDataKey objectStoreDataKey;
- keyPosition = ObjectStoreDataKey::decode(keyPosition, keyLimit, &objectStoreDataKey);
- if (!keyPosition) {
- INTERNAL_READ_ERROR(LoadCurrentRow);
- return false;
- }
-
- m_currentKey = objectStoreDataKey.userKey();
-
- int64_t version;
- const char* valuePosition = decodeVarInt(m_iterator->value().begin(), m_iterator->value().end(), version);
- if (!valuePosition) {
- INTERNAL_READ_ERROR(LoadCurrentRow);
- return false;
- }
-
- // FIXME: This re-encodes what was just decoded; try and optimize.
- m_recordIdentifier->reset(encodeIDBKey(*m_currentKey), version);
-
- return true;
-}
-
-class ObjectStoreCursorImpl : public IDBBackingStoreCursorLevelDB {
-public:
- static PassRefPtr<ObjectStoreCursorImpl> create(int64_t cursorID, LevelDBTransaction* transaction, const IDBBackingStoreCursorLevelDB::CursorOptions& cursorOptions)
- {
- return adoptRef(new ObjectStoreCursorImpl(cursorID, transaction, cursorOptions));
- }
-
- virtual PassRefPtr<IDBBackingStoreCursorLevelDB> clone()
- {
- return adoptRef(new ObjectStoreCursorImpl(this));
- }
-
- // IDBBackingStoreCursorLevelDB
- virtual PassRefPtr<SharedBuffer> value() const override { return m_currentValue; }
- virtual bool loadCurrentRow() override;
-
-protected:
- virtual Vector<char> encodeKey(const IDBKey &key)
- {
- return ObjectStoreDataKey::encode(m_cursorOptions.databaseId, m_cursorOptions.objectStoreId, key);
- }
-
-private:
- ObjectStoreCursorImpl(int64_t cursorID, LevelDBTransaction* transaction, const IDBBackingStoreCursorLevelDB::CursorOptions& cursorOptions)
- : IDBBackingStoreCursorLevelDB(cursorID, transaction, cursorOptions)
- {
- }
-
- ObjectStoreCursorImpl(const ObjectStoreCursorImpl* other)
- : IDBBackingStoreCursorLevelDB(other)
- , m_currentValue(other->m_currentValue)
- {
- }
-
- RefPtr<SharedBuffer> m_currentValue;
-};
-
-bool ObjectStoreCursorImpl::loadCurrentRow()
-{
- const char* keyPosition = m_iterator->key().begin();
- const char* keyLimit = m_iterator->key().end();
-
- ObjectStoreDataKey objectStoreDataKey;
- keyPosition = ObjectStoreDataKey::decode(keyPosition, keyLimit, &objectStoreDataKey);
- if (!keyPosition) {
- INTERNAL_READ_ERROR(LoadCurrentRow);
- return false;
- }
-
- m_currentKey = objectStoreDataKey.userKey();
-
- int64_t version;
- const char* valuePosition = decodeVarInt(m_iterator->value().begin(), m_iterator->value().end(), version);
- if (!valuePosition) {
- INTERNAL_READ_ERROR(LoadCurrentRow);
- return false;
- }
-
- // FIXME: This re-encodes what was just decoded; try and optimize.
- m_recordIdentifier->reset(encodeIDBKey(*m_currentKey), version);
-
- Vector<char> value;
- value.append(valuePosition, m_iterator->value().end() - valuePosition);
- m_currentValue = SharedBuffer::adoptVector(value);
- return true;
-}
-
-class IndexKeyCursorImpl final : public IDBBackingStoreCursorLevelDB {
-public:
- static PassRefPtr<IndexKeyCursorImpl> create(int64_t cursorID, LevelDBTransaction* transaction, const IDBBackingStoreCursorLevelDB::CursorOptions& cursorOptions)
- {
- return adoptRef(new IndexKeyCursorImpl(cursorID, transaction, cursorOptions));
- }
-
- virtual PassRefPtr<IDBBackingStoreCursorLevelDB> clone()
- {
- return adoptRef(new IndexKeyCursorImpl(this));
- }
-
- // IDBBackingStoreCursorLevelDB
- virtual PassRefPtr<SharedBuffer> value() const override { ASSERT_NOT_REACHED(); return 0; }
- virtual PassRefPtr<IDBKey> primaryKey() const override { return m_primaryKey; }
- virtual const IDBRecordIdentifier& recordIdentifier() const override { ASSERT_NOT_REACHED(); return *m_recordIdentifier; }
- virtual bool loadCurrentRow() override;
-
-protected:
- virtual Vector<char> encodeKey(const IDBKey &key)
- {
- return IndexDataKey::encode(m_cursorOptions.databaseId, m_cursorOptions.objectStoreId, m_cursorOptions.indexId, key);
- }
-
-private:
- IndexKeyCursorImpl(int64_t cursorID, LevelDBTransaction* transaction, const IDBBackingStoreCursorLevelDB::CursorOptions& cursorOptions)
- : IDBBackingStoreCursorLevelDB(cursorID, transaction, cursorOptions)
- {
- }
-
- IndexKeyCursorImpl(const IndexKeyCursorImpl* other)
- : IDBBackingStoreCursorLevelDB(other)
- , m_primaryKey(other->m_primaryKey)
- {
- }
-
- RefPtr<IDBKey> m_primaryKey;
-};
-
-bool IndexKeyCursorImpl::loadCurrentRow()
-{
- const char* keyPosition = m_iterator->key().begin();
- const char* keyLimit = m_iterator->key().end();
-
- IndexDataKey indexDataKey;
- keyPosition = IndexDataKey::decode(keyPosition, keyLimit, &indexDataKey);
-
- m_currentKey = indexDataKey.userKey();
-
- int64_t indexDataVersion;
- const char* valuePosition = decodeVarInt(m_iterator->value().begin(), m_iterator->value().end(), indexDataVersion);
- if (!valuePosition) {
- INTERNAL_READ_ERROR(LoadCurrentRow);
- return false;
- }
-
- valuePosition = decodeIDBKey(valuePosition, m_iterator->value().end(), m_primaryKey);
- if (!valuePosition) {
- INTERNAL_READ_ERROR(LoadCurrentRow);
- return false;
- }
-
- Vector<char> primaryLevelDBKey = ObjectStoreDataKey::encode(indexDataKey.databaseId(), indexDataKey.objectStoreId(), *m_primaryKey);
-
- Vector<char> result;
- bool found = false;
- bool ok = m_transaction->safeGet(primaryLevelDBKey, result, found);
- if (!ok) {
- INTERNAL_READ_ERROR(LoadCurrentRow);
- return false;
- }
- if (!found) {
- m_transaction->remove(m_iterator->key());
- return false;
- }
-
- int64_t objectStoreDataVersion;
- const char* t = decodeVarInt(result.begin(), result.end(), objectStoreDataVersion);
- if (!t) {
- INTERNAL_READ_ERROR(LoadCurrentRow);
- return false;
- }
-
- if (objectStoreDataVersion != indexDataVersion) {
- m_transaction->remove(m_iterator->key());
- return false;
- }
-
- return true;
-}
-
-class IndexCursorImpl final : public IDBBackingStoreCursorLevelDB {
-public:
- static PassRefPtr<IndexCursorImpl> create(int64_t cursorID, LevelDBTransaction* transaction, const IDBBackingStoreCursorLevelDB::CursorOptions& cursorOptions)
- {
- return adoptRef(new IndexCursorImpl(cursorID, transaction, cursorOptions));
- }
-
- virtual PassRefPtr<IDBBackingStoreCursorLevelDB> clone()
- {
- return adoptRef(new IndexCursorImpl(this));
- }
-
- // IDBBackingStoreCursorLevelDB
- virtual PassRefPtr<SharedBuffer> value() const override { return m_currentValue; }
- virtual PassRefPtr<IDBKey> primaryKey() const override { return m_primaryKey; }
- virtual const IDBRecordIdentifier& recordIdentifier() const override { ASSERT_NOT_REACHED(); return *m_recordIdentifier; }
- virtual bool loadCurrentRow() override;
-
-protected:
- virtual Vector<char> encodeKey(const IDBKey &key)
- {
- return IndexDataKey::encode(m_cursorOptions.databaseId, m_cursorOptions.objectStoreId, m_cursorOptions.indexId, key);
- }
-
-private:
- IndexCursorImpl(int64_t cursorID, LevelDBTransaction* transaction, const IDBBackingStoreCursorLevelDB::CursorOptions& cursorOptions)
- : IDBBackingStoreCursorLevelDB(cursorID, transaction, cursorOptions)
- {
- }
-
- IndexCursorImpl(const IndexCursorImpl* other)
- : IDBBackingStoreCursorLevelDB(other)
- , m_primaryKey(other->m_primaryKey)
- , m_currentValue(other->m_currentValue)
- , m_primaryLevelDBKey(other->m_primaryLevelDBKey)
- {
- }
-
- RefPtr<IDBKey> m_primaryKey;
- RefPtr<SharedBuffer> m_currentValue;
- Vector<char> m_primaryLevelDBKey;
-};
-
-bool IndexCursorImpl::loadCurrentRow()
-{
- const char* keyPosition = m_iterator->key().begin();
- const char* keyLimit = m_iterator->key().end();
-
- IndexDataKey indexDataKey;
- keyPosition = IndexDataKey::decode(keyPosition, keyLimit, &indexDataKey);
-
- m_currentKey = indexDataKey.userKey();
-
- const char* valuePosition = m_iterator->value().begin();
- const char* valueLimit = m_iterator->value().end();
-
- int64_t indexDataVersion;
- valuePosition = decodeVarInt(valuePosition, valueLimit, indexDataVersion);
- if (!valuePosition) {
- INTERNAL_READ_ERROR(LoadCurrentRow);
- return false;
- }
- valuePosition = decodeIDBKey(valuePosition, valueLimit, m_primaryKey);
- if (!valuePosition) {
- INTERNAL_READ_ERROR(LoadCurrentRow);
- return false;
- }
-
- m_primaryLevelDBKey = ObjectStoreDataKey::encode(indexDataKey.databaseId(), indexDataKey.objectStoreId(), *m_primaryKey);
-
- Vector<char> result;
- bool found = false;
- bool ok = m_transaction->safeGet(m_primaryLevelDBKey, result, found);
- if (!ok) {
- INTERNAL_READ_ERROR(LoadCurrentRow);
- return false;
- }
- if (!found) {
- m_transaction->remove(m_iterator->key());
- return false;
- }
-
- int64_t objectStoreDataVersion;
- valuePosition = decodeVarInt(result.begin(), result.end(), objectStoreDataVersion);
- if (!valuePosition) {
- INTERNAL_READ_ERROR(LoadCurrentRow);
- return false;
- }
-
- if (objectStoreDataVersion != indexDataVersion) {
- m_transaction->remove(m_iterator->key());
- return false;
- }
-
- Vector<char> value;
- value.append(valuePosition, result.end() - valuePosition);
- m_currentValue = SharedBuffer::adoptVector(value);
- return true;
-}
-
-static bool objectStoreCursorOptions(LevelDBTransaction* transaction, int64_t databaseId, int64_t objectStoreId, const IDBKeyRange* range, IndexedDB::CursorDirection direction, IDBBackingStoreCursorLevelDB::CursorOptions& cursorOptions)
-{
- cursorOptions.databaseId = databaseId;
- cursorOptions.objectStoreId = objectStoreId;
-
- bool lowerBound = range && range->lower();
- bool upperBound = range && range->upper();
- cursorOptions.forward = (direction == IndexedDB::CursorDirection::NextNoDuplicate || direction == IndexedDB::CursorDirection::Next);
- cursorOptions.unique = (direction == IndexedDB::CursorDirection::NextNoDuplicate || direction == IndexedDB::CursorDirection::PrevNoDuplicate);
-
- if (!lowerBound) {
- cursorOptions.lowKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, minIDBKey());
- cursorOptions.lowOpen = true; // Not included.
- } else {
- cursorOptions.lowKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, *range->lower());
- cursorOptions.lowOpen = range->lowerOpen();
- }
-
- if (!upperBound) {
- cursorOptions.highKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, maxIDBKey());
-
- if (cursorOptions.forward)
- cursorOptions.highOpen = true; // Not included.
- else {
- // We need a key that exists.
- if (!findGreatestKeyLessThanOrEqual(transaction, cursorOptions.highKey, cursorOptions.highKey))
- return false;
- cursorOptions.highOpen = false;
- }
- } else {
- cursorOptions.highKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, *range->upper());
- cursorOptions.highOpen = range->upperOpen();
-
- if (!cursorOptions.forward) {
- // For reverse cursors, we need a key that exists.
- Vector<char> foundHighKey;
- if (!findGreatestKeyLessThanOrEqual(transaction, cursorOptions.highKey, foundHighKey))
- return false;
-
- // If the target key should not be included, but we end up with a smaller key, we should include that.
- if (cursorOptions.highOpen && IDBBackingStoreLevelDB::compareIndexKeys(foundHighKey, cursorOptions.highKey) < 0)
- cursorOptions.highOpen = false;
-
- cursorOptions.highKey = foundHighKey;
- }
- }
-
- return true;
-}
-
-static bool indexCursorOptions(LevelDBTransaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKeyRange* range, IndexedDB::CursorDirection direction, IDBBackingStoreCursorLevelDB::CursorOptions& cursorOptions)
-{
- ASSERT(transaction);
- if (!KeyPrefix::validIds(databaseId, objectStoreId, indexId))
- return false;
-
- cursorOptions.databaseId = databaseId;
- cursorOptions.objectStoreId = objectStoreId;
- cursorOptions.indexId = indexId;
-
- bool lowerBound = range && range->lower();
- bool upperBound = range && range->upper();
- cursorOptions.forward = (direction == IndexedDB::CursorDirection::NextNoDuplicate || direction == IndexedDB::CursorDirection::Next);
- cursorOptions.unique = (direction == IndexedDB::CursorDirection::NextNoDuplicate || direction == IndexedDB::CursorDirection::PrevNoDuplicate);
-
- if (!lowerBound) {
- cursorOptions.lowKey = IndexDataKey::encodeMinKey(databaseId, objectStoreId, indexId);
- cursorOptions.lowOpen = false; // Included.
- } else {
- cursorOptions.lowKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, *range->lower());
- cursorOptions.lowOpen = range->lowerOpen();
- }
-
- if (!upperBound) {
- cursorOptions.highKey = IndexDataKey::encodeMaxKey(databaseId, objectStoreId, indexId);
- cursorOptions.highOpen = false; // Included.
-
- if (!cursorOptions.forward) { // We need a key that exists.
- if (!findGreatestKeyLessThanOrEqual(transaction, cursorOptions.highKey, cursorOptions.highKey))
- return false;
- cursorOptions.highOpen = false;
- }
- } else {
- cursorOptions.highKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, *range->upper());
- cursorOptions.highOpen = range->upperOpen();
-
- Vector<char> foundHighKey;
- if (!findGreatestKeyLessThanOrEqual(transaction, cursorOptions.highKey, foundHighKey)) // Seek to the *last* key in the set of non-unique keys.
- return false;
-
- // If the target key should not be included, but we end up with a smaller key, we should include that.
- if (cursorOptions.highOpen && IDBBackingStoreLevelDB::compareIndexKeys(foundHighKey, cursorOptions.highKey) < 0)
- cursorOptions.highOpen = false;
-
- cursorOptions.highKey = foundHighKey;
- }
-
- return true;
-}
-PassRefPtr<IDBBackingStoreCursorLevelDB> IDBBackingStoreLevelDB::openObjectStoreCursor(int64_t cursorID, IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseID, int64_t objectStoreId, const IDBKeyRange* range, IndexedDB::CursorDirection direction)
-
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::openObjectStoreCursor");
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
- IDBBackingStoreCursorLevelDB::CursorOptions cursorOptions;
- if (!objectStoreCursorOptions(levelDBTransaction, databaseID, objectStoreId, range, direction, cursorOptions))
- return 0;
- RefPtr<ObjectStoreCursorImpl> cursor = ObjectStoreCursorImpl::create(cursorID, levelDBTransaction, cursorOptions);
- if (!cursor->firstSeek())
- return 0;
-
- return cursor.release();
-}
-
-PassRefPtr<IDBBackingStoreCursorLevelDB> IDBBackingStoreLevelDB::openObjectStoreKeyCursor(int64_t cursorID, IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseID, int64_t objectStoreId, const IDBKeyRange* range, IndexedDB::CursorDirection direction)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::openObjectStoreKeyCursor");
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
- IDBBackingStoreCursorLevelDB::CursorOptions cursorOptions;
- if (!objectStoreCursorOptions(levelDBTransaction, databaseID, objectStoreId, range, direction, cursorOptions))
- return 0;
- RefPtr<ObjectStoreKeyCursorImpl> cursor = ObjectStoreKeyCursorImpl::create(cursorID, levelDBTransaction, cursorOptions);
- if (!cursor->firstSeek())
- return 0;
-
- return cursor.release();
-}
-
-PassRefPtr<IDBBackingStoreCursorLevelDB> IDBBackingStoreLevelDB::openIndexKeyCursor(int64_t cursorID, IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseID, int64_t objectStoreId, int64_t indexId, const IDBKeyRange* range, IndexedDB::CursorDirection direction)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::openIndexKeyCursor");
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
- IDBBackingStoreCursorLevelDB::CursorOptions cursorOptions;
- if (!indexCursorOptions(levelDBTransaction, databaseID, objectStoreId, indexId, range, direction, cursorOptions))
- return 0;
- RefPtr<IndexKeyCursorImpl> cursor = IndexKeyCursorImpl::create(cursorID, levelDBTransaction, cursorOptions);
- if (!cursor->firstSeek())
- return 0;
-
- return cursor.release();
-}
-
-PassRefPtr<IDBBackingStoreCursorLevelDB> IDBBackingStoreLevelDB::openIndexCursor(int64_t cursorID, IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseID, int64_t objectStoreId, int64_t indexId, const IDBKeyRange* range, IndexedDB::CursorDirection direction)
-{
- LOG(StorageAPI, "IDBBackingStoreLevelDB::openIndexCursor");
- LevelDBTransaction* levelDBTransaction = IDBBackingStoreTransactionLevelDB::levelDBTransactionFrom(transaction);
- IDBBackingStoreCursorLevelDB::CursorOptions cursorOptions;
- if (!indexCursorOptions(levelDBTransaction, databaseID, objectStoreId, indexId, range, direction, cursorOptions))
- return 0;
- RefPtr<IndexCursorImpl> cursor = IndexCursorImpl::create(cursorID, levelDBTransaction, cursorOptions);
- if (!cursor->firstSeek())
- return 0;
-
- return cursor.release();
-}
-
-void IDBBackingStoreLevelDB::establishBackingStoreTransaction(int64_t transactionID)
-{
- ASSERT(!m_backingStoreTransactions.contains(transactionID));
- m_backingStoreTransactions.set(transactionID, IDBBackingStoreTransactionLevelDB::create(transactionID, this));
-}
-
-void IDBBackingStoreLevelDB::removeBackingStoreTransaction(IDBBackingStoreTransactionLevelDB* transaction)
-{
- ASSERT(m_backingStoreTransactions.contains(transaction->transactionID()));
- m_backingStoreTransactions.remove(transaction->transactionID());
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreLevelDB.h b/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreLevelDB.h
deleted file mode 100644
index 9ef75e45c..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreLevelDB.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2011 Google 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 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 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.
- */
-
-#ifndef IDBBackingStoreLevelDB_h
-#define IDBBackingStoreLevelDB_h
-
-#if ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
-
-#include "IDBBackingStoreCursorLevelDB.h"
-#include "IDBBackingStoreTransactionLevelDB.h"
-#include "IDBDatabaseMetadata.h"
-#include "IDBKey.h"
-#include "IDBRecordIdentifier.h"
-#include "IndexedDB.h"
-#include "LevelDBIterator.h"
-#include "LevelDBTransaction.h"
-#include <functional>
-#include <wtf/OwnPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/WeakPtr.h>
-
-namespace WebCore {
-
-class LevelDBComparator;
-class LevelDBDatabase;
-class LevelDBTransaction;
-class IDBIndexWriterLevelDB;
-class IDBKey;
-class IDBKeyRange;
-class IDBTransactionBackend;
-class SecurityOrigin;
-class SharedBuffer;
-
-class LevelDBFactory {
-public:
- virtual ~LevelDBFactory() { }
- virtual PassOwnPtr<LevelDBDatabase> openLevelDB(const String& fileName, const LevelDBComparator*) = 0;
- virtual bool destroyLevelDB(const String& fileName) = 0;
-};
-
-class IDBBackingStoreLevelDB : public RefCounted<IDBBackingStoreLevelDB> {
-public:
- class Transaction;
-
- virtual ~IDBBackingStoreLevelDB();
- static PassRefPtr<IDBBackingStoreLevelDB> open(const SecurityOrigin&, const String& pathBase, const String& fileIdentifier);
- static PassRefPtr<IDBBackingStoreLevelDB> open(const SecurityOrigin&, const String& pathBase, const String& fileIdentifier, LevelDBFactory*);
- static PassRefPtr<IDBBackingStoreLevelDB> openInMemory(const String& identifier);
- static PassRefPtr<IDBBackingStoreLevelDB> openInMemory(const String& identifier, LevelDBFactory*);
- WeakPtr<IDBBackingStoreLevelDB> createWeakPtr() { return m_weakFactory.createWeakPtr(); }
-
- void establishBackingStoreTransaction(int64_t transactionID);
-
- Vector<String> getDatabaseNames();
-
- // New-style asynchronous callbacks
- void getOrEstablishIDBDatabaseMetadata(const String& name, std::function<void (const IDBDatabaseMetadata&, bool success)> callbackFunction);
- void deleteDatabase(const String& name, std::function<void (bool success)> successCallback);
-
- // Old-style synchronous callbacks
- bool updateIDBDatabaseVersion(IDBBackingStoreTransactionLevelDB&, int64_t rowId, uint64_t version);
-
- bool createObjectStore(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, const String& name, const IDBKeyPath&, bool autoIncrement);
- bool deleteObjectStore(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId) WARN_UNUSED_RETURN;
-
- bool getRecord(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, const IDBKey&, Vector<char>& record) WARN_UNUSED_RETURN;
- bool putRecord(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, const IDBKey&, PassRefPtr<SharedBuffer> value, IDBRecordIdentifier*) WARN_UNUSED_RETURN;
- bool clearObjectStore(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId) WARN_UNUSED_RETURN;
- bool deleteRecord(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, const IDBRecordIdentifier&) WARN_UNUSED_RETURN;
- bool getKeyGeneratorCurrentNumber(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t& currentNumber) WARN_UNUSED_RETURN;
- bool maybeUpdateKeyGeneratorCurrentNumber(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t newState, bool checkCurrent) WARN_UNUSED_RETURN;
- bool keyExistsInObjectStore(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, const IDBKey&, RefPtr<IDBRecordIdentifier>& foundIDBRecordIdentifier) WARN_UNUSED_RETURN;
-
- bool createIndex(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const String& name, const IDBKeyPath&, bool isUnique, bool isMultiEntry) WARN_UNUSED_RETURN;
- bool deleteIndex(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId) WARN_UNUSED_RETURN;
- bool putIndexDataForRecord(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, const IDBRecordIdentifier*) WARN_UNUSED_RETURN;
- bool getPrimaryKeyViaIndex(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, RefPtr<IDBKey>& primaryKey) WARN_UNUSED_RETURN;
- bool keyExistsInIndex(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey, bool& exists) WARN_UNUSED_RETURN;
-
- virtual PassRefPtr<IDBBackingStoreCursorLevelDB> openObjectStoreKeyCursor(int64_t cursorID, IDBBackingStoreTransactionLevelDB&, int64_t databaseID, int64_t objectStoreId, const IDBKeyRange*, IndexedDB::CursorDirection);
- virtual PassRefPtr<IDBBackingStoreCursorLevelDB> openObjectStoreCursor(int64_t cursorID, IDBBackingStoreTransactionLevelDB&, int64_t databaseID, int64_t objectStoreId, const IDBKeyRange*, IndexedDB::CursorDirection);
- virtual PassRefPtr<IDBBackingStoreCursorLevelDB> openIndexKeyCursor(int64_t cursorID, IDBBackingStoreTransactionLevelDB&, int64_t databaseID, int64_t objectStoreId, int64_t indexId, const IDBKeyRange*, IndexedDB::CursorDirection);
- virtual PassRefPtr<IDBBackingStoreCursorLevelDB> openIndexCursor(int64_t cursorID, IDBBackingStoreTransactionLevelDB&, int64_t databaseID, int64_t objectStoreId, int64_t indexId, const IDBKeyRange*, IndexedDB::CursorDirection);
-
- bool makeIndexWriters(int64_t transactionID, int64_t databaseId, const IDBObjectStoreMetadata&, IDBKey& primaryKey, bool keyWasGenerated, const Vector<int64_t>& indexIds, const Vector<Vector<RefPtr<IDBKey>>>&, Vector<RefPtr<IDBIndexWriterLevelDB>>& indexWriters, String* errorMessage, bool& completed) WARN_UNUSED_RETURN;
-
- virtual PassRefPtr<IDBKey> generateKey(IDBTransactionBackend&, int64_t databaseId, int64_t objectStoreId);
- bool updateKeyGenerator(IDBTransactionBackend&, int64_t databaseId, int64_t objectStoreId, const IDBKey&, bool checkCurrent);
-
- LevelDBDatabase* levelDBDatabase() { return m_db.get(); }
-
- static int compareIndexKeys(const LevelDBSlice&, const LevelDBSlice&);
-
- void removeBackingStoreTransaction(IDBBackingStoreTransactionLevelDB*);
-
-private:
- IDBBackingStoreLevelDB(const String& identifier, PassOwnPtr<LevelDBDatabase>, PassOwnPtr<LevelDBComparator>);
- static PassRefPtr<IDBBackingStoreLevelDB> create(const String& identifier, PassOwnPtr<LevelDBDatabase>, PassOwnPtr<LevelDBComparator>);
-
- // FIXME: LevelDB needs to support uint64_t as the version type.
- bool createIDBDatabaseMetaData(IDBDatabaseMetadata&);
- bool getIDBDatabaseMetaData(const String& name, IDBDatabaseMetadata*, bool& success) WARN_UNUSED_RETURN;
- bool getObjectStores(int64_t databaseId, IDBDatabaseMetadata::ObjectStoreMap* objectStores) WARN_UNUSED_RETURN;
-
- bool findKeyInIndex(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, Vector<char>& foundEncodedPrimaryKey, bool& found);
- bool getIndexes(int64_t databaseId, int64_t objectStoreId, IDBObjectStoreMetadata::IndexMap*) WARN_UNUSED_RETURN;
-
- String m_identifier;
-
- OwnPtr<LevelDBDatabase> m_db;
- OwnPtr<LevelDBComparator> m_comparator;
- WeakPtrFactory<IDBBackingStoreLevelDB> m_weakFactory;
-
- HashMap<int64_t, RefPtr<IDBBackingStoreTransactionLevelDB>> m_backingStoreTransactions;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
-
-#endif // IDBBackingStoreLevelDB_h
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreTransactionLevelDB.cpp b/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreTransactionLevelDB.cpp
deleted file mode 100644
index a7a5f66fa..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreTransactionLevelDB.cpp
+++ /dev/null
@@ -1,86 +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 "IDBBackingStoreTransactionLevelDB.h"
-
-#if ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
-
-#include "HistogramSupport.h"
-#include "IDBBackingStoreLevelDB.h"
-#include "Logging.h"
-#include <wtf/text/CString.h>
-
-namespace WebCore {
-
-IDBBackingStoreTransactionLevelDB::IDBBackingStoreTransactionLevelDB(int64_t transactionID, IDBBackingStoreLevelDB* backingStore)
- : m_transactionID(transactionID)
- , m_backingStore(backingStore)
-{
-}
-
-IDBBackingStoreTransactionLevelDB::~IDBBackingStoreTransactionLevelDB()
-{
- if (m_backingStore)
- m_backingStore->removeBackingStoreTransaction(this);
-}
-
-void IDBBackingStoreTransactionLevelDB::begin()
-{
- LOG(StorageAPI, "IDBBackingStoreTransactionLevelDB::begin");
- ASSERT(!m_transaction);
- m_transaction = LevelDBTransaction::create(reinterpret_cast<IDBBackingStoreLevelDB*>(m_backingStore)->levelDBDatabase());
-}
-
-bool IDBBackingStoreTransactionLevelDB::commit()
-{
- LOG(StorageAPI, "IDBBackingStoreTransactionLevelDB::commit");
- ASSERT(m_transaction);
- bool result = m_transaction->commit();
- m_transaction.clear();
- if (!result)
- LOG_ERROR("IndexedDB TransactionCommit Error");
- return result;
-}
-
-void IDBBackingStoreTransactionLevelDB::rollback()
-{
- LOG(StorageAPI, "IDBBackingStoreTransactionLevelDB::rollback");
- ASSERT(m_transaction);
- m_transaction->rollback();
- m_transaction.clear();
-}
-
-void IDBBackingStoreTransactionLevelDB::resetTransaction()
-{
- ASSERT(m_backingStore);
- m_backingStore->removeBackingStoreTransaction(this);
- m_backingStore = 0;
- m_transaction = 0;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreTransactionLevelDB.h b/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreTransactionLevelDB.h
deleted file mode 100644
index c7f7bc494..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreTransactionLevelDB.h
+++ /dev/null
@@ -1,71 +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.
- */
-
-#ifndef IDBBackingStoreTransactionLevelDB_h
-#define IDBBackingStoreTransactionLevelDB_h
-
-#include "LevelDBTransaction.h"
-
-#if ENABLE(INDEXED_DATABASE)
-#if USE(LEVELDB)
-
-namespace WebCore {
-
-class IDBBackingStoreLevelDB;
-
-class IDBBackingStoreTransactionLevelDB : public RefCounted<IDBBackingStoreTransactionLevelDB> {
-public:
- static PassRefPtr<IDBBackingStoreTransactionLevelDB> create(int64_t transactionID, IDBBackingStoreLevelDB* backingStore)
- {
- return adoptRef(new IDBBackingStoreTransactionLevelDB(transactionID, backingStore));
- }
-
- ~IDBBackingStoreTransactionLevelDB();
-
- void begin();
- bool commit();
- void rollback();
- void resetTransaction();
-
- static LevelDBTransaction* levelDBTransactionFrom(IDBBackingStoreTransactionLevelDB& transaction)
- {
- return static_cast<IDBBackingStoreTransactionLevelDB&>(transaction).m_transaction.get();
- }
-
- int64_t transactionID() { return m_transactionID; }
-
-private:
- IDBBackingStoreTransactionLevelDB(int64_t transactionID, IDBBackingStoreLevelDB*);
-
- int64_t m_transactionID;
- IDBBackingStoreLevelDB* m_backingStore;
- RefPtr<LevelDBTransaction> m_transaction;
-};
-
-} // namespace WebCore
-
-#endif // USE(LEVELDB)
-#endif // ENABLE(INDEXED_DATABASE)
-#endif // IDBBackingStoreTransactionLevelDB_h
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.cpp b/Source/WebCore/Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.cpp
deleted file mode 100644
index 3541fa88c..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2011 Google 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "IDBFactoryBackendLevelDB.h"
-
-#include "DOMStringList.h"
-#include "IDBBackingStoreLevelDB.h"
-#include "IDBCursorBackend.h"
-#include "IDBDatabaseBackend.h"
-#include "IDBDatabaseException.h"
-#include "IDBServerConnectionLevelDB.h"
-#include "IDBTransactionBackend.h"
-#include "IDBTransactionCoordinator.h"
-#include "Logging.h"
-#include "SecurityOrigin.h"
-
-#if ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
-
-namespace WebCore {
-
-template<typename K, typename M>
-static void cleanWeakMap(HashMap<K, WeakPtr<M> >& map)
-{
- HashMap<K, WeakPtr<M> > other;
- other.swap(map);
-
- typename HashMap<K, WeakPtr<M> >::const_iterator iter = other.begin();
- while (iter != other.end()) {
- if (iter->value.get())
- map.set(iter->key, iter->value);
- ++iter;
- }
-}
-
-static String computeFileIdentifier(const SecurityOrigin& securityOrigin)
-{
- static const char levelDBFileSuffix[] = "@1";
- return securityOrigin.databaseIdentifier() + levelDBFileSuffix;
-}
-
-static String computeUniqueIdentifier(const String& name, const SecurityOrigin& securityOrigin)
-{
- return computeFileIdentifier(securityOrigin) + name;
-}
-
-IDBFactoryBackendLevelDB::IDBFactoryBackendLevelDB(const String& databaseDirectory)
- : m_databaseDirectory(databaseDirectory)
-{
-}
-
-IDBFactoryBackendLevelDB::~IDBFactoryBackendLevelDB()
-{
-}
-
-void IDBFactoryBackendLevelDB::removeIDBDatabaseBackend(const String& uniqueIdentifier)
-{
- ASSERT(m_databaseBackendMap.contains(uniqueIdentifier));
- m_databaseBackendMap.remove(uniqueIdentifier);
-}
-
-void IDBFactoryBackendLevelDB::getDatabaseNames(PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<SecurityOrigin> securityOrigin, ScriptExecutionContext*, const String& dataDirectory)
-{
- ASSERT(securityOrigin);
- LOG(StorageAPI, "IDBFactoryBackendLevelDB::getDatabaseNames");
- RefPtr<IDBBackingStoreLevelDB> backingStore = openBackingStore(*securityOrigin, dataDirectory);
- if (!backingStore) {
- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error opening backing store for indexedDB.webkitGetDatabaseNames."));
- return;
- }
-
- RefPtr<DOMStringList> databaseNames = DOMStringList::create();
-
- Vector<String> foundNames = backingStore->getDatabaseNames();
- for (Vector<String>::const_iterator it = foundNames.begin(); it != foundNames.end(); ++it)
- databaseNames->append(*it);
-
- callbacks->onSuccess(databaseNames.release());
-}
-
-void IDBFactoryBackendLevelDB::deleteDatabase(const String& name, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<SecurityOrigin> securityOrigin, ScriptExecutionContext*, const String& dataDirectory)
-{
- LOG(StorageAPI, "IDBFactoryBackendLevelDB::deleteDatabase");
- const String uniqueIdentifier = computeUniqueIdentifier(name, *securityOrigin);
-
- IDBDatabaseBackendMap::iterator it = m_databaseBackendMap.find(uniqueIdentifier);
- if (it != m_databaseBackendMap.end()) {
- // If there are any connections to the database, directly delete the
- // database.
- it->value->deleteDatabase(callbacks);
- return;
- }
-
- // FIXME: Everything from now on should be done on another thread.
- RefPtr<IDBBackingStoreLevelDB> backingStore = openBackingStore(*securityOrigin, dataDirectory);
- if (!backingStore) {
- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error opening backing store for indexedDB.deleteDatabase."));
- return;
- }
-
- RefPtr<IDBServerConnection> serverConnection = IDBServerConnectionLevelDB::create(name, backingStore.get());
- RefPtr<IDBDatabaseBackend> databaseBackend = IDBDatabaseBackend::create(name, uniqueIdentifier, this, *serverConnection);
- if (databaseBackend) {
- m_databaseBackendMap.set(uniqueIdentifier, databaseBackend.get());
- databaseBackend->deleteDatabase(callbacks);
- m_databaseBackendMap.remove(uniqueIdentifier);
- } else
- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error creating database backend for indexedDB.deleteDatabase."));
-}
-
-PassRefPtr<IDBBackingStoreLevelDB> IDBFactoryBackendLevelDB::openBackingStore(const SecurityOrigin& securityOrigin, const String& dataDirectory)
-{
- const String fileIdentifier = computeFileIdentifier(securityOrigin);
- const bool openInMemory = dataDirectory.isEmpty();
-
- IDBBackingStoreLevelDBMap::iterator it2 = m_backingStoreMap.find(fileIdentifier);
- if (it2 != m_backingStoreMap.end() && it2->value.get())
- return it2->value.get();
-
- RefPtr<IDBBackingStoreLevelDB> backingStore;
- if (openInMemory)
- backingStore = IDBBackingStoreLevelDB::openInMemory(fileIdentifier);
- else
- backingStore = IDBBackingStoreLevelDB::open(securityOrigin, dataDirectory, fileIdentifier);
-
- if (backingStore) {
- cleanWeakMap(m_backingStoreMap);
- m_backingStoreMap.set(fileIdentifier, backingStore->createWeakPtr());
- // If an in-memory database, bind lifetime to this factory instance.
- if (openInMemory)
- m_sessionOnlyBackingStores.add(backingStore);
-
- // All backing stores associated with this factory should be of the same type.
- ASSERT(m_sessionOnlyBackingStores.isEmpty() || openInMemory);
-
- return backingStore.release();
- }
-
- return 0;
-}
-
-void IDBFactoryBackendLevelDB::open(const String& name, uint64_t version, int64_t transactionId, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks, const SecurityOrigin& openingOrigin, const SecurityOrigin&)
-{
- LOG(StorageAPI, "IDBFactoryBackendLevelDB::open");
- const String uniqueIdentifier = computeUniqueIdentifier(name, openingOrigin);
-
- RefPtr<IDBDatabaseBackend> databaseBackend;
- IDBDatabaseBackendMap::iterator it = m_databaseBackendMap.find(uniqueIdentifier);
- if (it == m_databaseBackendMap.end()) {
- RefPtr<IDBBackingStoreLevelDB> backingStore = openBackingStore(openingOrigin, m_databaseDirectory);
- if (!backingStore) {
- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error opening backing store for indexedDB.open."));
- return;
- }
-
- RefPtr<IDBServerConnection> serverConnection = IDBServerConnectionLevelDB::create(name, backingStore.get());
- databaseBackend = IDBDatabaseBackend::create(name, uniqueIdentifier, this, *serverConnection);
- if (databaseBackend)
- m_databaseBackendMap.set(uniqueIdentifier, databaseBackend.get());
- else {
- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error creating database backend for indexeddb.open."));
- return;
- }
- } else
- databaseBackend = it->value;
-
- databaseBackend->openConnection(callbacks, databaseCallbacks, transactionId, version);
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.h b/Source/WebCore/Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.h
deleted file mode 100644
index 004046062..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2010 Google 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE 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 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.
- */
-#ifndef IDBFactoryBackendLevelDB_h
-#define IDBFactoryBackendLevelDB_h
-
-#if ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
-
-#include "IDBCallbacks.h"
-#include "IDBDatabaseCallbacks.h"
-#include "IDBFactoryBackendInterface.h"
-#include "SecurityOrigin.h"
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
-#include <wtf/RefCounted.h>
-#include <wtf/WeakPtr.h>
-#include <wtf/text/StringHash.h>
-
-namespace WebCore {
-
-class DOMStringList;
-
-class IDBBackingStoreLevelDB;
-class IDBDatabaseBackend;
-
-class IDBFactoryBackendLevelDB : public IDBFactoryBackendInterface {
-public:
- static PassRefPtr<IDBFactoryBackendLevelDB> create(const String& databaseDirectory)
- {
- return adoptRef(new IDBFactoryBackendLevelDB(databaseDirectory));
- }
- virtual ~IDBFactoryBackendLevelDB();
-
- // Notifications from weak pointers.
- virtual void removeIDBDatabaseBackend(const String& uniqueIdentifier) override final;
-
- virtual void getDatabaseNames(PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, ScriptExecutionContext*, const String& dataDir) override final;
- virtual void open(const String& name, uint64_t version, int64_t transactionId, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBDatabaseCallbacks>, const SecurityOrigin& openingOrigin, const SecurityOrigin& mainFrameOrigin) override final;
-
- virtual void deleteDatabase(const String& name, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, ScriptExecutionContext*, const String& dataDir) override final;
-
-protected:
- virtual PassRefPtr<IDBBackingStoreLevelDB> openBackingStore(const SecurityOrigin&, const String& dataDir);
-
-private:
- explicit IDBFactoryBackendLevelDB(const String& databaseDirectory);
-
- typedef HashMap<String, RefPtr<IDBDatabaseBackend> > IDBDatabaseBackendMap;
- IDBDatabaseBackendMap m_databaseBackendMap;
-
- typedef HashMap<String, WeakPtr<IDBBackingStoreLevelDB> > IDBBackingStoreLevelDBMap;
- IDBBackingStoreLevelDBMap m_backingStoreMap;
-
- HashSet<RefPtr<IDBBackingStoreLevelDB> > m_sessionOnlyBackingStores;
-
- String m_databaseDirectory;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
-
-#endif // IDBFactoryBackendLevelDB_h
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBIndexWriterLevelDB.cpp b/Source/WebCore/Modules/indexeddb/leveldb/IDBIndexWriterLevelDB.cpp
deleted file mode 100644
index 75b824501..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBIndexWriterLevelDB.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- * 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 "IDBIndexWriterLevelDB.h"
-
-#include "IDBKey.h"
-#include <wtf/text/CString.h>
-
-#if ENABLE(INDEXED_DATABASE)
-#if USE(LEVELDB)
-
-namespace WebCore {
-
-IDBIndexWriterLevelDB::IDBIndexWriterLevelDB(const IDBIndexMetadata& metadata, const IndexKeys& keys)
- : m_indexMetadata(metadata)
- , m_indexKeys(keys)
-{
-}
-
-void IDBIndexWriterLevelDB::writeIndexKeys(const IDBRecordIdentifier* recordIdentifier, IDBBackingStoreLevelDB& backingStore, IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId) const
-{
- ASSERT(recordIdentifier);
- int64_t indexId = m_indexMetadata.id;
- for (size_t i = 0; i < m_indexKeys.size(); ++i) {
- bool ok = backingStore.putIndexDataForRecord(transaction, databaseId, objectStoreId, indexId, *(m_indexKeys)[i].get(), recordIdentifier);
- // This should have already been verified as a valid write during verifyIndexKeys.
- ASSERT_UNUSED(ok, ok);
- }
-}
-
-bool IDBIndexWriterLevelDB::verifyIndexKeys(IDBBackingStoreLevelDB& backingStore, IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, bool& canAddKeys, const IDBKey* primaryKey, String* errorMessage) const
-{
- canAddKeys = false;
- for (size_t i = 0; i < m_indexKeys.size(); ++i) {
- bool ok = addingKeyAllowed(backingStore, transaction, databaseId, objectStoreId, indexId, (m_indexKeys)[i].get(), primaryKey, canAddKeys);
- if (!ok)
- return false;
- if (!canAddKeys) {
- if (errorMessage)
- *errorMessage = String::format("Unable to add key to index '%s': at least one key does not satisfy the uniqueness requirements.", m_indexMetadata.name.utf8().data());
- return true;
- }
- }
- canAddKeys = true;
- return true;
-}
-
-bool IDBIndexWriterLevelDB::addingKeyAllowed(IDBBackingStoreLevelDB& backingStore, IDBBackingStoreTransactionLevelDB& transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey* indexKey, const IDBKey* primaryKey, bool& allowed) const
-{
- allowed = false;
- if (!m_indexMetadata.unique) {
- allowed = true;
- return true;
- }
-
- RefPtr<IDBKey> foundPrimaryKey;
- bool found = false;
- bool ok = backingStore.keyExistsInIndex(transaction, databaseId, objectStoreId, indexId, *indexKey, foundPrimaryKey, found);
- if (!ok)
- return false;
- if (!found || (primaryKey && foundPrimaryKey->isEqual(primaryKey)))
- allowed = true;
- return true;
-}
-
-
-} // namespace WebCore
-
-#endif // USE(LEVELDB)
-#endif // ENABLE(INDEXED_DATABASE)
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBIndexWriterLevelDB.h b/Source/WebCore/Modules/indexeddb/leveldb/IDBIndexWriterLevelDB.h
deleted file mode 100644
index 07e55538e..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBIndexWriterLevelDB.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- * 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.
- */
-
-#ifndef IDBIndexWriterLevelDB_h
-#define IDBIndexWriterLevelDB_h
-
-#include "IDBBackingStoreLevelDB.h"
-#include "IDBDatabaseBackend.h"
-#include "IDBDatabaseMetadata.h"
-#include <wtf/RefCounted.h>
-
-#if ENABLE(INDEXED_DATABASE)
-#if USE(LEVELDB)
-
-namespace WebCore {
-
-typedef Vector<RefPtr<IDBKey>> IndexKeys;
-
-class IDBIndexWriterLevelDB : public RefCounted<IDBIndexWriterLevelDB> {
-public:
- static PassRefPtr<IDBIndexWriterLevelDB> create(const IDBIndexMetadata& indexMetadata, const IndexKeys& indexKeys)
- {
- return adoptRef(new IDBIndexWriterLevelDB(indexMetadata, indexKeys));
- }
-
- bool verifyIndexKeys(IDBBackingStoreLevelDB&, IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId, bool& canAddKeys, const IDBKey* primaryKey = 0, String* errorMessage = 0) const WARN_UNUSED_RETURN;
-
- void writeIndexKeys(const IDBRecordIdentifier*, IDBBackingStoreLevelDB&, IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId) const;
-
-private:
- IDBIndexWriterLevelDB(const IDBIndexMetadata&, const IndexKeys&);
-
- bool addingKeyAllowed(IDBBackingStoreLevelDB&, IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey* indexKey, const IDBKey* primaryKey, bool& allowed) const WARN_UNUSED_RETURN;
-
- const IDBIndexMetadata m_indexMetadata;
- IndexKeys m_indexKeys;
-};
-
-} // namespace WebCore
-
-#endif // #if USE(LEVELDB)
-#endif // ENABLE(INDEXED_DATABASE)
-#endif // IDBIndexWriterLevelDB_h
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBLevelDBCoding.cpp b/Source/WebCore/Modules/indexeddb/leveldb/IDBLevelDBCoding.cpp
deleted file mode 100644
index a4dcb1ede..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBLevelDBCoding.cpp
+++ /dev/null
@@ -1,1807 +0,0 @@
-/*
- * Copyright (C) 2011 Google 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 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 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 "IDBLevelDBCoding.h"
-
-#if ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
-
-#include "IDBKey.h"
-#include "IDBKeyPath.h"
-#include "LevelDBSlice.h"
-#include <wtf/ByteOrder.h>
-#include <wtf/text/StringBuilder.h>
-
-// LevelDB stores key/value pairs. Keys and values are strings of bytes, normally of type Vector<char>.
-//
-// The keys in the backing store are variable-length tuples with different types
-// of fields. Each key in the backing store starts with a ternary prefix: (database id, object store id, index id). For each, 0 is reserved for meta-data.
-// The prefix makes sure that data for a specific database, object store, and index are grouped together. The locality is important for performance: common
-// operations should only need a minimal number of seek operations. For example, all the meta-data for a database is grouped together so that reading that
-// meta-data only requires one seek.
-//
-// Each key type has a class (in square brackets below) which knows how to encode, decode, and compare that key type.
-//
-// Global meta-data have keys with prefix (0,0,0), followed by a type byte:
-//
-// <0, 0, 0, 0> => IndexedDB/LevelDB schema version [SchemaVersionKey]
-// <0, 0, 0, 1> => The maximum database id ever allocated [MaxDatabaseIdKey]
-// <0, 0, 0, 2> => SerializedScriptValue version [DataVersionKey]
-// <0, 0, 0, 100, database id> => Existence implies the database id is in the free list [DatabaseFreeListKey]
-// <0, 0, 0, 201, utf16 origin name, utf16 database name> => Database id [DatabaseNameKey]
-//
-//
-// Database meta-data:
-//
-// Again, the prefix is followed by a type byte.
-//
-// <database id, 0, 0, 0> => utf16 origin name [DatabaseMetaDataKey]
-// <database id, 0, 0, 1> => utf16 database name [DatabaseMetaDataKey]
-// <database id, 0, 0, 2> => utf16 user version data [DatabaseMetaDataKey]
-// <database id, 0, 0, 3> => maximum object store id ever allocated [DatabaseMetaDataKey]
-// <database id, 0, 0, 4> => user integer version (var int) [DatabaseMetaDataKey]
-//
-//
-// Object store meta-data:
-//
-// The prefix is followed by a type byte, then a variable-length integer, and then another type byte.
-//
-// <database id, 0, 0, 50, object store id, 0> => utf16 object store name [ObjectStoreMetaDataKey]
-// <database id, 0, 0, 50, object store id, 1> => utf16 key path [ObjectStoreMetaDataKey]
-// <database id, 0, 0, 50, object store id, 2> => has auto increment [ObjectStoreMetaDataKey]
-// <database id, 0, 0, 50, object store id, 3> => is evictable [ObjectStoreMetaDataKey]
-// <database id, 0, 0, 50, object store id, 4> => last "version" number [ObjectStoreMetaDataKey]
-// <database id, 0, 0, 50, object store id, 5> => maximum index id ever allocated [ObjectStoreMetaDataKey]
-// <database id, 0, 0, 50, object store id, 6> => has key path (vs. null) [ObjectStoreMetaDataKey]
-// <database id, 0, 0, 50, object store id, 7> => key generator current number [ObjectStoreMetaDataKey]
-//
-//
-// Index meta-data:
-//
-// The prefix is followed by a type byte, then two variable-length integers, and then another type byte.
-//
-// <database id, 0, 0, 100, object store id, index id, 0> => utf16 index name [IndexMetaDataKey]
-// <database id, 0, 0, 100, object store id, index id, 1> => are index keys unique [IndexMetaDataKey]
-// <database id, 0, 0, 100, object store id, index id, 2> => utf16 key path [IndexMetaDataKey]
-// <database id, 0, 0, 100, object store id, index id, 3> => is index multi-entry [IndexMetaDataKey]
-//
-//
-// Other object store and index meta-data:
-//
-// The prefix is followed by a type byte. The object store and index id are variable length integers, the utf16 strings are variable length strings.
-//
-// <database id, 0, 0, 150, object store id> => existence implies the object store id is in the free list [ObjectStoreFreeListKey]
-// <database id, 0, 0, 151, object store id, index id> => existence implies the index id is in the free list [IndexFreeListKey]
-// <database id, 0, 0, 200, utf16 object store name> => object store id [ObjectStoreNamesKey]
-// <database id, 0, 0, 201, object store id, utf16 index name> => index id [IndexNamesKey]
-//
-//
-// Object store data:
-//
-// The prefix is followed by a type byte. The user key is an encoded IDBKey.
-//
-// <database id, object store id, 1, user key> => "version", serialized script value [ObjectStoreDataKey]
-//
-//
-// "Exists" entry:
-//
-// The prefix is followed by a type byte. The user key is an encoded IDBKey.
-//
-// <database id, object store id, 2, user key> => "version" [ExistsEntryKey]
-//
-//
-// Index data:
-//
-// The prefix is followed by a type byte. The index key is an encoded IDBKey. The sequence number is a variable length integer.
-// The primary key is an encoded IDBKey.
-//
-// <database id, object store id, index id, index key, sequence number, primary key> => "version", primary key [IndexDataKey]
-//
-// (The sequence number is obsolete; it was used to allow two entries with
-// the same user (index) key in non-unique indexes prior to the inclusion of
-// the primary key in the data. The "version" field is used to weed out stale
-// index data. Whenever new object store data is inserted, it gets a new
-// "version" number, and new index data is written with this number. When
-// the index is used for look-ups, entries are validated against the
-// "exists" entries, and records with old "version" numbers are deleted
-// when they are encountered in getPrimaryKeyViaIndex,
-// IndexCursorImpl::loadCurrentRow, and IndexKeyCursorImpl::loadCurrentRow).
-
-namespace WebCore {
-namespace IDBLevelDBCoding {
-
-#ifndef INT64_MAX
-#define INT64_MAX 0x7fffffffffffffffLL
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX 0x7fffffffL
-#endif
-
-static const unsigned char IDBKeyNullTypeByte = 0;
-static const unsigned char IDBKeyStringTypeByte = 1;
-static const unsigned char IDBKeyDateTypeByte = 2;
-static const unsigned char IDBKeyNumberTypeByte = 3;
-static const unsigned char IDBKeyArrayTypeByte = 4;
-static const unsigned char IDBKeyMinKeyTypeByte = 5;
-
-static const unsigned char IDBKeyPathTypeCodedByte1 = 0;
-static const unsigned char IDBKeyPathTypeCodedByte2 = 0;
-
-static const unsigned char ObjectStoreDataIndexId = 1;
-static const unsigned char ExistsEntryIndexId = 2;
-
-static const unsigned char SchemaVersionTypeByte = 0;
-static const unsigned char MaxDatabaseIdTypeByte = 1;
-static const unsigned char DataVersionTypeByte = 2;
-static const unsigned char MaxSimpleGlobalMetaDataTypeByte = 3; // Insert before this and increment.
-static const unsigned char DatabaseFreeListTypeByte = 100;
-static const unsigned char DatabaseNameTypeByte = 201;
-
-static const unsigned char ObjectStoreMetaDataTypeByte = 50;
-static const unsigned char IndexMetaDataTypeByte = 100;
-static const unsigned char ObjectStoreFreeListTypeByte = 150;
-static const unsigned char IndexFreeListTypeByte = 151;
-static const unsigned char ObjectStoreNamesTypeByte = 200;
-static const unsigned char IndexNamesKeyTypeByte = 201;
-
-static const unsigned char ObjectMetaDataTypeMaximum = 255;
-static const unsigned char IndexMetaDataTypeMaximum = 255;
-
-Vector<char> encodeByte(unsigned char c)
-{
- Vector<char, DefaultInlineBufferSize> v;
- v.append(c);
-
- ASSERT(v.size() <= DefaultInlineBufferSize);
- return v;
-}
-
-const char* decodeByte(const char* p, const char* limit, unsigned char& foundChar)
-{
- if (p >= limit)
- return 0;
-
- foundChar = *p++;
- return p;
-}
-
-Vector<char> maxIDBKey()
-{
- return encodeByte(IDBKeyNullTypeByte);
-}
-
-Vector<char> minIDBKey()
-{
- return encodeByte(IDBKeyMinKeyTypeByte);
-}
-
-Vector<char> encodeBool(bool b)
-{
- Vector<char, DefaultInlineBufferSize> ret;
- ret.append(b ? 1 : 0);
-
- ASSERT(ret.size() <= DefaultInlineBufferSize);
- return ret;
-}
-
-bool decodeBool(const char* begin, const char* end)
-{
- ASSERT_UNUSED(end, begin < end);
- return *begin;
-}
-
-Vector<char> encodeInt(int64_t nParam)
-{
- ASSERT(nParam >= 0);
- uint64_t n = static_cast<uint64_t>(nParam);
- Vector<char, DefaultInlineBufferSize> ret;
-
- do {
- unsigned char c = n;
- ret.append(c);
- n >>= 8;
- } while (n);
-
- ASSERT(ret.size() <= DefaultInlineBufferSize);
- return ret;
-}
-
-int64_t decodeInt(const char* begin, const char* end)
-{
- ASSERT(begin <= end);
- int64_t ret = 0;
-
- int shift = 0;
- while (begin < end) {
- unsigned char c = *begin++;
- ret |= static_cast<int64_t>(c) << shift;
- shift += 8;
- }
-
- return ret;
-}
-
-static int compareInts(int64_t a, int64_t b)
-{
- ASSERT(a >= 0);
- ASSERT(b >= 0);
-
- int64_t diff = a - b;
- if (diff < 0)
- return -1;
- if (diff > 0)
- return 1;
- return 0;
-}
-
-Vector<char> encodeVarInt(int64_t nParam)
-{
- ASSERT(nParam >= 0);
- uint64_t n = static_cast<uint64_t>(nParam);
- Vector<char, DefaultInlineBufferSize> ret;
-
- do {
- unsigned char c = n & 0x7f;
- n >>= 7;
- if (n)
- c |= 0x80;
- ret.append(c);
- } while (n);
-
- ASSERT(ret.size() <= DefaultInlineBufferSize);
- return ret;
-}
-
-const char* decodeVarInt(const char* p, const char* limit, int64_t& foundInt)
-{
- ASSERT(limit >= p);
- foundInt = 0;
- int shift = 0;
-
- do {
- if (p >= limit)
- return 0;
-
- unsigned char c = *p;
- foundInt |= static_cast<int64_t>(c & 0x7f) << shift;
- shift += 7;
- } while (*p++ & 0x80);
- return p;
-}
-
-Vector<char> encodeString(const String& s)
-{
- // Backing store is UTF-16BE, convert from host endianness.
- size_t length = s.length();
- Vector<char> ret(length * sizeof(UChar));
-
- const UChar* src = s.characters();
- UChar* dst = reinterpret_cast<UChar*>(ret.data());
- for (unsigned i = 0; i < length; ++i)
- *dst++ = htons(*src++);
-
- return ret;
-}
-
-String decodeString(const char* start, const char* end)
-{
- // Backing store is UTF-16BE, convert to host endianness.
- ASSERT(end >= start);
- ASSERT(!((end - start) % sizeof(UChar)));
-
- size_t length = (end - start) / sizeof(UChar);
- Vector<UChar> buffer(length);
-
- const UChar* src = reinterpret_cast<const UChar*>(start);
- UChar* dst = buffer.data();
- for (unsigned i = 0; i < length; ++i)
- *dst++ = ntohs(*src++);
-
- return String::adopt(buffer);
-}
-
-Vector<char> encodeStringWithLength(const String& s)
-{
- Vector<char> ret = encodeVarInt(s.length());
- ret.appendVector(encodeString(s));
- return ret;
-}
-
-const char* decodeStringWithLength(const char* p, const char* limit, String& foundString)
-{
- ASSERT(limit >= p);
- int64_t len;
- p = decodeVarInt(p, limit, len);
- if (!p || len < 0 || p + len * 2 > limit)
- return 0;
-
- foundString = decodeString(p, p + len * 2);
- p += len * 2;
- return p;
-}
-
-int compareEncodedStringsWithLength(const char*& p, const char* limitP, const char*& q, const char* limitQ, bool& ok)
-{
- ASSERT(&p != &q);
- ASSERT(limitP >= p);
- ASSERT(limitQ >= q);
- int64_t lenP, lenQ;
- p = decodeVarInt(p, limitP, lenP);
- q = decodeVarInt(q, limitQ, lenQ);
- if (!p || !q || lenP < 0 || lenQ < 0) {
- ok = false;
- return 0;
- }
- ASSERT(p && q);
- ASSERT(lenP >= 0);
- ASSERT(lenQ >= 0);
- ASSERT(p + lenP * 2 <= limitP);
- ASSERT(q + lenQ * 2 <= limitQ);
-
- const char* startP = p;
- const char* startQ = q;
- p += lenP * 2;
- q += lenQ * 2;
-
- if (p > limitP || q > limitQ) {
- ok = false;
- return 0;
- }
-
- ok = true;
- const size_t lmin = static_cast<size_t>(lenP < lenQ ? lenP : lenQ);
- if (int x = memcmp(startP, startQ, lmin * 2))
- return x;
-
- if (lenP == lenQ)
- return 0;
-
- return (lenP > lenQ) ? 1 : -1;
-}
-
-Vector<char> encodeDouble(double x)
-{
- // FIXME: It would be nice if we could be byte order independent.
- const char* p = reinterpret_cast<char*>(&x);
- Vector<char, DefaultInlineBufferSize> v;
- v.append(p, sizeof(x));
-
- ASSERT(v.size() <= DefaultInlineBufferSize);
- return v;
-}
-
-const char* decodeDouble(const char* p, const char* limit, double* d)
-{
- if (p + sizeof(*d) > limit)
- return 0;
-
- char* x = reinterpret_cast<char*>(d);
- for (size_t i = 0; i < sizeof(*d); ++i)
- *x++ = *p++;
- return p;
-}
-
-Vector<char> encodeIDBKey(const IDBKey& key)
-{
- Vector<char, DefaultInlineBufferSize> ret;
- encodeIDBKey(key, ret);
- return ret;
-}
-
-void encodeIDBKey(const IDBKey& key, Vector<char, DefaultInlineBufferSize>& into)
-{
- size_t previousSize = into.size();
- ASSERT(key.isValid());
- switch (key.type()) {
- case IDBKey::InvalidType:
- case IDBKey::MinType:
- ASSERT_NOT_REACHED();
- into.appendVector(encodeByte(IDBKeyNullTypeByte));
- return;
- case IDBKey::ArrayType: {
- into.appendVector(encodeByte(IDBKeyArrayTypeByte));
- size_t length = key.array().size();
- into.appendVector(encodeVarInt(length));
- for (size_t i = 0; i < length; ++i)
- encodeIDBKey(*key.array()[i], into);
- ASSERT_UNUSED(previousSize, into.size() > previousSize);
- return;
- }
- case IDBKey::StringType:
- into.appendVector(encodeByte(IDBKeyStringTypeByte));
- into.appendVector(encodeStringWithLength(key.string()));
- ASSERT_UNUSED(previousSize, into.size() > previousSize);
- return;
- case IDBKey::DateType:
- into.appendVector(encodeByte(IDBKeyDateTypeByte));
- into.appendVector(encodeDouble(key.date()));
- ASSERT_UNUSED(previousSize, into.size() - previousSize == 9);
- return;
- case IDBKey::NumberType:
- into.appendVector(encodeByte(IDBKeyNumberTypeByte));
- into.appendVector(encodeDouble(key.number()));
- ASSERT_UNUSED(previousSize, into.size() - previousSize == 9);
- return;
- }
-
- ASSERT_NOT_REACHED();
-}
-
-
-const char* decodeIDBKey(const char* p, const char* limit, RefPtr<IDBKey>& foundKey)
-{
- ASSERT(limit >= p);
- if (p >= limit)
- return 0;
-
- unsigned char type = *p++;
-
- switch (type) {
- case IDBKeyNullTypeByte:
- foundKey = IDBKey::createInvalid();
- return p;
-
- case IDBKeyArrayTypeByte: {
- int64_t length;
- p = decodeVarInt(p, limit, length);
- if (!p || length < 0)
- return 0;
- IDBKey::KeyArray array;
- while (length--) {
- RefPtr<IDBKey> key;
- p = decodeIDBKey(p, limit, key);
- if (!p)
- return 0;
- array.append(key);
- }
- foundKey = IDBKey::createArray(array);
- return p;
- }
- case IDBKeyStringTypeByte: {
- String s;
- p = decodeStringWithLength(p, limit, s);
- if (!p)
- return 0;
- foundKey = IDBKey::createString(s);
- return p;
- }
- case IDBKeyDateTypeByte: {
- double d;
- p = decodeDouble(p, limit, &d);
- if (!p)
- return 0;
- foundKey = IDBKey::createDate(d);
- return p;
- }
- case IDBKeyNumberTypeByte: {
- double d;
- p = decodeDouble(p, limit, &d);
- if (!p)
- return 0;
- foundKey = IDBKey::createNumber(d);
- return p;
- }
- }
-
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-const char* extractEncodedIDBKey(const char* start, const char* limit, Vector<char>* result = 0)
-{
- const char* p = start;
- if (p >= limit)
- return 0;
-
- unsigned char type = *p++;
-
- switch (type) {
- case IDBKeyNullTypeByte:
- case IDBKeyMinKeyTypeByte:
- break;
- case IDBKeyArrayTypeByte: {
- int64_t length;
- p = decodeVarInt(p, limit, length);
- if (!p || length < 0)
- return 0;
- while (length--) {
- p = extractEncodedIDBKey(p, limit);
- if (!p)
- return 0;
- }
- break;
- }
- case IDBKeyStringTypeByte: {
- int64_t length;
- p = decodeVarInt(p, limit, length);
- if (!p || length < 0 || p + length * 2 > limit)
- return 0;
- p += length * 2;
- break;
- }
- case IDBKeyDateTypeByte:
- case IDBKeyNumberTypeByte:
- if (p + sizeof(double) > limit)
- return 0;
- p += sizeof(double);
- break;
- }
-
- if (result) {
- ASSERT(p);
- ASSERT(p <= limit);
- result->clear();
- result->append(start, p - start);
- }
-
- return p;
-}
-
-static IDBKey::Type keyTypeByteToKeyType(unsigned char type)
-{
- switch (type) {
- case IDBKeyNullTypeByte:
- return IDBKey::InvalidType;
- case IDBKeyArrayTypeByte:
- return IDBKey::ArrayType;
- case IDBKeyStringTypeByte:
- return IDBKey::StringType;
- case IDBKeyDateTypeByte:
- return IDBKey::DateType;
- case IDBKeyNumberTypeByte:
- return IDBKey::NumberType;
- case IDBKeyMinKeyTypeByte:
- return IDBKey::MinType;
- }
-
- ASSERT_NOT_REACHED();
- return IDBKey::InvalidType;
-}
-
-static int compareEncodedIDBKeys(const char*& ptrA, const char* limitA, const char*& ptrB, const char* limitB, bool& ok)
-{
- ok = true;
- ASSERT(&ptrA != &ptrB);
- ASSERT_WITH_SECURITY_IMPLICATION(ptrA < limitA);
- ASSERT_WITH_SECURITY_IMPLICATION(ptrB < limitB);
- unsigned char typeA = *ptrA++;
- unsigned char typeB = *ptrB++;
-
- if (int x = IDBKey::compareTypes(keyTypeByteToKeyType(typeA), keyTypeByteToKeyType(typeB)))
- return x;
-
- switch (typeA) {
- case IDBKeyNullTypeByte:
- case IDBKeyMinKeyTypeByte:
- // Null type or max type; no payload to compare.
- return 0;
- case IDBKeyArrayTypeByte: {
- int64_t lengthA, lengthB;
- ptrA = decodeVarInt(ptrA, limitA, lengthA);
- ptrB = decodeVarInt(ptrB, limitB, lengthB);
- if (!ptrA || !ptrB || lengthA < 0 || lengthB < 0) {
- ok = false;
- return 0;
- }
- for (int64_t i = 0; i < lengthA && i < lengthB; ++i) {
- int result = compareEncodedIDBKeys(ptrA, limitA, ptrB, limitB, ok);
- if (!ok || result)
- return result;
- }
- if (lengthA < lengthB)
- return -1;
- if (lengthA > lengthB)
- return 1;
- return 0;
- }
- case IDBKeyStringTypeByte:
- return compareEncodedStringsWithLength(ptrA, limitA, ptrB, limitB, ok);
- case IDBKeyDateTypeByte:
- case IDBKeyNumberTypeByte: {
- double d, e;
- ptrA = decodeDouble(ptrA, limitA, &d);
- ptrB = decodeDouble(ptrB, limitB, &e);
- ASSERT(ptrA);
- ASSERT(ptrB);
- if (!ptrA || !ptrB) {
- ok = false;
- return 0;
- }
- if (d < e)
- return -1;
- if (d > e)
- return 1;
- return 0;
- }
- }
-
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-int compareEncodedIDBKeys(const Vector<char>& keyA, const Vector<char>& keyB, bool& ok)
-{
- ASSERT(keyA.size() >= 1);
- ASSERT(keyB.size() >= 1);
-
- const char* ptrA = keyA.data();
- const char* limitA = ptrA + keyA.size();
- const char* ptrB = keyB.data();
- const char* limitB = ptrB + keyB.size();
-
- return compareEncodedIDBKeys(ptrA, limitA, ptrB, limitB, ok);
-}
-
-Vector<char> encodeIDBKeyPath(const IDBKeyPath& keyPath)
-{
- // May be typed, or may be a raw string. An invalid leading
- // byte is used to identify typed coding. New records are
- // always written as typed.
- Vector<char, DefaultInlineBufferSize> ret;
- ret.append(IDBKeyPathTypeCodedByte1);
- ret.append(IDBKeyPathTypeCodedByte2);
- ret.append(static_cast<char>(keyPath.type()));
- switch (keyPath.type()) {
- case IDBKeyPath::NullType:
- break;
- case IDBKeyPath::StringType:
- ret.appendVector(encodeStringWithLength(keyPath.string()));
- break;
- case IDBKeyPath::ArrayType: {
- const Vector<String>& array = keyPath.array();
- size_t count = array.size();
- ret.appendVector(encodeVarInt(count));
- for (size_t i = 0; i < count; ++i)
- ret.appendVector(encodeStringWithLength(array[i]));
- break;
- }
- }
- return ret;
-}
-
-IDBKeyPath decodeIDBKeyPath(const char* p, const char* limit)
-{
- // May be typed, or may be a raw string. An invalid leading
- // byte sequence is used to identify typed coding. New records are
- // always written as typed.
- if (p == limit || (limit - p >= 2 && (*p != IDBKeyPathTypeCodedByte1 || *(p + 1) != IDBKeyPathTypeCodedByte2)))
- return IDBKeyPath(decodeString(p, limit));
- p += 2;
-
- ASSERT(p != limit);
- IDBKeyPath::Type type = static_cast<IDBKeyPath::Type>(*p++);
- switch (type) {
- case IDBKeyPath::NullType:
- ASSERT(p == limit);
- return IDBKeyPath();
- case IDBKeyPath::StringType: {
- String string;
- p = decodeStringWithLength(p, limit, string);
- ASSERT(p == limit);
- return IDBKeyPath(string);
- }
- case IDBKeyPath::ArrayType: {
- Vector<String> array;
- int64_t count;
- p = decodeVarInt(p, limit, count);
- ASSERT(p);
- ASSERT(count >= 0);
- while (count--) {
- String string;
- p = decodeStringWithLength(p, limit, string);
- ASSERT(p);
- array.append(string);
- }
- ASSERT(p == limit);
- return IDBKeyPath(array);
- }
- }
- ASSERT_NOT_REACHED();
- return IDBKeyPath();
-}
-
-namespace {
-
-template<typename KeyType>
-int compare(const LevelDBSlice& a, const LevelDBSlice& b, bool, bool& ok)
-{
- KeyType keyA;
- KeyType keyB;
-
- const char* ptrA = KeyType::decode(a.begin(), a.end(), &keyA);
- ASSERT(ptrA);
- if (!ptrA) {
- ok = false;
- return 0;
- }
- const char* ptrB = KeyType::decode(b.begin(), b.end(), &keyB);
- ASSERT(ptrB);
- if (!ptrB) {
- ok = false;
- return 0;
- }
-
- ok = true;
- return keyA.compare(keyB);
-}
-
-template<>
-int compare<ExistsEntryKey>(const LevelDBSlice& a, const LevelDBSlice& b, bool, bool& ok)
-{
- KeyPrefix prefixA;
- KeyPrefix prefixB;
- const char* ptrA = KeyPrefix::decode(a.begin(), a.end(), &prefixA);
- const char* ptrB = KeyPrefix::decode(b.begin(), b.end(), &prefixB);
- ASSERT(ptrA);
- ASSERT(ptrB);
- ASSERT(prefixA.m_databaseId);
- ASSERT(prefixA.m_objectStoreId);
- ASSERT(prefixA.m_indexId == ExistsEntryKey::SpecialIndexNumber);
- ASSERT(prefixB.m_databaseId);
- ASSERT(prefixB.m_objectStoreId);
- ASSERT(prefixB.m_indexId == ExistsEntryKey::SpecialIndexNumber);
- ASSERT(ptrA != a.end());
- ASSERT(ptrB != b.end());
- // Prefixes are not compared - it is assumed this was already done.
- ASSERT(!prefixA.compare(prefixB));
-
- return compareEncodedIDBKeys(ptrA, a.end(), ptrB, b.end(), ok);
-}
-
-template<>
-int compare<ObjectStoreDataKey>(const LevelDBSlice& a, const LevelDBSlice& b, bool, bool& ok)
-{
- KeyPrefix prefixA;
- KeyPrefix prefixB;
- const char* ptrA = KeyPrefix::decode(a.begin(), a.end(), &prefixA);
- const char* ptrB = KeyPrefix::decode(b.begin(), b.end(), &prefixB);
- ASSERT(ptrA);
- ASSERT(ptrB);
- ASSERT(prefixA.m_databaseId);
- ASSERT(prefixA.m_objectStoreId);
- ASSERT(prefixA.m_indexId == ObjectStoreDataKey::SpecialIndexNumber);
- ASSERT(prefixB.m_databaseId);
- ASSERT(prefixB.m_objectStoreId);
- ASSERT(prefixB.m_indexId == ObjectStoreDataKey::SpecialIndexNumber);
- ASSERT(ptrA != a.end());
- ASSERT(ptrB != b.end());
- // Prefixes are not compared - it is assumed this was already done.
- ASSERT(!prefixA.compare(prefixB));
-
- return compareEncodedIDBKeys(ptrA, a.end(), ptrB, b.end(), ok);
-}
-
-template<>
-int compare<IndexDataKey>(const LevelDBSlice& a, const LevelDBSlice& b, bool ignoreDuplicates, bool& ok)
-{
- KeyPrefix prefixA;
- KeyPrefix prefixB;
- const char* ptrA = KeyPrefix::decode(a.begin(), a.end(), &prefixA);
- const char* ptrB = KeyPrefix::decode(b.begin(), b.end(), &prefixB);
- ASSERT(ptrA);
- ASSERT(ptrB);
- ASSERT(prefixA.m_databaseId);
- ASSERT(prefixA.m_objectStoreId);
- ASSERT(prefixA.m_indexId >= MinimumIndexId);
- ASSERT(prefixB.m_databaseId);
- ASSERT(prefixB.m_objectStoreId);
- ASSERT(prefixB.m_indexId >= MinimumIndexId);
- ASSERT(ptrA != a.end());
- ASSERT(ptrB != b.end());
- // Prefixes are not compared - it is assumed this was already done.
- ASSERT(!prefixA.compare(prefixB));
-
- // index key
- int result = compareEncodedIDBKeys(ptrA, a.end(), ptrB, b.end(), ok);
- if (!ok || result)
- return result;
- if (ignoreDuplicates)
- return 0;
-
- // sequence number [optional]
- int64_t sequenceNumberA = -1;
- int64_t sequenceNumberB = -1;
- if (ptrA != a.end())
- ptrA = decodeVarInt(ptrA, a.end(), sequenceNumberA);
- if (ptrB != b.end())
- ptrB = decodeVarInt(ptrB, b.end(), sequenceNumberB);
-
- // primary key [optional]
- if (!ptrA || !ptrB)
- return 0;
- if (ptrA == a.end() && ptrB == b.end())
- return 0;
- if (ptrA == a.end())
- return -1;
- if (ptrB == b.end())
- return 1;
-
- result = compareEncodedIDBKeys(ptrA, a.end(), ptrB, b.end(), ok);
- if (!ok || result)
- return result;
-
- return compareInts(sequenceNumberA, sequenceNumberB);
-}
-
-int compare(const LevelDBSlice& a, const LevelDBSlice& b, bool indexKeys, bool& ok)
-{
- const char* ptrA = a.begin();
- const char* ptrB = b.begin();
- const char* endA = a.end();
- const char* endB = b.end();
-
- KeyPrefix prefixA;
- KeyPrefix prefixB;
-
- ptrA = KeyPrefix::decode(ptrA, endA, &prefixA);
- ptrB = KeyPrefix::decode(ptrB, endB, &prefixB);
- ASSERT(ptrA);
- ASSERT(ptrB);
- if (!ptrA || !ptrB) {
- ok = false;
- return 0;
- }
-
- ok = true;
- if (int x = prefixA.compare(prefixB))
- return x;
-
- if (prefixA.type() == KeyPrefix::GlobalMetaData) {
- ASSERT(ptrA != endA);
- ASSERT(ptrB != endB);
-
- unsigned char typeByteA = *ptrA++;
- unsigned char typeByteB = *ptrB++;
-
- if (int x = typeByteA - typeByteB)
- return x;
- if (typeByteA < MaxSimpleGlobalMetaDataTypeByte)
- return 0;
-
- const bool ignoreDuplicates = false;
- if (typeByteA == DatabaseFreeListTypeByte)
- return compare<DatabaseFreeListKey>(a, b, ignoreDuplicates, ok);
- if (typeByteA == DatabaseNameTypeByte)
- return compare<DatabaseNameKey>(a, b, ignoreDuplicates, ok);
- }
-
- if (prefixA.type() == KeyPrefix::DatabaseMetaData) {
- ASSERT(ptrA != endA);
- ASSERT(ptrB != endB);
-
- unsigned char typeByteA = *ptrA++;
- unsigned char typeByteB = *ptrB++;
-
- if (int x = typeByteA - typeByteB)
- return x;
- if (typeByteA < DatabaseMetaDataKey::MaxSimpleMetaDataType)
- return 0;
-
- const bool ignoreDuplicates = false;
- if (typeByteA == ObjectStoreMetaDataTypeByte)
- return compare<ObjectStoreMetaDataKey>(a, b, ignoreDuplicates, ok);
- if (typeByteA == IndexMetaDataTypeByte)
- return compare<IndexMetaDataKey>(a, b, ignoreDuplicates, ok);
- if (typeByteA == ObjectStoreFreeListTypeByte)
- return compare<ObjectStoreFreeListKey>(a, b, ignoreDuplicates, ok);
- if (typeByteA == IndexFreeListTypeByte)
- return compare<IndexFreeListKey>(a, b, ignoreDuplicates, ok);
- if (typeByteA == ObjectStoreNamesTypeByte)
- return compare<ObjectStoreNamesKey>(a, b, ignoreDuplicates, ok);
- if (typeByteA == IndexNamesKeyTypeByte)
- return compare<IndexNamesKey>(a, b, ignoreDuplicates, ok);
- }
-
- if (prefixA.type() == KeyPrefix::ObjectStoreData) {
- if (ptrA == endA && ptrB == endB)
- return 0;
- if (ptrA == endA)
- return -1;
- if (ptrB == endB)
- return 1; // FIXME: This case of non-existing user keys should not have to be handled this way.
-
- const bool ignoreDuplicates = false;
- return compare<ObjectStoreDataKey>(a, b, ignoreDuplicates, ok);
- }
- if (prefixA.type() == KeyPrefix::ExistsEntry) {
- if (ptrA == endA && ptrB == endB)
- return 0;
- if (ptrA == endA)
- return -1;
- if (ptrB == endB)
- return 1; // FIXME: This case of non-existing user keys should not have to be handled this way.
-
- const bool ignoreDuplicates = false;
- return compare<ExistsEntryKey>(a, b, ignoreDuplicates, ok);
- }
- if (prefixA.type() == KeyPrefix::IndexData) {
- if (ptrA == endA && ptrB == endB)
- return 0;
- if (ptrA == endA)
- return -1;
- if (ptrB == endB)
- return 1; // FIXME: This case of non-existing user keys should not have to be handled this way.
-
- bool ignoreDuplicates = indexKeys;
- return compare<IndexDataKey>(a, b, ignoreDuplicates, ok);
- }
-
- ASSERT_NOT_REACHED();
- ok = false;
- return 0;
-}
-
-}
-
-int compare(const LevelDBSlice& a, const LevelDBSlice& b, bool indexKeys)
-{
- bool ok;
- int result = compare(a, b, indexKeys, ok);
- ASSERT(ok);
- if (!ok)
- return 0;
- return result;
-}
-
-KeyPrefix::KeyPrefix()
- : m_databaseId(InvalidType)
- , m_objectStoreId(InvalidType)
- , m_indexId(InvalidType)
-{
-}
-
-KeyPrefix::KeyPrefix(int64_t databaseId)
- : m_databaseId(databaseId)
- , m_objectStoreId(0)
- , m_indexId(0)
-{
- ASSERT(KeyPrefix::isValidDatabaseId(databaseId));
-}
-
-KeyPrefix::KeyPrefix(int64_t databaseId, int64_t objectStoreId)
- : m_databaseId(databaseId)
- , m_objectStoreId(objectStoreId)
- , m_indexId(0)
-{
- ASSERT(KeyPrefix::isValidDatabaseId(databaseId));
- ASSERT(KeyPrefix::isValidObjectStoreId(objectStoreId));
-}
-
-KeyPrefix::KeyPrefix(int64_t databaseId, int64_t objectStoreId, int64_t indexId)
- : m_databaseId(databaseId)
- , m_objectStoreId(objectStoreId)
- , m_indexId(indexId)
-{
- ASSERT(KeyPrefix::isValidDatabaseId(databaseId));
- ASSERT(KeyPrefix::isValidObjectStoreId(objectStoreId));
- ASSERT(KeyPrefix::isValidIndexId(indexId));
-}
-
-KeyPrefix::KeyPrefix(Type type, int64_t databaseId, int64_t objectStoreId, int64_t indexId)
- : m_databaseId(databaseId)
- , m_objectStoreId(objectStoreId)
- , m_indexId(indexId)
-{
- ASSERT_UNUSED(type, type == InvalidType);
- ASSERT(KeyPrefix::isValidDatabaseId(databaseId));
- ASSERT(KeyPrefix::isValidObjectStoreId(objectStoreId));
-}
-
-
-KeyPrefix KeyPrefix::createWithSpecialIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId)
-{
- ASSERT(KeyPrefix::isValidDatabaseId(databaseId));
- ASSERT(KeyPrefix::isValidObjectStoreId(objectStoreId));
- ASSERT(indexId);
- return KeyPrefix(InvalidType, databaseId, objectStoreId, indexId);
-}
-
-
-bool KeyPrefix::isValidDatabaseId(int64_t databaseId)
-{
- return (databaseId > 0) && (databaseId < KeyPrefix::kMaxDatabaseId);
-}
-
-bool KeyPrefix::isValidObjectStoreId(int64_t objectStoreId)
-{
- return (objectStoreId > 0) && (objectStoreId < KeyPrefix::kMaxObjectStoreId);
-}
-
-bool KeyPrefix::isValidIndexId(int64_t indexId)
-{
- return (indexId >= MinimumIndexId) && (indexId < KeyPrefix::kMaxIndexId);
-}
-
-const char* KeyPrefix::decode(const char* start, const char* limit, KeyPrefix* result)
-{
- if (start == limit)
- return 0;
-
- unsigned char firstByte = *start++;
-
- int databaseIdBytes = ((firstByte >> 5) & 0x7) + 1;
- int objectStoreIdBytes = ((firstByte >> 2) & 0x7) + 1;
- int indexIdBytes = (firstByte & 0x3) + 1;
-
- if (start + databaseIdBytes + objectStoreIdBytes + indexIdBytes > limit)
- return 0;
-
- result->m_databaseId = decodeInt(start, start + databaseIdBytes);
- start += databaseIdBytes;
- result->m_objectStoreId = decodeInt(start, start + objectStoreIdBytes);
- start += objectStoreIdBytes;
- result->m_indexId = decodeInt(start, start + indexIdBytes);
- start += indexIdBytes;
-
- return start;
-}
-
-Vector<char> KeyPrefix::encodeEmpty()
-{
- const Vector<char, 4> result(4, 0);
- ASSERT(encodeInternal(0, 0, 0) == Vector<char>(4, 0));
- return result;
-}
-
-Vector<char> KeyPrefix::encode() const
-{
- ASSERT(m_databaseId != InvalidId);
- ASSERT(m_objectStoreId != InvalidId);
- ASSERT(m_indexId != InvalidId);
- return encodeInternal(m_databaseId, m_objectStoreId, m_indexId);
-}
-
-Vector<char> KeyPrefix::encodeInternal(int64_t databaseId, int64_t objectStoreId, int64_t indexId)
-{
- Vector<char> databaseIdString = encodeIntSafely(databaseId, kMaxDatabaseId);
- Vector<char> objectStoreIdString = encodeIntSafely(objectStoreId, kMaxObjectStoreId);
- Vector<char> indexIdString = encodeIntSafely(indexId, kMaxIndexId);
-
- ASSERT(databaseIdString.size() <= kMaxDatabaseIdSizeBytes);
- ASSERT(objectStoreIdString.size() <= kMaxObjectStoreIdSizeBytes);
- ASSERT(indexIdString.size() <= kMaxIndexIdSizeBytes);
-
- unsigned char firstByte = (databaseIdString.size() - 1) << (kMaxObjectStoreIdSizeBits + kMaxIndexIdSizeBits) | (objectStoreIdString.size() - 1) << kMaxIndexIdSizeBits | (indexIdString.size() - 1);
- COMPILE_ASSERT(kMaxDatabaseIdSizeBits + kMaxObjectStoreIdSizeBits + kMaxIndexIdSizeBits == sizeof(firstByte) * 8, CANT_ENCODE_IDS);
- Vector<char, DefaultInlineBufferSize> ret;
- ret.append(firstByte);
- ret.appendVector(databaseIdString);
- ret.appendVector(objectStoreIdString);
- ret.appendVector(indexIdString);
-
- ASSERT(ret.size() <= DefaultInlineBufferSize);
- return ret;
-}
-
-int KeyPrefix::compare(const KeyPrefix& other) const
-{
- ASSERT(m_databaseId != InvalidId);
- ASSERT(m_objectStoreId != InvalidId);
- ASSERT(m_indexId != InvalidId);
-
- if (m_databaseId != other.m_databaseId)
- return compareInts(m_databaseId, other.m_databaseId);
- if (m_objectStoreId != other.m_objectStoreId)
- return compareInts(m_objectStoreId, other.m_objectStoreId);
- if (m_indexId != other.m_indexId)
- return compareInts(m_indexId, other.m_indexId);
- return 0;
-}
-
-KeyPrefix::Type KeyPrefix::type() const
-{
- ASSERT(m_databaseId != InvalidId);
- ASSERT(m_objectStoreId != InvalidId);
- ASSERT(m_indexId != InvalidId);
-
- if (!m_databaseId)
- return GlobalMetaData;
- if (!m_objectStoreId)
- return DatabaseMetaData;
- if (m_indexId == ObjectStoreDataIndexId)
- return ObjectStoreData;
- if (m_indexId == ExistsEntryIndexId)
- return ExistsEntry;
- if (m_indexId >= MinimumIndexId)
- return IndexData;
-
- ASSERT_NOT_REACHED();
- return InvalidType;
-}
-
-Vector<char> SchemaVersionKey::encode()
-{
- Vector<char> ret = KeyPrefix::encodeEmpty();
- ret.appendVector(encodeByte(SchemaVersionTypeByte));
- return ret;
-}
-
-Vector<char> MaxDatabaseIdKey::encode()
-{
- Vector<char> ret = KeyPrefix::encodeEmpty();
- ret.appendVector(encodeByte(MaxDatabaseIdTypeByte));
- return ret;
-}
-
-Vector<char> DataVersionKey::encode()
-{
- Vector<char> ret = KeyPrefix::encodeEmpty();
- ret.appendVector(encodeByte(DataVersionTypeByte));
- return ret;
-}
-
-DatabaseFreeListKey::DatabaseFreeListKey()
- : m_databaseId(-1)
-{
-}
-
-const char* DatabaseFreeListKey::decode(const char* start, const char* limit, DatabaseFreeListKey* result)
-{
- KeyPrefix prefix;
- const char* p = KeyPrefix::decode(start, limit, &prefix);
- if (!p)
- return 0;
- ASSERT(!prefix.m_databaseId);
- ASSERT(!prefix.m_objectStoreId);
- ASSERT(!prefix.m_indexId);
- if (p == limit)
- return 0;
- unsigned char typeByte = 0;
- p = decodeByte(p, limit, typeByte);
- ASSERT_UNUSED(typeByte, typeByte == DatabaseFreeListTypeByte);
- if (p == limit)
- return 0;
- return decodeVarInt(p, limit, result->m_databaseId);
-}
-
-Vector<char> DatabaseFreeListKey::encode(int64_t databaseId)
-{
- Vector<char> ret = KeyPrefix::encodeEmpty();
- ret.appendVector(encodeByte(DatabaseFreeListTypeByte));
- ret.appendVector(encodeVarInt(databaseId));
- return ret;
-}
-
-Vector<char> DatabaseFreeListKey::encodeMaxKey()
-{
- return encode(INT64_MAX);
-}
-
-int64_t DatabaseFreeListKey::databaseId() const
-{
- ASSERT(m_databaseId >= 0);
- return m_databaseId;
-}
-
-int DatabaseFreeListKey::compare(const DatabaseFreeListKey& other) const
-{
- ASSERT(m_databaseId >= 0);
- return compareInts(m_databaseId, other.m_databaseId);
-}
-
-const char* DatabaseNameKey::decode(const char* start, const char* limit, DatabaseNameKey* result)
-{
- KeyPrefix prefix;
- const char* p = KeyPrefix::decode(start, limit, &prefix);
- if (!p)
- return p;
- ASSERT(!prefix.m_databaseId);
- ASSERT(!prefix.m_objectStoreId);
- ASSERT(!prefix.m_indexId);
- if (p == limit)
- return 0;
- unsigned char typeByte = 0;
- p = decodeByte(p, limit, typeByte);
- ASSERT_UNUSED(typeByte, typeByte == DatabaseNameTypeByte);
- if (p == limit)
- return 0;
- p = decodeStringWithLength(p, limit, result->m_origin);
- if (!p)
- return 0;
- return decodeStringWithLength(p, limit, result->m_databaseName);
-}
-
-Vector<char> DatabaseNameKey::encode(const String& origin, const String& databaseName)
-{
- Vector<char> ret = KeyPrefix::encodeEmpty();
- ret.appendVector(encodeByte(DatabaseNameTypeByte));
- ret.appendVector(encodeStringWithLength(origin));
- ret.appendVector(encodeStringWithLength(databaseName));
- return ret;
-}
-
-Vector<char> DatabaseNameKey::encodeMinKeyForOrigin(const String& origin)
-{
- return encode(origin, "");
-}
-
-Vector<char> DatabaseNameKey::encodeStopKeyForOrigin(const String& origin)
-{
- // just after origin in collation order
- return encodeMinKeyForOrigin(origin + "\x01");
-}
-
-int DatabaseNameKey::compare(const DatabaseNameKey& other)
-{
- if (int x = codePointCompare(m_origin, other.m_origin))
- return x;
- return codePointCompare(m_databaseName, other.m_databaseName);
-}
-
-Vector<char> DatabaseMetaDataKey::encode(int64_t databaseId, MetaDataType metaDataType)
-{
- KeyPrefix prefix(databaseId);
- Vector<char> ret = prefix.encode();
- ret.appendVector(encodeByte(metaDataType));
- return ret;
-}
-
-ObjectStoreMetaDataKey::ObjectStoreMetaDataKey()
- : m_objectStoreId(-1)
- , m_metaDataType(-1)
-{
-}
-
-const char* ObjectStoreMetaDataKey::decode(const char* start, const char* limit, ObjectStoreMetaDataKey* result)
-{
- KeyPrefix prefix;
- const char* p = KeyPrefix::decode(start, limit, &prefix);
- if (!p)
- return 0;
- ASSERT(prefix.m_databaseId);
- ASSERT(!prefix.m_objectStoreId);
- ASSERT(!prefix.m_indexId);
- if (p == limit)
- return 0;
- unsigned char typeByte = 0;
- p = decodeByte(p, limit, typeByte);
- ASSERT_UNUSED(typeByte, typeByte == ObjectStoreMetaDataTypeByte);
- if (p == limit)
- return 0;
- p = decodeVarInt(p, limit, result->m_objectStoreId);
- if (!p)
- return 0;
- ASSERT(result->m_objectStoreId);
- if (p == limit)
- return 0;
- return decodeByte(p, limit, result->m_metaDataType);
-}
-
-Vector<char> ObjectStoreMetaDataKey::encode(int64_t databaseId, int64_t objectStoreId, unsigned char metaDataType)
-{
- KeyPrefix prefix(databaseId);
- Vector<char> ret = prefix.encode();
- ret.appendVector(encodeByte(ObjectStoreMetaDataTypeByte));
- ret.appendVector(encodeVarInt(objectStoreId));
- ret.appendVector(encodeByte(metaDataType));
- return ret;
-}
-
-Vector<char> ObjectStoreMetaDataKey::encodeMaxKey(int64_t databaseId)
-{
- return encode(databaseId, INT64_MAX, ObjectMetaDataTypeMaximum);
-}
-
-Vector<char> ObjectStoreMetaDataKey::encodeMaxKey(int64_t databaseId, int64_t objectStoreId)
-{
- return encode(databaseId, objectStoreId, ObjectMetaDataTypeMaximum);
-}
-
-int64_t ObjectStoreMetaDataKey::objectStoreId() const
-{
- ASSERT(m_objectStoreId >= 0);
- return m_objectStoreId;
-}
-unsigned char ObjectStoreMetaDataKey::metaDataType() const
-{
- return m_metaDataType;
-}
-
-int ObjectStoreMetaDataKey::compare(const ObjectStoreMetaDataKey& other)
-{
- ASSERT(m_objectStoreId >= 0);
- if (int x = compareInts(m_objectStoreId, other.m_objectStoreId))
- return x;
- int64_t result = m_metaDataType - other.m_metaDataType;
- if (result < 0)
- return -1;
- return (result > 0) ? 1 : result;
-}
-
-IndexMetaDataKey::IndexMetaDataKey()
- : m_objectStoreId(-1)
- , m_indexId(-1)
- , m_metaDataType(0)
-{
-}
-
-const char* IndexMetaDataKey::decode(const char* start, const char* limit, IndexMetaDataKey* result)
-{
- KeyPrefix prefix;
- const char* p = KeyPrefix::decode(start, limit, &prefix);
- if (!p)
- return 0;
- ASSERT(prefix.m_databaseId);
- ASSERT(!prefix.m_objectStoreId);
- ASSERT(!prefix.m_indexId);
- if (p == limit)
- return 0;
- unsigned char typeByte = 0;
- p = decodeByte(p, limit, typeByte);
- ASSERT_UNUSED(typeByte, typeByte == IndexMetaDataTypeByte);
- if (p == limit)
- return 0;
- p = decodeVarInt(p, limit, result->m_objectStoreId);
- if (!p)
- return 0;
- p = decodeVarInt(p, limit, result->m_indexId);
- if (!p)
- return 0;
- if (p == limit)
- return 0;
- return decodeByte(p, limit, result->m_metaDataType);
-}
-
-Vector<char> IndexMetaDataKey::encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, unsigned char metaDataType)
-{
- KeyPrefix prefix(databaseId);
- Vector<char> ret = prefix.encode();
- ret.appendVector(encodeByte(IndexMetaDataTypeByte));
- ret.appendVector(encodeVarInt(objectStoreId));
- ret.appendVector(encodeVarInt(indexId));
- ret.appendVector(encodeByte(metaDataType));
- return ret;
-}
-
-Vector<char> IndexMetaDataKey::encodeMaxKey(int64_t databaseId, int64_t objectStoreId)
-{
- return encode(databaseId, objectStoreId, INT64_MAX, IndexMetaDataTypeMaximum);
-}
-
-Vector<char> IndexMetaDataKey::encodeMaxKey(int64_t databaseId, int64_t objectStoreId, int64_t indexId)
-{
- return encode(databaseId, objectStoreId, indexId, IndexMetaDataTypeMaximum);
-}
-
-int IndexMetaDataKey::compare(const IndexMetaDataKey& other)
-{
- ASSERT(m_objectStoreId >= 0);
- ASSERT(m_indexId >= 0);
-
- if (int x = compareInts(m_objectStoreId, other.m_objectStoreId))
- return x;
- if (int x = compareInts(m_indexId, other.m_indexId))
- return x;
- return m_metaDataType - other.m_metaDataType;
-}
-
-int64_t IndexMetaDataKey::indexId() const
-{
- ASSERT(m_indexId >= 0);
- return m_indexId;
-}
-
-ObjectStoreFreeListKey::ObjectStoreFreeListKey()
- : m_objectStoreId(-1)
-{
-}
-
-const char* ObjectStoreFreeListKey::decode(const char* start, const char* limit, ObjectStoreFreeListKey* result)
-{
- KeyPrefix prefix;
- const char* p = KeyPrefix::decode(start, limit, &prefix);
- if (!p)
- return 0;
- ASSERT(prefix.m_databaseId);
- ASSERT(!prefix.m_objectStoreId);
- ASSERT(!prefix.m_indexId);
- if (p == limit)
- return 0;
- unsigned char typeByte = 0;
- p = decodeByte(p, limit, typeByte);
- ASSERT_UNUSED(typeByte, typeByte == ObjectStoreFreeListTypeByte);
- if (p == limit)
- return 0;
- return decodeVarInt(p, limit, result->m_objectStoreId);
-}
-
-Vector<char> ObjectStoreFreeListKey::encode(int64_t databaseId, int64_t objectStoreId)
-{
- KeyPrefix prefix(databaseId);
- Vector<char> ret = prefix.encode();
- ret.appendVector(encodeByte(ObjectStoreFreeListTypeByte));
- ret.appendVector(encodeVarInt(objectStoreId));
- return ret;
-}
-
-Vector<char> ObjectStoreFreeListKey::encodeMaxKey(int64_t databaseId)
-{
- return encode(databaseId, INT64_MAX);
-}
-
-int64_t ObjectStoreFreeListKey::objectStoreId() const
-{
- ASSERT(m_objectStoreId >= 0);
- return m_objectStoreId;
-}
-
-int ObjectStoreFreeListKey::compare(const ObjectStoreFreeListKey& other)
-{
- // FIXME: It may seem strange that we're not comparing database id's,
- // but that comparison will have been made earlier.
- // We should probably make this more clear, though...
- ASSERT(m_objectStoreId >= 0);
- return compareInts(m_objectStoreId, other.m_objectStoreId);
-}
-
-IndexFreeListKey::IndexFreeListKey()
- : m_objectStoreId(-1)
- , m_indexId(-1)
-{
-}
-
-const char* IndexFreeListKey::decode(const char* start, const char* limit, IndexFreeListKey* result)
-{
- KeyPrefix prefix;
- const char* p = KeyPrefix::decode(start, limit, &prefix);
- if (!p)
- return 0;
- ASSERT(prefix.m_databaseId);
- ASSERT(!prefix.m_objectStoreId);
- ASSERT(!prefix.m_indexId);
- if (p == limit)
- return 0;
- unsigned char typeByte = 0;
- p = decodeByte(p, limit, typeByte);
- ASSERT_UNUSED(typeByte, typeByte == IndexFreeListTypeByte);
- if (p == limit)
- return 0;
- p = decodeVarInt(p, limit, result->m_objectStoreId);
- if (!p)
- return 0;
- return decodeVarInt(p, limit, result->m_indexId);
-}
-
-Vector<char> IndexFreeListKey::encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId)
-{
- KeyPrefix prefix(databaseId);
- Vector<char> ret = prefix.encode();
- ret.appendVector(encodeByte(IndexFreeListTypeByte));
- ret.appendVector(encodeVarInt(objectStoreId));
- ret.appendVector(encodeVarInt(indexId));
- return ret;
-}
-
-Vector<char> IndexFreeListKey::encodeMaxKey(int64_t databaseId, int64_t objectStoreId)
-{
- return encode(databaseId, objectStoreId, INT64_MAX);
-}
-
-int IndexFreeListKey::compare(const IndexFreeListKey& other)
-{
- ASSERT(m_objectStoreId >= 0);
- ASSERT(m_indexId >= 0);
- if (int x = compareInts(m_objectStoreId, other.m_objectStoreId))
- return x;
- return compareInts(m_indexId, other.m_indexId);
-}
-
-int64_t IndexFreeListKey::objectStoreId() const
-{
- ASSERT(m_objectStoreId >= 0);
- return m_objectStoreId;
-}
-
-int64_t IndexFreeListKey::indexId() const
-{
- ASSERT(m_indexId >= 0);
- return m_indexId;
-}
-
-// FIXME: We never use this to look up object store ids, because a mapping
-// is kept in the IDBDatabaseBackend. Can the mapping become unreliable?
-// Can we remove this?
-const char* ObjectStoreNamesKey::decode(const char* start, const char* limit, ObjectStoreNamesKey* result)
-{
- KeyPrefix prefix;
- const char* p = KeyPrefix::decode(start, limit, &prefix);
- if (!p)
- return 0;
- ASSERT(prefix.m_databaseId);
- ASSERT(!prefix.m_objectStoreId);
- ASSERT(!prefix.m_indexId);
- if (p == limit)
- return 0;
- unsigned char typeByte = 0;
- p = decodeByte(p, limit, typeByte);
- ASSERT_UNUSED(typeByte, typeByte == ObjectStoreNamesTypeByte);
- return decodeStringWithLength(p, limit, result->m_objectStoreName);
-}
-
-Vector<char> ObjectStoreNamesKey::encode(int64_t databaseId, const String& objectStoreName)
-{
- KeyPrefix prefix(databaseId);
- Vector<char> ret = prefix.encode();
- ret.appendVector(encodeByte(ObjectStoreNamesTypeByte));
- ret.appendVector(encodeStringWithLength(objectStoreName));
- return ret;
-}
-
-int ObjectStoreNamesKey::compare(const ObjectStoreNamesKey& other)
-{
- return codePointCompare(m_objectStoreName, other.m_objectStoreName);
-}
-
-IndexNamesKey::IndexNamesKey()
- : m_objectStoreId(-1)
-{
-}
-
-// FIXME: We never use this to look up index ids, because a mapping
-// is kept at a higher level.
-const char* IndexNamesKey::decode(const char* start, const char* limit, IndexNamesKey* result)
-{
- KeyPrefix prefix;
- const char* p = KeyPrefix::decode(start, limit, &prefix);
- if (!p)
- return 0;
- ASSERT(prefix.m_databaseId);
- ASSERT(!prefix.m_objectStoreId);
- ASSERT(!prefix.m_indexId);
- if (p == limit)
- return 0;
- unsigned char typeByte = 0;
- p = decodeByte(p, limit, typeByte);
- ASSERT_UNUSED(typeByte, typeByte == IndexNamesKeyTypeByte);
- if (p == limit)
- return 0;
- p = decodeVarInt(p, limit, result->m_objectStoreId);
- if (!p)
- return 0;
- return decodeStringWithLength(p, limit, result->m_indexName);
-}
-
-Vector<char> IndexNamesKey::encode(int64_t databaseId, int64_t objectStoreId, const String& indexName)
-{
- KeyPrefix prefix(databaseId);
- Vector<char> ret = prefix.encode();
- ret.appendVector(encodeByte(IndexNamesKeyTypeByte));
- ret.appendVector(encodeVarInt(objectStoreId));
- ret.appendVector(encodeStringWithLength(indexName));
- return ret;
-}
-
-int IndexNamesKey::compare(const IndexNamesKey& other)
-{
- ASSERT(m_objectStoreId >= 0);
- if (int x = compareInts(m_objectStoreId, other.m_objectStoreId))
- return x;
- return codePointCompare(m_indexName, other.m_indexName);
-}
-
-const char* ObjectStoreDataKey::decode(const char* start, const char* end, ObjectStoreDataKey* result)
-{
- KeyPrefix prefix;
- const char* p = KeyPrefix::decode(start, end, &prefix);
- if (!p)
- return 0;
- ASSERT(prefix.m_databaseId);
- ASSERT(prefix.m_objectStoreId);
- ASSERT(prefix.m_indexId == SpecialIndexNumber);
- if (p == end)
- return 0;
- return extractEncodedIDBKey(p, end, &result->m_encodedUserKey);
-}
-
-Vector<char> ObjectStoreDataKey::encode(int64_t databaseId, int64_t objectStoreId, const Vector<char> encodedUserKey)
-{
- KeyPrefix prefix(KeyPrefix::createWithSpecialIndex(databaseId, objectStoreId, SpecialIndexNumber));
- Vector<char> ret = prefix.encode();
- ret.appendVector(encodedUserKey);
-
- return ret;
-}
-
-Vector<char> ObjectStoreDataKey::encode(int64_t databaseId, int64_t objectStoreId, const IDBKey& userKey)
-{
- return encode(databaseId, objectStoreId, encodeIDBKey(userKey));
-}
-
-int ObjectStoreDataKey::compare(const ObjectStoreDataKey& other, bool& ok)
-{
- return compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey, ok);
-}
-
-PassRefPtr<IDBKey> ObjectStoreDataKey::userKey() const
-{
- RefPtr<IDBKey> key;
- decodeIDBKey(m_encodedUserKey.begin(), m_encodedUserKey.end(), key);
- return key;
-}
-
-const int64_t ObjectStoreDataKey::SpecialIndexNumber = ObjectStoreDataIndexId;
-
-const char* ExistsEntryKey::decode(const char* start, const char* end, ExistsEntryKey* result)
-{
- KeyPrefix prefix;
- const char* p = KeyPrefix::decode(start, end, &prefix);
- if (!p)
- return 0;
- ASSERT(prefix.m_databaseId);
- ASSERT(prefix.m_objectStoreId);
- ASSERT(prefix.m_indexId == SpecialIndexNumber);
- if (p == end)
- return 0;
- return extractEncodedIDBKey(p, end, &result->m_encodedUserKey);
-}
-
-Vector<char> ExistsEntryKey::encode(int64_t databaseId, int64_t objectStoreId, const Vector<char>& encodedKey)
-{
- KeyPrefix prefix(KeyPrefix::createWithSpecialIndex(databaseId, objectStoreId, SpecialIndexNumber));
- Vector<char> ret = prefix.encode();
- ret.appendVector(encodedKey);
- return ret;
-}
-
-Vector<char> ExistsEntryKey::encode(int64_t databaseId, int64_t objectStoreId, const IDBKey& userKey)
-{
- return encode(databaseId, objectStoreId, encodeIDBKey(userKey));
-}
-
-int ExistsEntryKey::compare(const ExistsEntryKey& other, bool& ok)
-{
- return compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey, ok);
-}
-
-PassRefPtr<IDBKey> ExistsEntryKey::userKey() const
-{
- RefPtr<IDBKey> key;
- decodeIDBKey(m_encodedUserKey.begin(), m_encodedUserKey.end(), key);
- return key;
-}
-
-const int64_t ExistsEntryKey::SpecialIndexNumber = ExistsEntryIndexId;
-
-IndexDataKey::IndexDataKey()
- : m_databaseId(-1)
- , m_objectStoreId(-1)
- , m_indexId(-1)
- , m_sequenceNumber(-1)
-{
-}
-
-const char* IndexDataKey::decode(const char* start, const char* limit, IndexDataKey* result)
-{
- KeyPrefix prefix;
- const char* p = KeyPrefix::decode(start, limit, &prefix);
- if (!p)
- return 0;
- ASSERT(prefix.m_databaseId);
- ASSERT(prefix.m_objectStoreId);
- ASSERT(prefix.m_indexId >= MinimumIndexId);
- result->m_databaseId = prefix.m_databaseId;
- result->m_objectStoreId = prefix.m_objectStoreId;
- result->m_indexId = prefix.m_indexId;
- result->m_sequenceNumber = -1;
- result->m_encodedPrimaryKey = minIDBKey();
-
- p = extractEncodedIDBKey(p, limit, &result->m_encodedUserKey);
- if (!p)
- return 0;
-
- // [optional] sequence number
- if (p == limit)
- return p;
- p = decodeVarInt(p, limit, result->m_sequenceNumber);
- if (!p)
- return 0;
-
- // [optional] primary key
- if (p == limit)
- return p;
- p = extractEncodedIDBKey(p, limit, &result->m_encodedPrimaryKey);
- if (!p)
- return 0;
-
- return p;
-}
-
-Vector<char> IndexDataKey::encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const Vector<char>& encodedUserKey, const Vector<char>& encodedPrimaryKey, int64_t sequenceNumber)
-{
- KeyPrefix prefix(databaseId, objectStoreId, indexId);
- Vector<char> ret = prefix.encode();
- ret.appendVector(encodedUserKey);
- ret.appendVector(encodeVarInt(sequenceNumber));
- ret.appendVector(encodedPrimaryKey);
- return ret;
-}
-
-Vector<char> IndexDataKey::encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& userKey)
-{
- return encode(databaseId, objectStoreId, indexId, encodeIDBKey(userKey), minIDBKey());
-}
-
-Vector<char> IndexDataKey::encodeMinKey(int64_t databaseId, int64_t objectStoreId, int64_t indexId)
-{
- return encode(databaseId, objectStoreId, indexId, minIDBKey(), minIDBKey());
-}
-
-Vector<char> IndexDataKey::encodeMaxKey(int64_t databaseId, int64_t objectStoreId, int64_t indexId)
-{
- return encode(databaseId, objectStoreId, indexId, maxIDBKey(), maxIDBKey(), INT64_MAX);
-}
-
-int IndexDataKey::compare(const IndexDataKey& other, bool ignoreDuplicates, bool& ok)
-{
- ASSERT(m_databaseId >= 0);
- ASSERT(m_objectStoreId >= 0);
- ASSERT(m_indexId >= 0);
- int result = compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey, ok);
- if (!ok || result)
- return result;
- if (ignoreDuplicates)
- return 0;
- result = compareEncodedIDBKeys(m_encodedPrimaryKey, other.m_encodedPrimaryKey, ok);
- if (!ok || result)
- return result;
- return compareInts(m_sequenceNumber, other.m_sequenceNumber);
-}
-
-int64_t IndexDataKey::databaseId() const
-{
- ASSERT(m_databaseId >= 0);
- return m_databaseId;
-}
-
-int64_t IndexDataKey::objectStoreId() const
-{
- ASSERT(m_objectStoreId >= 0);
- return m_objectStoreId;
-}
-
-int64_t IndexDataKey::indexId() const
-{
- ASSERT(m_indexId >= 0);
- return m_indexId;
-}
-
-PassRefPtr<IDBKey> IndexDataKey::userKey() const
-{
- RefPtr<IDBKey> key;
- decodeIDBKey(m_encodedUserKey.begin(), m_encodedUserKey.end(), key);
- return key;
-}
-
-PassRefPtr<IDBKey> IndexDataKey::primaryKey() const
-{
- RefPtr<IDBKey> key;
- decodeIDBKey(m_encodedPrimaryKey.begin(), m_encodedPrimaryKey.end(), key);
- return key;
-}
-
-} // namespace IDBLevelDBCoding
-} // namespace WebCore
-
-#endif // ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBLevelDBCoding.h b/Source/WebCore/Modules/indexeddb/leveldb/IDBLevelDBCoding.h
deleted file mode 100644
index 9ac39bfd3..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBLevelDBCoding.h
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Copyright (C) 2011 Google 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 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 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.
- */
-
-#ifndef IDBLevelDBCoding_h
-#define IDBLevelDBCoding_h
-
-#if ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
-
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class IDBKey;
-class IDBKeyPath;
-class LevelDBSlice;
-
-namespace IDBLevelDBCoding {
-
-const unsigned char MinimumIndexId = 30;
-
-// As most of the IDBKeys and encoded values are short, we initialize some Vectors with a default inline buffer size
-// to reduce the memory re-allocations when the Vectors are appended.
-static const size_t DefaultInlineBufferSize = 32;
-
-Vector<char> encodeByte(unsigned char);
-const char* decodeByte(const char* p, const char* limit, unsigned char& foundChar);
-Vector<char> maxIDBKey();
-Vector<char> minIDBKey();
-Vector<char> encodeBool(bool);
-bool decodeBool(const char* begin, const char* end);
-Vector<char> encodeInt(int64_t);
-inline Vector<char> encodeIntSafely(int64_t nParam, int64_t max)
-{
- ASSERT_UNUSED(max, nParam <= max);
- return encodeInt(nParam);
-}
-int64_t decodeInt(const char* begin, const char* end);
-Vector<char> encodeVarInt(int64_t);
-const char* decodeVarInt(const char* p, const char* limit, int64_t& foundInt);
-Vector<char> encodeString(const String&);
-String decodeString(const char* p, const char* end);
-Vector<char> encodeStringWithLength(const String&);
-const char* decodeStringWithLength(const char* p, const char* limit, String& foundString);
-int compareEncodedStringsWithLength(const char*& p, const char* limitP, const char*& q, const char* limitQ, bool& ok);
-Vector<char> encodeDouble(double);
-const char* decodeDouble(const char* p, const char* limit, double*);
-void encodeIDBKey(const IDBKey&, Vector<char, DefaultInlineBufferSize>& into);
-Vector<char> encodeIDBKey(const IDBKey&);
-const char* decodeIDBKey(const char* p, const char* limit, RefPtr<IDBKey>& foundKey);
-const char* extractEncodedIDBKey(const char* start, const char* limit, Vector<char>* result);
-int compareEncodedIDBKeys(const Vector<char>&, const Vector<char>&, bool& ok);
-Vector<char> encodeIDBKeyPath(const IDBKeyPath&);
-IDBKeyPath decodeIDBKeyPath(const char*, const char*);
-
-int compare(const LevelDBSlice&, const LevelDBSlice&, bool indexKeys = false);
-
-class KeyPrefix {
-public:
- KeyPrefix();
- explicit KeyPrefix(int64_t databaseId);
- KeyPrefix(int64_t databaseId, int64_t objectStoreId);
- KeyPrefix(int64_t databaseId, int64_t objectStoreId, int64_t indexId);
- static KeyPrefix createWithSpecialIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId);
-
- static const char* decode(const char* start, const char* limit, KeyPrefix* result);
- Vector<char> encode() const;
- static Vector<char> encodeEmpty();
- int compare(const KeyPrefix& other) const;
-
- enum Type {
- GlobalMetaData,
- DatabaseMetaData,
- ObjectStoreData,
- ExistsEntry,
- IndexData,
- InvalidType
- };
-
- static const size_t kMaxDatabaseIdSizeBits = 3;
- static const size_t kMaxObjectStoreIdSizeBits = 3;
- static const size_t kMaxIndexIdSizeBits = 2;
-
- static const size_t kMaxDatabaseIdSizeBytes = 1ULL << kMaxDatabaseIdSizeBits; // 8
- static const size_t kMaxObjectStoreIdSizeBytes = 1ULL << kMaxObjectStoreIdSizeBits; // 8
- static const size_t kMaxIndexIdSizeBytes = 1ULL << kMaxIndexIdSizeBits; // 4
-
- static const size_t kMaxDatabaseIdBits = kMaxDatabaseIdSizeBytes * 8 - 1; // 63
- static const size_t kMaxObjectStoreIdBits = kMaxObjectStoreIdSizeBytes * 8 - 1; // 63
- static const size_t kMaxIndexIdBits = kMaxIndexIdSizeBytes * 8 - 1; // 31
-
- static const int64_t kMaxDatabaseId = (1ULL << kMaxDatabaseIdBits) - 1; // max signed int64_t
- static const int64_t kMaxObjectStoreId = (1ULL << kMaxObjectStoreIdBits) - 1; // max signed int64_t
- static const int64_t kMaxIndexId = (1ULL << kMaxIndexIdBits) - 1; // max signed int32_t
-
- static bool isValidDatabaseId(int64_t databaseId);
- static bool isValidObjectStoreId(int64_t indexId);
- static bool isValidIndexId(int64_t indexId);
- static bool validIds(int64_t databaseId, int64_t objectStoreId, int64_t indexId)
- {
- return isValidDatabaseId(databaseId) && isValidObjectStoreId(objectStoreId) && isValidIndexId(indexId);
- }
- static bool validIds(int64_t databaseId, int64_t objectStoreId)
- {
- return isValidDatabaseId(databaseId) && isValidObjectStoreId(objectStoreId);
- }
-
- Type type() const;
-
- int64_t m_databaseId;
- int64_t m_objectStoreId;
- int64_t m_indexId;
-
- static const int64_t InvalidId = -1;
-
-private:
- static Vector<char> encodeInternal(int64_t databaseId, int64_t objectStoreId, int64_t indexId);
- // Special constructor for createWithSpecialIndex()
- KeyPrefix(Type, int64_t databaseId, int64_t objectStoreId, int64_t indexId);
-};
-
-class SchemaVersionKey {
-public:
- static Vector<char> encode();
-};
-
-class MaxDatabaseIdKey {
-public:
- static Vector<char> encode();
-};
-
-class DataVersionKey {
-public:
- static Vector<char> encode();
-};
-
-class DatabaseFreeListKey {
-public:
- DatabaseFreeListKey();
- static const char* decode(const char* start, const char* limit, DatabaseFreeListKey* result);
- static Vector<char> encode(int64_t databaseId);
- static Vector<char> encodeMaxKey();
- int64_t databaseId() const;
- int compare(const DatabaseFreeListKey& other) const;
-
-private:
- int64_t m_databaseId;
-};
-
-class DatabaseNameKey {
-public:
- static const char* decode(const char* start, const char* limit, DatabaseNameKey* result);
- static Vector<char> encode(const String& origin, const String& databaseName);
- static Vector<char> encodeMinKeyForOrigin(const String& origin);
- static Vector<char> encodeStopKeyForOrigin(const String& origin);
- String origin() const { return m_origin; }
- String databaseName() const { return m_databaseName; }
- int compare(const DatabaseNameKey& other);
-
-private:
- String m_origin; // FIXME: Store encoded strings, or just pointers.
- String m_databaseName;
-};
-
-class DatabaseMetaDataKey {
-public:
- enum MetaDataType {
- OriginName = 0,
- DatabaseName = 1,
- UserVersion = 2,
- MaxObjectStoreId = 3,
- UserIntVersion = 4,
- MaxSimpleMetaDataType = 5
- };
-
- static Vector<char> encode(int64_t databaseId, MetaDataType);
-};
-
-class ObjectStoreMetaDataKey {
-public:
- enum MetaDataType {
- Name = 0,
- KeyPath = 1,
- AutoIncrement = 2,
- Evictable = 3,
- LastVersion = 4,
- MaxIndexId = 5,
- HasKeyPath = 6,
- KeyGeneratorCurrentNumber = 7
- };
-
- ObjectStoreMetaDataKey();
- static const char* decode(const char* start, const char* limit, ObjectStoreMetaDataKey* result);
- static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, unsigned char metaDataType);
- static Vector<char> encodeMaxKey(int64_t databaseId);
- static Vector<char> encodeMaxKey(int64_t databaseId, int64_t objectStoreId);
- int64_t objectStoreId() const;
- unsigned char metaDataType() const;
- int compare(const ObjectStoreMetaDataKey& other);
-
-private:
- int64_t m_objectStoreId;
- unsigned char m_metaDataType;
-};
-
-class IndexMetaDataKey {
-public:
- enum MetaDataType {
- Name = 0,
- Unique = 1,
- KeyPath = 2,
- MultiEntry = 3
- };
-
- IndexMetaDataKey();
- static const char* decode(const char* start, const char* limit, IndexMetaDataKey* result);
- static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, unsigned char metaDataType);
- static Vector<char> encodeMaxKey(int64_t databaseId, int64_t objectStoreId);
- static Vector<char> encodeMaxKey(int64_t databaseId, int64_t objectStoreId, int64_t indexId);
- int compare(const IndexMetaDataKey& other);
- int64_t indexId() const;
- unsigned char metaDataType() const { return m_metaDataType; }
-
-private:
- int64_t m_objectStoreId;
- int64_t m_indexId;
- unsigned char m_metaDataType;
-};
-
-class ObjectStoreFreeListKey {
-public:
- ObjectStoreFreeListKey();
- static const char* decode(const char* start, const char* limit, ObjectStoreFreeListKey* result);
- static Vector<char> encode(int64_t databaseId, int64_t objectStoreId);
- static Vector<char> encodeMaxKey(int64_t databaseId);
- int64_t objectStoreId() const;
- int compare(const ObjectStoreFreeListKey& other);
-
-private:
- int64_t m_objectStoreId;
-};
-
-class IndexFreeListKey {
-public:
- IndexFreeListKey();
- static const char* decode(const char* start, const char* limit, IndexFreeListKey* result);
- static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId);
- static Vector<char> encodeMaxKey(int64_t databaseId, int64_t objectStoreId);
- int compare(const IndexFreeListKey& other);
- int64_t objectStoreId() const;
- int64_t indexId() const;
-
-private:
- int64_t m_objectStoreId;
- int64_t m_indexId;
-};
-
-class ObjectStoreNamesKey {
-public:
- // FIXME: We never use this to look up object store ids, because a mapping
- // is kept in the IDBDatabaseBackend. Can the mapping become unreliable?
- // Can we remove this?
- static const char* decode(const char* start, const char* limit, ObjectStoreNamesKey* result);
- static Vector<char> encode(int64_t databaseId, const String& objectStoreName);
- int compare(const ObjectStoreNamesKey& other);
- String objectStoreName() const { return m_objectStoreName; }
-
-private:
- String m_objectStoreName; // FIXME: Store the encoded string, or just pointers to it.
-};
-
-class IndexNamesKey {
-public:
- IndexNamesKey();
- // FIXME: We never use this to look up index ids, because a mapping
- // is kept at a higher level.
- static const char* decode(const char* start, const char* limit, IndexNamesKey* result);
- static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const String& indexName);
- int compare(const IndexNamesKey& other);
- String indexName() const { return m_indexName; }
-
-private:
- int64_t m_objectStoreId;
- String m_indexName;
-};
-
-class ObjectStoreDataKey {
-public:
- static const char* decode(const char* start, const char* end, ObjectStoreDataKey* result);
- static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const Vector<char> encodedUserKey);
- static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const IDBKey& userKey);
- int compare(const ObjectStoreDataKey& other, bool& ok);
- PassRefPtr<IDBKey> userKey() const;
- static const int64_t SpecialIndexNumber;
-
-private:
- Vector<char> m_encodedUserKey;
-};
-
-class ExistsEntryKey {
-public:
- static const char* decode(const char* start, const char* end, ExistsEntryKey* result);
- static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const Vector<char>& encodedKey);
- static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, const IDBKey& userKey);
- int compare(const ExistsEntryKey& other, bool& ok);
- PassRefPtr<IDBKey> userKey() const;
-
- static const int64_t SpecialIndexNumber;
-
-private:
- Vector<char> m_encodedUserKey;
-};
-
-class IndexDataKey {
-public:
- IndexDataKey();
- static const char* decode(const char* start, const char* limit, IndexDataKey* result);
- static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const Vector<char>& encodedUserKey, const Vector<char>& encodedPrimaryKey, int64_t sequenceNumber = 0);
- static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& userKey);
- static Vector<char> encodeMinKey(int64_t databaseId, int64_t objectStoreId, int64_t indexId);
- static Vector<char> encodeMaxKey(int64_t databaseId, int64_t objectStoreId, int64_t indexId);
- int compare(const IndexDataKey& other, bool ignoreDuplicates, bool& ok);
- int64_t databaseId() const;
- int64_t objectStoreId() const;
- int64_t indexId() const;
- PassRefPtr<IDBKey> userKey() const;
- PassRefPtr<IDBKey> primaryKey() const;
-
-private:
- int64_t m_databaseId;
- int64_t m_objectStoreId;
- int64_t m_indexId;
- Vector<char> m_encodedUserKey;
- Vector<char> m_encodedPrimaryKey;
- int64_t m_sequenceNumber;
-};
-
-} // namespace IDBLevelDBCoding
-
-} // namespace WebCore
-
-#endif // ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
-
-#endif // IDBLevelDBCoding_h
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)
diff --git a/Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h b/Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h
deleted file mode 100644
index e574f389f..000000000
--- a/Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h
+++ /dev/null
@@ -1,100 +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.
- */
-
-#ifndef IDBServerConnectionLevelDB_h
-#define IDBServerConnectionLevelDB_h
-
-#include "IDBServerConnection.h"
-
-#if ENABLE(INDEXED_DATABASE)
-#if USE(LEVELDB)
-
-namespace WebCore {
-
-class IDBBackingStoreCursorLevelDB;
-class IDBBackingStoreLevelDB;
-class IDBBackingStoreTransactionLevelDB;
-
-class IDBServerConnectionLevelDB final : public IDBServerConnection {
-public:
- static PassRefPtr<IDBServerConnection> create(const String& databaseName, IDBBackingStoreLevelDB* backingStore)
- {
- return adoptRef(new IDBServerConnectionLevelDB(databaseName, backingStore));
- }
-
- virtual ~IDBServerConnectionLevelDB();
-
- virtual bool isClosed() override;
-
- // Factory-level operations
- virtual void deleteDatabase(const String& name, BoolCallbackFunction successCallback) override;
-
- // Database-level operations
- virtual void getOrEstablishIDBDatabaseMetadata(GetIDBDatabaseMetadataFunction) override;
- virtual void close() override;
-
- // Transaction-level operations
- virtual void openTransaction(int64_t transactionID, const HashSet<int64_t>& objectStoreIds, IndexedDB::TransactionMode, BoolCallbackFunction successCallback) override;
- virtual void beginTransaction(int64_t transactionID, std::function<void()> completionCallback) override;
- virtual void commitTransaction(int64_t transactionID, BoolCallbackFunction successCallback) override;
- virtual void resetTransaction(int64_t transactionID, std::function<void()> completionCallback) override;
- virtual void rollbackTransaction(int64_t transactionID, std::function<void()> completionCallback) override;
- virtual void setIndexKeys(int64_t transactionID, int64_t databaseID, int64_t objectStoreID, const IDBObjectStoreMetadata&, IDBKey& primaryKey, const Vector<int64_t>& indexIDs, const Vector<Vector<RefPtr<IDBKey>>>& indexKeys, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback);
-
- virtual void createObjectStore(IDBTransactionBackend&, const CreateObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
- virtual void createIndex(IDBTransactionBackend&, const CreateIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
- virtual void deleteIndex(IDBTransactionBackend&, const DeleteIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
- virtual void get(IDBTransactionBackend&, const GetOperation&, std::function<void(const IDBGetResult&, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
- virtual void put(IDBTransactionBackend&, const PutOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
- virtual void openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
- virtual void count(IDBTransactionBackend&, const CountOperation&, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
- virtual void deleteRange(IDBTransactionBackend&, const DeleteRangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
- virtual void clearObjectStore(IDBTransactionBackend&, const ClearObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
- virtual void deleteObjectStore(IDBTransactionBackend&, const DeleteObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
- virtual void changeDatabaseVersion(IDBTransactionBackend&, const IDBDatabaseBackend::VersionChangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
-
- // Cursor-level operations
- virtual void cursorAdvance(IDBCursorBackend&, const CursorAdvanceOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
- virtual void cursorIterate(IDBCursorBackend&, const CursorIterationOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
-
-private:
- IDBServerConnectionLevelDB(const String& databaseName, IDBBackingStoreLevelDB*);
-
- RefPtr<IDBBackingStoreLevelDB> m_backingStore;
- HashMap<int64_t, RefPtr<IDBBackingStoreTransactionLevelDB>> m_backingStoreTransactions;
- HashMap<int64_t, RefPtr<IDBBackingStoreCursorLevelDB>> m_backingStoreCursors;
-
- int64_t m_nextCursorID;
-
- bool m_closed;
-
- String m_databaseName;
-};
-
-} // namespace WebCore
-
-#endif // USE(LEVELDB)
-#endif // ENABLE(INDEXED_DATABASE)
-#endif // IDBServerConnectionLevelDB_h