summaryrefslogtreecommitdiffstats
path: root/WebCore/loader/appcache/ApplicationCacheStorage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/loader/appcache/ApplicationCacheStorage.cpp')
-rw-r--r--WebCore/loader/appcache/ApplicationCacheStorage.cpp54
1 files changed, 52 insertions, 2 deletions
diff --git a/WebCore/loader/appcache/ApplicationCacheStorage.cpp b/WebCore/loader/appcache/ApplicationCacheStorage.cpp
index 791df22..1c59581 100644
--- a/WebCore/loader/appcache/ApplicationCacheStorage.cpp
+++ b/WebCore/loader/appcache/ApplicationCacheStorage.cpp
@@ -43,6 +43,44 @@ using namespace std;
namespace WebCore {
+class ResourceStorageIDJournal {
+public:
+ ~ResourceStorageIDJournal()
+ {
+ size_t size = m_records.size();
+ for (size_t i = 0; i < size; ++i)
+ m_records[i].restore();
+ }
+
+ void add(ApplicationCacheResource* resource, unsigned storageID)
+ {
+ m_records.append(Record(resource, storageID));
+ }
+
+ void commit()
+ {
+ m_records.clear();
+ }
+
+private:
+ class Record {
+ public:
+ Record() : m_resource(0), m_storageID(0) { }
+ Record(ApplicationCacheResource* resource, unsigned storageID) : m_resource(resource), m_storageID(storageID) { }
+
+ void restore()
+ {
+ m_resource->setStorageID(m_storageID);
+ }
+
+ private:
+ ApplicationCacheResource* m_resource;
+ unsigned m_storageID;
+ };
+
+ Vector<Record> m_records;
+};
+
static unsigned urlHostHash(const KURL& url)
{
unsigned hostStart = url.hostStart();
@@ -436,10 +474,11 @@ bool ApplicationCacheStorage::store(ApplicationCacheGroup* group)
return true;
}
-bool ApplicationCacheStorage::store(ApplicationCache* cache)
+bool ApplicationCacheStorage::store(ApplicationCache* cache, ResourceStorageIDJournal* storageIDJournal)
{
ASSERT(cache->storageID() == 0);
ASSERT(cache->group()->storageID() != 0);
+ ASSERT(storageIDJournal);
SQLiteStatement statement(m_database, "INSERT INTO Caches (cacheGroup) VALUES (?)");
if (statement.prepare() != SQLResultOk)
@@ -456,8 +495,13 @@ bool ApplicationCacheStorage::store(ApplicationCache* cache)
{
ApplicationCache::ResourceMap::const_iterator end = cache->end();
for (ApplicationCache::ResourceMap::const_iterator it = cache->begin(); it != end; ++it) {
+ unsigned oldStorageID = it->second->storageID();
if (!store(it->second.get(), cacheStorageID))
return false;
+
+ // Storing the resource succeeded. Log its old storageID in case
+ // it needs to be restored later.
+ storageIDJournal->add(it->second.get(), oldStorageID);
}
}
@@ -618,8 +662,13 @@ bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group)
ASSERT(!group->isObsolete());
ASSERT(!group->newestCache()->storageID());
+ // Log the storageID changes to the in-memory resource objects. The journal
+ // object will roll them back automatically in case a database operation
+ // fails and this method returns early.
+ ResourceStorageIDJournal storageIDJournal;
+
// Store the newest cache
- if (!store(group->newestCache()))
+ if (!store(group->newestCache(), &storageIDJournal))
return false;
// Update the newest cache in the group.
@@ -634,6 +683,7 @@ bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group)
if (!executeStatement(statement))
return false;
+ storageIDJournal.commit();
storeCacheTransaction.commit();
return true;
}