Lazy-load IndexedDB

pull/165/head
Thibaut 10 years ago
parent 9b1402cb71
commit ccf9171ccc

@ -61,7 +61,7 @@
bootOne: -> bootOne: ->
@doc = new app.models.Doc @DOC @doc = new app.models.Doc @DOC
@docs.reset [@doc] @docs.reset [@doc]
@doc.load @bootDB.bind(@), @onBootError.bind(@), readCache: true @doc.load @start.bind(@), @onBootError.bind(@), readCache: true
new app.views.Notice 'singleDoc', @doc new app.views.Notice 'singleDoc', @doc
delete @DOC delete @DOC
return return
@ -72,21 +72,17 @@
(if docs.indexOf(doc.slug) >= 0 then @docs else @disabledDocs).add(doc) (if docs.indexOf(doc.slug) >= 0 then @docs else @disabledDocs).add(doc)
@docs.sort() @docs.sort()
@disabledDocs.sort() @disabledDocs.sort()
@docs.load @bootDB.bind(@), @onBootError.bind(@), readCache: true, writeCache: true @docs.load @start.bind(@), @onBootError.bind(@), readCache: true, writeCache: true
delete @DOCS delete @DOCS
return return
bootDB: -> start: ->
for doc in @docs.all() for doc in @docs.all()
@entries.add doc.toEntry() @entries.add doc.toEntry()
@entries.add type.toEntry() for type in doc.types.all() @entries.add type.toEntry() for type in doc.types.all()
@entries.add doc.entries.all() @entries.add doc.entries.all()
@db = new app.DB() @db = new app.DB()
@db.init(@start.bind(@))
return
start: ->
@trigger 'ready' @trigger 'ready'
@router.start() @router.start()
@hideLoading() @hideLoading()

@ -4,14 +4,23 @@ class app.DB
constructor: -> constructor: ->
@useIndexedDB = @useIndexedDB() @useIndexedDB = @useIndexedDB()
init: (@_callback) -> db: (fn) ->
if @useIndexedDB return fn @_db unless @useIndexedDB and @_db is undefined
@initIndexedDB()
else if @callback isnt undefined
@callback() _callback = @callback
return @callback = =>
_callback()
fn @_db
return
return
@callback = =>
@_db ?= false
delete @callback
fn @_db
return
initIndexedDB: ->
try try
req = indexedDB.open(NAME, @indexedDBVersion()) req = indexedDB.open(NAME, @indexedDBVersion())
req.onerror = @callback req.onerror = @callback
@ -21,20 +30,12 @@ class app.DB
@callback() @callback()
return return
isEnabled: ->
!!@db
callback: =>
@_callback?()
@_callback = null
return
onOpenSuccess: (event) => onOpenSuccess: (event) =>
try try
@db = event.target.result @_db = event.target.result
@db.transaction(['docs', app.docs.all()[0].slug], 'readwrite').abort() # https://bugs.webkit.org/show_bug.cgi?id=136937 @_db.transaction(['docs', app.docs.all()[0].slug], 'readwrite').abort() # https://bugs.webkit.org/show_bug.cgi?id=136937
catch catch
@db = null @_db = false
@callback() @callback()
return return
@ -53,43 +54,61 @@ class app.DB
return return
store: (doc, data, onSuccess, onError) -> store: (doc, data, onSuccess, onError) ->
txn = @db.transaction ['docs', doc.slug], 'readwrite' @db (db) ->
txn.oncomplete = -> if txn.error then onError() else onSuccess() unless db
onError()
return
txn = db.transaction ['docs', doc.slug], 'readwrite'
txn.oncomplete = -> if txn.error then onError() else onSuccess()
store = txn.objectStore(doc.slug) store = txn.objectStore(doc.slug)
store.clear() store.clear()
store.add(content, path) for path, content of data store.add(content, path) for path, content of data
store = txn.objectStore('docs') store = txn.objectStore('docs')
store.put(doc.mtime, doc.slug) store.put(doc.mtime, doc.slug)
return
return return
unstore: (doc, onSuccess, onError) -> unstore: (doc, onSuccess, onError) ->
txn = @db.transaction ['docs', doc.slug], 'readwrite' @db (db) ->
txn.oncomplete = -> if txn.error then onError() else onSuccess() unless db
onError()
return
txn = db.transaction ['docs', doc.slug], 'readwrite'
txn.oncomplete = -> if txn.error then onError() else onSuccess()
store = txn.objectStore(doc.slug) store = txn.objectStore(doc.slug)
store.clear() store.clear()
store = txn.objectStore('docs') store = txn.objectStore('docs')
store.delete(doc.slug) store.delete(doc.slug)
return
return return
version: (doc, callback) -> version: (doc, fn) ->
txn = @db.transaction ['docs'], 'readonly' @db (db) ->
store = txn.objectStore('docs') unless db
fn(false)
return
req = store.get(doc.slug) txn = db.transaction ['docs'], 'readonly'
req.onsuccess = -> callback(!!req.result) store = txn.objectStore('docs')
req.onerror = -> callback(false)
req = store.get(doc.slug)
req.onsuccess = -> fn(!!req.result)
req.onerror = -> fn(false)
return
return return
load: (entry, onSuccess, onError) -> load: (entry, onSuccess, onError) ->
if @isEnabled() if @useIndexedDB and @_db isnt false
onError = @loadWithXHR.bind(@, entry, onSuccess, onError) onError = @loadWithXHR.bind(@, entry, onSuccess, onError)
@loadWithIDB(entry, onSuccess, onError) @loadWithIDB entry, onSuccess, onError
else else
@loadWithXHR(entry, onSuccess, onError) @loadWithXHR entry, onSuccess, onError
loadWithXHR: (entry, onSuccess, onError) -> loadWithXHR: (entry, onSuccess, onError) ->
ajax ajax
@ -99,14 +118,19 @@ class app.DB
error: onError error: onError
loadWithIDB: (entry, onSuccess, onError) -> loadWithIDB: (entry, onSuccess, onError) ->
txn = @db.transaction [entry.doc.slug], 'readonly' @db (db) ->
store = txn.objectStore(entry.doc.slug) unless db
onError()
return
txn = db.transaction [entry.doc.slug], 'readonly'
store = txn.objectStore(entry.doc.slug)
req = store.get(entry.path) req = store.get(entry.path)
req.onsuccess = -> if req.result then onSuccess(req.result) else onError() req.onsuccess = -> if req.result then onSuccess(req.result) else onError()
req.onerror = onError req.onerror = onError
txn txn
reset: -> reset: ->
try indexedDB?.deleteDatabase(NAME) catch try indexedDB?.deleteDatabase(NAME) catch

Loading…
Cancel
Save