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)); |