summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/storage/IDBIndexBackendImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/storage/IDBIndexBackendImpl.cpp')
-rw-r--r--Source/WebCore/storage/IDBIndexBackendImpl.cpp127
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