diff options
author | Ben Murdoch <benm@google.com> | 2011-05-24 11:24:40 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-06-02 09:53:15 +0100 |
commit | 81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch) | |
tree | 7a9e5ed86ff429fd347a25153107221543909b19 /Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp | |
parent | 94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff) | |
download | external_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.cpp | 290 |
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++); } |