| Index: Source/WebCore/storage/IDBLevelDBBackingStore.cpp
|
| ===================================================================
|
| --- Source/WebCore/storage/IDBLevelDBBackingStore.cpp (revision 97254)
|
| +++ Source/WebCore/storage/IDBLevelDBBackingStore.cpp (working copy)
|
| @@ -212,59 +212,91 @@
|
| return 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;
|
| +}
|
| +
|
| void IDBLevelDBBackingStore::getObjectStores(int64_t databaseId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bool>& foundAutoIncrementFlags)
|
| {
|
| const Vector<char> startKey = ObjectStoreMetaDataKey::encode(databaseId, 1, 0);
|
| const Vector<char> stopKey = ObjectStoreMetaDataKey::encodeMaxKey(databaseId);
|
|
|
| OwnPtr<LevelDBIterator> it = m_db->createIterator();
|
| - for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) {
|
| + 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()) {
|
| + LOG_ERROR("Internal Indexed DB error.");
|
| + return;
|
| + }
|
|
|
| int64_t objectStoreId = metaDataKey.objectStoreId();
|
| -
|
| String objectStoreName = decodeString(it->value().begin(), it->value().end());
|
|
|
| it->next();
|
| - if (!it->isValid()) {
|
| + if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 1)) {
|
| LOG_ERROR("Internal Indexed DB error.");
|
| return;
|
| }
|
| String keyPath = decodeString(it->value().begin(), it->value().end());
|
| + bool hasKeyPath = true;
|
|
|
| it->next();
|
| - if (!it->isValid()) {
|
| + if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 2)) {
|
| LOG_ERROR("Internal Indexed DB error.");
|
| return;
|
| }
|
| + // FIXME: Add encode/decode functions for bools
|
| bool autoIncrement = *it->value().begin();
|
|
|
| it->next(); // Is evicatble.
|
| - if (!it->isValid()) {
|
| + if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 3)) {
|
| LOG_ERROR("Internal Indexed DB error.");
|
| return;
|
| }
|
|
|
| it->next(); // Last version.
|
| - if (!it->isValid()) {
|
| + if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 4)) {
|
| LOG_ERROR("Internal Indexed DB error.");
|
| return;
|
| }
|
|
|
| it->next(); // Maxium index id allocated.
|
| - if (!it->isValid()) {
|
| + if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 5)) {
|
| LOG_ERROR("Internal Indexed DB error.");
|
| return;
|
| }
|
|
|
| + it->next(); // [optional] has key path (is not null)
|
| + if (checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 6)) {
|
| + // FIXME: Add encode/decode functions for bools
|
| + hasKeyPath = *it->value().begin();
|
| + if (!hasKeyPath && !keyPath.isEmpty()) {
|
| + LOG_ERROR("Internal Indexed DB error.");
|
| + return;
|
| + }
|
| + it->next();
|
| + }
|
| +
|
| foundIds.append(objectStoreId);
|
| foundNames.append(objectStoreName);
|
| - foundKeyPaths.append(keyPath);
|
| + foundKeyPaths.append(hasKeyPath ? keyPath : String());
|
| foundAutoIncrementFlags.append(autoIncrement);
|
| }
|
| }
|
| @@ -298,6 +330,7 @@
|
| const Vector<char> evictableKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 3);
|
| const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 4);
|
| const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 5);
|
| + const Vector<char> hasKeyPathKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 6);
|
| const Vector<char> namesKey = ObjectStoreNamesKey::encode(databaseId, name);
|
|
|
| bool ok = putString(m_currentTransaction.get(), nameKey, name);
|
| @@ -336,6 +369,12 @@
|
| return false;
|
| }
|
|
|
| + ok = putInt(m_currentTransaction.get(), hasKeyPathKey, !keyPath.isNull());
|
| + if (!ok) {
|
| + LOG_ERROR("Internal Indexed DB error.");
|
| + return false;
|
| + }
|
| +
|
| ok = putInt(m_currentTransaction.get(), namesKey, objectStoreId);
|
| if (!ok) {
|
| LOG_ERROR("Internal Indexed DB error.");
|
| @@ -365,7 +404,7 @@
|
| String objectStoreName;
|
| getString(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), objectStoreName);
|
|
|
| - if (!deleteRange(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 6)))
|
| + if (!deleteRange(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), ObjectStoreMetaDataKey::encodeMaxKey(databaseId, objectStoreId)))
|
| return; // FIXME: Report error.
|
|
|
| m_currentTransaction->remove(ObjectStoreNamesKey::encode(databaseId, objectStoreName));
|
|
|