summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-24 11:24:40 +0100
committerBen Murdoch <benm@google.com>2011-06-02 09:53:15 +0100
commit81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch)
tree7a9e5ed86ff429fd347a25153107221543909b19 /Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp
parent94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff)
downloadexternal_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp')
-rw-r--r--Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp290
1 files changed, 92 insertions, 198 deletions
diff --git a/Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp b/Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp
index 921bbab..0433ed7 100644
--- a/Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp
+++ b/Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp
@@ -30,6 +30,7 @@
#include "CrossThreadTask.h"
#include "DOMStringList.h"
+#include "IDBBackingStore.h"
#include "IDBBindingUtilities.h"
#include "IDBCallbacks.h"
#include "IDBCursorBackendImpl.h"
@@ -40,12 +41,8 @@
#include "IDBKeyPath.h"
#include "IDBKeyPathBackendImpl.h"
#include "IDBKeyRange.h"
-#include "IDBSQLiteDatabase.h"
#include "IDBTransactionBackendInterface.h"
#include "ScriptExecutionContext.h"
-#include "SQLiteDatabase.h"
-#include "SQLiteStatement.h"
-#include "SQLiteTransaction.h"
namespace WebCore {
@@ -53,8 +50,8 @@ IDBObjectStoreBackendImpl::~IDBObjectStoreBackendImpl()
{
}
-IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBSQLiteDatabase* database, int64_t id, const String& name, const String& keyPath, bool autoIncrement)
- : m_database(database)
+IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBBackingStore* backingStore, int64_t id, const String& name, const String& keyPath, bool autoIncrement)
+ : m_backingStore(backingStore)
, m_id(id)
, m_name(name)
, m_keyPath(keyPath)
@@ -64,8 +61,8 @@ IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBSQLiteDatabase* database
loadIndexes();
}
-IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBSQLiteDatabase* database, const String& name, const String& keyPath, bool autoIncrement)
- : m_database(database)
+IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBBackingStore* backingStore, const String& name, const String& keyPath, bool autoIncrement)
+ : m_backingStore(backingStore)
, m_id(InvalidId)
, m_name(name)
, m_keyPath(keyPath)
@@ -82,17 +79,6 @@ PassRefPtr<DOMStringList> IDBObjectStoreBackendImpl::indexNames() const
return indexNames.release();
}
-static String whereClause(IDBKey* key)
-{
- return "WHERE objectStoreId = ? AND " + key->whereSyntax();
-}
-
-static void bindWhereClause(SQLiteStatement& query, int64_t id, IDBKey* key)
-{
- query.bindInt64(1, id);
- key->bind(query, 2);
-}
-
void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
{
RefPtr<IDBObjectStoreBackendImpl> objectStore = this;
@@ -104,22 +90,13 @@ void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCal
void IDBObjectStoreBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks)
{
- SQLiteStatement query(objectStore->sqliteDatabase(), "SELECT keyString, keyDate, keyNumber, value FROM ObjectStoreData " + whereClause(key.get()));
- bool ok = query.prepare() == SQLResultOk;
- ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
-
- bindWhereClause(query, objectStore->id(), key.get());
- if (query.step() != SQLResultRow) {
+ String wireData = objectStore->m_backingStore->getObjectStoreRecord(objectStore->id(), *key);
+ if (wireData.isNull()) {
callbacks->onSuccess(SerializedScriptValue::undefinedValue());
return;
}
- ASSERT((key->type() == IDBKey::StringType) != query.isColumnNull(0));
- ASSERT((key->type() == IDBKey::DateType) != query.isColumnNull(1));
- ASSERT((key->type() == IDBKey::NumberType) != query.isColumnNull(2));
-
- callbacks->onSuccess(SerializedScriptValue::createFromWire(query.getColumnBlobAsString(3)));
- ASSERT(query.step() != SQLResultRow);
+ callbacks->onSuccess(SerializedScriptValue::createFromWire(wireData));
}
static PassRefPtr<IDBKey> fetchKeyFromKeyPath(SerializedScriptValue* value, const String& keyPath)
@@ -134,49 +111,9 @@ static PassRefPtr<IDBKey> fetchKeyFromKeyPath(SerializedScriptValue* value, cons
return keys[0].release();
}
-static bool putObjectStoreData(SQLiteDatabase& db, IDBKey* key, SerializedScriptValue* value, int64_t objectStoreId, int64_t& dataRowId)
+static PassRefPtr<SerializedScriptValue> injectKeyIntoKeyPath(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
{
- String sql = dataRowId != IDBObjectStoreBackendImpl::InvalidId ? "UPDATE ObjectStoreData SET keyString = ?, keyDate = ?, keyNumber = ?, value = ? WHERE id = ?"
- : "INSERT INTO ObjectStoreData (keyString, keyDate, keyNumber, value, objectStoreId) VALUES (?, ?, ?, ?, ?)";
- SQLiteStatement query(db, sql);
- if (query.prepare() != SQLResultOk)
- return false;
- key->bindWithNulls(query, 1);
- query.bindBlob(4, value->toWireString());
- if (dataRowId != IDBDatabaseBackendImpl::InvalidId)
- query.bindInt64(5, dataRowId);
- else
- query.bindInt64(5, objectStoreId);
-
- if (query.step() != SQLResultDone)
- return false;
-
- if (dataRowId == IDBDatabaseBackendImpl::InvalidId)
- dataRowId = db.lastInsertRowID();
-
- return true;
-}
-
-static bool deleteIndexData(SQLiteDatabase& db, int64_t objectStoreDataId)
-{
- SQLiteStatement deleteQuery(db, "DELETE FROM IndexData WHERE objectStoreDataId = ?");
- if (deleteQuery.prepare() != SQLResultOk)
- return false;
- deleteQuery.bindInt64(1, objectStoreDataId);
-
- return deleteQuery.step() == SQLResultDone;
-}
-
-static bool putIndexData(SQLiteDatabase& db, IDBKey* key, int64_t indexId, int64_t objectStoreDataId)
-{
- SQLiteStatement putQuery(db, "INSERT INTO IndexData (keyString, keyDate, keyNumber, indexId, objectStoreDataId) VALUES (?, ?, ?, ?, ?)");
- if (putQuery.prepare() != SQLResultOk)
- return false;
- key->bindWithNulls(putQuery, 1);
- putQuery.bindInt64(4, indexId);
- putQuery.bindInt64(5, objectStoreDataId);
-
- return putQuery.step() == SQLResultDone;
+ return IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue(key, value, keyPath);
}
void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, PutMode putMode, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
@@ -197,7 +134,7 @@ void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue,
ec = IDBDatabaseException::NOT_ALLOWED_ERR;
}
-PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::selectKeyForPut(IDBObjectStoreBackendImpl* objectStore, SerializedScriptValue* value, IDBKey* key, PutMode putMode, IDBCallbacks* callbacks)
+PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::selectKeyForPut(IDBObjectStoreBackendImpl* objectStore, IDBKey* key, PutMode putMode, IDBCallbacks* callbacks, RefPtr<SerializedScriptValue>& value)
{
if (putMode == CursorUpdate)
ASSERT(key);
@@ -220,19 +157,24 @@ PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::selectKeyForPut(IDBObjectStoreBack
if (!hasKeyPath)
return objectStore->genAutoIncrementKey();
- RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value, objectStore->m_keyPath);
+ RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value.get(), objectStore->m_keyPath);
if (keyPathKey) {
objectStore->resetAutoIncrementKeyCache();
return keyPathKey;
}
- // FIXME: Generate auto increment key, and inject it through the key path.
- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Adding data to object stores with auto increment and in-line keys not yet supported."));
- return 0;
+ RefPtr<IDBKey> autoIncKey = objectStore->genAutoIncrementKey();
+ RefPtr<SerializedScriptValue> valueAfterInjection = injectKeyIntoKeyPath(autoIncKey, value, objectStore->m_keyPath);
+ if (!valueAfterInjection) {
+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "The generated key could not be inserted into the object using the keyPath."));
+ return 0;
+ }
+ value = valueAfterInjection;
+ return autoIncKey.release();
}
if (hasKeyPath) {
- RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value, objectStore->m_keyPath);
+ RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value.get(), objectStore->m_keyPath);
if (!keyPathKey) {
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "The key could not be fetched from the keyPath."));
@@ -258,7 +200,7 @@ PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::selectKeyForPut(IDBObjectStoreBack
void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction)
{
RefPtr<SerializedScriptValue> value = prpValue;
- RefPtr<IDBKey> key = selectKeyForPut(objectStore.get(), value.get(), prpKey.get(), putMode, callbacks.get());
+ RefPtr<IDBKey> key = selectKeyForPut(objectStore.get(), prpKey.get(), putMode, callbacks.get(), value);
if (!key)
return;
@@ -285,12 +227,9 @@ void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr<
indexKeys.append(key.release());
}
- SQLiteStatement getQuery(objectStore->sqliteDatabase(), "SELECT id FROM ObjectStoreData " + whereClause(key.get()));
- bool ok = getQuery.prepare() == SQLResultOk;
- ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+ int64_t dataRowId = InvalidId;
+ bool isExistingValue = objectStore->m_backingStore->keyExistsInObjectStore(objectStore->id(), *key, dataRowId);
- bindWhereClause(getQuery, objectStore->id(), key.get());
- bool isExistingValue = getQuery.step() == SQLResultRow;
if (putMode == AddOnly && isExistingValue) {
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "Key already exists in the object store."));
return;
@@ -298,15 +237,14 @@ void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr<
// Before this point, don't do any mutation. After this point, rollback the transaction in case of error.
- int64_t dataRowId = isExistingValue ? getQuery.getColumnInt(0) : InvalidId;
- if (!putObjectStoreData(objectStore->sqliteDatabase(), key.get(), value.get(), objectStore->id(), dataRowId)) {
+ if (!objectStore->m_backingStore->putObjectStoreRecord(objectStore->id(), *key, value->toWireString(), dataRowId, dataRowId == InvalidId)) {
// FIXME: The Indexed Database specification does not have an error code dedicated to I/O errors.
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Error writing data to stable storage."));
transaction->abort();
return;
}
- if (!deleteIndexData(objectStore->sqliteDatabase(), dataRowId)) {
+ if (!objectStore->m_backingStore->deleteIndexDataForRecord(dataRowId)) {
// FIXME: The Indexed Database specification does not have an error code dedicated to I/O errors.
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Error writing data to stable storage."));
transaction->abort();
@@ -315,7 +253,9 @@ void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr<
int i = 0;
for (IndexMap::iterator it = objectStore->m_indexes.begin(); it != objectStore->m_indexes.end(); ++it, ++i) {
- if (!putIndexData(objectStore->sqliteDatabase(), indexKeys[i].get(), it->second->id(), dataRowId)) {
+ if (!it->second->hasValidId())
+ continue; // The index object has been created, but does not exist in the database yet.
+ if (!objectStore->m_backingStore->putIndexDataForRecord(it->second->id(), *indexKeys[i], dataRowId)) {
// FIXME: The Indexed Database specification does not have an error code dedicated to I/O errors.
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Error writing data to stable storage."));
transaction->abort();
@@ -343,35 +283,13 @@ void IDBObjectStoreBackendImpl::deleteFunction(PassRefPtr<IDBKey> prpKey, PassRe
void IDBObjectStoreBackendImpl::deleteInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks)
{
- SQLiteStatement idQuery(objectStore->sqliteDatabase(), "SELECT id FROM ObjectStoreData " + whereClause(key.get()));
- bool ok = idQuery.prepare() == SQLResultOk;
- ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
- bindWhereClause(idQuery, objectStore->id(), key.get());
- if (idQuery.step() != SQLResultRow) {
+ int64_t id;
+ if (!objectStore->m_backingStore->keyExistsInObjectStore(objectStore->id(), *key, id)) {
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Key does not exist in the object store."));
return;
}
- int64_t id = idQuery.getColumnInt64(0);
-
- SQLiteStatement osQuery(objectStore->sqliteDatabase(), "DELETE FROM ObjectStoreData WHERE id = ?");
- ok = osQuery.prepare() == SQLResultOk;
- ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
-
- osQuery.bindInt64(1, id);
-
- ok = osQuery.step() == SQLResultDone;
- ASSERT_UNUSED(ok, ok);
-
- SQLiteStatement indexQuery(objectStore->sqliteDatabase(), "DELETE FROM IndexData WHERE objectStoreDataId = ?");
- ok = indexQuery.prepare() == SQLResultOk;
- ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
-
- indexQuery.bindInt64(1, id);
-
- ok = indexQuery.step() == SQLResultDone;
- ASSERT_UNUSED(ok, ok);
-
+ objectStore->m_backingStore->deleteObjectStoreRecord(objectStore->id(), id);
callbacks->onSuccess(SerializedScriptValue::nullValue());
}
@@ -389,22 +307,46 @@ void IDBObjectStoreBackendImpl::clear(PassRefPtr<IDBCallbacks> prpCallbacks, IDB
ec = IDBDatabaseException::NOT_ALLOWED_ERR;
}
-static void doDelete(SQLiteDatabase& db, const char* sql, int64_t id)
+void IDBObjectStoreBackendImpl::clearInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBCallbacks> callbacks)
{
- SQLiteStatement deleteQuery(db, sql);
- bool ok = deleteQuery.prepare() == SQLResultOk;
- ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
- deleteQuery.bindInt64(1, id);
- ok = deleteQuery.step() == SQLResultDone;
- ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
+ objectStore->m_backingStore->clearObjectStore(objectStore->id());
+ callbacks->onSuccess(SerializedScriptValue::undefinedValue());
}
-void IDBObjectStoreBackendImpl::clearInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBCallbacks> callbacks)
-{
- doDelete(objectStore->sqliteDatabase(), "DELETE FROM IndexData WHERE objectStoreDataId IN (SELECT id FROM ObjectStoreData WHERE objectStoreId = ?)", objectStore->id());
- doDelete(objectStore->sqliteDatabase(), "DELETE FROM ObjectStoreData WHERE objectStoreId = ?", objectStore->id());
+namespace {
+class PopulateIndexCallback : public IDBBackingStore::ObjectStoreRecordCallback {
+public:
+ PopulateIndexCallback(IDBBackingStore& backingStore, const String& indexKeyPath, int64_t indexId)
+ : m_backingStore(backingStore)
+ , m_indexKeyPath(indexKeyPath)
+ , m_indexId(indexId)
+ {
+ }
- callbacks->onSuccess(SerializedScriptValue::undefinedValue());
+ virtual bool callback(int64_t objectStoreDataId, const String& value)
+ {
+ RefPtr<SerializedScriptValue> objectValue = SerializedScriptValue::createFromWire(value);
+ RefPtr<IDBKey> indexKey = fetchKeyFromKeyPath(objectValue.get(), m_indexKeyPath);
+
+ if (!m_backingStore.putIndexDataForRecord(m_indexId, *indexKey, objectStoreDataId))
+ return false;
+
+ return true;
+ }
+
+private:
+ IDBBackingStore& m_backingStore;
+ const String& m_indexKeyPath;
+ int64_t m_indexId;
+};
+}
+
+static bool populateIndex(IDBBackingStore& backingStore, int64_t objectStoreId, int64_t indexId, const String& indexKeyPath)
+{
+ PopulateIndexCallback callback(backingStore, indexKeyPath, indexId);
+ if (!backingStore.forEachObjectStoreRecord(objectStoreId, callback))
+ return false;
+ return true;
}
PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::createIndex(const String& name, const String& keyPath, bool unique, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
@@ -418,7 +360,7 @@ PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::createIndex(cons
return 0;
}
- RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(m_database.get(), name, m_name, keyPath, unique);
+ RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(m_backingStore.get(), name, m_name, keyPath, unique);
ASSERT(index->name() == name);
RefPtr<IDBObjectStoreBackendImpl> objectStore = this;
@@ -435,21 +377,19 @@ PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::createIndex(cons
void IDBObjectStoreBackendImpl::createIndexInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBTransactionBackendInterface> transaction)
{
- SQLiteStatement insert(objectStore->sqliteDatabase(), "INSERT INTO Indexes (objectStoreId, name, keyPath, isUnique) VALUES (?, ?, ?, ?)");
- if (insert.prepare() != SQLResultOk) {
+ int64_t id;
+ if (!objectStore->m_backingStore->createIndex(objectStore->m_id, index->name(), index->keyPath(), index->unique(), id)) {
transaction->abort();
return;
}
- insert.bindInt64(1, objectStore->m_id);
- insert.bindText(2, index->name());
- insert.bindText(3, index->keyPath());
- insert.bindInt(4, static_cast<int>(index->unique()));
- if (insert.step() != SQLResultDone) {
+
+ index->setId(id);
+
+ if (!populateIndex(*objectStore->m_backingStore, objectStore->m_id, id, index->keyPath())) {
transaction->abort();
return;
}
- int64_t id = objectStore->sqliteDatabase().lastInsertRowID();
- index->setId(id);
+
transaction->didCompleteTaskEvents();
}
@@ -488,9 +428,7 @@ void IDBObjectStoreBackendImpl::deleteIndex(const String& name, IDBTransactionBa
void IDBObjectStoreBackendImpl::deleteIndexInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBTransactionBackendInterface> transaction)
{
- doDelete(objectStore->sqliteDatabase(), "DELETE FROM Indexes WHERE id = ?", index->id());
- doDelete(objectStore->sqliteDatabase(), "DELETE FROM IndexData WHERE indexId = ?", index->id());
-
+ objectStore->m_backingStore->deleteIndex(index->id());
transaction->didCompleteTaskEvents();
}
@@ -506,64 +444,32 @@ void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> prpRange, uns
void IDBObjectStoreBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> range, unsigned short tmpDirection, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction)
{
- bool lowerBound = range && range->lower();
- bool upperBound = range && range->upper();
-
- // Several files depend on this order of selects.
- String sql = "SELECT id, keyString, keyDate, keyNumber, value FROM ObjectStoreData WHERE ";
- if (lowerBound)
- sql += range->lower()->lowerCursorWhereFragment(range->lowerWhereClauseComparisonOperator());
- if (upperBound)
- sql += range->upper()->upperCursorWhereFragment(range->upperWhereClauseComparisonOperator());
- sql += "objectStoreId = ? ORDER BY ";
-
IDBCursor::Direction direction = static_cast<IDBCursor::Direction>(tmpDirection);
- if (direction == IDBCursor::NEXT || direction == IDBCursor::NEXT_NO_DUPLICATE)
- sql += "keyString, keyDate, keyNumber";
- else
- sql += "keyString DESC, keyDate DESC, keyNumber DESC";
-
- OwnPtr<SQLiteStatement> query = adoptPtr(new SQLiteStatement(objectStore->sqliteDatabase(), sql));
- bool ok = query->prepare() == SQLResultOk;
- ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
-
- int currentColumn = 1;
- if (lowerBound)
- currentColumn += range->lower()->bind(*query, currentColumn);
- if (upperBound)
- currentColumn += range->upper()->bind(*query, currentColumn);
- query->bindInt64(currentColumn, objectStore->id());
-
- if (query->step() != SQLResultRow) {
+
+ RefPtr<IDBBackingStore::Cursor> backingStoreCursor = objectStore->m_backingStore->openObjectStoreCursor(objectStore->id(), range.get(), direction);
+ if (!backingStoreCursor) {
callbacks->onSuccess(SerializedScriptValue::nullValue());
return;
}
- RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(objectStore->m_database.get(), range, direction, query.release(), true, transaction.get(), objectStore.get());
+ RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(backingStoreCursor.release(), direction, IDBCursorBackendInterface::ObjectStoreCursor, transaction.get(), objectStore.get());
callbacks->onSuccess(cursor.release());
}
void IDBObjectStoreBackendImpl::loadIndexes()
{
- SQLiteStatement indexQuery(sqliteDatabase(), "SELECT id, name, keyPath, isUnique FROM Indexes WHERE objectStoreId = ?");
- bool ok = indexQuery.prepare() == SQLResultOk;
- ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
-
- indexQuery.bindInt64(1, m_id);
+ Vector<int64_t> ids;
+ Vector<String> names;
+ Vector<String> keyPaths;
+ Vector<bool> uniqueFlags;
+ m_backingStore->getIndexes(m_id, ids, names, keyPaths, uniqueFlags);
- while (indexQuery.step() == SQLResultRow) {
- int64_t id = indexQuery.getColumnInt64(0);
- String name = indexQuery.getColumnText(1);
- String keyPath = indexQuery.getColumnText(2);
- bool unique = !!indexQuery.getColumnInt(3);
+ ASSERT(names.size() == ids.size());
+ ASSERT(keyPaths.size() == ids.size());
+ ASSERT(uniqueFlags.size() == ids.size());
- m_indexes.set(name, IDBIndexBackendImpl::create(m_database.get(), id, name, m_name, keyPath, unique));
- }
-}
-
-SQLiteDatabase& IDBObjectStoreBackendImpl::sqliteDatabase() const
-{
- return m_database->db();
+ for (size_t i = 0; i < ids.size(); i++)
+ m_indexes.set(names[i], IDBIndexBackendImpl::create(m_backingStore.get(), ids[i], names[i], m_name, keyPaths[i], uniqueFlags[i]));
}
void IDBObjectStoreBackendImpl::removeIndexFromMap(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBIndexBackendImpl> index)
@@ -584,19 +490,7 @@ PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::genAutoIncrementKey()
if (m_autoIncrementNumber > 0)
return IDBKey::createNumber(m_autoIncrementNumber++);
- String sql = "SELECT max(keyNumber) + 1 FROM ObjectStoreData WHERE objectStoreId = ? AND keyString IS NULL AND keyDate IS NULL";
-
- SQLiteStatement query(sqliteDatabase(), sql);
- bool ok = query.prepare() == SQLResultOk;
- ASSERT_UNUSED(ok, ok);
-
- query.bindInt64(1, id());
-
- if (query.step() != SQLResultRow || query.isColumnNull(0))
- m_autoIncrementNumber = 1;
- else
- m_autoIncrementNumber = static_cast<int>(query.getColumnDouble(0));
-
+ m_autoIncrementNumber = static_cast<int>(m_backingStore->nextAutoIncrementNumber(id()));
return IDBKey::createNumber(m_autoIncrementNumber++);
}