@@ -324,6 +324,17 @@ HashMap<String, String> SQLiteStorageArea::allItems()
324324}
325325
326326Expected<void , StorageError> SQLiteStorageArea::setItem (IPC::Connection::UniqueID connection, StorageAreaImplIdentifier storageAreaImplID, String&& key, String&& value, const String& urlString)
327+ {
328+ String oldValue;
329+ if (auto valueOrError = getItem (key))
330+ oldValue = valueOrError.value ();
331+ auto settingOutcome = setItem (key, value, true );
332+ if (settingOutcome)
333+ dispatchEvents (connection, storageAreaImplID, key, oldValue, value, urlString);
334+ return settingOutcome;
335+ }
336+
337+ Expected<void , StorageError> SQLiteStorageArea::setItem (const String& key, const String& value, bool handleDatabaseCorruption)
327338{
328339 ASSERT (!isMainRunLoop ());
329340
@@ -334,9 +345,6 @@ Expected<void, StorageError> SQLiteStorageArea::setItem(IPC::Connection::UniqueI
334345 return makeUnexpected (StorageError::QuotaExceeded);
335346
336347 startTransactionIfNecessary ();
337- String oldValue;
338- if (auto valueOrError = getItem (key))
339- oldValue = valueOrError.value ();
340348
341349 auto statement = cachedStatement (StatementType::SetItem);
342350 if (!statement || statement->bindText (1 , key) || statement->bindBlob (2 , value)) {
@@ -346,12 +354,13 @@ Expected<void, StorageError> SQLiteStorageArea::setItem(IPC::Connection::UniqueI
346354
347355 const auto result = statement->step ();
348356 if (result != SQLITE_DONE) {
349- RELEASE_LOG_ERROR (Storage, " SQLiteStorageArea::setItem failed on stepping statement (%d) - %s" , m_database->lastError (), m_database->lastErrorMsg ());
350- handleDatabaseCorruptionIfNeeded (result);
351- return makeUnexpected (StorageError::Database);
357+ if (!handleDatabaseCorruption || !handleDatabaseCorruptionIfNeeded (result))
358+ return makeUnexpected (StorageError::Database);
359+ statement = cachedStatement (StatementType::SetItem);
360+ if (!statement || statement->bindText (1 , key) || statement->bindBlob (2 , value) || statement->step () != SQLITE_DONE)
361+ return makeUnexpected (StorageError::Database);
352362 }
353363
354- dispatchEvents (connection, storageAreaImplID, key, oldValue, value, urlString);
355364 updateCacheIfNeeded (key, value);
356365
357366 return { };
@@ -454,11 +463,16 @@ bool SQLiteStorageArea::handleDatabaseCorruptionIfNeeded(int databaseError)
454463 if (databaseError != SQLITE_CORRUPT && databaseError != SQLITE_NOTADB)
455464 return false ;
456465
457- m_database = nullptr ;
458- m_cache = std::nullopt ;
459- m_cacheSize = std::nullopt ;
466+ HashMap<String, Value> cache (WTFMove (*m_cache));
467+ close ();
460468 RELEASE_LOG (Storage, " SQLiteStorageArea::handleDatabaseCorruption deletes corrupted database file '%s'" , m_path.utf8 ().data ());
461469 WebCore::SQLiteFileSystem::deleteDatabaseFile (m_path);
470+
471+ // Reconstruct database based on cache.
472+ for (auto & [key, value] : cache)
473+ if (auto * valueString = std::get_if<String>(&value))
474+ setItem (key, *valueString, false );
475+
462476 return true ;
463477}
464478
0 commit comments