Changeset 116170 in webkit
- Timestamp:
- May 4, 2012 2:20:23 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r116167 r116170 1 2012-05-04 Joshua Bell <jsbell@chromium.org> 2 3 IndexedDB: Remove all index metadata records when deleting an index 4 https://bugs.webkit.org/show_bug.cgi?id=85557 5 6 Reviewed by Tony Chang. 7 8 An assert is hit when re-loading database from backing store due to stale index 9 metadata entry. Do a range delete to clear all metadata entries when deleting an 10 index. Define metadata entries as enum and limits as consts instead of hardcoded ints. 11 12 No new tests - issue does not repro as layout test. Will land test in Chromium. 13 14 * Modules/indexeddb/IDBLevelDBBackingStore.cpp: 15 (WebCore::getBool): Helper functions; replaces pattern of putInt()/read only lead byte. 16 (WebCore): 17 (WebCore::putBool): 18 (WebCore::IDBLevelDBBackingStore::getObjectStores): Skip stale data. Use enums, helpers. 19 (WebCore::IDBLevelDBBackingStore::createObjectStore): Use enums. 20 (WebCore::IDBLevelDBBackingStore::deleteObjectStore): Use enums. 21 (WebCore::getNewVersionNumber): Use enums. 22 (WebCore::IDBLevelDBBackingStore::getIndexes): Skip stale data. Use enums, helpers. 23 (WebCore::getNewIndexId): Use enums. 24 (WebCore::IDBLevelDBBackingStore::createIndex): Use enums. 25 (WebCore::IDBLevelDBBackingStore::deleteIndex): Delete metadata by range. 26 * Modules/indexeddb/IDBLevelDBCoding.cpp: 27 (IDBLevelDBCoding): Add constants for metadata maximum values. 28 (WebCore::IDBLevelDBCoding::encodeBool): 29 (WebCore::IDBLevelDBCoding::decodeBool): 30 (WebCore::IDBLevelDBCoding::ObjectStoreMetaDataKey::encodeMaxKey): Use consts. 31 (WebCore::IDBLevelDBCoding::IndexMetaDataKey::encodeMaxKey): Use consts. 32 * Modules/indexeddb/IDBLevelDBCoding.h: 33 (IDBLevelDBCoding): Expose enums for metadata types. 34 1 35 2012-05-04 Anders Carlsson <andersca@apple.com> 2 36 -
trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp
r115997 r116170 47 47 48 48 template <typename DBOrTransaction> 49 static bool getBool(DBOrTransaction* db, const Vector<char>& key, bool& foundBool) 50 { 51 Vector<char> result; 52 if (!db->get(key, result)) 53 return false; 54 55 foundBool = decodeBool(result.begin(), result.end()); 56 return true; 57 } 58 59 template <typename DBOrTransaction> 60 static bool putBool(DBOrTransaction* db, const Vector<char>& key, bool value) 61 { 62 return db->put(key, encodeBool(value)); 63 } 64 65 template <typename DBOrTransaction> 49 66 static bool getInt(DBOrTransaction* db, const Vector<char>& key, int64_t& foundInt) 50 67 { … … 331 348 p = ObjectStoreMetaDataKey::decode(p, limit, &metaDataKey); 332 349 ASSERT(p); 333 if (metaDataKey.metaDataType()) { 350 if (metaDataKey.metaDataType() != ObjectStoreMetaDataKey::kName) { 351 LOG_ERROR("Internal Indexed DB error."); 352 // Possible stale metadata, but don't fail the load. 353 it->next(); 354 continue; 355 } 356 357 int64_t objectStoreId = metaDataKey.objectStoreId(); 358 359 // FIXME: Do this by direct key lookup rather than iteration, to simplify. 360 String objectStoreName = decodeString(it->value().begin(), it->value().end()); 361 362 it->next(); 363 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::kKeyPath)) { 334 364 LOG_ERROR("Internal Indexed DB error."); 335 365 return; 336 366 } 337 338 int64_t objectStoreId = metaDataKey.objectStoreId(); 339 String objectStoreName = decodeString(it->value().begin(), it->value().end()); 367 String keyPath = decodeString(it->value().begin(), it->value().end()); 368 bool hasKeyPath = true; 340 369 341 370 it->next(); 342 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 1)) {371 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::kAutoIncrement)) { 343 372 LOG_ERROR("Internal Indexed DB error."); 344 373 return; 345 374 } 346 String keyPath = decodeString(it->value().begin(), it->value().end()); 347 bool hasKeyPath = true; 348 349 it->next(); 350 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 2)) { 375 bool autoIncrement = decodeBool(it->value().begin(), it->value().end()); 376 377 it->next(); // Is evicatble. 378 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::kEvictable)) { 351 379 LOG_ERROR("Internal Indexed DB error."); 352 380 return; 353 381 } 354 // FIXME: Add encode/decode functions for bools. 355 bool autoIncrement = *it->value().begin(); 356 357 it->next(); // Is evicatble. 358 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 3)) { 382 383 it->next(); // Last version. 384 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::kLastVersion)) { 359 385 LOG_ERROR("Internal Indexed DB error."); 360 386 return; 361 387 } 362 388 363 it->next(); // Last version.364 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 4)) {389 it->next(); // Maximum index id allocated. 390 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::kMaxIndexId)) { 365 391 LOG_ERROR("Internal Indexed DB error."); 366 392 return; 367 393 } 368 394 369 it->next(); // Maxium index id allocated.370 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 5)) {371 LOG_ERROR("Internal Indexed DB error.");372 return;373 }374 375 395 it->next(); // [optional] has key path (is not null) 376 if (checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 6)) { 377 // FIXME: Add encode/decode functions for bools. 378 hasKeyPath = *it->value().begin(); 396 if (checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::kHasKeyPath)) { 397 hasKeyPath = decodeBool(it->value().begin(), it->value().end()); 379 398 if (!hasKeyPath && !keyPath.isEmpty()) { 380 399 LOG_ERROR("Internal Indexed DB error."); … … 414 433 return false; 415 434 416 const Vector<char> nameKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0);417 const Vector<char> keyPathKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 1);418 const Vector<char> autoIncrementKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 2);419 const Vector<char> evictableKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 3);420 const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 4);421 const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 5);422 const Vector<char> hasKeyPathKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 6);435 const Vector<char> nameKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kName); 436 const Vector<char> keyPathKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kKeyPath); 437 const Vector<char> autoIncrementKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kAutoIncrement); 438 const Vector<char> evictableKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kEvictable); 439 const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kLastVersion); 440 const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kMaxIndexId); 441 const Vector<char> hasKeyPathKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kHasKeyPath); 423 442 const Vector<char> namesKey = ObjectStoreNamesKey::encode(databaseId, name); 424 443 … … 459 478 } 460 479 461 ok = put Int(m_currentTransaction.get(), hasKeyPathKey, !keyPath.isNull());480 ok = putBool(m_currentTransaction.get(), hasKeyPathKey, !keyPath.isNull()); 462 481 if (!ok) { 463 482 LOG_ERROR("Internal Indexed DB error."); … … 481 500 482 501 String objectStoreName; 483 getString(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), objectStoreName);502 getString(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kName), objectStoreName); 484 503 485 504 if (!deleteRange(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 0), ObjectStoreMetaDataKey::encodeMaxKey(databaseId, objectStoreId))) … … 537 556 static int64_t getNewVersionNumber(LevelDBTransaction* transaction, int64_t databaseId, int64_t objectStoreId) 538 557 { 539 const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 4);558 const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kLastVersion); 540 559 541 560 int64_t lastVersion = -1; … … 720 739 p = IndexMetaDataKey::decode(p, limit, &metaDataKey); 721 740 ASSERT(p); 722 741 if (metaDataKey.metaDataType() != IndexMetaDataKey::kName) { 742 LOG_ERROR("Internal Indexed DB error."); 743 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail the load. 744 it->next(); 745 continue; 746 } 747 748 // FIXME: Do this by direct key lookup rather than iteration, to simplify. 723 749 int64_t indexId = metaDataKey.indexId(); 724 ASSERT(!metaDataKey.metaDataType());725 726 750 String indexName = decodeString(it->value().begin(), it->value().end()); 727 751 728 752 it->next(); // unique flag 729 if (!checkIndexAndMetaDataKey(it.get(), stopKey, indexId, 1)) {753 if (!checkIndexAndMetaDataKey(it.get(), stopKey, indexId, IndexMetaDataKey::kUnique)) { 730 754 LOG_ERROR("Internal Indexed DB error."); 731 755 return; 732 756 } 733 // FIXME: Add encode/decode functions for bools. 734 bool indexUnique = *it->value().begin(); 757 bool indexUnique = decodeBool(it->value().begin(), it->value().end()); 735 758 736 759 it->next(); // keyPath 737 if (!checkIndexAndMetaDataKey(it.get(), stopKey, indexId, 2)) {760 if (!checkIndexAndMetaDataKey(it.get(), stopKey, indexId, IndexMetaDataKey::kKeyPath)) { 738 761 LOG_ERROR("Internal Indexed DB error."); 739 762 return; … … 743 766 it->next(); // [optional] multiEntry flag 744 767 bool indexMultiEntry = false; 745 if (checkIndexAndMetaDataKey(it.get(), stopKey, indexId, 3)) { 746 // FIXME: Add encode/decode functions for bools. 747 indexMultiEntry = *it->value().begin(); 768 if (checkIndexAndMetaDataKey(it.get(), stopKey, indexId, IndexMetaDataKey::kMultiEntry)) { 769 indexMultiEntry = decodeBool(it->value().begin(), it->value().end()); 748 770 it->next(); 749 771 } … … 760 782 { 761 783 int64_t maxIndexId = -1; 762 const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, 5);784 const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kMaxIndexId); 763 785 if (!getInt(transaction, maxIndexIdKey, maxIndexId)) 764 786 maxIndexId = kMinimumIndexId; … … 780 802 return false; 781 803 782 const Vector<char> nameKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 0);783 const Vector<char> uniqueKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 1);784 const Vector<char> keyPathKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 2);785 const Vector<char> multiEntryKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 3);804 const Vector<char> nameKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, IndexMetaDataKey::kName); 805 const Vector<char> uniqueKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, IndexMetaDataKey::kUnique); 806 const Vector<char> keyPathKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, IndexMetaDataKey::kKeyPath); 807 const Vector<char> multiEntryKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, IndexMetaDataKey::kMultiEntry); 786 808 787 809 bool ok = putString(m_currentTransaction.get(), nameKey, name); … … 791 813 } 792 814 793 ok = put Int(m_currentTransaction.get(), uniqueKey, isUnique);815 ok = putBool(m_currentTransaction.get(), uniqueKey, isUnique); 794 816 if (!ok) { 795 817 LOG_ERROR("Internal Indexed DB error."); … … 803 825 } 804 826 805 ok = put Int(m_currentTransaction.get(), multiEntryKey, isMultiEntry);827 ok = putBool(m_currentTransaction.get(), multiEntryKey, isMultiEntry); 806 828 if (!ok) { 807 829 LOG_ERROR("Internal Indexed DB error."); … … 816 838 ASSERT(m_currentTransaction); 817 839 818 const Vector<char> nameKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 0); 819 const Vector<char> uniqueKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 1); 820 const Vector<char> keyPathKey = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 2); 821 822 if (!m_currentTransaction->remove(nameKey)) { 823 LOG_ERROR("Internal Indexed DB error."); 824 return; 825 } 826 if (!m_currentTransaction->remove(uniqueKey)) { 827 LOG_ERROR("Internal Indexed DB error."); 828 return; 829 } 830 if (!m_currentTransaction->remove(keyPathKey)) { 840 const Vector<char> indexMetaDataStart = IndexMetaDataKey::encode(databaseId, objectStoreId, indexId, 0); 841 const Vector<char> indexMetaDataEnd = IndexMetaDataKey::encodeMaxKey(databaseId, objectStoreId, indexId); 842 843 if (!deleteRange(m_currentTransaction.get(), indexMetaDataStart, indexMetaDataEnd)) { 831 844 LOG_ERROR("Internal Indexed DB error."); 832 845 return; -
trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp
r116028 r116170 129 129 namespace IDBLevelDBCoding { 130 130 131 #ifndef INT64_MAX 132 #define INT64_MAX 0x7fffffffffffffffLL 133 #endif 134 #ifndef INT32_MAX 135 #define INT32_MAX 0x7fffffffL 136 #endif 137 131 138 static const unsigned char kIDBKeyNullTypeByte = 0; 132 139 static const unsigned char kIDBKeyStringTypeByte = 1; … … 151 158 static const unsigned char kIndexNamesKeyTypeByte = 201; 152 159 153 #ifndef INT64_MAX 154 #define INT64_MAX 0x7fffffffffffffffLL 155 #endif 156 #ifndef INT32_MAX 157 #define INT32_MAX 0x7fffffffL 158 #endif 159 160 static const int64_t kObjectMetaDataTypeMaximum = INT64_MAX; 161 static const unsigned char kIndexMetaDataTypeMaximum = 255; 160 162 161 163 Vector<char> encodeByte(unsigned char c) … … 174 176 { 175 177 return encodeByte(kIDBKeyMinKeyTypeByte); 178 } 179 180 Vector<char> encodeBool(bool b) 181 { 182 Vector<char> ret(1); 183 ret.append(b ? 1 : 0); 184 return ret; 185 } 186 187 bool decodeBool(const char* begin, const char* end) 188 { 189 ASSERT(begin < end); 190 return *begin; 176 191 } 177 192 … … 1002 1017 Vector<char> ObjectStoreMetaDataKey::encodeMaxKey(int64_t databaseId) 1003 1018 { 1004 return encode(databaseId, INT64_MAX, INT64_MAX);1019 return encode(databaseId, INT64_MAX, kObjectMetaDataTypeMaximum); 1005 1020 } 1006 1021 1007 1022 Vector<char> ObjectStoreMetaDataKey::encodeMaxKey(int64_t databaseId, int64_t objectStoreId) 1008 1023 { 1009 return encode(databaseId, objectStoreId, INT64_MAX);1024 return encode(databaseId, objectStoreId, kObjectMetaDataTypeMaximum); 1010 1025 } 1011 1026 … … 1077 1092 Vector<char> IndexMetaDataKey::encodeMaxKey(int64_t databaseId, int64_t objectStoreId) 1078 1093 { 1079 return encode(databaseId, objectStoreId, INT64_MAX, 255); 1094 return encode(databaseId, objectStoreId, INT64_MAX, kIndexMetaDataTypeMaximum); 1095 } 1096 1097 Vector<char> IndexMetaDataKey::encodeMaxKey(int64_t databaseId, int64_t objectStoreId, int64_t indexId) 1098 { 1099 return encode(databaseId, objectStoreId, indexId, kIndexMetaDataTypeMaximum); 1080 1100 } 1081 1101 -
trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.h
r109493 r116170 46 46 Vector<char> maxIDBKey(); 47 47 Vector<char> minIDBKey(); 48 Vector<char> encodeBool(bool); 49 bool decodeBool(const char* begin, const char* end); 48 50 Vector<char> encodeInt(int64_t); 49 51 int64_t decodeInt(const char* begin, const char* end); … … 144 146 class ObjectStoreMetaDataKey { 145 147 public: 148 enum MetaDataType { 149 kName = 0, 150 kKeyPath = 1, 151 kAutoIncrement = 2, 152 kEvictable = 3, 153 kLastVersion = 4, 154 kMaxIndexId = 5, 155 kHasKeyPath = 6 156 }; 157 146 158 ObjectStoreMetaDataKey(); 147 159 static const char* decode(const char* start, const char* limit, ObjectStoreMetaDataKey* result); … … 160 172 class IndexMetaDataKey { 161 173 public: 174 enum MetaDataType { 175 kName = 0, 176 kUnique = 1, 177 kKeyPath = 2, 178 kMultiEntry = 3 179 }; 180 162 181 IndexMetaDataKey(); 163 182 static const char* decode(const char* start, const char* limit, IndexMetaDataKey* result); 164 183 static Vector<char> encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, unsigned char metaDataType); 165 184 static Vector<char> encodeMaxKey(int64_t databaseId, int64_t objectStoreId); 185 static Vector<char> encodeMaxKey(int64_t databaseId, int64_t objectStoreId, int64_t indexId); 166 186 int compare(const IndexMetaDataKey& other); 167 187 int64_t indexId() const;
Note: See TracChangeset
for help on using the changeset viewer.