| @@ -25,8 +25,8 @@ class app.DB · 24 unmodified lines |
| 25 | 25 | try |
| 26 | 26 | db = event.target.result |
| 27 | 27 | unless @checkedBuggyIDB |
| 28 | | − @idbTransaction(db, stores: ['docs', app.docs.all()[0].slug], mode: 'readwrite').abort() # https://bugs.webkit.org/show_bug.cgi?id=136937 |
| 29 | 28 | @checkedBuggyIDB = true |
| 29 | + @idbTransaction(db, stores: $.makeArray(db.objectStoreNames)[0..1], mode: 'readwrite').abort() # https://bugs.webkit.org/show_bug.cgi?id=136937 |
| 30 | 30 | catch |
| 31 | 31 | try db.close() |
| 32 | 32 | @reason = 'apple' |
| @@ -124,11 +124,11 @@ class app.DB · 91 unmodified lines |
| 124 | 124 | onError(event) |
| 125 | 125 | return |
| 126 | 126 | |
| 127 | | − store = txn.objectStore(doc.slug) |
| 128 | | − store.clear() |
| 129 | | − |
| 130 | 127 | store = txn.objectStore('docs') |
| 131 | 128 | store.delete(doc.slug) |
| 129 | + |
| 130 | + store = txn.objectStore(doc.slug) |
| 131 | + store.clear() |
| 132 | 132 | return |
| 133 | 133 | return |
| 134 | 134 | |
| @@ -239,9 +239,11 @@ class app.DB · 104 unmodified lines |
| 239 | 239 | @cachedDocs = {} |
| 240 | 240 | |
| 241 | 241 | txn = @idbTransaction db, stores: ['docs'], mode: 'readonly' |
| 242 | | − store = txn.objectStore('docs') |
| 242 | + txn.oncomplete = => |
| 243 | + setTimeout(@checkForCorruptedDocs, 50) |
| 244 | + return |
| 243 | 245 | |
| 244 | | − req = store.openCursor() |
| 246 | + req = txn.objectStore('docs').openCursor() |
| 245 | 247 | req.onsuccess = (event) => |
| 246 | 248 | return unless cursor = event.target.result |
| 247 | 249 | @cachedDocs[cursor.key] = cursor.value |
| @@ -252,6 +254,41 @@ class app.DB · 4 unmodified lines |
| 252 | 254 | return |
| 253 | 255 | return |
| 254 | 256 | |
| 257 | + checkForCorruptedDocs: => |
| 258 | + @db (db) => |
| 259 | + @corruptedDocs = [] |
| 260 | + docs = (key for key, value of @cachedDocs when value) |
| 261 | + return if docs.length is 0 |
| 262 | + |
| 263 | + for slug in docs when not app.docs.findBy('slug', slug) |
| 264 | + @corruptedDocs.push(slug) |
| 265 | + |
| 266 | + for slug in @corruptedDocs |
| 267 | + $.arrayDelete(docs, slug) |
| 268 | + |
| 269 | + txn = @idbTransaction(db, stores: docs, mode: 'readonly', ignoreError: false) |
| 270 | + txn.oncomplete = => |
| 271 | + setTimeout(@deleteCorruptedDocs, 0) if @corruptedDocs.length > 0 |
| 272 | + return |
| 273 | + |
| 274 | + for doc in docs |
| 275 | + txn.objectStore(doc).get('index').onsuccess = (event) => |
| 276 | + @corruptedDocs.push(event.target.source.name) unless event.target.result |
| 277 | + return |
| 278 | + return |
| 279 | + return |
| 280 | + |
| 281 | + deleteCorruptedDocs: => |
| 282 | + @db (db) => |
| 283 | + txn = @idbTransaction(db, stores: ['docs'], mode: 'readwrite', ignoreError: false) |
| 284 | + store = txn.objectStore('docs') |
| 285 | + while doc = @corruptedDocs.pop() |
| 286 | + @cachedDocs[doc] = false |
| 287 | + store.delete(doc) |
| 288 | + return |
| 289 | + Raven.captureMessage 'corruptedDocs', extra: { docs: @corruptedDocs.join(',') } |
| 290 | + return |
| 291 | + |
| 255 | 292 | shouldLoadWithIDB: (entry) -> |
| 256 | 293 | @useIndexedDB and (not @cachedDocs or @cachedDocs[entry.doc.slug]) |
| 257 | 294 | |