diff options
Diffstat (limited to 'Source/WebCore/storage/IDBIndexBackendImpl.cpp')
| -rw-r--r-- | Source/WebCore/storage/IDBIndexBackendImpl.cpp | 127 |
1 files changed, 42 insertions, 85 deletions
diff --git a/Source/WebCore/storage/IDBIndexBackendImpl.cpp b/Source/WebCore/storage/IDBIndexBackendImpl.cpp index 6eba189..62e5364 100644 --- a/Source/WebCore/storage/IDBIndexBackendImpl.cpp +++ b/Source/WebCore/storage/IDBIndexBackendImpl.cpp @@ -29,6 +29,7 @@ #if ENABLE(INDEXED_DATABASE) #include "CrossThreadTask.h" +#include "IDBBackingStore.h" #include "IDBCallbacks.h" #include "IDBCursorBackendImpl.h" #include "IDBDatabaseBackendImpl.h" @@ -36,14 +37,11 @@ #include "IDBKey.h" #include "IDBKeyRange.h" #include "IDBObjectStoreBackendImpl.h" -#include "IDBSQLiteDatabase.h" -#include "SQLiteDatabase.h" -#include "SQLiteStatement.h" namespace WebCore { -IDBIndexBackendImpl::IDBIndexBackendImpl(IDBSQLiteDatabase* database, int64_t id, const String& name, const String& storeName, const String& keyPath, bool unique) - : m_database(database) +IDBIndexBackendImpl::IDBIndexBackendImpl(IDBBackingStore* backingStore, int64_t id, const String& name, const String& storeName, const String& keyPath, bool unique) + : m_backingStore(backingStore) , m_id(id) , m_name(name) , m_storeName(storeName) @@ -52,8 +50,8 @@ IDBIndexBackendImpl::IDBIndexBackendImpl(IDBSQLiteDatabase* database, int64_t id { } -IDBIndexBackendImpl::IDBIndexBackendImpl(IDBSQLiteDatabase* database, const String& name, const String& storeName, const String& keyPath, bool unique) - : m_database(database) +IDBIndexBackendImpl::IDBIndexBackendImpl(IDBBackingStore* backingStore, const String& name, const String& storeName, const String& keyPath, bool unique) + : m_backingStore(backingStore) , m_id(InvalidId) , m_name(name) , m_storeName(storeName) @@ -66,40 +64,26 @@ IDBIndexBackendImpl::~IDBIndexBackendImpl() { } -void IDBIndexBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> range, unsigned short untypedDirection, bool objectCursor, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction) +void IDBIndexBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> range, unsigned short untypedDirection, IDBCursorBackendInterface::CursorType cursorType, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction) { - // Several files depend on this order of selects. - String sql = String("SELECT IndexData.id, IndexData.keyString, IndexData.keyDate, IndexData.keyNumber, ") - + ("ObjectStoreData.value, ObjectStoreData.keyString, ObjectStoreData.keyDate, ObjectStoreData.keyNumber ") - + "FROM IndexData INNER JOIN ObjectStoreData ON IndexData.objectStoreDataId = ObjectStoreData.id WHERE "; - - bool lowerBound = range && range->lower(); - bool upperBound = range && range->upper(); - - if (lowerBound) - sql += range->lower()->lowerCursorWhereFragment(range->lowerWhereClauseComparisonOperator(), "IndexData."); - if (upperBound) - sql += range->upper()->upperCursorWhereFragment(range->upperWhereClauseComparisonOperator(), "IndexData."); - sql += "IndexData.indexId = ? ORDER BY "; - IDBCursor::Direction direction = static_cast<IDBCursor::Direction>(untypedDirection); - if (direction == IDBCursor::NEXT || direction == IDBCursor::NEXT_NO_DUPLICATE) - sql += "IndexData.keyString, IndexData.keyDate, IndexData.keyNumber, IndexData.id"; - else - sql += "IndexData.keyString DESC, IndexData.keyDate DESC, IndexData.keyNumber DESC, IndexData.id DESC"; - - OwnPtr<SQLiteStatement> query = adoptPtr(new SQLiteStatement(index->sqliteDatabase(), sql)); - bool ok = query->prepare() == SQLResultOk; - ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? - - int indexColumn = 1; - if (lowerBound) - indexColumn += range->lower()->bind(*query, indexColumn); - if (upperBound) - indexColumn += range->upper()->bind(*query, indexColumn); - query->bindInt64(indexColumn, index->id()); - - if (query->step() != SQLResultRow) { + + RefPtr<IDBBackingStore::Cursor> backingStoreCursor; + + switch (cursorType) { + case IDBCursorBackendInterface::IndexKeyCursor: + backingStoreCursor = index->m_backingStore->openIndexKeyCursor(index->id(), range.get(), direction); + break; + case IDBCursorBackendInterface::IndexCursor: + backingStoreCursor = index->m_backingStore->openIndexCursor(index->id(), range.get(), direction); + break; + case IDBCursorBackendInterface::ObjectStoreCursor: + case IDBCursorBackendInterface::InvalidCursorType: + ASSERT_NOT_REACHED(); + break; + } + + if (!backingStoreCursor) { callbacks->onSuccess(SerializedScriptValue::nullValue()); return; } @@ -108,7 +92,7 @@ void IDBIndexBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr RefPtr<IDBObjectStoreBackendInterface> objectStore = transaction->objectStore(index->m_storeName, ec); ASSERT(objectStore && !ec); - RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(index->m_database.get(), range, direction, query.release(), objectCursor, transaction.get(), objectStore.get()); + RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(backingStoreCursor.get(), direction, cursorType, transaction.get(), objectStore.get()); callbacks->onSuccess(cursor.release()); } @@ -118,7 +102,7 @@ void IDBIndexBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpKeyRange, unsign RefPtr<IDBKeyRange> keyRange = prpKeyRange; RefPtr<IDBCallbacks> callbacks = prpCallbacks; RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr; - if (!transaction->scheduleTask(createCallbackTask(&openCursorInternal, index, keyRange, direction, true, callbacks, transaction))) + if (!transaction->scheduleTask(createCallbackTask(&openCursorInternal, index, keyRange, direction, IDBCursorBackendInterface::IndexCursor, callbacks, transaction))) ec = IDBDatabaseException::NOT_ALLOWED_ERR; } @@ -128,33 +112,28 @@ void IDBIndexBackendImpl::openKeyCursor(PassRefPtr<IDBKeyRange> prpKeyRange, uns RefPtr<IDBKeyRange> keyRange = prpKeyRange; RefPtr<IDBCallbacks> callbacks = prpCallbacks; RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr; - if (!transaction->scheduleTask(createCallbackTask(&openCursorInternal, index, keyRange, direction, false, callbacks, transaction))) + if (!transaction->scheduleTask(createCallbackTask(&openCursorInternal, index, keyRange, direction, IDBCursorBackendInterface::IndexKeyCursor, callbacks, transaction))) ec = IDBDatabaseException::NOT_ALLOWED_ERR; } void IDBIndexBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKey> key, bool getObject, PassRefPtr<IDBCallbacks> callbacks) { - String sql = String("SELECT ") - + (getObject ? "ObjectStoreData.value " : "ObjectStoreData.keyString, ObjectStoreData.keyDate, ObjectStoreData.keyNumber ") - + "FROM IndexData INNER JOIN ObjectStoreData ON IndexData.objectStoreDataId = ObjectStoreData.id " - + "WHERE IndexData.indexId = ? AND " + key->whereSyntax("IndexData.") - + "ORDER BY IndexData.id LIMIT 1"; // Order by insertion order when all else fails. - SQLiteStatement query(index->sqliteDatabase(), sql); - bool ok = query.prepare() == SQLResultOk; - ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? - - query.bindInt64(1, index->id()); - key->bind(query, 2); - if (query.step() != SQLResultRow) { - callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Key does not exist in the index.")); - return; + // FIXME: Split getInternal into two functions, getting rid off |getObject|. + if (getObject) { + String value = index->m_backingStore->getObjectViaIndex(index->id(), *key); + if (value.isNull()) { + callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Key does not exist in the index.")); + return; + } + callbacks->onSuccess(SerializedScriptValue::createFromWire(value)); + } else { + RefPtr<IDBKey> keyResult = index->m_backingStore->getPrimaryKeyViaIndex(index->id(), *key); + if (!keyResult) { + callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Key does not exist in the index.")); + return; + } + callbacks->onSuccess(keyResult.get()); } - - if (getObject) - callbacks->onSuccess(SerializedScriptValue::createFromWire(query.getColumnText(0))); - else - callbacks->onSuccess(IDBKey::fromQuery(query, 0)); - ASSERT(query.step() != SQLResultRow); } void IDBIndexBackendImpl::get(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction, ExceptionCode& ec) @@ -175,34 +154,12 @@ void IDBIndexBackendImpl::getKey(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallba ec = IDBDatabaseException::NOT_ALLOWED_ERR; } -static String whereClause(IDBKey* key) -{ - return "WHERE indexId = ? AND " + key->whereSyntax(); -} - -static void bindWhereClause(SQLiteStatement& query, int64_t id, IDBKey* key) -{ - query.bindInt64(1, id); - key->bind(query, 2); -} - bool IDBIndexBackendImpl::addingKeyAllowed(IDBKey* key) { if (!m_unique) return true; - SQLiteStatement query(sqliteDatabase(), "SELECT id FROM IndexData " + whereClause(key)); - bool ok = query.prepare() == SQLResultOk; - ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? - bindWhereClause(query, m_id, key); - bool existingValue = query.step() == SQLResultRow; - - return !existingValue; -} - -SQLiteDatabase& IDBIndexBackendImpl::sqliteDatabase() const -{ - return m_database->db(); + return !m_backingStore->keyExistsInIndex(m_id, *key); } } // namespace WebCore |
